compile-time explicitness

Gor F. Gyolchanyan gor.f.gyolchanyan at gmail.com
Fri Sep 23 08:51:35 PDT 2011


I have a proposal to introduce and optional explicit separation of
compile-time facilities from run-time facilities.
There is a new keyword, called compiletime (or something similar).
The keyword can be used with `is` expression to detect whether the current
scope is executing in compile-time or not.

static if(__traits(compiletime))
{
    // ...
}

The keyword is a storage class for declarations of variables, types and functions.

A variable, declared with this keyword behaves much like a enum:

compiletime float dmdVersion = 2.055;

This keyword reflects the nature of dmdVersion much better, then the `enum`
keyword, since it does not actually enumerate anything.
dmdVersion does not exist at run-time (hence, cannot be taken address of) just
like enums.

compiletime void myfunc() { }
void myfunc() { }

functions, marked with compiletime keyword do not exist at run-time (cannot be
taken address of, exported from DLLs, etc.). Functions (even with the same set
of arguments) can overload on this storage class, allowing to seamlessly
specialize compile-time version of any function or method. If the function is
marked as compiletime, then all it's parameters are marked as such too (in
current CTFE, they're still deemed run-time, because the function itself
doesn't know that it's running at compile-time), essentially making it a
template, but with no mandatory functional programming style.

compiletime struct MyStyruct {}
compiletime alias MyAlias;
compiletime union MyUnion {}

Type definitions, marked as compiletime do not exist at run-time (have no
TypeInfo, cannot declare run-time variables) and they enforce their instances
to be compiletime as well. This allows to further enhance the expressiveness
of the language:

compiletime alias ulong Version;

void func(int templateParam)()
{
    Version v = (templateParam + 5) / 2 - veryComplexExpression;
    static if(v > 25) // ok, v got compiletime from it's type.
    {
        doTheStuff();
    }
}

Template functions will have a very convenient syntax sugar:

void myFunc(int arg1, compiletime int arg2, char arg3, compiletime char arg4)
{
}

, which is equivalent to:

vodi myFunc(int arg2, int arg3)(int arg1, int arg4)
{
}

functions, which differ only by the difference of compiletime-ness of their
arguments (the number and types are equal) can overload against each other,
allowing the function implementor to specialize functions, so that each
compile-time argument, passed to the function may dramatically increase the
run-time performance of the function (essentially allowing to conditionally
hardcode parts of the function at compile time).

The function parameters can be marked as auto compiletime:

void f(auto compiletime arg)
{
    static if(__traits(compiletime, arg))
    {
        // partially specialize the function right in the scope.
    }
}

, which will allow the programmer to write a single function, where each of
it's arguments can dramatically increase the run-time performance of the
function by being compile-time.

And, of course, if everything else fails, the good ol' CTFE will come to the
rescue.

Now for the best part:

All this (almost) does not break any code!!! The almost stands for the keyword
itself, which may be annotated @compiletime (like @safe) until D3, where the
annotation will either be removed or, everything else will get annotated too.

I will closely study DMD's source code to start implementing this myself if
and when you guys approve this idea.

What do you think?
What application of the keyword did i miss?
Do i deserve a candy for this or not? :-)


More information about the Digitalmars-d mailing list