Metaprogramming in D : Some Real-world Examples

Lutger lutger.blijdestijn at gmail.com
Tue Nov 10 03:32:11 PST 2009


Bill Baxter wrote:

> On Mon, Nov 9, 2009 at 4:09 PM, Walter Bright
> <newshound1 at digitalmars.com> wrote:
>> Looks like Bill Baxter is giving a presentation on D Nov. 18!
>>
>> http://www.nwcpp.org/
> 
> Yep, that's right, and I'd be quite grateful to you smart folks here
> if you could share your meta-programming favorites with me!   If
> you've got a real-world example of meta-programming in D that you
> think is particularly handy, then please send it my way
> 
> I'm looking for small-but-useful things that are easy to explain, and
> make something easier than it would be otherwise.  Things like places
> where static if can save your butt,  or loop unrolling,  and passing
> code snippets to functions like in std.algorithm.
> 
> Things like a compile-time raytracer or regexp parser (though quite
> cool!) are not what I'm after.  Too involved for a short talk.
> 
> --bb

Great, I hope to see some slides or a video!

Here is a watered down example of what I currently use to help with the 
boilerplate code of a visitor. It doesn't look much, but it's helpful when 
you have lots of visitable classes and in case of adding new classes. The 
code should run as is: 

import std.stdio;

enum Visitable =
q{
    override void accept(IVisitor visitor)
    {
        visitor.visit(this);
    }
};

interface IExpression
{
    void accept(IVisitor visitor);
}

class Sum : IExpression
{
    mixin(Visitable);
}

class Product : IExpression
{
    mixin(Visitable);
}

string visitMethodOf(string type)
{
    return "void visit(" ~ type ~ ");";
}

string FoldStringsOf(alias F)(string[] list)
{
    string result = "";
    foreach (element ; list)
        result ~= F(element);
    return result;
}

interface IVisitor
{
    mixin( FoldStringsOf!visitMethodOf( ["Sum", "Product"] ) );
}

class Visitor : IVisitor
{
    void visit(Sum node)
    {
        writeln("sum");
    }

    void visit(Product node)
    {
        writeln("product");
    }
}

void main()
{
    auto printer = new Visitor();
    
    IExpression sum = new Sum();
    IExpression product = new Product();
    
    sum.accept(printer);
    product.accept(printer);
}


More information about the Digitalmars-d-announce mailing list