# Pure function within another function

I am writing a function along the lines of the following:

func[basis_,coordinates_,vars_]:=Table[Function[vars,monomial]@@@coordinates,{monomial,basis}]


The idea would be to call somethings like

func[{x,x*y},{{0,1},{1,2}},{x,y}]


and then receive as output

{{0,1},{0,2}}


However, vars as it appears on the right hand side is not the same vars as appears on the left hand side because of how Function works. (Mathematica warns of this by highlighting vars in red with the message "A variable name has been used twice in a nested scoping construct, in a way that is likely to be an error.")

First, how can I get around the name scope problem that Mathematica warns about? Then, is this even a appropriate way to go about what I am trying to do?

Thanks!

• Alternative to pure functions: {x, x*y} /. Thread[{x, y} -> Transpose@{{0, 1}, {1, 2}}] or basis /. Thread[vars -> Transpose@coordinates] (provided basis consists of poly/mo-nomials). – Michael E2 Jul 7 '17 at 16:50
• Related tutorial: reference.wolfram.com/language/tutorial/…. Related Q&A: (13757), (20766), (95471) – Michael E2 Jul 7 '17 at 17:24
• Thanks for the references! – Grayscale Jul 12 '17 at 12:59

## 3 Answers

ClearAll[func1]
func1[basis_, coordinates_, vars_] :=
Table[(Function @@ {vars, monomial}) @@@ coordinates, {monomial, basis}]

func1[{x, x*y}, {{0, 1}, {1, 2}}, {x, y}]


{{0, 1}, {0, 2}}

or

ClearAll[func2]
func2[basis_, coordinates_, vars_] :=
Table[(Function[x, y] /. {x -> vars, y -> monomial}) @@@ coordinates, {monomial, basis}]

func2[{x, x*y}, {{0, 1}, {1, 2}}, {x, y}]


{{0, 1}, {0, 2}}

Another way:

func[basis_, coordinates_, vars_] := Function[vars, #] @@@ coordinates & /@ basis;

func[{x, x*y}, {{0, 1}, {1, 2}}, {x, y}]
(*  {{0, 1}, {0, 2}}  *)


After some tinkering, this seems to work:

func[basis_, coordinates_, vars_] :=
Table[With[{monomial = monomial},
Function[Evaluate@vars, monomial] @@@ coordinates], {monomial,
basis}]


The Evaluate@vars prevents Function from treating vars as a symbol (which would result in a one-parameter Function). Instead, it passes {x,y}, as you need. See comments on this answer for discussion of why this is wrong.

I confess I don't full understand why we need the With statement. My current level of understanding is that there's some funny business going on between the Table variable's scoping and the Function's HoldAll attribute, so we need With to force the Function to properly deal with monomial as a table variable. See other questions, e.g. (Function in Table) or perhaps (How can I create a List of Functions), for more informed discussion.

• The need for the With statement is curious... it looks like it can be replaced however by evaluating monomial within Function, like this: func[basis_, coordinates_, vars_] := Table[Function[Evaluate@vars, Evaluate@monomial] @@@ coordinates, {monomial, basis}]. Why it needs to be evaluated, I am still not sure though. – Grayscale Jul 7 '17 at 16:04
• Also it seems like the Module[{mon},...] is not needed... how come you have that in the function definition? – Grayscale Jul 7 '17 at 16:06
• @Grayscale Ah, good catch on the Module[{mon},...] -- it's an unwelcome relic of a bygone version of the code. I'll get rid of it presently. – jjc385 Jul 7 '17 at 16:24
• @Grayscale Yes, I actually realized that after I read klgr's answer -- a nice trick I learned on this site is to use f@@{a,b} rather than f[Evaluate@a, Evaluate@b]. The point of the With[{monomial=monomial},... statement is to force the variable to evaluate anyway. – jjc385 Jul 7 '17 at 16:31
• If you Trace[] the command, it shows the renaming: func[basis_, coordinates_, vars_] := Table[With[{monomial = monomial}, Function[vars, monomial] @@@ coordinates], {monomial, basis}]; func[{x, x*y}, {{0, 1}, {1, 2}}, {x, y}] // Trace. (Note that monomial is also renamed, but that is irrelevant to the problem, I think.) The red vars is just a warning of a potential scoping conflict, which we have in this case but not in my answer. – Michael E2 Jul 8 '17 at 3:54