mixin extension

Daniel Keep daniel.keep.lists at gmail.com
Wed May 3 21:45:39 PDT 2006


Howdy.

Matthias Spycher wrote:
> Here's an idea to extend mixins in a manner that would allow you to mix
> code around a block in D.
> 
> If you had:
> 
> template Trace(f:char[])
> {
>   printf("Entering %s", f);
> }
> {
>   printf("Exiting %s", f);
> }

How about this instead:

template Trace(f:char[], block inner_block)
{
    writefln("Entering %s", f);
    inner_block;
    writefln("Exiting %s", f);
}

That way, you can also support more complicated constructs like this:

template Repeat(int times, block inner_block)
{
    for( int i=0; i<times; i++ )
        inner_block;
}

Of course, the problem with this is that templates only allow for
declarations, not arbitrary statements.  Perhaps we could then add the
following, which would mix a block into the instantiating scope:

template Repeat(int times, block inner_block)
{
    block Repeat
    {
        for( int i=0; i<times; i++ )
            inner_block;
    }
}

> 
> Note the two blocks associated with a single template declaration. You
> might mix code around a third block with:
> 
> void test()
> {
>   mixin Trace!("test") {
>     do_something();
>     more_here();
>   }
> }
> 

Personally, I'd like to be able to drop the "mixin" keyword.  I realise
that semantically, it makes sense since you're mixing the contents of
the template in, but without it, it just looks cooler :)

void test()
{
    Trace!("test")
    {
        do_something();
        more_here();
    }
}

> resulting in the equivalent of:
> 
> void test()
> {
>   printf("Entering %s", f);
>   do_something();
>   more_here();
>   printf("Exiting %s", f);
> }
> 
> Ideally, such a construct could be used in conjunction with a
> conditional version statement:
> 
> void test()
> {
>   version (Log) mixin Trace!("test") {
>     do_something();
>     more_here();
>   }
> }
> 
> which when logging is disabled would evaluate to:
> 
> void test()
> {
>   do_something();
>   more_here();
> }
> 
> Is this feasible? Are there better ways?
> 
> Matthias

I'll steal a Pythonism, and vote +1.  This would be *really* handy, and
it would allow for the creation of almost arbitrary control structures!

For the longest time, I've had evil thoughts of making a D preprocessor
that only operated on complete, valid parse trees.  It would basically
be a D compiler that read in D, modified it in some way, then spat it
back out.  With that, you could make structures like this:

fori( int i; 10 )
    block;

Which would be "expanded" by the preprocessor as:

for( int i=0; i<10; i++ )
    block;

But using the above idea, you could just write this as a template:

template fori(alias variable, int limit, block inner)
{
    block fori
    {
        for( variable = 0; variable < limit; variable++ )
            inner;
    }
}

Of course, this would be helped if we could drop in arbitrary symbols or
declarations, but I can live without that :)

	-- Daniel "Must... have... meta... programming..." Keep

-- 

v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D
a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP    http://hackerkey.com/



More information about the Digitalmars-d mailing list