The infamous issue https://github.com/JuliaLang/julia/issues/28789 has been on most of our minds for a while now. Although I’ve stopped posting there, I can tell you I’ve been thinking about it a lot, as have Stefan and Jameson and others, and we have continued discussing it off and on. We should really try to get it right.
Last time around, we more-or-less settled on changing only the REPL, which has the main advantage of being non-breaking for most code. But after sleeping on it, it does not sit well to have different behavior in the REPL and files. So I’m coming around to another possible solution, which falls out of assuming the following two properties are mandatory:
- Updating global variables in loops in “just works”.
- The scope of variables in top-level expressions can be determined statelessly; i.e. it doesn’t depend on what has been evaluated before.
From discussions with Stefan and Jameson, the simplest solution to these constraints seems to be just making everything outside of a function global, unless it is explicitly declared with local
or let
(or a for
loop iteration variable, since for
works like “repeated let
”). Another way to state the rule is that assignments can only implicitly declare local variables inside functions.
This is similar to what we had pre-0.7, but simpler since it does not depend on which global variables have been assigned already. The downside, of course, is that it makes more variables global “by default”, which can be particularly painful in long test suites, but the simplicity and possibility of local reasoning mostly make up for that in my mind.
Of course, this would be a breaking change, but we can separate what the “right thing” is from how to get there. One piece of good news is that since the 1.0 behavior has the stateless property, it should be straightforward to write a femtocleaner rule that inserts needed local
declarations to retain 1.0 behavior where needed.
Thoughts?