62,137 reputation
6188280
bio website mathprogramming-intro.org
location St. Petersburg, Russia
age 38
visits member for 3 years
seen 22 mins ago

Ok, an obligatory note: opinions expressed here are mine and not those of my employer.


19h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@Mr.Wizard Actually, one thought that crossed my mind is that when I get a spare moment, I will try to write down those scoping rules, such that the set of those rules would explain all cases we discussed here on SE, as well as all other known cases. Having those rules would probably be useful, because presumably they would make it quite easy to predict the outcome in most or all cases. Although, some of them are indeed borderline bugs, like the one about nested bindings, that I discussed in the linked question.
19h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@Mr.Wizard And yes, of course, you have my vote. As to the settings, I don't really know. I think, in different situations, either one or the other may have advantages. I'd set StrictLexicalScoping to True, probably.
20h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@SimonWoods Perhaps the exemption should not apply from the end user's point of view, but I was trying to make a point that this behavior is consistent with the general principles that underpin the lexical scoping machinery in Mathematica. If something has to be changed, that should be the core principles, not specific consequences like this one, IMO. That's what Daniel's new option / mode does: it changes some of these principles, which affects a bunch of different cases at once. He was able to find a solution which resolved all or most of them at once.
20h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@Mr.Wizard Oh, I am sure you do, you always have valid points. I actually think we've never went so deep into these sorts of issues before in our discussions here on SE, this is certainly one of the darker corners of the language. We shouldn't go too deep, though, if we want to heed Daniel's warning and avoid the outcome of being institutionalized.
21h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@Mr.Wizard So, according to the rules of how scoping constructs work and resolve conflicts in inner constructs, the observed behavior is actually correct, when we recall that Set is 1. Scoping construct requesting to protect its variable bindings (both l.h.s. and r.h.s, this has nothing to do with its evaluation semantics), and 2. Has evaluation semantics which in fact evaluates the r.h.s during assignment.
21h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@Mr.Wizard So, during the binding stage, both l.h.s. and r.h.s. pattern variables are being protected. It is this "protection request", that forces Module to disable its binding procedure for these inner local variables. In other words, from the binding perspective, h remains local also for Rule and Set, and the fact that the global value is used for it during evaluation, is an effect of evaluation semantics, and happens during evaluation stage, which follows the binding stage.
21h
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@Mr.Wizard I don't quite agree with your conclusions here. And here is why. The fact that Rule and Set aren't HoldAll, does not prevent them from being scoping constructs. The defining property of a scoping construct is that, apart from special evaluation stage and semantics, it also has a precluding variable binding stage. That Rule and Set are not HoldAll, influence their evaluation semantics, but not binding semantics, which is for them in fact the same, as for RuleDelayed and SetDelayed, respectively. Namely, protect their bindings from outer scoping constructs.
1d
awarded  Enlightened
1d
awarded  Nice Answer
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau Which is what your new lexical scoping mode actually does, as far as I understand.
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau As to working correctly in all cases, I am not even sure that the "transparent" model of lexical scoping where all bindings are programmatically exposed and we have transparent (say to pattern-matching) expressions, allows that even in theory. You will probably be able to construct counter-examples with leaks no matter how sophisticated the new design of lexical scoping would be, if we keep this kind of transparency. At least I wouldn't be very surprised if that were true. So the question may be more about solving it for the vast majority of actual uses, than completely.
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau For me, the main value in such deeper digging is that occasionally, one can find constructive uses of such behavior. Because really, even though it is flawed, it can be entirely controlled by the user (who has a clue of how these things work), like those techniques to fool that mechanism in some cases. So experienced users knowing what they are doing can take advantage of that. Sealing the scoping more tightly is likely to close a number of such possibilities. Still, for the majority of users, the correct but less controllable behavior is better.
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau All right, correction accepted :). I should be very thankful that I never had the time and will power to try looking at it myself.
1d
revised I define a variable as local to a module BUT then the module uses its global value! Why?
Restructed the answer to be more logically consistent
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau I have added a note with your suggestion to my post - see if you agree with what I wrote, or please feel free to edit to your liking.
1d
revised I define a variable as local to a module BUT then the module uses its global value! Why?
Added a note on Daniel's suggestion to use the StrictLexicalScoping option to avoid this behavior
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau But I have not looked at internal code, let alone understand it in all detail, while you did, so I may well be wrong here. Perhaps, my main point here was to enforce Occam's razor principle and show how the observed behavior can be consistently explained from a smaller set of principles of how scoping constructs operate currently (in the default mode) in Mathematica. It would be nice if your StrictLexicalScoping mode could become a default some time soon.
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@DanielLichtblau I knew in general, but it didn't occur to me to test it in this particular case. Here I tried to describe the current default model (the old one, before your work), and actually it is kind of logical for what it does. It's another question that, from the language design point of view, it is indeed a flaw - but I'd say, more flaw in that design, than in implementation. If we assume that the design is that Set and SetDelayed protect their bindings no matter what, then the implementation works fine. I think that if something is flawed, it is this design.
1d
comment Assigning new value in association
I have covered exactly this case in this answer, towards the end of the section named "Complications". What works is temp[[1]][[Key["Gender"]]] = "M" (apart from suggestions from other answers, but I believe my suggestion is closer to your original attempt).
1d
comment I define a variable as local to a module BUT then the module uses its global value! Why?
@pan_e_gaban Was glad to help! Thanks for the accept. Just keep in mind, that generally, it is a good practice to wait with accepting an answer for a little bit, to encourage others contribute more answers.