I am using Block inside the definition of some recursive functions.

If the Block definitions use short variable names, like {s = First[param], r = Rest[param]}, an infinite recursion occurs when param contains one of the symbols s or r.

Using tortured local symbols names minimizes this risk, but

  • it makes code unreadable,
  • it does not prevent the collision risk, but only minimizes it.

How to deal with local variable assignment without any collision risk?

Substitution rules and Modules have their own problems with recursive functions, which is why I use Blocks, but it's maybe the wrong tool.

Edit: There is no good reason not to use Module, except if one wants to locally modify the recursion limit, it seems. For my part, I was just confused, and I should just use Module.

  • 3
    $\begingroup$ What is the problem with using Module? I think it would be the right tool here. $\endgroup$ – celtschk May 4 '12 at 7:41
  • 1
    $\begingroup$ When there's a chance that symbols will be passed to your function, and you have no control over what those symbols might be (i.e. it's an end-user accessible function), then Block is almost never a good solution. So what's wrong with Module? It seems to me that Module is the way to go here, but you didn't explain what the problem is with it. $\endgroup$ – Szabolcs May 4 '12 at 7:42
  • 2
    $\begingroup$ Why don't you provide a complete minimal self-contained example of what you are trying to achieve and which problems you encounter. Your current question does not contain enough information for a meaningful answer. $\endgroup$ – Leonid Shifrin May 4 '12 at 7:45
  • 2
    $\begingroup$ @ruebenko Personally, I tend to rewrite my code in a tail-recursive style as soon as I discover a need to change the $RecursionLimit - it is all to easy to crash the kernel resetting this value, and I would not trust the code which does that. $\endgroup$ – Leonid Shifrin May 4 '12 at 7:51
  • 2
    $\begingroup$ If you absolutely must use Block and cannot use Module, put the local variable symbols in a private context: Begin["myfun`"]; myfun[x_] := Block[{s=1}, x+s]; End[]. Now myfun[s] will return s+1 as expected. $\endgroup$ – Szabolcs May 4 '12 at 7:51

If you don't want to have the Module inside the function, you can also put it around the function, and then use Block inside, as in

  f[param_List]:=Block[{s = First[param], r = Rest[param]}, ... ]

However, for this special case, I'd use the abilities of the pattern matcher:

f[{s_,r___}] := ...
  • $\begingroup$ Thanks, I actually can use Module, I was confused. I will edit my question to clarify that and accept your answer :) $\endgroup$ – agravier May 5 '12 at 18:51
  • $\begingroup$ @agravier: Thank you for the accept. $\endgroup$ – celtschk May 5 '12 at 19:51

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.