I have a module which calls number of other smaller helper modules. But those other helper modules are not used by another module, so there is no needed to have them in global context. So I wanted to move them to be inside the main module which is the only one that uses them to help improve the code. But I found two main issue when doing this.
First issue conflict in names of argument input
If the helper function uses the same input argument name, as in the main module, error is generated when moving the helper module inside it.
Here is a MWE. This is the before layout of the code
boo[a_]:=Module[{b=5}, b+a ];
foo[a_]:=Module[{}, boo[a]];
Now foo[3]
returns 8
and works. Now moving boo
inside foo
for better encapulation
since boo[]
is only needed by foo
, the layout becomes
foo[a_]:=Module[{boo},
boo[a_]:=Module[{b=5}, b+a]; (*boo now local*)
boo[a]
];
But M does not like the above
You can ask, why not simply rename the argument(s) of boo and rename all references inside the boo
code to the new name(s)? Yes, in this simple example I can change the code and do
foo[a_]:=Module[{boo},
boo[aa_]:=Module[{b=5}, b+aa];
boo[a]
];
foo[3]
(* 8 *)
Second issue helper function uses same local variable name as input argument of main module
If the helper function happened to have local variable in it, which has same name as the input argument of the main module, then also an error is generated. Here is an example. The before, which works
boo[aa_]:=Module[{b=5,a=3},b+aa+a];
foo[a_]:=Module[{},boo[a]]
foo[3]
(* 11 *)
The after layout
foo[a_]:=Module[{boo},
boo[aa_]:=Module[{b=5,a=3},
b+aa+a
];
boo[a]
];
foo[3]
The above examples shows that it is not easy to do what I wanted, without careful code rewrite all the time due to these conflicts.
The above are simple examples. The code I have is much larger which means I have to go make number of changes, renaming variables all over the place each time. So I end up now having many smaller functions all in global space, even though many of them can be put inside the Modules that really uses them.
Is there a trick to bypass this problem? Is there a better way do the above? Would workbench help in this?
Maple have no problem using the same setup
references safe-way-to-put-a-pattern-on-the-right-hand-side-of-a-rule http://reference.wolfram.com/language/ref/message/Rule/rhs.html
boo
doesn't depend on the arguments tofoo
, thenfoo
has to work harder because it definesboo
every time it is called, instead of havingboo
defined once. Also, ifboo
is ever left unevaluated, either in the output offoo
or in a side effect, thenboo
will never get removed, causing a memory leak. Finally, it is much harder to debugboo
when it is defined in a Module. $\endgroup$boo
each time parent module is called. Too advanced for me to understand now. Thanks,. $\endgroup$