Define function args via reification

I know how to define a function via:

FFun({
	args:functionArgs,
	expr: macro {
		$b{[fields.map((f)->macro this.push($i{f.name}))]}
		return length;
	}
 });

But Is there a way to define the function args via reification, ex:

public function push($a{functionArgs}):Int
{
	$b{[fields.map((f)->macro this.push($i{f.name}))]}
	return length;
}

I was told it’s not possible, any know?

Certainly!


Function arguments cannot be directly defined via reification in method signatures like your example. Consider using macros or dynamic handling within the function body for similar functionality.

1 Like

Thanks! where did you find that? I didn’t see anything here: Expression Reification - Haxe - The Cross-platform Toolkit

That sounds like they copied the answer from ChatGPT, which isn’t very good at citing its sources. It’s right that in this specific case you could handle the arguments dynamically (though it should have mentioned rest arguments), but that’s missing the point.


To answer your question, $a{ } ought to work here, but doesn’t. Maybe we should submit an issue. In the meantime, I would declare the function without any arguments, then add them later:

final definition:TypeDefinition = macro class MyClass {
	public function push(/* args defined below */):Int
	{
		$b{[fields.map((f)->macro this.push($i{f.name}))]}
		return length;
	}
};

switch(Lambda.find(definition.fields, field -> field.name == "push").kind) {
	case FFun(f):
		f.args = functionArgs;
	default:
}

Since that second part is a bit messy, I would probably extract it into a helper function (e.g., setFunctionArgs("push", functionArgs)). You don’t have to include the comment, but IMO the main reason to use reification is to make it human-readable, so it’s important to leave notes about counterintuitive stuff.