COMMUNITY

Macro Reification Question

I did not quite understand how to use reification.

			var className = eventClass.name + 'Dispatcher';
			var eventComType = eventType.toComplexType();
			var eventArguments:Array<FunctionArg> = getFunctionArgs(eventClass.constructor.get());

			var newEventExpr = {
				expr: ENew({pack: eventClass.pack, name: eventClass.name}, [for (arg in eventArguments) macro $i{arg.name}]),
				pos: Context.currentPos()
			};

			var dispatcherDef = macro class $className extends eventu.EventDispatcher<$eventComType> {}

			dispatcherDef.fields.push({
				name: 'dispatch',
				pos: Context.currentPos(),
				access: [APublic, AInline, AFinal],
				kind: FFun({
					args: eventArguments,
					ret: macro:Null<$eventComType>,
					expr: macro {
						var event = null;
						if (hasListeners()) {
							event = $newEventExpr; //??????
							dispatchEvent(event);
						}
						return event;
					}
				})
			});

Can I get rid of the variable newEventExpr and insert its calculation in the site where the variable is used

Coming from a beginner myself, as far as I can tell: technically yes, but you would still need to at least create an array holding the event argument identifiers, something like:

var args: Array<Expr> = [for (arg in eventArguments) macro $i{arg.name}];

The line in question could then be replaced with:

event = new $className($a{args});

But you lose the Position information, which is invaluable to debugging. Again, I just started learning about macros today myself, so chances are I got something wrong or forgot about something… :wink:

1 Like

It seems it does not work. As I understand it, the reification syntax can only be used for very simple expressions and for something more serious, you should in any case use the creation of structures from the haxe.macro package. I mistakenly adopted the reification syntax for something like string interpolation, but it has much more limitations. We cannot even read values ​​from nested structures. I also tried to generate a class with fields from a string, but again I failed.

Reification works for new expressions but you need to use a TypePath as argument for it.

Here’s a working example: http://try-haxe.mrcdk.com/#22246

1 Like

Thanks, this example has helped me to understand something. But initially I wanted the code

  public static macro function test() : Expr {
    var classTypePath : TypePath = {
      name : "MyClass",
      pack : []
    }
    
    var args = [(macro 1), (macro "hi")];
    
    return macro new $classTypePath($a{args});
  }

would look something like this

public static macro function test(infos:MacroInfos) : Expr {
    return macro new ${infos.path}($a{[for (arg in infos.argumentsData) getArg(arg)]});
}

It’s just that even for such a simple example, you have to declare a whole bunch of variables that are used only once. And we cannot even place them in some kind of structure in order to at least somehow group the data. It turns out that the classic way of creating expressions can be more compact and readable than reification.

1 Like