17-Jun-2014 23:41, Ary Borenszweig пишет:
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?

Not limiting it to just calling some external tools, but plugins and services, I agree. Well, see the link by Dicebot.

I belive this is more practical and useful stuff for heavy meta-programming.
My reasons pro:
a) Not everything could be done in CTFE envirnoment, e.g. please go ahead and compile a HLSL shader for me. b) Performance of standalone optimized code and definitive boundaries for caching of results.

Some points against:
a) Can't be as deeply integrated into compiler. Passing arbitrary D types won't work, for instance, or it needs to share type info with compiler. Same limitations with meta-data. b) We haven't seen a proper interpreter for CTFE yet at all, so are unable to truly assess its performance.

Overall I think it's much more practical (yet hackish) way that can be easily done in near future.


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.

Well, there are ways to constrain plugins,
even in system languages like D.


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", "^.*/([^/]+)/?$") }}


--
Dmitry Olshansky

Reply via email to