Ceylon language

David Nadlinger see at klickverbot.at
Sat Apr 16 01:46:55 PDT 2011


On 4/15/11 8:19 PM, Andrej Mitrovic wrote:
> […] My biggest issue is that
> I can't modify variables at compile time. I wish there was some
> special CTFE int type which is only visible at compile-time and which
> we can use however we want. That way I could keep count of things, for
> example I could generate a list of indexes that can then be mixed in
> as a string.
> […]
> I dunno, CTFE overall seems like a buggy thing where I have to guesswhether something will work or not. It's very stress-inducing.

Correct me if I'm wrong, but might it be that you are conflating 
templates and CTFE, which are – although they are both used for 
metaprogramming – two entirely different concepts?

Maybe it helps to think of calling a function at compile time as a gate 
into a parallel universe. In this other world, you can modify variables, 
call functions, etc. as you please, just as if you were executing code 
at runtime (well, inside the more or less implementation-defined 
boundaries of CTFE). The only restriction is that you can only return a 
single value through the gate, there is no other way to influence the 
»compiler« universe from inside the functions you call. More 
specifically, there is no way to manipulate types in the compiler 
universe – although you can instantiate templates in CTFE functions just 
like normal, you will never be able to »return« them back to the outside 
world. Also, be aware of the fact that a CTFE function can just work on 
_values_, like every other runtime function, not on types.

So much for CTFE. Templates, on the other hand, are basically just named 
scopes with a few extra features which happen to make a Turing complete 
language. As such, there will never be something like a runtime variable 
modifiable at compile time in templates, as you asked (at least I hope 
so). The interesting thing about templates is that they allow you to 
work with types themselves. Due to the absence of mutable state, you are 
generally limited to functional techniques, though, which can be 
uncomfortably similar to the proverbial Turing tarpit in some cases 
(although it's surprising how easy it is to write certain algorithms in 
a functional manner once you got the hang of it).

However, there are ways to combine templates and CTFE to your advantage. 
Without any concrete question, it's obviously hard to give a good 
suggestion, but an example would be to use template functions called at 
compile time to produce string mixins:

---
string generateCode(T...)() {
     string code;
     [… construct a string containing some declarations …]
     return code;
}

template Foo(T...) {
     alias DoSomethingWithATypeTuple!(T) U;
     mixin(generateCode(U));
}
---

You can also shorten this by using delegate literals:
---
template Foo(T...) {
     alias DoSomethingWithATypeTuple!(T) U;
     mixin({
         […]
         return "<some code generated while having access to T and U>";
     }());
}
---

Another small template metaprogramming example showing a way to process 
a list of types without needing mutable state. Specifically, it aliases 
a new type tuple to Result which doesn't contain any items where 
Exp.numerator is 0 (you can do the same with eponymous templates). 
TypeTuples are automatically flattened, which allows for a concise 
implementation here.

---
template Process(T...) {
     static if (T.length == 0) {
         alias TypeTuple!() Result;
     } else {
         alias T[0] A;
         static if (A.Exp.numerator == 0) {
             alias Process!(T[1..$]).Result Result;
         } else {
             alias TypeTuple!(A, Process!(T[1..$]).Result) Result;
         }
     }
}
---

As for constructing lists of indices and then generating code of them: 
If you need to work on types for generating the list, you could e.g. use 
some recursive template to construct a type tuple of integer literals 
(that name really doesn't fit well), and then process it via CTFE to 
generate code to be mixed in – or whatever you need in your specific 
case. Feel free to ask about any specific problems in d.D.learn.

David


More information about the Digitalmars-d mailing list