Skip to main content
Changed answer
Source Link
Michael E2
  • 244.7k
  • 18
  • 350
  • 774

Maybe this will be[First answer was wrong - deleted.]

New answer

I rather like Carl Woll's advice, but the problem is an acceptable practical workaroundinteresting exercise nonetheless. Add

Here's an approach that leverages the fact that Mathematics rewrites pattern parameters (adds a def[boo_] := $ in front of) when code is injected. Wrap all functionsthe definitions in booHold to be localized. Then calland add the list of symbols defined by the definitions:

Hold[code, symbols]

Then inject def[boo]code insideinto the definition of the top-level function, with symbols localized with Module. Here's an example that has several definitions to show better how it works (and was a problem in my original answer):

Remove[boo];  (* gives error if youClearAll[foo];
Hold[
 haven't defined boo asboo[a_Integer] in:= theModule[{b first= code5}, inb OP+ *)
a];
def[boo_] := boo[a_] boo[a_Real] := Module[{b = 5}, b +- a];
foo[a_]   boo[a_] := boo2[a];
   boo2[a_] := Module[{boob = 10}, a*b],
   def[boo];{boo, boo2}
 ] /.
 boo[2 a]];Hold[code_, symbols_] :>
   (*foo[a_] this:= changeModule[symbols,
 was convenient in my testing :)code;
 *     {boo[2 a], boo2[a]}])
 ;

Tests:

foo[3]
(*  {11, 30}  *)

DownValues@boo  foo[3.]
(* show the definition of boo{-1., is30.} localized *) 

foo[x]
(*  {20 x, 10 x}  *)

Check the definition of foo:

? foo

Mathematica graphics

Maybe this will be an acceptable practical workaround. Add def[boo_] := in front of all functions boo to be localized. Then call def[boo] inside the Module.

Remove[boo];  (* gives error if you haven't defined boo as in the first code in OP *)

def[boo_] := boo[a_] := Module[{b = 5}, b + a];
foo[a_] := Module[{boo},
   def[boo];
   boo[2 a]];  (* this change was convenient in my testing :) *)
 
foo[3]
(*  11  *)

DownValues@boo  (* show the definition of boo is localized *)
(*  {}  *)

[First answer was wrong - deleted.]

New answer

I rather like Carl Woll's advice, but the problem is an interesting exercise nonetheless.

Here's an approach that leverages the fact that Mathematics rewrites pattern parameters (adds a $) when code is injected. Wrap all the definitions in Hold and add the list of symbols defined by the definitions:

Hold[code, symbols]

Then inject code into the definition of the top-level function, with symbols localized with Module. Here's an example that has several definitions to show better how it works (and was a problem in my original answer):

ClearAll[foo];
Hold[
   boo[a_Integer] := Module[{b = 5}, b + a];
   boo[a_Real] := Module[{b = 5}, b - a];
   boo[a_] := boo2[a];
   boo2[a_] := Module[{b = 10}, a*b],
   {boo, boo2}
 ] /.
  Hold[code_, symbols_] :>
   (foo[a_] := Module[symbols,
      code;
      {boo[2 a], boo2[a]}]);

Tests:

foo[3]
(*  {11, 30}  *)

foo[3.]
(*  {-1., 30.}  *) 

foo[x]
(*  {20 x, 10 x}  *)

Check the definition of foo:

? foo

Mathematica graphics

Source Link
Michael E2
  • 244.7k
  • 18
  • 350
  • 774

Maybe this will be an acceptable practical workaround. Add def[boo_] := in front of all functions boo to be localized. Then call def[boo] inside the Module.

Remove[boo];  (* gives error if you haven't defined boo as in the first code in OP *)

def[boo_] := boo[a_] := Module[{b = 5}, b + a];
foo[a_] := Module[{boo},
   def[boo];
   boo[2 a]];  (* this change was convenient in my testing :) *)

foo[3]
(*  11  *)

DownValues@boo  (* show the definition of boo is localized *)
(*  {}  *)