# Defining pure function using module

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.)

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

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]

• 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 – goweon Oct 13 at 3:14
• @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] – xzczd Oct 13 at 12:58

From comment by Jason B: Evaluate the body.

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