Nick Sabalausky wrote:

Maybe this is naive, but what about an AST-level template/generic? Couldn't that provide for the best of both worlds?

For instance, suppose (purely hypothetically) that the .NET assembly system were changed to allow the source for a D/C++ style of source-level template to be embedded into the assembly. Then they'd be able to do D/C++ style source-level template/code-generation. Right? Now obviously the big problem with that is it would only be usable in the same language it was originally written in. So, instead of getting that cross-language support by going all the way down to the IL bytecode level to implement generics (which, as you said, would somehow prevent the flexibility that the D/C++ style enjoys) suppose it only went down as far as a language-agnostic AST?

I suppose that might make reverse-engineering easier which MS might not like, but I'm not suggesting this as something that MS should like or should even do, but rather suggesting it as (business issues completely aside) something that would possibly gain the benefits of both styles.


that's the exact opposite of a good solution.
I already mentioned several times before the language Nemerle which provide the correct solution. important fact - Nemerle is a .NET language and it does _NOT_ need to modify the underlining system.

The way it works in Nemerle is pretty simple:
the language has a syntax to compose/decompose AST.
a Macro in nemerle is just a plain old function that uses the same syntax you'd use at run-time and this "function" can use APIs to access the compiler's internal data structures (the AST) and manipulate it. you "connect" it to your regular code by either just calling it like a regular function or by using attributes.

let's compare to see the benefits:
in D:
tango.io.Stdout("Hello World").newline; // prints at run-time
pragma(msg, "Hello World"); // prints at compile-time

in Nemerle:
macro m () {
  Nemerle.IO.printf ("compile-time\n");
  <[ Nemerle.IO.printf ("run-time\n") ]>;
}
// and you call it like this:
m();
Nemerle.IO.printf ("run-time\n");

notice how both use the same code, the same printf function?
the only change is that the second line inside the macro is enclosed inside <[ ]> which means output (return) the AST for this code instead of actually running the code and returning the result of the call.

Macros in Nemerle need to be compiled since they are regular Nemerle code and they need to be loaded by the compiler (added to the command line) in order to compile the code the calls the macros.

essentially these are just plugins for the compiler.

compared to the elegance of this solution, templates are just a crude copy-paste mechanism implemented inside the compiler.

Reply via email to