I am almost sure that this question has been asked somewhere. I found similar ones, but I cannot find exactly what I need, which might mean that I am on the wrong track.
I search a method to pass an unevaluated function with arguments to a second function. I could achieve this with SetAttribute[,HoldAll]
. However the arguments of the first function should be evaluated when I pass it, which does not seem to be the case with Hold
.
To give an example: I tried things like:
mytest[test_] := Module[{}, Print[test];]
mytest1[test_] := Module[{}, myvar = 2; ReleaseHold[test];]
SetAttributes[mytest1, HoldAll]
myvar = 1
mytest1[mytest[myvar]]
This prints 2
, because that is the value of myvar
when ReleaseHold
is called. However I want it to print 1
, the value of myvar
when I call mytest1
. In general myvar would be an expression which may contain global variables. I do not insist on using ReleaseHold
. In fact the solution should be such that mytest
would be evaluated by NIntegrate
. In Maple I would achieve this by enclosing the name mytest
in single quotes when passing it to mytest1
which would delay evaluation by one step.
Edit
For clarification consider the following example, which is closer to the real case:
parameters = {a -> 1}
mytest[expr_, parameters_] := Module[{},
NIntegrate[expr*a /. parameters, {var, 0, 1}]
]
mytest1[parameters_] := Module[{},
globpar = 1;
NIntegrate[mytest[globpar*var*var1, parameters], {var1, 0, 1}]
]
mytest1[parameters]
Mathematica returns the correct result 0.25
for this, but it issues a couple of error messages like NIntegrate::inumr: "The integrand var\ var1 has evaluated to non-numerical values for all sampling points in the region with boundaries {{0,1}}."
. I want to avoid this (not by suppressing the error message!), because I want it to be fast and also the real function mytest
might have a worse behavior if you insert non-numerical values. Hence I want that NIntegrate in mytest1
first inserts a numerical value for var1
and then passes the resulting expression as an argument to mytest
to integrate it over var
. I.e. I want that it evaluates the argument of the function first, which can however still contain names after evaluation.
Unevaluated
comes close but it's not the same). $\endgroup$With[{myvar=1}, mytest1[mytest[myvar]]]
?With
can be used to inject something into a held expression. $\endgroup$