December 08, 2017
Walter Bright wrote:

> 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.

still, why `__ctfe` was designed as variable, and not as `enum ctfe = <bool>;`?
December 08, 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.
December 08, 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.
December 08, 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.
December 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
December 08, 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.
December 08, 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!

December 08, 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:
>> 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 Davis
>>
>> I 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.
>
> If all you need is a runtime error, you can already put assert(__ctfe); in your function.

It's to avoid having a run-time error, so something that would produce a run-time call gives a compile-time error.
December 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?
December 08, 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: [...]
>> 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

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...

/Paolo