version(ctfe)

Don nospam at nospam.com
Mon Oct 19 07:28:38 PDT 2009


dsimcha wrote:
> == Quote from Don (nospam at nospam.com)'s article
>> Denis Koroskin wrote:
>>> On Mon, 19 Oct 2009 17:13:46 +0400, dsimcha <dsimcha at yahoo.com> wrote:
>>>
>>>> This discussion originated in the T[new] thread, but I think it
>>>> deserves its own
>>>> thread.
>>>>
>>>> == Quote from Denis Koroskin (2korden at gmail.com)'s article
>>>>> An Array!(T) is really just a different name to a T[new]. You'll have
>>>>> the
>>>>> same problem explaining difference between Array!(T) and T[].
>>>>> But you are also creating a nightmare for CTFE. Since you can't use
>>>>> "a ~=
>>>>> b;" anymore, you'll have to use "a = a ~ b;" which *always*
>>>>> allocates. Not
>>>>> only it is syntactically less pleasant, this way you render this
>>>>> function
>>>>> useless at run-time - who in the sane mind will use such an inefficient
>>>>> stuff?
>>>> Maybe what we need is a version(ctfe) statement.  Stuff inside such a
>>>> block would
>>>> be executed only if a function is being compile time evaluated.  When
>>>> code is
>>>> generated for runtime evaluation the else block would be used.  This
>>>> would allow
>>>> problems like this to be solved in a well-encapsulated way.  Example:
>>>>
>>>> uint[] findPrimes(uint maxPrime) {
>>>>     version(ctfe) {
>>>>         uint[] ret;
>>>>     } else {
>>>>         ArrayBuilder!uint ret;
>>>>     }
>>>>
>>>>     foreach(i; 0..maxPrime) {
>>>>         if(!isPrime(i)) {
>>>>              continue;
>>>>         }
>>>>
>>>>         version(ctfe) {
>>>>             ret = ret ~ i;
>>>>         } else {
>>>>             ret ~= i;
>>>>         }
>>>>     }
>>>> }
>>>>
>>>> Given that CTFE will likely never support everything that is supported
>>>> at runtime,
>>>> this will likely make it much more useful.
>>> It was suggested before and IIRC Walter said it is next to impossible to
>>> implement.
>> I had a bit of an attempt at it. version(ctfe) seems to be nearly
>> impossible.
>> But I'm almost certain I could get a magic bool __ctfe to work:
>> if (__ctfe) {
>>    ...      // only contains D code
>> } else {
>>     asm { .... }
>> }
>> It would only be accessible inside unsafe modules (which are the only
>> place you'd need it).
>>> What you suggest is almost the same as writing 2 different functions.
>>> The killer feature of CTFE is that you write it just once and use both
>>> at compile and run-time without modifications.
>> Yes, but there are problems. A few low-level, high-speed functions can't
>> be used in CTFE because they use asm or nasty unions.
>> eg, std.math.poly()
> 
> So this magic bool would be like a regular if statement in that it would create a
> new scope?  I guess if you could do it such that it worked with static if, you'd
> be able to get it to work with version.

It'd just be a variable, which the CTFE interpreter would evaluate as 
'true', but would be a normal bool variable everywhere else. Similar to 
the magic variable __dollar.
It'd only become false just before being sent to the code generator. 
Dead code elimination would remove the CTFE part.

The important thing is that the AST must be identical for both CTFE and 
run-time.



More information about the Digitalmars-d mailing list