Another way to do CTFE
Ary Borenszweig via Digitalmars-d
digitalmars-d at puremagic.com
Tue Jun 17 12:41:58 PDT 2014
CTFE is really nice but has its limitations: you can't do anything you
want, and since it's interpreted it requires an interpreter and it's
generally slow. Nimrod does the same thing, and now they are
implementing a VM to run the interpreted code faster. Is this really the
way to go?
In our language we are thinking about allowing code generation at
compile time but in a different way. The idea is, at compile time, to
compile and execute another program that would generate the code that
would be mixed into the current program. This program could receive the
execution context as arguments, along with any AST nodes that are passed
to the program.
So right now in D you can do ctRegex:
auto ctr = ctRegex!(`^.*/([^/]+)/?$`);
I don't know what the syntax could be, but the idea is to have a file
ct_regex.d. This file would receive the string as an argument and must
generate the code that would be mixed in the program. Since this program
is a program (compiled and executed), it has no limits on what it can
do. Then you would do something like this:
mixin(compile_time_execute("ct_regex.d", `^.*/([^/]+)/?$`));
The compiler could be smart and cache the executable so that anytime it
has to expand it it just needs to invoke it (skip the compile phase).
What do you think?
I know, I know. The first answer I'll get is: "Oh, no! But that way I
could download a program, compile it and suddenly all my files are
gone". My reply is: If you downloaded and compiled that program, weren't
you going to execute it afterwards? At that point the program could do
something harmful, so what's the difference?. You must either way check
the source code to see that something fishy isn't happening there.
Just as a reference that something like this is possible, in our
language you can already do this:
build_date = {{ system("date").stringify }}
puts build_date
That generates a program that has the build date embedded in it. We can
also get the git hash of a repo and stick it into the executable without
an additional Makefile or some build process. "system" is our first step
towards doing this compile-time things. The next thing would be do do:
ct_regex = {{ run("ct_regex", "^.*/([^/]+)/?$") }}
More information about the Digitalmars-d
mailing list