Skip to main content
1 of 4
Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k

Shotgun thoughts:

  • You don't need the Hold/ReleaseHold pair; Unevaluated will do: Unevaluated[f] /. rules

  • You can use direct destructuring to extract extvar: curvature[f_, range : {var_, __}] :=

  • By using var 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.

Mr.Wizard
  • 273.1k
  • 34
  • 595
  • 1.4k