%mathpiper,def="Apply"

10 # Apply(_applyoper,_applyargs) _ (Or(IsString(applyoper), IsList(applyoper))) <-- ApplyFast(applyoper,applyargs);
20 # Apply(applyoper_IsAtom,_applyargs) <-- ApplyFast(ToString(applyoper),applyargs);

30 # Apply(Lambda(_args,_body),_applyargs) <-- `ApplyFast(Hold({@args,@body}),applyargs);
UnFence("Apply",2);

%/mathpiper



%mathpiper_docs,name="Apply",categories="User Functions;Functional Operators"
*CMD Apply --- apply a function to arguments
*STD
*CALL
	Apply(fn, arglist)

*PARMS

{fn} -- function to apply

{arglist} -- list of arguments

*DESC

This function applies the function "fn" to the arguments in
"arglist" and returns the result. The first parameter "fn" can
either be a string containing the name of a function or a pure
function. Pure functions, modeled after lambda-expressions, have the
form "{varlist,body}", where "varlist" is the list of formal
parameters. Upon application, the formal parameters are assigned the
values in "arglist" (the second parameter of {Apply}) and the "body" is evaluated.

Another way to define a pure function is with the Lambda construct.
Here, instead of passing in "{varlist,body}", one can pass in
"Lambda(varlist,body)". Lambda has the advantage that its arguments
are not evaluated (using lists can have undesirable effects because
lists are evaluated). Lambda can be used everywhere a pure function
is expected, in principle, because the function Apply is the only function
dealing with pure functions. So all places where a pure function can
be passed in will also accept Lambda.

An shorthand for {Apply} is provided by the {@} operator.

*E.G.
In> Apply("+", {5,9});
Result: 14;

In> Apply({{x,y}, x-y^2}, {Cos(a), Sin(a)});
Result: Cos(a)-Sin(a)^2;

In>  Apply(Lambda({x,y}, x-y^2), {Cos(a), Sin(a)});
Result: Cos(a)-Sin(a)^2

In>  Lambda({x,y}, x-y^2) @ {Cos(a), Sin(a)}
Result: Cos(a)-Sin(a)^2

*SEE Map, MapSingle, @, Lambda
%/mathpiper_docs