Stumbled on Local variables when defining function in Mathematica in math.SE and decided to ask it here. Apologies if it is a duplicate - the only really relevant question with a detailed answer I could find here is How to avoid nested With[]? but I find it sort of too technical somehow, and not really the same in essence.

Briefly, things like f[n_]:=Sum[Binomial[n,k],{k,0,n}] are very dangerous since you never know when you will use symbolic k: say, f[k-1] evaluates to 0. This was actually a big surprise to me: by some reason I thought that summation variables and the dummy variables in constructs like Table are automatically localized!

As discussed in answers there, it is not entirely clear what to use here: Module is completely OK but would share variables across stack frames. Block does not solve the problem. There were also suggestions to use Unique or Formal symbols.

What is the optimal solution? Is there an option to automatically localize dummy variables somehow?

  • $\begingroup$ Related: Do Table iteration variables need to be localized using Module?. The question asks about Table but it applies to Sum as well. Short answer: use Module. $\endgroup$ – WReach May 4 at 17:48
  • $\begingroup$ @WReach Thank you. Seems mine is a duplicate, except there is this thing in an answer to that math.SE question I linked to - that Module would share variables across stack frames. Is this correct? $\endgroup$ – მამუკა ჯიბლაძე May 4 at 19:21
  • 1
    $\begingroup$ Yes, I did not vote to close because of the "extra question". I don't have time to write up a proper answer now, but... Unique would just replicate what Module does internally. Sum uses an implicit Block already, so adding another does not help. Formal variables run the risk of name collisions. The unique temporary symbols generated by Module simulate local variables well enough to be indistinguishable from them for most practical purposes. $\endgroup$ – WReach May 4 at 21:31
  • 1
    $\begingroup$ For this specific example you can use f[n_] := Evaluate@Sum[Binomial[n, k], {k, 0, n}] $\endgroup$ – Bob Hanlon May 5 at 5:15

The main issue and its solution are discussed in Do Table iteration variables need to be localized using Module? In short, using Module is the correct way to guard against accidental variable name collisions.

Addressing some of the comments from the linked question:

  • Adding an explicit use of Block will not change the situation because Sum and Table already use an implicit Block to temporarily block any pre-existing value of the summation or iteration variable.
  • "when you use recursion, a local variable defined in Module will be shared across stack frames, Block will have a separate version of the variable in each call". This statement is misleading. For each call Module creates a new symbol while Block reuses the same symbol (albeit after temporarily clearing the existing value). Perhaps this claim refers to the fact that Module only simulates local variables by generating uniquely named temporary variables in the global scope. But the net result is indistinguishable from true local variables for most practical purposes, including recursion. It would take some effort on our part to actually share the values of these variables across the Wolfram Language analog to stack frames (likely using Hold etc).
  • Explicit use of Unique and Temporary to create temporary unique variables would just be a more verbose way to achieve the same effect as we get by using Module.
  • Use of formal symbols would run the risk of a name conflict if the caller happens to use the same formal symbols as those used within the called function.

For discussion about the differences between Module and Block (and With), see What are the use cases for different scoping constructs?

| improve this answer | |

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.