Title: on passing a pure function to a module
Tags: wolfram-mathematica
Question: Just wanted to check if it safe to do the following:
Lets say I have a function 'f(x)' that also depends on other parameters. For example, the function a*Exp[ (x-x0)^2/(2*std^2)]
From the UI I read the user input values (via sliders) for the parameters a and x0 and std, then I make a pure function variable
f=Function[{x,a,x0,std}, a*Exp[ (x-x0)^2/(2*std^2)]
The above is done in the same context (in the Manipulate control area), when I am reading the user input, then when the user hits a button to run the program, I call another lower level function to process this input, like this
foo[f,a,x0,std]
then inside foo, it evaluates f over some grid points (x1,x2,etc...) by making calls like this
foo[f_,a_,x0,std_]:=Module[{x1,x2...},
.....
f[x1,a,x0,std];
f[x2,a,x0,std];
f[x3,a,x0,std]; etc...
....
Notice that inside foo, only the x parameter to the pure function is used, the rest are just coming along for the ride.
But since they are not used inside foo, I am thinking of not passing all the other parameters a,x0,std.
So, I changed the pure function to become
f=Function[{x}, a*Exp[ (x-x0)^2/(2*std^2)];
then called foo like this
foo[f]
then inside foo, I do
foo[f_]:=Module[{},
.....
f[x1];
f[x2];
f[x3]; etc...
....
I tested this, and it works. (at first I thought since the context is different inside Module foo, I had to pass a,x0,std along with f. But I did not have to. It seems the a, x0 and stdx values inside the pure function as saved as globals and passed in the pure function body.
My question: do you see any problem with the second approach above? something I am overlooking? in the tests I've done, it works fine so far. And it would make it much simpler, since now I only need to pass the pure function itself, and not pass all the other parameters used to build up, since they are not needed inside foo.
In other words, I am trying to decide between these 2 setups:
Just thought to check.
thanks

Here is the accepted answer: How about something along these lines:
mkf[a_, x0_, std_] :=
Function[{x}, Evaluate[a*Exp[(x - x0)^2/(2*std^2)]]]
foo[f_] := Module[{x},
x = 1;
f[x]
]
foo[mkf[1, 1, 1]]
You generate the function you want to use before passing it onwards.
Comment for this answer: With is fine too; in some cases you may be able to use Evaluate to get things simplified as much as possible. The point is to generate a new function that is independent of other variables.
Comment for this answer: The fact that I used Evaluate[] was to show that this method actually can have the advantage that the function body can already at this stage be manipulated (optimized); you could generate a compiled function instead. Adding a Block[{x}] might be good, if you use global variables.
Comment for this answer: +1 - I would have done it similarly (generate a closure with embedded constants). One thing though: since you use `Evaluate` (which is not strictly needed here), only the renaming of `x` to `x$`, done by (presumably) `SetDelayed / RuleDelayed`, saves `x` in the function body from accidental collisions with the possible global value for `x`. (which happens e.g. here: `x = 1;Function[{x}, Evaluate[a*Exp[(x - x0)^2/(2*std^2)]]]`). I don't know whether we can always count on renaming scheme in such cases, but one easy protective measure would be to wrap the r.h.s. of `mkf` into `Block[{x},...]`.
Comment for this answer: @Nasser You can use the method suggested here, also in case when your parameters are not known in advance, or you find it inconveneinet to generate a function beforehand: simply generate the function already inside the `Module`, and then apply it.
Comment for this answer: good idea. So you basically replaced the parameters by numbers, except for the x, so that when the pure function is passed, only x the free variable in it. Should be safer. How about in this case, if I use With to build f? as I show in my edit(1). Same idea as yours. seems to have the same result. thanks
Comment for this answer: Actually I tried With now, and it is not giving the exact looking FullForm as yours. Hard to read. But I'll stick with your method. Seems simpler. So I Evaluate it, this changes all the other parameters to numbers, and this seems much better. Do not need to worry about symbols in the body of the pure function. thanks.


{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 1, 'CommentCount': 0, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2012:00:01/12/12', 'FavoriteCount': 1.0, 'PostTypeId': 1, 'Tags': '<wolfram-mathematica>', 'Title': 'on passing a pure function to a module', 'ViewCount': 1638, 'id': 8835292, 'user_AboutMe': None, 'user_AccountId': 399717.0, 'user_DisplayName': 'Nasser', 'user_Reputation': 12637.0, 'user_Views': 1372.0, 'user_id': 765271.0}}