3
$\begingroup$

Here is an example code:

a = 1;
b = 1;
c = a + b;

f[x_, y_] := Module[{a = 3, b = 2, c}, c = (x + y)*(a + b)];

a,b,c are used outside of the function f and also inside f.

How can I ensure that all used variables in a function are local WITHOUT specifing all of them in Module[{local variables},...]. This can be extremely annoying when I use many variables.

$\endgroup$
  • $\begingroup$ Why not just create unique variables then? $\endgroup$ – Feyre May 5 '17 at 11:49
  • $\begingroup$ @Feyre: I want to reuse some SAME variable names outside and inside the function. $\endgroup$ – lio May 5 '17 at 12:32
4
$\begingroup$

I guess this is a duplicate but I can't find it. Here's something you may find useful:

myModule // ClearAll
myModule // Attributes = {HoldAll}
myModule[expr_] := Module[
    { spec = (
          Union[ Join @@ Cases[
              Hold[expr]
           ,  s_Symbol /; Context[Unevaluated[s]] === "Global`" :> Hold[s]
           , {-1}
           , Heads -> False
          ]]
      ) /. Hold[spec__] :> Hold[{spec}]
    }
  , Module @@ (Hold[Evaluate[Unevaluated @@ spec], expr])
]

a = 1;
b = 1;
c = a + b;

f[x_, y_] := myModule[a = 3; b = 2; c = (x + y)*(a + b)];

f[1, 2]
a
b

15

1

1

Short explanation

  • Cases extracts all symbols from Global` context, could be not from System` but then Package symbols would be used too. I know Global` isn't always the $Context so maybe $Context would be better? Don't know, up to you.

    It ignores head so from f[g,h] only g and h will be extracted. Do you want that? Again, don't know, feel free to change it.

    At the end it returns {Hold[g], Hold[h],...

  • then we transform this result to Hold[{g,h,...}

  • Module assembling

$\endgroup$
  • $\begingroup$ This is exactly what I was looking for. Perfect. But, I am not able to understand what the code is doing. Could you please shortly describe in words what you main idea was. Thank you. $\endgroup$ – lio May 5 '17 at 13:01
  • $\begingroup$ @lio let me know if that is enough $\endgroup$ – Kuba May 5 '17 at 13:16
  • $\begingroup$ Thank you for the explanation. This is a very important solution for all newbies who are coming from other languages to Mathematica. Am I really the first who is asking this question, I cannot believe it? $\endgroup$ – lio May 5 '17 at 13:36
0
$\begingroup$

As described in Modules and Local Variables, there is no other way of making variable literally local, than specifying it in the Module statement. You may consider declaring list as a local variable: Module[{locVars={1, 3, 4}}... and referring its elements or introduce an wolfram language package with its own private symbols: Setting Up Wolfram Language Packages.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.