version(ctfe) (was: The demise of T[new])

Denis Koroskin 2korden at gmail.com
Mon Oct 19 06:32:27 PDT 2009


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.

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.

I'd like to write it as

immutable(uint)[] findPrimes(uint maxPrime) {
     ArrayOfInt ret;

     foreach(i; 0..maxPrime) {
         if(!isPrime(i)) {
              continue;
         }

         ret ~= i;
     }

     return assumeUnique(ret[]);
}

ArrayOfInt may be an alias to Array!(int), int[] or int[new], or whatever  
else. All I care is it should be valid and efficient for both run- and  
compile-time cases.



More information about the Digitalmars-d mailing list