Reification for Macros
In case you don't know, Haxe has a power macro system which allows you to do a lot of compile-time checking and code generation. It's a really neat feature that enable you to extend the language in many different ways while still keeping the same syntax and being strictly typed.
But up to now it was quite difficult to write macros, since you had to construct the AST (which is the piece of Haxe code you want to generate) by-hand with enums. For instance let's say you want to generate a String "Hello World", you would have to write :
@:macro static function hello() { var pos = haxe.macro.Context.currentPosition(); return { expr : EConst(CString("Hello World")), pos : pos }; }
And for a more complex for( x in 0...n )
loop :
// repeat the expression 'e' for 'n' times @:macro static function repeat( e : Expr, n : Int ) { var pos = haxe.macro.Context.currentPosition(); // 0...n var ezero = { expr : EConst(CInt(0)), pos : pos }; var eN = { expr : EConst(CInt(n)), pos : pos }; var iter = { expr : EBinop(OpInterval,ezero,eN), pos : pos }; // x in n var ein = { expr : EIn({ expr : EConst(CIdent("x")), pos : pos },iter), pos : pos }; return { expr : EFor(ein,e), pos : pos }; }
This looks quite hard to read, and while you can construct the whole language expressions this way, the more complex it become, the longer it takes.
Until today.
On SVN we have just added a new macro
special word that will greatly simplify the task of writing macro, let's look at how the two previous examples are translated :
@:macro static function hello() { return macro "Hello World"; } @:macro static function repeat( e : Expr, eN : Expr ) { return macro for( x in 0...$eN ) $e; }
What macro
does is to translate a Haxe expression into the corresponding AST enum, by also replacing all $-prefixed identifiers by the corresponding variable value.
I guess this way will make Haxe macros much more easy to write and maintain !
PS : we will make a 2.10 release of Haxe very soon, since we have many great things to share. This will be part of it.
Yes!
This looks much easier :)
I still need to get into the basics of Haxe macros. Up until now it has felt like a "dark art" that only a few understand, but I'm sure there are ways it could come in handy!
I'm just keeping my eye out for the WWX presentations, so I can catch the HXCPP and Macro presentations I missed.
Thanks!
Great. Much easier. No more eval playing.
Looks so simple. Up until now I've only been able to do the most basic of macros, but hopefully with this I can attempt a whole lot more. Very powerful tool now a whole lot easier to use. Thanks very much!
Jason
This is pretty cool!
I was doing some simple macros with a lot of pain before...
What is the possible timeline for this to go mainstream and in Haxe NME?
Sorry but those macros makes HaXe code unreadable. Best example is the great physics engine Nape that is full of macros. perhaps t is usefull only when you work alone.
Ha, I just read in documentation that macros purpose is to make code unreadable... :)
Rytis, actually Nape doesn't use Haxe macros. It uses its own preprocessor called CaXe; Haxe macros aren't like that.
@ex : in 2.10, very soon
hi
i don't understand your for loop example...
@:macro static function repeat( e : Expr, eN : Expr ) {
return macro for( x in 0...$eN ) $e;
}
if i compile repeat(i++, 5)
is $e expression repeated like this
I++;I++;I++;I++;I++;
or like this
for( x in 0...5 ) i++;
and in this case. how to make the fist result with this new keyword ?
What is the scope of the keyword, macro scoped, apply only to the next exp ? can we use parenthesis ?
@peterPh: The second option
So how would one use this with @:build and @:autoBuild type generators?
@Rammserker thanks, i did some investigation since.
not really happy with the syntax.. macro keyword for reification is stange. but it's a really good feature ! macro for everyone now !
will prefer instead... (like string interpolation)