digitalmars.D - ctfeonly
- Nicholas Wilson (8/8) Dec 06 2017 I'd like to add an attribute to indicate that the annotated
- H. S. Teoh (10/19) Dec 06 2017 I'd like to have this too. Some of my template-heavy code use a good
- ketmar (6/23) Dec 06 2017 this is a hack for something that really should be done in linker,
- Nicholas Wilson (9/34) Dec 06 2017 Not all of the generated code goes through a linker ;)
- ketmar (12/16) Dec 06 2017 this is solvable without any additional flags, tho: compiler should just...
- ketmar (7/13) Dec 06 2017 p.s.: actually, dmd already creates .a files suitable for smartlinking
- Johannes Pfau (45/62) Dec 07 2017 AFAIK there's a design flaw in D which prevents a compiler from
- lobo (9/18) Dec 06 2017 Shouldn't the linker do this already?
- Jonathan M Davis (27/44) Dec 06 2017 As I understand it, if you're statically linking it should, but it can't
- Nicholas Wilson (7/34) Dec 06 2017 Unfortunately I don't have a linker to do that for me with
- meppl (8/12) Dec 06 2017 llvm has "Aggressive Dead Code Elimination"- and "Dead Code
- Jonathan M Davis (11/46) Dec 06 2017 It may be that an attribute is required in at least some cases, but it s...
- Johannes Pfau (8/12) Dec 07 2017 You probably never call isInputRange at runtime, so the code is likely
- Iain Buclaw (11/26) Dec 07 2017 It should be possible to add heuristics for this (mark a function as
- Mike Franklin (26/29) Dec 06 2017 I've thought about this in the past, but never really pursued it
- Jonathan M Davis (7/11) Dec 06 2017 The simplest way to do that is to write a unit test that uses a static
- bauss (6/9) Dec 06 2017 On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis
- E.S. Quinn (3/13) Dec 06 2017 If all you need is a runtime error, you can already put
- Mike Franklin (3/5) Dec 06 2017 For me, a runtime error is exactly what I want to avoid.
- bauss (3/17) Dec 08 2017 It's to avoid having a run-time error, so something that would
- Mike Franklin (6/11) Dec 06 2017 Not bad, but that is swaying into the cumbersome category. If
- Jonathan M Davis (14/24) Dec 07 2017 In the vast majority of cases, when a function is used for CTFE, it's al...
- Johannes Pfau (9/16) Dec 07 2017 Not only string mixins. When programming for microcontrollers you want
- Walter Bright (3/12) Dec 07 2017 More and more attributes to do essentially trivial things is cumbersomen...
- Johannes Pfau (6/21) Dec 07 2017 I think this is more of an optimization UDA than a standard attribute.
- Stefan Koch (5/14) Dec 06 2017 Hi Nicholas,
- Walter Bright (3/8) Dec 07 2017 Put these functions into a separate import. Then import the file and use...
- Nicholas Wilson (2/12) Dec 07 2017 Doesn't work for templates.
- Walter Bright (3/4) Dec 07 2017 I don't know how your code is organized, but if the template is instanti...
- Nicholas Wilson (19/24) Dec 07 2017 As a trivial example:
- Walter Bright (16/47) Dec 07 2017 bar.d:
- Nicholas Wilson (6/21) Dec 07 2017 That requires that I know what instantiations I will have a head
- Manu (5/14) Dec 07 2017 Misuse of the API; ie, a runtime call, will result in an unsuspecting us...
- Walter Bright (4/7) Dec 07 2017 I think Nicholas is talking about functions for which code cannot be gen...
- Manu (10/19) Dec 07 2017 Right, but that's what I'm saying; using your solution of putting a
- Walter Bright (3/8) Dec 07 2017 That's exactly what happens if you put a declaration in a .h file, call ...
- Manu (3/13) Dec 08 2017 Nicholas wants a *compile* error, not a link error.
- David Nadlinger (5/6) Dec 08 2017 I don't think this is necessarily implied from the original post.
- Manu (9/32) Dec 07 2017 I tried this, and was surprised it didn't work:
- Nicholas Wilson (12/20) Dec 07 2017 I think that's because __ctfe, despite being magic, is actually a
- Manu (5/27) Dec 08 2017 Oh, sorry, I forgot key detail! (parens)
- Walter Bright (6/13) Dec 07 2017 The error is:
-
ketmar
(2/14)
Dec 07 2017
still, why `__ctfe` was designed as variable, and not as `enum ctfe =
- ketmar (6/8) Dec 07 2017 p.s.: i see only one reason for this rationale: to explicitly prevent
- ketmar (7/9) Dec 07 2017 ah, sorry, i remembered. that was stupid question.
- H. S. Teoh (6/7) Dec 08 2017 https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
- Manu (3/17) Dec 08 2017 Sorry, in my mind, it was meant to be a template function...
- Mike Franklin (52/60) Dec 07 2017 Interestingly, if you put `__ctfe` in a function it does seem to
- ketmar (4/6) Dec 07 2017 string s = onlyCompileTime();
- Mike Franklin (2/4) Dec 07 2017 damnit!
- =?UTF-8?B?TWljaGHFgg==?= (7/16) Dec 07 2017 I once tried to use dmd's -vgc option but it is not so useful
- Jonathan M Davis (10/42) Dec 07 2017 In spite of the fact that CTFE is done at compile time, __ctfe is a runt...
- H. S. Teoh (8/17) Dec 07 2017 [...]
- Paolo Invernizzi (5/21) Dec 08 2017 Woaaa... amazing job, Teoh!
- H. S. Teoh (11/36) Dec 08 2017 [...]
- John Colvin (4/13) Dec 08 2017 How would such a thing interact with __traits(compiles, ...) and
- Nicholas Wilson (17/31) Dec 08 2017 VERY good question, I'm not sure.
- Stefan Koch (6/29) Dec 08 2017 You might want to wait until Dconf 2018 before you start
- Joakim (6/15) Dec 08 2017 This doesn't fulfill everything you're looking for, ie no
I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?
Dec 06 2017
On Thu, Dec 07, 2017 at 01:21:11AM +0000, Nicholas Wilson via Digitalmars-d wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?I'd like to have this too. Some of my template-heavy code use a good number of CTFE-only functions that are only called at compile-time. Since they are nested inside the template, they do quickly add up to a lot of dead code in the executable. Having a ctfeonly annotation that tells the compiler not to codegen the (many instantiations of the) function would be greatly welcomed. T -- Let's eat some disquits while we format the biskettes.
Dec 06 2017
H. S. Teoh wrote:On Thu, Dec 07, 2017 at 01:21:11AM +0000, Nicholas Wilson via Digitalmars-d wrote:this is a hack for something that really should be done in linker, automatically. please, people, let's not turn D into C++! ;-) i mean: this has a short-time benefits, but makes the language more complex, less clear, and completely destroys any incentive to make smartlinking work as intended in case it is broken.I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?I'd like to have this too. Some of my template-heavy code use a good number of CTFE-only functions that are only called at compile-time. Since they are nested inside the template, they do quickly add up to a lot of dead code in the executable. Having a ctfeonly annotation that tells the compiler not to codegen the (many instantiations of the) function would be greatly welcomed. T
Dec 06 2017
On Thursday, 7 December 2017 at 02:33:49 UTC, ketmar wrote:H. S. Teoh wrote:Not all of the generated code goes through a linker ;) For dcompute strings aren't even supported yet! Let alone concatenation. Also not generating the code in the first place means less I/O for the compiler and less work for the linker. I definitely don't want D to become C++. What is smartlinking? This is intended for stuff like code that generates strings for mixins.On Thu, Dec 07, 2017 at 01:21:11AM +0000, Nicholas Wilson via Digitalmars-d wrote:this is a hack for something that really should be done in linker, automatically. please, people, let's not turn D into C++! ;-) i mean: this has a short-time benefits, but makes the language more complex, less clear, and completely destroys any incentive to make smartlinking work as intended in case it is broken.[...]I'd like to have this too. Some of my template-heavy code use a good number of CTFE-only functions that are only called at compile-time. Since they are nested inside the template, they do quickly add up to a lot of dead code in the executable. Having a ctfeonly annotation that tells the compiler not to codegen the (many instantiations of the) function would be greatly welcomed. T
Dec 06 2017
Nicholas Wilson wrote:Also not generating the code in the first place means less I/O for the compiler and less work for the linker.this is solvable without any additional flags, tho: compiler should just skip codegen phase for any function that is not referenced by another compiled function (except for library case).I definitely don't want D to become C++. What is smartlinking?any decent linker simply drops anything that is not reveferenced. i.e. any function that is not referenced from another function that is definitely included in the binary, will be skipped. as linker knows program entry point, it is able to build reference tree, and do "smart" linking instead of just putting everything into resulting binary.This is intended for stuff like code that generates strings for mixins.as i said, this is something compiler can do automatically, without user's help. we already have too much attributes, i believe, adding even more won't do any good.
Dec 06 2017
ketmar wrote:Nicholas Wilson wrote:p.s.: actually, dmd already creates .a files suitable for smartlinking (otherwise any binary would include the whole libphobos2.a ;-). but for "dmd mycode.d" dmd doesn't do this ('cause it is quite compilcated for non-library case). the whole issue prolly can be solved by "generate smart object files for linking" flag (which will create .a files for everything, so linker can do it's smart work).Also not generating the code in the first place means less I/O for the compiler and less work for the linker.this is solvable without any additional flags, tho: compiler should just skip codegen phase for any function that is not referenced by another compiled function (except for library case).
Dec 06 2017
Am Thu, 7 Dec 2017 05:55:54 +0200 schrieb ketmar <ketmar ketmar.no-ip.org>:ketmar wrote:AFAIK there's a design flaw in D which prevents a compiler from doing any such operations without additional user input: Currently you can write code like this: ------------------------------------------------------------------- module mod; private int thisIsNeverUsed() { return 42; } private int thisIsUsed(int a) { return 42 + a; } int someTemplate(T)(T t) { return t.thisIsUsed(); } ------------------------------------------------------------------- Whether thisIsUsed and thisIsNeverUsed actually have to appear in the object file depends on how someTemplate is instantiated. Generally, when compiling module mod you can never know whether thisIsUsed or thisIsNeverUsed are actually required. You can not evaluate the someTemplate template without specifying a concrete type for T. This means neither the compiler nor the linker can remove seemingly unused, private functions. For GDC this means we simply mark all functions as TREE_PUBLIC in the GCC backend. Note that this is also an issue for exporting templates from DLLs on windows. I think the DLL DIP which requires to mark private functions as 'export' if they are used outside outside of the module (even via templates) will fix this problem and allow for some nice optimizations. Until then, smart linking isn't really possible. BTW: The private/export combination probably still wouldn't solve all problems: Maybe you want to mark the whole module as nogc. nogc checking is done in semantic phase, so it will still error about GC usage in functions which later turn out to be only used in CTFE. Detecting this in the linker or compiler backend is too late. So we'd have to detect unexported, unused private functions in semantic. I'm not sure if this is feasible or whether a simple ctfeonly UDA isn't much simpler to implement. Additionally ctfeonly documents intended usage and allows for nice error messages when using a function at runtime. Relying on the linker to remove private, unexported functions can break easily. -- JohannesNicholas Wilson wrote:p.s.: actually, dmd already creates .a files suitable for smartlinking (otherwise any binary would include the whole libphobos2.a ;-). but for "dmd mycode.d" dmd doesn't do this ('cause it is quite compilcated for non-library case). the whole issue prolly can be solved by "generate smart object files for linking" flag (which will create .a files for everything, so linker can do it's smart work).Also not generating the code in the first place means less I/O for the compiler and less work for the linker.this is solvable without any additional flags, tho: compiler should just skip codegen phase for any function that is not referenced by another compiled function (except for library case).
Dec 07 2017
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?Shouldn't the linker do this already? Once the compiler has CTFE'd the function any call in the code should be replaced with the function evaluation. The linker should then drop the code out of the binary because it really is dead code. bye, lobo
Dec 06 2017
On Thursday, December 07, 2017 02:09:56 lobo via Digitalmars-d wrote:On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:As I understand it, if you're statically linking it should, but it can't with dynamic linking - at least not right now. With the export improvements that Martin Nowak and Benjamin Thaut want to do (where IIUC, export would then be required for anything in a shared library to be accessible outside it), then it would be possible, but right now, everything gets exported (at least on all systems other than Windows), so none of it can be stripped out as unused, since the linker doesn't know what's actually going to be used. Executables should be in the same boat as static libraries though. Also, I think that in some cases, stuff like ModuleInfo ends up referring to stuff and keeping it around even though it isn't necessarily really used, but I'm not sure. Folks have talked about all kinds of template code and stuff being kept around in binaries even though it was only used at compile time (e.g. stuff like isInputRange), but I don't know how much that's actually true. Personally, I don't care much about binary sizes. I certainly agree that having unused symbols stripped out where possible is a good thing, but AFAIK, it doesn't really matter for most of the stuff I do, and having a binary be 5MiB instead of 1MiB doesn't matter much to me, much as I agree that having the binary smaller is good. It just isn't usually enough disk space or memory to matter much in practice. Clearly, some people care quite a bit about that sort of thing, but I don't know how much it actually matters in practice unless you're doing something with embedded systems. Regardless, needing something like an attribute to tell the compiler to strip stuff out of the binary seems like a hack to me. It may actually be necessary in some cases, but it just feels like it should be unnecessary. - Jonathan M DavisI'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?Shouldn't the linker do this already? Once the compiler has CTFE'd the function any call in the code should be replaced with the function evaluation. The linker should then drop the code out of the binary because it really is dead code.
Dec 06 2017
On Thursday, 7 December 2017 at 03:18:57 UTC, Jonathan M Davis wrote:On Thursday, December 07, 2017 02:09:56 lobo via Digitalmars-d wrote:Unfortunately I don't have a linker to do that for me with DCompute.On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?Shouldn't the linker do this already? Once the compiler has CTFE'd the function any call in the code should be replaced with the function evaluation. The linker should then drop the code out of the binary because it really is dead code.Regardless, needing something like an attribute to tell the compiler to strip stuff out of the binary seems like a hack to me. It may actually be necessary in some cases, but it just feels like it should be unnecessary.Do you have any other ideas about how to achieve this other than an attribute? Having an attribute seems the most simple and straightforward.
Dec 06 2017
On Thursday, 7 December 2017 at 03:43:42 UTC, Nicholas Wilson wrote:... Do you have any other ideas about how to achieve this other than an attribute? Having an attribute seems the most simple and straightforward.llvm has "Aggressive Dead Code Elimination"- and "Dead Code Elimination"-switches, who I find interesting. https://llvm.org/docs/Passes.html#transform-passes I remember once I actually stripped off kinda 99% of a statically linked phobos-library with that and I got a small executable who was still working
Dec 06 2017
On Thursday, December 07, 2017 03:43:42 Nicholas Wilson via Digitalmars-d wrote:On Thursday, 7 December 2017 at 03:18:57 UTC, Jonathan M Davis wrote:It may be that an attribute is required in at least some cases, but it seems like it shouldn't be and that if the compiler and/or linker isn't smart enough to strip out stuff that's only used at compile time, then it should be fixed to be smart enough. However, too often, there's some detail that's not obvious that makes it so that things can't work they way that it seems like they should. And of course, I have no clue how whatever you're doing works if you're not using a linker with dcompute, so I don't know how it differs from normal. I've never done anything with GPU programming. - Jonathan M DavisOn Thursday, December 07, 2017 02:09:56 lobo via Digitalmars-d wrote:Unfortunately I don't have a linker to do that for me with DCompute.On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?Shouldn't the linker do this already? Once the compiler has CTFE'd the function any call in the code should be replaced with the function evaluation. The linker should then drop the code out of the binary because it really is dead code.Regardless, needing something like an attribute to tell the compiler to strip stuff out of the binary seems like a hack to me. It may actually be necessary in some cases, but it just feels like it should be unnecessary.Do you have any other ideas about how to achieve this other than an attribute? Having an attribute seems the most simple and straightforward.
Dec 06 2017
Am Wed, 06 Dec 2017 20:18:57 -0700 schrieb Jonathan M Davis <newsgroup.d jmdavisprog.com>:Folks have talked about all kinds of template code and stuff being kept around in binaries even though it was only used at compile time (e.g. stuff like isInputRange), but I don't know how much that's actually true.You probably never call isInputRange at runtime, so the code is likely stripped. However, TypeInfo of structs used only at CTFE is still generated and not stripped. I remember we once had this problem with gcc.attribute, a module which shouldn't generate any code but generated useless TypeInfo. -- Johannes
Dec 07 2017
On 7 December 2017 at 03:09, lobo via Digitalmars-d <digitalmars-d puremagic.com> wrote:On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:It should be possible to add heuristics for this (mark a function as being instantiated and only used at compile-time). It just doesn't exist yet. As for normal functions, regardless of protection, they will always be compiled as a function visible outside the CU. You're either going to rely on LTO support in the compiler, kindly request that DIP45 be given another thought, or write a new DIP that considers another way to control symbol visibility. But I wouldn't hold my breath on anything happening soon.I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?Shouldn't the linker do this already? Once the compiler has CTFE'd the function any call in the code should be replaced with the function evaluation. The linker should then drop the code out of the binary because it really is dead code.
Dec 07 2017
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?I've thought about this in the past, but never really pursued it much to see if there are already existing facilities in the language to accomplish what I want. I want to enforce that a method is only used at compile time. That is I want either the compiler or the linker to throw an error if I've accidentally used a function at runtime when I only intended it to be used at compile-time. Also, I want the compiler to let me know if my intended-for-compile-time-only function cannot be used at compile-time because I mistakenly made it dependent on something that is only available at runtime. That being said, I want D's features to carry their weight. I would first like to prove that facilities don't already exist or that existing facilities are too cumbersome to accomplish said goal before adding such a feature. Also, my primary motivation for using D is so I can program resource-constrained microcontrollers in a more fun and convenient language than C/C++. I've definitely encountered code-size problems in D, but they were mostly due to the compiler's unnecessary coupling to the runtime, and the way the compiler generated code as the linker couldn't prove that the code was dead (Exhibit A: https://issues.dlang.org/show_bug.cgi?id=14758). I don't yet see how ctfeonly would help with that. Mike
Dec 06 2017
On Thursday, December 07, 2017 03:59:09 Mike Franklin via Digitalmars-d wrote:Also, I want the compiler to let me know if my intended-for-compile-time-only function cannot be used at compile-time because I mistakenly made it dependent on something that is only available at runtime.The simplest way to do that is to write a unit test that uses a static assertion. As I understand it, with the way CTFE works, it pretty much can't know whether a function can be called at compile time until it tries, but a unit test can catch it if the function no longer works at compile time. - Jonathan M Davis
Dec 06 2017
On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote: As I understand it, with the way CTFE works,it pretty much can't know whether a function can be called at compile time until it tries - Jonathan M DavisI think that's the point of the attribute. You tell the compiler that this function can only be called at compile-time and any attempt to call it during run-time would be an error.
Dec 06 2017
On Thursday, 7 December 2017 at 05:53:06 UTC, bauss wrote:On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote: As I understand it, with the way CTFE works,If all you need is a runtime error, you can already put assert(__ctfe); in your function.it pretty much can't know whether a function can be called at compile time until it tries - Jonathan M DavisI think that's the point of the attribute. You tell the compiler that this function can only be called at compile-time and any attempt to call it during run-time would be an error.
Dec 06 2017
On Thursday, 7 December 2017 at 06:33:42 UTC, E.S. Quinn wrote:If all you need is a runtime error, you can already put assert(__ctfe); in your function.For me, a runtime error is exactly what I want to avoid. Mike
Dec 06 2017
On Thursday, 7 December 2017 at 06:33:42 UTC, E.S. Quinn wrote:On Thursday, 7 December 2017 at 05:53:06 UTC, bauss wrote:It's to avoid having a run-time error, so something that would produce a run-time call gives a compile-time error.On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote: As I understand it, with the way CTFE works,If all you need is a runtime error, you can already put assert(__ctfe); in your function.it pretty much can't know whether a function can be called at compile time until it tries - Jonathan M DavisI think that's the point of the attribute. You tell the compiler that this function can only be called at compile-time and any attempt to call it during run-time would be an error.
Dec 08 2017
On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote:The simplest way to do that is to write a unit test that uses a static assertion. As I understand it, with the way CTFE works, it pretty much can't know whether a function can be called at compile time until it tries, but a unit test can catch it if the function no longer works at compile time.Not bad, but that is swaying into the cumbersome category. If that's the best we can do, a ctfeonly attribute starts looking pretty good. Mike
Dec 06 2017
On Thursday, December 07, 2017 07:41:18 Mike Franklin via Digitalmars-d wrote:On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote:In the vast majority of cases, when a function is used for CTFE, it's also used during runtime. So, in most cases, you want to ensure that a function works both with CTFE and without, and in those cases something like ctfeonly wouldn't make any sense. In my experience, pretty much the only time that something like ctfeonly would make any sense would be with a function for generating a string mixin. I'm sure that there are folks who have other uses for functions that would only be used during CTFE, but really, CTFE is designed with the idea that functions would be useable both at runtime and at compile time, and most functions that are used during CTFE were not designed just for CTFE. Certainly, trying to test or enforce that a function is only used at compile time is not going to be the common case. - Jonathan M DavisThe simplest way to do that is to write a unit test that uses a static assertion. As I understand it, with the way CTFE works, it pretty much can't know whether a function can be called at compile time until it tries, but a unit test can catch it if the function no longer works at compile time.Not bad, but that is swaying into the cumbersome category. If that's the best we can do, a ctfeonly attribute starts looking pretty good.
Dec 07 2017
Am Thu, 07 Dec 2017 01:32:35 -0700 schrieb Jonathan M Davis <newsgroup.d jmdavisprog.com>:In the vast majority of cases, when a function is used for CTFE, it's also used during runtime. So, in most cases, you want to ensure that a function works both with CTFE and without, and in those cases something like ctfeonly wouldn't make any sense. In my experience, pretty much the only time that something like ctfeonly would make any sense would be with a function for generating a string mixin.Not only string mixins. When programming for microcontrollers you want to do as much in CTFE as possible, as space for executable code is severely limited. So you may for example want to use CTFE to generate some lookup tables and similar stuff. Basically the whole 'initialize a variable / constant using CTFE' idiom benefits a lot from such an attribute. -- Johannes
Dec 07 2017
On 12/6/2017 11:41 PM, Mike Franklin wrote:On Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote:More and more attributes to do essentially trivial things is cumbersomeness all on its own.The simplest way to do that is to write a unit test that uses a static assertion. As I understand it, with the way CTFE works, it pretty much can't know whether a function can be called at compile time until it tries, but a unit test can catch it if the function no longer works at compile time.Not bad, but that is swaying into the cumbersome category. If that's the best we can do, a ctfeonly attribute starts looking pretty good.
Dec 07 2017
Am Thu, 7 Dec 2017 13:38:54 -0800 schrieb Walter Bright <newshound2 digitalmars.com>:On 12/6/2017 11:41 PM, Mike Franklin wrote:I think this is more of an optimization UDA than a standard attribute. So it's similar to all the noinline, forceinline, weak, section etc. attributes: https://wiki.dlang.org/Using_GDC#Attributes -- JohannesOn Thursday, 7 December 2017 at 04:45:15 UTC, Jonathan M Davis wrote:=20=20 More and more attributes to do essentially trivial things is cumbersomeness all on its own.The simplest way to do that is to write a unit test that uses a static assertion. As I understand it, with the way CTFE works, it pretty much can't know whether a function can be called at compile time until it tries, but a unit test can catch it if the function no longer works at compile time. =20=20 Not bad, but that is swaying into the cumbersome category.=C2=A0 If that's the best we can do, a ctfeonly attribute starts looking pretty good. =20
Dec 07 2017
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?Hi Nicholas, I am going to add a feature which will help you in this case; As part of the work I am doing to make templates faster.
Dec 06 2017
On 12/6/2017 5:21 PM, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function.Put these functions into a separate import. Then import the file and use the functions at compile time. They will not have code generated for them.
Dec 07 2017
On Thursday, 7 December 2017 at 09:34:51 UTC, Walter Bright wrote:On 12/6/2017 5:21 PM, Nicholas Wilson wrote:Doesn't work for templates.I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function.Put these functions into a separate import. Then import the file and use the functions at compile time. They will not have code generated for them.
Dec 07 2017
On 12/7/2017 2:07 AM, Nicholas Wilson wrote:Doesn't work for templates.I don't know how your code is organized, but if the template is instantiated in another file, it won't have code generated for it either.
Dec 07 2017
On Thursday, 7 December 2017 at 21:32:24 UTC, Walter Bright wrote:On 12/7/2017 2:07 AM, Nicholas Wilson wrote:As a trivial example: bar.d: module bar; string generatesMixin(T)() { return T.stringof ~ " foo;"; } a.d: compute(CompileFor.deviceOnly) module a; int baz() { mixin(generatesMixin!int()); return foo; } a's symbol table contains `baz` and `generatesMixin!int`. generateMixin deals with strings which are not allowed (global variables are unsupported). This would fail compilation. If `generatesMixin` were to be marked ` ctfeonly`, this would pass.Doesn't work for templates.I don't know how your code is organized, but if the template is instantiated in another file, it won't have code generated for it either.
Dec 07 2017
On 12/7/2017 3:41 PM, Nicholas Wilson wrote:On Thursday, 7 December 2017 at 21:32:24 UTC, Walter Bright wrote:bar.d: module bar; string generateString(T)() { return T.stringof ~ " foo;"; } enum s = generateString!int(); a.d: compute(CompileFor.deviceOnly) module a; int baz() { import bar; bar.s; return foo; }On 12/7/2017 2:07 AM, Nicholas Wilson wrote:As a trivial example: bar.d: module bar; string generatesMixin(T)() { return T.stringof ~ " foo;"; } a.d: compute(CompileFor.deviceOnly) module a; int baz() { mixin(generatesMixin!int()); return foo; } a's symbol table contains `baz` and `generatesMixin!int`. generateMixin deals with strings which are not allowed (global variables are unsupported). This would fail compilation. If `generatesMixin` were to be marked ` ctfeonly`, this would pass.Doesn't work for templates.I don't know how your code is organized, but if the template is instantiated in another file, it won't have code generated for it either.
Dec 07 2017
On Friday, 8 December 2017 at 03:41:05 UTC, Walter Bright wrote:bar.d: module bar; string generateString(T)() { return T.stringof ~ " foo;"; } enum s = generateString!int(); a.d: compute(CompileFor.deviceOnly) module a; int baz() { import bar; bar.s; return foo; }That requires that I know what instantiations I will have a head of time or I have to maintain a "header file" of named instantiations. Both of which I consider subpar solutions. Also while it may not bloat the GPU binary it will still bloat the host binary.
Dec 07 2017
On 7 December 2017 at 01:34, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 12/6/2017 5:21 PM, Nicholas Wilson wrote:Misuse of the API; ie, a runtime call, will result in an unsuspecting user getting a surprising link error, rather than a nice compile-time error explaining what they did wrong...I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function.Put these functions into a separate import. Then import the file and use the functions at compile time. They will not have code generated for them.
Dec 07 2017
On 12/7/2017 11:41 AM, Manu wrote:Misuse of the API; ie, a runtime call, will result in an unsuspecting user getting a surprising link error, rather than a nice compile-time error explaining what they did wrong...I think Nicholas is talking about functions for which code cannot be generated. In any case, in C/C++/D if you call functions in .h files (or imports) that are not linked in, you'll get a linker error.
Dec 07 2017
On 7 December 2017 at 13:35, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 12/7/2017 11:41 AM, Manu wrote:Right, but that's what I'm saying; using your solution of putting a function in a module that's not compiled to inhibit code generation won't inhibit people from *attempting* to making runtime calls (and getting link errors)... whereas a compile error trying to runtime-call a function that shouldn't be runtime-called might be more desirable. I'm not actually registering support for ctfeonly, just that I think it's a pattern that I have wanted and should be supported in some way, and a compile-time error would be nicer than a link error.Misuse of the API; ie, a runtime call, will result in an unsuspecting user getting a surprising link error, rather than a nice compile-time error explaining what they did wrong...I think Nicholas is talking about functions for which code cannot be generated. In any case, in C/C++/D if you call functions in .h files (or imports) that are not linked in, you'll get a linker error.
Dec 07 2017
On 12/7/2017 5:20 PM, Manu wrote:Right, but that's what I'm saying; using your solution of putting a function in a module that's not compiled to inhibit code generation won't inhibit people from *attempting* to making runtime calls (and getting link errors)... whereas a compile error trying to runtime-call a function that shouldn't be runtime-called might be more desirable.That's exactly what happens if you put a declaration in a .h file, call the function, and don't link in the implementation. I don't see the difference.
Dec 07 2017
On 7 December 2017 at 19:43, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 12/7/2017 5:20 PM, Manu wrote:Nicholas wants a *compile* error, not a link error.Right, but that's what I'm saying; using your solution of putting a function in a module that's not compiled to inhibit code generation won't inhibit people from *attempting* to making runtime calls (and getting link errors)... whereas a compile error trying to runtime-call a function that shouldn't be runtime-called might be more desirable.That's exactly what happens if you put a declaration in a .h file, call the function, and don't link in the implementation. I don't see the difference.
Dec 08 2017
On Friday, 8 December 2017 at 18:59:00 UTC, Manu wrote:Nicholas wants a *compile* error, not a link error.I don't think this is necessarily implied from the original post. Certainly, a linker error would just work fine for the original use case (avoiding unsupported codegen on compute targets). -David
Dec 08 2017
On 7 December 2017 at 17:20, Manu <turkeyman gmail.com> wrote:On 7 December 2017 at 13:35, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; } This would probably solve the problem in a satisfying way without an attribute?On 12/7/2017 11:41 AM, Manu wrote:Right, but that's what I'm saying; using your solution of putting a function in a module that's not compiled to inhibit code generation won't inhibit people from *attempting* to making runtime calls (and getting link errors)... whereas a compile error trying to runtime-call a function that shouldn't be runtime-called might be more desirable. I'm not actually registering support for ctfeonly, just that I think it's a pattern that I have wanted and should be supported in some way, and a compile-time error would be nicer than a link error.Misuse of the API; ie, a runtime call, will result in an unsuspecting user getting a surprising link error, rather than a nice compile-time error explaining what they did wrong...I think Nicholas is talking about functions for which code cannot be generated. In any case, in C/C++/D if you call functions in .h files (or imports) that are not linked in, you'll get a linker error.
Dec 07 2017
On Friday, 8 December 2017 at 01:30:13 UTC, Manu wrote:I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; } This would probably solve the problem in a satisfying way without an attribute?I think that's because __ctfe, despite being magic, is actually a regular variable. While this looks not too inelegant for a user perspective, I dont know how to handle this from a compiler perspective: filtering by attribute is as easy as "does this function have a UDA ctfeonly? If so, don't code generate it. Generating errors at codegen time is also trivial: when generating a call check to see if the callee is ctfeonly, if it is give an error message I don't know how to do that for a `static assert(__ctfe);`. That would require changes and semantic analysis in the front end which I am much less familiar with.
Dec 07 2017
On 7 December 2017 at 17:45, Nicholas Wilson via Digitalmars-d < digitalmars-d puremagic.com> wrote:On Friday, 8 December 2017 at 01:30:13 UTC, Manu wrote:Oh, sorry, I forgot key detail! (parens) int ctfeOnly()(int x) ... (in my mind, it was a template function, which means it would instantiate for the ctfe call separately to regular calls(?))I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; } This would probably solve the problem in a satisfying way without an attribute?I think that's because __ctfe, despite being magic, is actually a regular variable. While this looks not too inelegant for a user perspective, I dont know how to handle this from a compiler perspective: filtering by attribute is as easy as "does this function have a UDA ctfeonly? If so, don't code generate it. Generating errors at codegen time is also trivial: when generating a call check to see if the callee is ctfeonly, if it is give an error message I don't know how to do that for a `static assert(__ctfe);`. That would require changes and semantic analysis in the front end which I am much less familiar with.
Dec 08 2017
On 12/7/2017 5:30 PM, Manu wrote:I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; }The error is: test2.d(3): Error: variable __ctfe cannot be read at compile time test2.d(3): while evaluating: static assert(__ctfe) because static asserts are evaluated when the function is semantically analyzed, not when it is executed.
Dec 07 2017
Walter Bright wrote:On 12/7/2017 5:30 PM, Manu wrote:still, why `__ctfe` was designed as variable, and not as `enum ctfe = <bool>;`?I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; }The error is: test2.d(3): Error: variable __ctfe cannot be read at compile time test2.d(3): while evaluating: static assert(__ctfe) because static asserts are evaluated when the function is semantically analyzed, not when it is executed.
Dec 07 2017
ketmar wrote:still, why `__ctfe` was designed as variable, and not as `enum ctfe = <bool>;`?p.s.: i see only one reason for this rationale: to explicitly prevent people using `static if` to separate CTFE and non-CTFE code (that is, to lessen the chance than function heaves differently in runtime and in compile-time). but that doesn't work, as `if (__ctfe)` allows two completely different code pathes anyway.
Dec 07 2017
ketmar wrote:still, why `__ctfe` was designed as variable, and not as `enum ctfe = <bool>;`?ah, sorry, i remembered. that was stupid question. the rationale is: `static if` and `static assert` are processed *before* CTFE phase. i.e. CTFE interpreter never sees them, and cannot do the choice. and on semantic analysis phase it is not known yet if the code is for CTFE or not. that is, to allow `static assert(__ctfe)` to work, the whole semantic phase must be redesigned.
Dec 07 2017
On Fri, Dec 08, 2017 at 05:53:37AM +0200, ketmar via Digitalmars-d wrote: [...]still, why `__ctfe` was designed as variable, and not as `enum ctfe = <bool>;`?https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T -- I think the conspiracy theorists are out to get us...
Dec 08 2017
On 7 December 2017 at 19:49, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:On 12/7/2017 5:30 PM, Manu wrote:Sorry, in my mind, it was meant to be a template function...I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; }The error is: test2.d(3): Error: variable __ctfe cannot be read at compile time test2.d(3): while evaluating: static assert(__ctfe) because static asserts are evaluated when the function is semantically analyzed, not when it is executed.
Dec 08 2017
On Friday, 8 December 2017 at 01:30:13 UTC, Manu wrote:I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; } This would probably solve the problem in a satisfying way without an attribute?Interestingly, if you put `__ctfe` in a function it does seem to work (unless I'm missing something). Check this out. import std.stdio; bool isRunTime() { return !__ctfe; } bool isCompileTime() { static if (!isRunTime()) return __ctfe; else return false; } string onlyCompileTime() { static assert(isCompileTime(), "This function can only be executed at compile time"); assert(isCompileTime(), "This function can only be execute at compile time"); return "onlyCompileTime"; } string onlyRunTime() { // This assert will actually throw an error at compile-time, // if an attempt is made to execute it at compile time. assert(isRunTime(), "This function can only be executed at run time"); return "onlyRunTime"; } void main(string[] args) { static assert(isCompileTime()); static assert (!isRunTime()); assert(!isCompileTime()); assert(isRunTime()); static assert(onlyCompileTime() == "onlyCompileTime"); // Compile-time Error: Good! //static assert(onlyRunTime() == "onlyRunTime"); assert(onlyRunTime() == "onlyRunTime"); // Compile-time Error: Good! // pragma(msg, onlyRunTime()); // I couldn't figure out how to force `onlyCompileTime` to // execute at runtime. That's probably a good thing. } https://run.dlang.io/is/64fRRX I guess this is due to the fact that wrapping `__ctfe` in a function causes it to run at compile-time instead of at...well...compile-time (i.e. https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time) Mike
Dec 07 2017
Mike Franklin wrote:// I couldn't figure out how to force `onlyCompileTime` to // execute at runtime. That's probably a good thing.string s = onlyCompileTime(); no compilation errors, runtime assert. that is, it is technically still executed in runtime.
Dec 07 2017
On Friday, 8 December 2017 at 06:39:10 UTC, ketmar wrote:no compilation errors, runtime assert. that is, it is technically still executed in runtime.damnit!
Dec 07 2017
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?I once tried to use dmd's -vgc option but it is not so useful when all CTFE funtions to generate D code trigger warnings about GC alcoations. I think such an attribute would silence this warnings, dmd -vgc would be much cleaner then.
Dec 07 2017
On Thursday, December 07, 2017 17:30:13 Manu via Digitalmars-d wrote:On 7 December 2017 at 17:20, Manu <turkeyman gmail.com> wrote:In spite of the fact that CTFE is done at compile time, __ctfe is a runtime thing - it's just that it's runtime from the perspective of CTFE. So, stuff like static if or static assert doesn't work. You have to use if or a ternary operator or some other runtime conditional, though it's a common misunderstanding that __ctfe is used with static if, and people screw it up all the time. I don't know why it's a runtime thing rather than a compile time thing though. There's probably a good reason for it, but at first glance, it seems like a rather weird choice. - Jonathan M DavisOn 7 December 2017 at 13:35, Walter Bright via Digitalmars-d < digitalmars-d puremagic.com> wrote:I tried this, and was surprised it didn't work: int ctfeOnly(int x) { static assert(__ctfe); return x + 1; } This would probably solve the problem in a satisfying way without an attribute?On 12/7/2017 11:41 AM, Manu wrote:Right, but that's what I'm saying; using your solution of putting a function in a module that's not compiled to inhibit code generation won't inhibit people from *attempting* to making runtime calls (and getting link errors)... whereas a compile error trying to runtime-call a function that shouldn't be runtime-called might be more desirable. I'm not actually registering support for ctfeonly, just that I think it's a pattern that I have wanted and should be supported in some way, and a compile-time error would be nicer than a link error.Misuse of the API; ie, a runtime call, will result in an unsuspecting user getting a surprising link error, rather than a nice compile-time error explaining what they did wrong...I think Nicholas is talking about functions for which code cannot be generated. In any case, in C/C++/D if you call functions in .h files (or imports) that are not linked in, you'll get a linker error.
Dec 07 2017
On Thu, Dec 07, 2017 at 07:20:57PM -0700, Jonathan M Davis via Digitalmars-d wrote: [...]In spite of the fact that CTFE is done at compile time, __ctfe is a runtime thing - it's just that it's runtime from the perspective of CTFE. So, stuff like static if or static assert doesn't work. You have to use if or a ternary operator or some other runtime conditional, though it's a common misunderstanding that __ctfe is used with static if, and people screw it up all the time. I don't know why it's a runtime thing rather than a compile time thing though. There's probably a good reason for it, but at first glance, it seems like a rather weird choice.[...] Sigh: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T -- Everybody talks about it, but nobody does anything about it! -- Mark Twain
Dec 07 2017
On Friday, 8 December 2017 at 02:14:09 UTC, H. S. Teoh wrote:On Thu, Dec 07, 2017 at 07:20:57PM -0700, Jonathan M Davis via Digitalmars-d wrote: [...]Woaaa... amazing job, Teoh! It seems that no link in the wiki points to that, or I'm wrong? That valuable stuff should be more visible... /PaoloIn spite of the fact that CTFE is done at compile time, __ctfe is a runtime thing - it's just that it's runtime from the perspective of CTFE. So, stuff like static if or static assert doesn't work. You have to use if or a ternary operator or some other runtime conditional, though it's a common misunderstanding that __ctfe is used with static if, and people screw it up all the time. I don't know why it's a runtime thing rather than a compile time thing though. There's probably a good reason for it, but at first glance, it seems like a rather weird choice.[...] Sigh: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T
Dec 08 2017
On Fri, Dec 08, 2017 at 11:03:34AM +0000, Paolo Invernizzi via Digitalmars-d wrote:On Friday, 8 December 2017 at 02:14:09 UTC, H. S. Teoh wrote:[...] The reason nothing (official) points to it, is because it's still a draft that hasn't been polished, and some parts may not be 100% accurate. Unfortunately, I haven't had the time to work on finishing it up. But since it's a wiki, if you're up to it, contributions are welcome. :-) T -- Life is unfair. Ask too much from it, and it may decide you don't deserve what you have now either.On Thu, Dec 07, 2017 at 07:20:57PM -0700, Jonathan M Davis via Digitalmars-d wrote: [...]Woaaa... amazing job, Teoh! It seems that no link in the wiki points to that, or I'm wrong? That valuable stuff should be more visible...In spite of the fact that CTFE is done at compile time, __ctfe is a runtime thing - it's just that it's runtime from the perspective of CTFE. So, stuff like static if or static assert doesn't work. You have to use if or a ternary operator or some other runtime conditional, though it's a common misunderstanding that __ctfe is used with static if, and people screw it up all the time. I don't know why it's a runtime thing rather than a compile time thing though. There's probably a good reason for it, but at first glance, it seems like a rather weird choice.[...] Sigh: https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time T
Dec 08 2017
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?How would such a thing interact with __traits(compiles, ...) and is-expressions?
Dec 08 2017
On Friday, 8 December 2017 at 10:46:20 UTC, John Colvin wrote:On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:VERY good question, I'm not sure. From a purely practical perspective I'd say it should pass __traits(compiles, ...) and is-expressions purely because the kind of things that ctfeonly would be used to cull from the produced binaries are used as is-expressions (e.g. the template lambda that determines isInputRange), although I expect it use to be rare. Ultimately I think this this feature would fall in to the category of "use responsibly" and it would be the responsibility of the user. They could always reflect on the presence of the attribute if need be. From a point of consistency, probably however semantic constraints on things like LDC's magic attributes are done. I'm not sure how that is handled, but I suspect that __traits(compiles,...) does not take it into account. Johan? I will think more on it. Thanks.I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?How would such a thing interact with __traits(compiles, ...) and is-expressions?
Dec 08 2017
On Friday, 8 December 2017 at 11:48:26 UTC, Nicholas Wilson wrote:On Friday, 8 December 2017 at 10:46:20 UTC, John Colvin wrote:You might want to wait until Dconf 2018 before you start implementing something. As it happens I am working on a way which will make ctfe-only functions possible (though that's s side-effect rather then the goal)On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:VERY good question, I'm not sure. From a purely practical perspective I'd say it should pass __traits(compiles, ...) and is-expressions purely because the kind of things that ctfeonly would be used to cull from the produced binaries are used as is-expressions (e.g. the template lambda that determines isInputRange), although I expect it use to be rare. Ultimately I think this this feature would fall in to the category of "use responsibly" and it would be the responsibility of the user. They could always reflect on the presence of the attribute if need be. From a point of consistency, probably however semantic constraints on things like LDC's magic attributes are done. I'm not sure how that is handled, but I suspect that __traits(compiles,...) does not take it into account. Johan? I will think more on it. Thanks.[...]How would such a thing interact with __traits(compiles, ...) and is-expressions?
Dec 08 2017
On Thursday, 7 December 2017 at 01:21:11 UTC, Nicholas Wilson wrote:I'd like to add an attribute to indicate that the annotated function is only available at compile time so that in cases where the operation is invalid at runtime (strings and concatenation on a GPU for instance) but the result is only used at compile time (for a mixin) the compiler is free to not codegen that function. I can add this to LDC pretty easily, but does anyone else have a use for this (e.g. shrinking binary sizes for mixin heavy codebases) and would benefit having this as a standard thing?This doesn't fulfill everything you're looking for, ie no compile-time error if tried to use at runtime, but isn't this existing idiom good enough? https://github.com/dlang/phobos/blob/master/std/functional.d#L307
Dec 08 2017