# Fix function that doesn't evaluate when passed to a package?

GROUPS:
 Hi, I'm baffled by the following...if I define a function in a notebook as follows: func = Function[x^2][x]; I can call it in the notebook: Table[func, {x, 1, 6}] {1, 4, 9, 16, 25, 36} I can also call it in a function defined in the notebook: runNb[func_] := Module[{}, Table[func, {x, 1, 6}] ] runNb[func] {1, 4, 9, 16, 25, 36} but, when I try to run this as a package, the function doesn't evaluate: BeginPackage["run"] run::usage = "run[func]" Begin["Private"] run[func_] := Module[{}, Table[func, {x, 1, 6}] ] End[] EndPackage[] and, calling from the notebook: << run.m run[func] {x^2, x^2, x^2, x^2, x^2, x^2} Makes no sense to me! Can anyone please explain?Thanks
10 months ago
7 Replies
 Perhaps the local variable x inside the package is not the same as the global variable in the definition of func. Try this: BeginPackage["run"] run::usage = "run[func]" Begin["Private"] run[func_] := Table[{Context[x], func}, {x, 1, 6}]; End[] EndPackage[] and evaluate run[func]. I get {{"runPrivate", x^2}, {"runPrivate", x^2}, {"runPrivate", x^2}, {"runPrivate", x^2}, {"runPrivate", x^2}, {"runPrivate", x^2}} I don't know what you are trying to achieve with func. The variable x in [x] in Function[x^2][x] does not matter. You get the same output with Function[x^2][y].
10 months ago
 Hi Gianlunca and thanks for the reply.Original problem was I wanted to take a list of functions and pass them into a package which had a plotting function. This did not work, so I started stripping things down and found the core of the problem was that the functions were not evaluating. I had written the functions like so: funcs = {x^2, x^3, x^4} I thought it might be because I wasn't explicitly defining an anonymous function, so that's why I used the Function call above.I did try to use global x in the package like so: BeginPackage["run"] run::usage = "run[func]" Begin["Private"] run[func_] := Module[{x = Globalx}, Table[func, {x, 1, 6}] ] End[] EndPackage[] But this didn't help. I think the x is local to the Table block and so should just be replaced in the anonymous function. Either using global x or not shouldn't matter.
10 months ago
 Gianluca Gorni 1 Vote Module does not replace the local variable x in Table: Module[{x = 3}, Table[x, {x, 0, 2}]] You can do that with With: BeginPackage["run"]; run::usage = "run[func]"; Begin["Private"]; run[func_] := With[{x = Globalx}, Table[{x, func}, {x, 1, 6}]]; End[]; EndPackage[]; The way I would define a function and do a table of the values is this, however: f[x_] := x^2; BeginPackage["run"]; run::usage = "run[func]"; Begin["Private"]; run[func_] := Table[func[x], {x, 1, 6}]; End[]; EndPackage[]; run[f] 
10 months ago
 John Hendrickson 1 Vote Note that it's a bad practice to use x from Globalbecause (users/you) may be using it for something else and other "bad" packages may introduce further confusion. For this reason when it's necessary to offer convenience to use Global use a LONG NAME (and not something cryptic). However: use of Options[run] is a better way to handle allowing (user) to set variables generally used by parts of a package. Yet another way is to define something outside of Private that can be replaced by user without need of Unprotect[], ex runx (note this can still become a problem with Global).Note also that your code "could work" (the x inside table will be runPrivatex if you check ?runPrivate*, in general if x does not exist Mathematica will create it - in this case not in Global). If a Private defined function that is also public (outside of Private) takes arguments, the arguments can of course, be functions. However you need to study Context[] closely. It's well likely your problem is a corrupt runtime environment confusing things (you may have Globalrun defined and not realize it).Finally, if you find Mathematica is USING Globalx in the Table (it shouldn't), then use run[func_]:=Module[...]. Also note Mathematica WONT use Globalx if you define x in runor runPrivate.Study more about Context[]
 @Gianluca thanks for the help, I like what you did with your second piece of code.@John totally agree about not using Globalx. I find Mathematica's handling of variables pretty frustrating sometimes.Well, I would say I'm still not happy here. It makes no sense to me that you cannot pass a function defined in a notebook to another function defined in a package. It's just my expectation that the function will evaluate. I don't think using Globalx is the way to go. Although I like Gianluca's second approach, I think it is a workaround and doesn't solve the initial problem.
 Gianluca Gorni 2 Votes Your way to define a function func = Function[x^2][x] is very bizarre. It is totally equivalent to writing func = x^2 so that it is more an algebraic expression than a function. You cannot write func[2] to get its value when x=2, but you have to do something like func/.x->2 or Block[{x = 2}, func]. Your use of the global variable x is dangerous for various reason.The usual, elementary way to define a function is this: func[x_] := x^2 You can also use Function, but the correct syntax would be something like this: func = Function[x, x^2] Either way you evaluate func[2] and get 4.
 OK, I got everything working now, thanks to Gianluca Gorni. As pointed out, my mistake was how I was defining functions. Even though it was incorrect, it was working in the notebook. New code that is working both in the notebook and with a package follows.Package is now: BeginPackage["mypackage"] run::usage = "run[func]" Begin["Private"] run[func_] := Module[{}, Table[func[x], {x, 1, 6}] ] End[] EndPackage[] and code in notebook is: << mypackage.m func = #^2 &; run[func] `Thanks for taking the time to help me out on this!