5
$\begingroup$

I am creating a function fun which takes a parameter p and returns a pure function:

ClearAll[fun];
fun[p_] :=
 Module[{f, x0},
  f = 1 + #^2 &;
  x0 = p;
  f[#]/f[x0] &]

But the resulting fun seems to preserve some scoping stuff; for example

fun[0]
(* f$317[#1] / f$317[x0$317] & *)

instead of returning 1 + #1^2 & as expected. On the other hand, passing an argument to the pure function makes it work normally:

fun[0][x]
fun[1][x]
(* 1 + x^2 *)
(* (1 + x^2) / 2 *)

How can I make fun[0] return 1 + #1^2 &?

(The reason I use Module[{f,x0},...] is because I want to obtain x0 from solving an equation involving f' and p, but that is unrelated to the scoping problem, which occurs even for the simple assignment x0 = p.)

$\endgroup$
1
  • 6
    $\begingroup$ fun[p_] := Module[{f, x0}, f = 1 + #^2 &; x0 = p; Evaluate[ f[#]/f[x0] ] &] $\endgroup$
    – Jason B.
    Apr 27, 2017 at 15:06

2 Answers 2

2
$\begingroup$

The main issue here is Function has attribute HoldAll so you need to break it through in this case. Jason B has shown one solution in the comment, another possible way is to make use of Apply:

ClearAll[fun];
fun[p_] := Module[{f, x0}, f = 1 + #^2 &;
  x0 = p;
  Function @@ {f[#]/f[x0]}]

fun[0]
$\endgroup$
2
  • $\begingroup$ How would this work with named formal parameters instead of slots? e.g. Function[x, 2x]. For example, Module[{expr}, expr = 2 x; Function[x, Evaluate[expr]]] does not work and the resulting function always returns 2x as an expression rather than double the input $\endgroup$
    – goweon
    Oct 13, 2019 at 3:14
  • 1
    $\begingroup$ @goweon I guess you've commented in the wrong place? Apply is free of this issue: Module[{expr}, expr = 2 x; Function @@ {x, expr}] Another possible solution is: Module[{expr}, expr = 2 x; Function[x, #] &@expr] $\endgroup$
    – xzczd
    Oct 13, 2019 at 12:58
1
$\begingroup$

From comment by Jason B: Evaluate the body.

fun[p_] :=
 Module[{f, x0},
  f = 1 + #^2 &;
  x0 = p;
  Evaluate[ f[#]/f[x0] ] &
 ]
$\endgroup$

Your Answer

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