DIP 50 - AST macros
luka8088
luka8088 at owave.net
Wed Nov 13 00:15:29 PST 2013
On 10.11.2013. 22:20, Jacob Carlborg wrote:
> I've been thinking quite long of how AST macros could look like in D.
> I've been posting my vision of AST macros here in the newsgroup a couple
> of times already. I've now been asked to create a DIP out of it, so here
> it is:
>
> http://wiki.dlang.org/DIP50
>
I took a look at it as here is my conclusion for now:
Statement and attribute macro examples look great. But I don't like Linq
example. I don't think code like the following should be allowed.
query {
from element in array
where element > 2
add element to data
}
>From my point of view this whole idea is great as it makes it easier
what is already possible. For example, with current behavior if I wanted
to write.
foo {
writeln("foo");
writeln("foo again");
}
I would have to write:
mixin(foo!(q{
writeln("foo");
writeln("foo again");
}));
So the proposed behavior looks much nicer, and I agree with it as the
content of foo block is actually written in D and I think whoever is
reading it would be comfortable with it.
However, for other, non-D syntax-es I would prefer something like:
query q{
from element in array
where element > 2
add element to data
}
Which can be handled by:
macro query (Context context, string dsl) {
return domainSpecificLanguageToD(dsl);
}
This in terms is already possible by writing the following, it only
allows to be written in a more readable way. And the q{ ... } notation
clearly points out that there is something special going on. Also by
passing such content as string user can implement custom (or call one of
the predefined) tokenizer/lexer/parser.
mixin(query!(q{
from element in array
where element > 2
add element to data
}));
I also don't like the <[ ... ]> syntax because:
1. Like others have said, it looks very foreign.
2. I don't think there is a need to add a new syntax.
I think that string concatenation is enough (at least for now), and if
you want another syntax for templates you can write a macro for that.
For example:
macro myAssert (Context context, Ast!(bool) val, Ast!(string) str = null) {
auto message = str ? "Assertion failure: " ~ str.eval : val.toString();
auto msgExpr = literal(constant(message));
return "
if (!" ~ val ~ ")
throw new AssertError(" ~ msgExpr ~ ");
";
// or
return astTemplate q{
if (!$val)
throw new AssertError($msgExpr);
};
}
void main () {
myAssert(1 + 2 == 4);
}
What do you guys think?
--
Luka
More information about the Digitalmars-d
mailing list