Hello,
I’m looking for a way to create a zero-touch node that takes a function as an argument. Technically, functions taking other functions as arguments are called HOF (higher-order functions) and Dynamo got such the nodes, e.g. List.Map, Function.Apply or Function.Compose.
For clarity, let’s say I want to recreate Function.Apply taking a function as first argument and single inputs as the rest plus performing additional operations on the function results. My first approach was to use delegates as follows:
public class object MyApply(Delegate func, params object[] args)
{
return func.DynamicInvoke(args);
}
But actually nope, this approach doesn’t work as dedicated Function type is required instead of Delegate. I looked into Dynamo sources and found that the original Function.Apply is built on DesignScript-based FunctionObject.ds library and its __ApplyList method.
The __ApplyList method is then triggered by Apply.cs:
public override IEnumerable<AssociativeNode> BuildOutputAst(List<AssociativeNode> inputAstNodes)
{
return new[]
{
AstFactory.BuildAssignment(
GetAstIdentifierForOutputIndex(0),
new FunctionCallNode
{
Function = AstFactory.BuildIdentifier("__ApplyList"),
FormalArguments = new List<AssociativeNode>
{
inputAstNodes[0],
AstFactory.BuildExprList(inputAstNodes.Skip(1).ToList())
}
})
};
}
My problem is: I would like to use __ApplyList output in further operations in my custom node. Is there any way to get numerical results out of FunctionCallNode or BuildAssignment before BuildOutputAst return? Also preferably without interfering DesignScript as external DLLs must be used on values returned by __ApplyList.
Maybe any other way to take function as argument, without BuildIdentifier("__ApplyList")?