Shotgun thoughts: - You don't need the `Hold`/`ReleaseHold` pair; `Unevaluated` will do: `Unevaluated[f] /. rules` - You can use direct [destructuring][1] to extract `extvar`: `curvature[f_, range : {var_, __}] :=` - By extracting `var` as above you can `Block` it directly, simplifying everything. - You can leave the `Table` variable out of the main `Block` as it is already localized. - `res /. {z_} :> z` can replace the line `If[Length[res] == 1, res = res[[1]]]; res` - In fact `res` can be eliminated and the rule applied to the `Table` - You can pre-evaluate your `1/Sqrt[Total[D[fn,var]^2]]` expression; this should be faster, and also eliminates the need for the replacement inside the `Table` Putting it together I would write: SetAttributes[curvature, HoldAll]; curvature[f_, range : {var_, __}] := Block[{var, fn}, fn = If[ListQ[f], f, {var, f}]; fn = 1/Sqrt[Total[D[fn, var]^2]]; Table[fn, range] /. {z_} :> z ] You will notice red highlighting of `var` signifying a *possible* conflict; this is *not* a problem and is in fact exactly what I desire: the sharing of `var` between the function, the `Block`, and the `Table`. [1]: http://mathematica.stackexchange.com/a/8399/121