5

Is it allowed to define local functions inside the Module in Mathematica? For example, out of the two codes below which one is correct?

First:

plt1[a_, b_] := 
    Module[{x, y},
        f[x_, y_] := Sin[x*y];
        Plot3D[f[x, y], {x, -a, a}, {y, -b, b}]
    ];

plt1[1, 2]

Second:

plt2[a_, b_] := 
    Module[{f},
        f[x_, y_] := Sin[x*y];
        Plot3D[f[x, y], {x, -a, a}, {y, -b, b}]
    ];

plt2[1, 2]

Harken
  • 105
  • 6
  • 4
    The first one makes x,y local, but f global. Making x,y, local is not necessary, because Plot3D localizes its variables. The second one makes f local. Therefore, the second one is the right way. – Daniel Huber Jan 08 '22 at 14:15
  • @Daniel Your point is made very clearly in your comment. Perhaps you could convert it to an answer. – MarcoB Jan 08 '22 at 17:57
  • @Daniel Thanks a lot for the clarifications. – Harken Jan 08 '22 at 22:12
  • You have to be careful with local functions like your f in the second example, since often (but not in your case above) they will not be automatically garbage-collected. I recommend reading this Q/A for more information on that. – Leonid Shifrin Jan 10 '22 at 16:48

2 Answers2

5

The first example makes x,y local, but f global. Making x,y, local is not necessary, because Plot3D localizes its variables. This leaves f global what can creates troubles.

The second example makes f local and does not unnecessarily localize x and y. Therefore, the second example is the right way.

Daniel Huber
  • 51,463
  • 1
  • 23
  • 57
4

Yes. Have a look at the localized definition of a function using a localized symbol.

Module[{f}, f[x_] := x^2; DownValues[f]]
(* {HoldPattern[f$6838[x_]] :> x^2} *)

Module renames the localized symbols. In this case f becomes f$6838. You may do the same things with a localized symbol that you can do with a global symbol.

John Doty
  • 13,712
  • 1
  • 22
  • 42