I'm trying to make a function where the input is an expression, but somehow it just won't be evaluated. For example, this little function doesn't work:

test[exp_] := Module[{x}, NestList[Function[x, exp], 2, 3]]
(* {2, x^2, x^2, x^2} *)

And I would really like this output:

NestList[Function[x, x^2], 2, 3]
(* {2, 4, 16, 256} *)

Can anybody help?

  • 2
    $\begingroup$ Try NestList[ #^2 &, 2, 3] $\endgroup$
    – Artes
    Oct 27, 2012 at 20:23
  • $\begingroup$ as @Artes points out: test[exp_] := NestList[exp, 2, 3]; test[#^2 &] does the trick? Or following your investigation test[Function[x,x^2]] $\endgroup$
    – chris
    Oct 27, 2012 at 20:41
  • 1
    $\begingroup$ b.t.w. welcome to Mathematica.SE! I suggest the following: 1) As you receive help, try to give it too, by answering questions in your area of expertise. 2) Read the FAQs! 3) When you see good Q&A, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge. ALSO, remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign` $\endgroup$
    – chris
    Oct 27, 2012 at 20:44
  • $\begingroup$ Thanks for your answer. But I would really like the input to be test[x^2] or test[2x+5], and not test[Function[x,x^2]]. Isn't that possible? $\endgroup$
    – Simon
    Oct 27, 2012 at 21:30
  • 1
    $\begingroup$ Something to think about: It's not worth writing several lines of code that relies on a more complicated function (e.g., extractPureFunction) just because you don't want to write it as test[#^2&] or test[x^2,x]. The saner thing to do in such cases would be to adopt the style that results in shorter and cleaner coding. $\endgroup$
    – rm -rf
    Oct 27, 2012 at 22:25

2 Answers 2


Good question (and one that has bitten me in the past:) The reason for your troubles is the ways scoping of Function works. That's easiest to demonstrate with module however.


You see that instead of x x$nnn was returned. For more info I recommend reading this.

Block has the expected behavior by the way:


How about function? The file states: help file

A small test

test[exp_] := Function[x, exp]
(*Function[x$, x^2]*)

So we see that the formal parameters of function have been renamed to x$ and no longer match the x you have put in. Here are some solutions:

Pass the function to your method

As has been suggested in the comments, you can pass the function as the argument.

test[f_] := Module[{x}, NestList[f, 2, 3]]
test[#^2 &]
test[Function[x, x^2]]

(* ==> {2, 4, 16, 256} *)    
(* ==> {2, 4, 16, 256} *)

Pass the variables along with the expression

test[exp_, vars_] := Function[Evaluate@vars, exp]
test[x^2, x]
(*Function[x, x^2]*)

Or inserted into your original example

test[exp_, vars_] := NestList[Function[Evaluate@vars, exp], 2, 3]
test[x^2, x]
(*{2, 4, 16, 256}*)

Oh and if you give your function the HoldAll attribute, then it will not be bothered by existing assignments to x

SetAttributes[test, HoldAll]
test[exp_, vars_] := NestList[Function[vars, exp], 2, 3]
x = 5
test[x^2, x]
(*{2, 4, 16, 256}*)
  • $\begingroup$ Hey, you've almost made it to the first page! congrats! $\endgroup$
    – rcollyer
    Oct 28, 2012 at 3:02
  • $\begingroup$ Thank you everybody for your help. My problem is solved. Have made my little function, that will save me a lot of time. Ajasja: I see your point, but the function I gave you was just an example of what was troubling me... Thank you again everybody! $\endgroup$
    – Simon
    Oct 28, 2012 at 16:43

Since @Artes does not seem to want to write up his answer, let me explain why you attempt almost works but not quite.

This works

  test[exp_] := NestList[exp, 2, 3];

  (* {2, 4, 16, 256} *)

That doesn't

  test[exp_] := Module[{x}, NestList[Function[x, exp], 2, 3]]

because, within the Function, x is a local variable (say x$123) which does not match the one involved in the argument of test when you call test[x^2].

Without pure functions

So if you really want to be able to use a formal expression (rather than a pure function) as an argument to test, you could use the function extractPureFunction that was implemented and discussed in this thread as follows

  test[exp_] := Module[{ff=extractPureFunction[exp]}, NestList[ff, 2, 3]]

so that

  test[x^2]; test[Sin[y]]; test[Sin[x]+x+4];

works. But keep in mind this construction is not bullet proof: for instance


doesn't work (because it identifies a function of two parameters x and y).

As I find the extractPureFunction quite useful (I have it in my init.m file) I repeat it here (with as a bonus the getAllVariables function that it uses). The credit goes to Daniel Lichtblau I believe(?)

 headlist = {Or, And, Equal, Unequal, Less, LessEqual, Greater, GreaterEqual, Inequality};
 getAllVariables[f_?NumericQ] := Sequence[]
 getAllVariables[{}] := Sequence[]
 getAllVariables[t_] /; MemberQ[headlist, t] := Sequence[]
 getAllVariables[ll_List] :=Flatten[Union[Map[getAllVariables[#] &, ll]]]
 getAllVariables[Derivative[n_Integer][f_][arg__]] :=
 getAllVariables[f_Symbol[arg__]] :=Module[{fvars},
    If[MemberQ[Attributes[f], NumericFunction] || MemberQ[headlist, f],
       fvars = getAllVariables[{arg}],(*else*)fvars = f[arg]]; fvars]
 getAllVariables[other_] := other

 extractPureFunction[expr_] := 
 Module[{vars, func}, vars = getAllVariables[expr];
 If[Length[vars] > 1, vars = Union[vars]];
 func[vars, expr] /. func -> Function]
  • $\begingroup$ because, within the Module, x is a local variable (say x$123) which does not match the one involved in the argument of test when you call test[x^2] I think that Module is not at fault here, but that Function renames it's formal parameters anyway. $\endgroup$
    – Ajasja
    Oct 27, 2012 at 21:42
  • $\begingroup$ @Ajasja you are most certainly right. $\endgroup$
    – chris
    Oct 27, 2012 at 21:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.