HaxeDoc2

(やまだぃちぅ) #1

It is important to understand that arguments to macros are not guaranteed to be evaluated,
so any intended side-effect is not guaranteed to occur. On the other hand, it is also important to
understand that an argument expression may be duplicated by a macro and used multiple times
in the returned expression:
1 import haxe.macro.Expr;
2
3 class Main {
4 static public function main() {
5 var x = 0;
6 var b = add(x++);
7 trace(x); // 2
8 }
9
10 macro static function add(e:Expr){
11 return macro $e + $e;
12 }
13 }


The macroaddis called withx++as argument and thus returnsx++ + x++using expression
reification (9.3.1), causingxto be incremented twice.

9.2.1 ExprOf........................................


SinceExpris compatible with any possible input, Haxe provides the typehaxe.macro.ExprOf.
For the most part, this type is identical toExpr, but it allows constraining the type of accepted
expressions. This is useful when combining macros with static extensions (6.3):
1 import haxe.macro.Expr;
2 using Main;
3
4 class Main {
5 static public function main() {
6 identity("foo");
7 identity(1);
8 "foo".identity();
9 // Int has no field identity
10 //1.identity();
11 }
12
13 macro static function
14 identity(e:ExprOf) {
15 return e;
16 }
17 }


The two direct calls toidentityare accepted, even though the argument is declared as
ExprOf<String>. It might come as a surprise that theInt 1is accepted, but it is a logical
consequence of what was explained about macro arguments (9.2): The argument expressions are
never typed, so it is not possible for the compiler to check their compatibility by unifying (3.5).
This is different for the next two lines which are using static extensions (note theusing
Main): For these it is mandatory to type the left side ("foo"and 1 ) first in order to make sense
of theidentityfield access. This makes it possible to check the types against the argument
types, which causes1.identity()to not considerMain.identity()as a suitable field.
Free download pdf