mixin + CTFE, to big a hammer??

janderson askme at me.com
Thu Mar 1 22:05:51 PST 2007


BCS wrote:
> Reply to Reiner,
> 
>>
>> I think they have already proven useful, looking at what people are
>> doing with them:
> 
> Oh, they are most defiantly useful
> 
>>
>> - renoX's improvement on format strings, to allow putf("x is %d{x}");
>> - Kevin Bealer's reflective enums
>> - Kirk says that mixins resulted in a vast reduction of code for using
>> PyD
>> Sure, *perhaps* only some people will write mixin code, but these
>> three examples could be of direct use to many people; anyone can
>> understand how putf should behave, even if the implementation is
>> trickier.
>>
> 
> good examples
> 
>> As I see it, the major use of mixins is to completely solve the
>> identof(char[]) problem: we can now very simply make an identifier out
>> of a compile-time char[], and I believe that this is what all 3 of
>> these projects make use of.
> 
> But that is one of the most trivial uses of mixins. I would expect that 
> they most of this benefit of mixins can be had while limiting ones self 
> to cases where only a single expression or a simple statement is used:
> 
> a = mixin(IdentName) + 1;
> j = mixin(FnName ~ "(arg1, arg2, arg3)");
> 
> These are vary useful features and I wouldn't expect them to show any of 
> the "hard to use" issues I referred to.
> 
>>
>> Mixins are also quite useful in mostly-D DSLs; instead of parsing all
>> the DSL code and converting it into D code, you just need to get the
>> overall structure, and then mixin the D code again:
>>
>>> mixin MyStateMachine(`
>>> state Finished { /* Some D code */ ... }
>>> state Starting { /+ More D code +/ ... }
>>> `);
>> It's relatively easy to write a parser which just counts bracket
>> levels, so all you have to do is parse 'state Finished' and 'state 
>> Starting' and then capture the D code and mix it back in. I've done 
>> this kind of thing for implementing pattern-matching, and it is quite 
>> painless; mixins are what make this possible.
> 
> Again a good example of where mixins are good.
> 
>> CTFE is an improvement on template meta-programming, since it allows
>> for plain D code implementations of compile-time functions. This is
>> therefore inherently /easier/ to read than template meta-programs, and
>> I think it is preferable in all cases: anyone who can read D code can
>> understand it.
>>
> 
> CTFE is great, No doubt about it.
> 
>> Of course, neither of these mechanisms are mature yet, so there are
>> syntactic issues and other gripes, but we can rest assured that these
>> will (mostly) be fixed as we get more experience with them.
>>
>> Cheers,
>>
>> Reiner
>>
> 
> Mostly I wanted to get a discussion going. The issue isn't that 
> mixin+CTFE is bad, it's that often the cost is high and the benefit 
> (over other solutions) is low. What I would like to see is more effort 
> put into thouse other options.
> 
> I'd say that as a rule of thumb, if you have a mixin that takes more 
> than two or three ~ to build, you'd better think a lot about it. I'd 
> mutch rather work with static foreaches with a few mixins inside it than 
> the same code generated as a string inside of a single mixin.
> 
> With a few additions and tweaks to static foreach and friends this 
> becomes vary practical.
> 
> which of these would you rather use?
> 
> |static foeach(char[] ident; SplitByChar(String, ';'))
> |    writef("%s", mixin(ident));
> 
> vs.
> 
> |mixin(build(String));
> |
> |... // lost of other code
> |
> |char[] build(char[] ins)
> |{
> |    char[] ret = "";
> |    foreach(char[] ident; SplitByChar(String, ';'))
> |        ret ~= `writef("%s",` ~ ident ~ `);`;
> |    return ret;
> |}
> 
> 


You could write a mixin that works like:

mixin( sforeach("char[] ident; SplitByChar(String, ';')",
	"writef("%s", mixin(ident));"
));

Still static foreach would/will be nice.

If the mixin syntax is improved it could look like:

static_foreach("char[] ident; SplitByChar(String, ';')",
		"writef("%s", mixin(ident));");

or (not sure if this will ever be possible:

//With the out syntax Andrie is working on
static_foreach("char[] ident; SplitByChar(String, ';')") =
	"writef("%s", mixin(ident));";

Still not perfect and i agree, static foreachs are a basic construct, so 
should be part of the language rather then a work around.

-Joel



More information about the Digitalmars-d-announce mailing list