Thesis on metaprogramming in D

Don Clugston dac at nospam.com.au
Tue Nov 28 08:10:17 PST 2006


Daniel Keep wrote:
> Don Clugston wrote:
>> Andrey Khropov wrote:
>>
>>> Steve Horne wrote:
>>>
>>>> My view of the ideal handling of metaprogramming is that it should
>>>> have access to all the features that are available at runtime. The
>>>> only languages that I know that genuinely achieve that are the
>>>> Lisp-alikes such as Scheme.
>>>>
>>>> My ideal is being able to define 'quoted' blocks that are parsed and
>>>> translated to ASTs, with those ASTs being processed by other code to
>>>> derive new ASTs which are then submitted for the final back-end
>>>> optimisation and code generation.
>>>
>>>
>>> Nemerle does exactly that way!
>>
>>
>> When I looked at the Nemerle website, I didn't see much that couldn't 
>> be done easily with D templates. It would be interesting to find 
>> something it can do, that D can't.
>>
> 
>  > def sr = System.IO.StreamReader ("SomeFile.txt");
> 
> Immutable run-time variables.  You can assign anything to them, and then 
> it can't change.  AFAIK, D's const doesn't let you do that.
> 
>  > someFunction(if (cond) expr_1 else expr_2);
> 
> No statements--everything is an expression.  And yes, it is VERY handy :)
> 
>  > import some.namespace.SomeClass;
> 
> Import contents of static classes as well as modules.
> 
>  > match (control) {
>  >   | button is Button => ...
>  >   | listv is ListView => ...
>  >   | _ => ... // null case
>  > }
> 
> switch eat your heart out.  You can use literal, pattern matching... 
> just about anything.
> 
>  > def res2 = frobnicate (7, do_qux = true,
>  >                           do_baz = false,
>  >                           do_bar = true);
> 
> Named parameters.  D doesn't even have hashtable literals, so faking it 
> would be a complete pain.
> 
>  > ()
> 
> That's the void literal.  Basically, makes void act like any other type. 
>  Try writing generic code where functions can have void return values, 
> and you'll end up writing everything twice since you can't have void 
> variables.
> 
>  > variant RgbColor {
>  >   | Red
>  >   | Yellow
>  >   | Green
>  >   | Different {
>  >       red : float;
>  >       green : float;
>  >       blue : float;
>  >     }
>  > }
> 
> Different to a union since it remembers what kind of thing is being 
> stored.  Fun trick with trees is to use a variant to store either a 
> branch or a leaf.
> 
>  > macro while_macro (cond, body)
>  > syntax ("while", "(", cond, ")", body) {
>  >   <[
>  >     def loop () {
>  >       when ($cond) {
>  >         $body;
>  >         loop ()
>  >       }
>  >     }
>  >     loop ()
>  >   ]>
>  > }
> 
> Do THAT with templates :3

The 'lazy evaluation' page has a similar example. :-)

>  >> def x = 3;
>  >> System.Console.WriteLine ($"My value of x is $x and I'm happy");
>  >
>  > expands to
>  >
>  >> def x = 3;
>  >> System.Console.WriteLine ({
>  >>   def sb = System.Text.StringBuilder ("My value of x is ");
>  >>   sb.Append (x.ToString ());
>  >>   sb.Append (" and I'm happy");
>  >>   sb.ToString ()
>  >> });
> 
> Even if you could fake the one just above that, there's no way you can 
> do that in D.

You could if we got the identifier() keyword which I've previously 
proposed. Admittedly, it still wouldn't be pretty. But there's really 
because there's no support for embedded variables.

But doing the same thing for
System.Console.WriteLine("My value of x is ", x, " and I'm happy");
is trivial with the new tuples.

> It would be foolish to think that Nemerle isn't an amazingly powerful 
> language.  D is good, and its' templates are very powerful, but they're 
> not THAT powerful.

I still have the impression that the functionality isn't much different.

> There is always more to learn :)
> 
>     -- Daniel



More information about the Digitalmars-d mailing list