7

In a recent question [1] OP asked how to make Module scope working inside Set, so how to get:

f[x$123_] = x$123

instead of

f[x_] = x

from

Module[{x}, Defer[f[x_] = x] ]

It is stated in Details of Module ref page that:

Before evaluating expr, Module substitutes new symbols for each of the local variables that appear anywhere in expr except as local variables in scoping constructs.

My question is - why this exception is present? What common usage cases dictated this behaviour? Does this makes something safer?

I don't complain, I'm just curious. I don't know why Module can't just change every x it sees to x$1232? Current rule looks like an exception which causes only troubles.


It is even more interesting when we introduce y which will rename x

Module[{x , y = 1},
 Defer[f[x_] = x y]
 ]
f[x$_] = x$ y$7519

[1] How to scope Pattern labels in rules/set?

Kuba
  • 136,707
  • 13
  • 279
  • 740
  • Sorry, I didn't follow everything. Is this about weirdness like this? x = 1; Module[{x = 2}, Print[x_ -> x]] Note how the x within the Module is actually evaluating to its global value. – Szabolcs Jul 03 '16 at 10:21
  • 1
    SetSystemOptions["StrictLexicalScoping" -> True] fixes that. – Szabolcs Jul 03 '16 at 10:56
  • Is this a duplicate? Be sure to read all the comments. I asked there why StrictLexicalScoping is not turned on by default. – Szabolcs Jul 03 '16 at 11:04
  • @Szabolcs I'm aware of that option but it gives f[x$_] = x$ not x$1231. Moreover, the question is why a particular implementation was chosen. – Kuba Jul 03 '16 at 11:04
  • We can also use Block instead of Module here as a kind of workaround. I know that brings its own issues. – Szabolcs Jul 03 '16 at 11:07
  • @Szabolcs yes, I should add your comments to the question so it's clear those things are known. Yep Block has own issues, here 20766 Block fixes it but expr (and all symbols that are really temporary) shouldn't be Block's variables, yet mixing Block and Module will generate the problem again... – Kuba Jul 03 '16 at 11:17
  • @Szabolcs ... So here we are again, why something like that isn't default, why won't Module change every x it sees to x$1232? inner scoping constructs can deal with this, inner Module will further rename to x$1232$1233 so why not? That seems like a clear rule and meanwhile we have to workaround renaming that was supposed to make life easier. Again, StrictLexicalScoping isn't the answer here, x$ is not enough imo. – Kuba Jul 03 '16 at 11:18
  • @Szabolcs just for the record, while both questions ask "why" my asks for something different so I don't agree it is a duplicate. Also, I have rephrased the question, is it clearer maybe? – Kuba Jul 03 '16 at 15:28
  • I didn't vote to close, I just put the link there ... – Szabolcs Jul 03 '16 at 17:08
  • @Szabolcs sure, but you asked a question so I answered ;) – Kuba Jul 03 '16 at 19:23
  • Closely related, perhaps a duplicate candidate: (72758) – Mr.Wizard Jul 08 '16 at 06:53
  • 1
    @Mr.Wizard While Leonid says he will explain "what and why" he rather explains "what and how". There is a statement "such renaming h -> h$123 has to be prevented." which my question really ask about. Why it has to be prevented. You have started to explain it too but with not real examples "why" it is not desired for Set and Rule. So if you want to extend your thought about that specific part, here is a good place ;) – Kuba Jul 08 '16 at 07:12
  • The last sample can be further simplified: Module[{y}, Defer[f[x_] = x y]] – xzczd Feb 06 '22 at 15:18

0 Answers0