On Tuesday, 17 June 2014 at 19:41:59 UTC, Ary Borenszweig wrote:
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", "^.*/([^/]+)/?$") }}

I had a similar idea a while ago. The only difference was that
instead of compiling and running some d file at compile time,
mine was simply run some pre-compiled executable at compile time
and return the output as a string(similar to string imports). I
expressed similar use cases as you mentioned, replace extremely
slow ctfe, but it didn't seem to catch on. Every one screamed
that it was a security risk and it died there.

-tofu

Reply via email to