# Evaluation in lambda function

If I have a function, that returns a function, for example:

f[a_] := a^2 * # &


then

f[3] == 3^2 # &


Is there a way to tell mathematica that I want part of the function evaluated, so that

f[3] == 9 # &


Obviously this example is quite simple, but in general the evaluation may be slow, and better if it's only performed once. I tried wrapping the important part (in this case, a^2) in 'Evaluate', but that didn't help.

Thanks!

• You need to wrap the whole thing in Evaluate. Try: Evaluate[a^2 * # ] &
– rm -rf
Feb 8, 2014 at 18:26

The general way to construct functions with partially evaluated pieces is to use With, which is a general device for injecting evaluated pieces in otherwise unevaluated or held expressions. In your case, it would look like

f[a_] := With[{sqa = a^2}, sqa * # &]


The method based on Evaluate is generally less powerful, since evaluation of the entire body may be not desirable, while more deeply nested Evaluate will not result in what you want, due to the (local) way of how Evaluate works (because Function does not evaluate its body at the time it is constructed, the evaluation process, associated with the construction of the function, simply won't come to more deeply nested Evaluate instructions).

• I thought the OP wants to cache the result of f[3] such that f[3] can be run many times without calculating a^2 again and again (though he is happy with this answer). In this case, a single With or Evaluate doesn't help. Caching is also needed: f[a_] := f[a] = With[{x = a^2}, x*# &]. One can use Trace to see the difference. Feb 8, 2014 at 19:46
• With your answer, if I run f[3] // Trace, the result is {f[3],With[{sqa=3^2},sqa #1&],{3^2,9},9 #1&}. I guess the OP does not only want to run f[3] and get 9 # &, but also f[3] is only calculated once. This is what I can read from his sentence "Obviously this example is quite simple, but in general the evaluation may be slow, and better if it's only performed once. " I didn't see how With[...] can speed up things here without memorization. Feb 8, 2014 at 20:23
• Well, I think there are two cases depending on how to use f[3] with the calculation "only performed once". One way is let, say, g=f[3], and use g many times. Another is directly use f[3] many times. In the former case you are right, and your answer fully fills the OP's need. In the latter case, memorization is also needed. I don't know which is the exact case here... Feb 8, 2014 at 20:30
• @YiWang No need to explain to me why f[3] recomputes every time with my method, I don't disagree with you on that. My point is that, from where I stand, the OP did not ask for the f[n] calls optimization, and his problem was how to inject evaluated parts into otherwise unevaluated body of the function. In my experience, it is often better to not make additional assumptions, w.r.t. those made by the OP. Particularly in this case, where the question has been formulated quite clearly. If the OP wants memoization, there is plenty of information on it on this site already. Feb 8, 2014 at 20:35
• @LeonidShifrin For what it's worth, I understood the question the same way as Yi Wang, i.e. define f so that 3^2 is not computed each time in f[3] (but not necessarily via memoization). I don't disagree with your answer though.
– rm -rf
Feb 9, 2014 at 3:13

Leonid already named the big one, With, but there are a few more approaches I'd like to outline. First of all you can use Evaluate if you wish to evaluate the entire body of the Function, and if the Function isn't part of some larger held expression. I fully agree with Leonid however that With is more general and less prone to surprises here. Nevertheless for reference:

f[a_] := Evaluate[a^2 #] &
f[7]

49 #1 &


Likewise you can Apply Function to a List (or any other inert Head without a hold attribute):

f[a_] := Function @@ {a^2 #}
f[7]

49 #1 &


For spot evaluation in a deeper expression (like With) you can use a replacement rule in an inverted fashion. (See this Q&A for more examples.)

f[a_] := a^2 /. x_ :> (x # + 2 + 2 &)
f[7]

49 #1 + 2 + 2 &


Note that 2 + 2 is not evaluated. Also note the placement of ( ) to group the right-hand-side of RuleDelayed, because & has low operator precedence.