Compile time function execution...

Bill Baxter dnewsgroup at billbaxter.com
Thu Feb 15 16:23:05 PST 2007


Walter Bright wrote:
> Bill Baxter wrote:
>> Walter Bright wrote:
>>> ... is now in DMD 1.006. For example:
>>>
>>
>> Very nice!
>>
>> A few questions:
>> 1) You say recursion is allowed -- does it do proper tail recursion?
> 
> Tail recursion is a performance optimization, it has no effect on 
> semantics, so it's not an issue for compile time execution.
> 
>> 2) Can't you just ignore 'synchronized' at compile time?
> 
> Pure functions (the kind that can be compile time executed) don't need 
> to be synchronized anyway.
> 
>> 3) Would it be possible to add some sort of a version(CompileTime)? 
>> This would make it possible for those who want to be *sure* the 
>> function is only used at compile time to simply have it not exist as a 
>> runtime call.  It could also be used to make slight modifications to 
>> functions that one would like to use as both compile-time and 
>> run-time.  For example if you want to have 
>> synchronized/try/catch/throw/writefln type things in the runtime version.
> 
> Once more, there is never a situation where a function *might* or *might 
> not* get executed at compile time. A function is *always* executed at 
> runtime unless it is in a situation where it *must* be executed at 
> compile time, such as in an initializer for a global.

Right.  But if I understand correctly, the same code can get called 
either at runtime or compile time depending on the situation.

But what if I want the runtime version to print out a message.  Or add 
to a global counter variable for some simple home-brew profiling stats. 
  It would be handy then if I could do:

int square(int x) {
    version(compiletime) {}else{
      writefln("trace: square");
      G_CallsToSquare++;
    }
    return (x*x);
}

I think I'm getting at the same kind of thing Andrei is talking about. 
I don't want to have to limit what I do in the runtime version in order 
to make it acceptable for compile time.  He's saying I should be able to 
have two versions of the function, one for compile time and one for run 
time.  I think that's useful too.  But for simpler cases like the above, 
it would be nice I think if one could just version-out the bad parts.

And in this case:

int calculationIShouldOnlyDoAtCompileTime(int x)
{
    // * whatever it is *
}

int K = calculationIShouldOnlyDoAtCompileTime(4);

Whoops!  Silly programmer, looks like I forgot the 'const' on K.  Would 
be nice if I could get the compiler to remind me when I'm silly like 
that.  That could be arranged if there were a version(CompileTime).

I think one holy grail of this stuff (and one Lisp apparently attained 
in the 60's or 70's) is to just be able to treat everything as either 
compile-time or run-time depending on how much information you have.

For instance, it's not uncommon to make a fixed length vector class 
using templates.  Vec!(N) kind of thing.  But it would really be nice if 
the majority of that code could remain even when N is not constant. 
That means both on the user side and on the implementation side.  I 
don't know how realistic that is, but I often find myself sitting on the 
fence trying to decide -- do I make this a compile-time parameter, 
thereby cutting off all opportunity for runtime creation of a particular 
instance, or do I make it runtime, thereby cutting my and the compiler's 
opportunity to make several obvious optimizations.

--bb



More information about the Digitalmars-d mailing list