That example was intended to be interpreted in the context of the potential change proposed in the thread (or in v0.6), for which s is indeed global in the loop.
Of course, I was not talking about the syntax itself changing the performance, but the interpretation of that syntax by the compiler.
It’s not a matter of time so much as whether we have enough improvements to be worth breaking things again (see Another possible solution to the global scope debacle - #19 by jeff.bezanson). If tomorrow we had a way to make the language 10 times faster and solve everybody’s problems with breaking changes, it could indeed make sense to release 2.0 tomorrow. However I think that would still be perceived negatively. It would look like we’re still breaking things just as much as we always did, and merely labeling it differently.
This is the part that concerns me. In my understanding of SemVer, there is no negative consequence of incrementing major versions - it’s simply a notification that there are one or more breaking changes in the code and that the stability agreements need to be changed.
The reality is as you’ve described, however. We’re now in a position where a change that is necessary for adoption (assuming one believes, as I do, that not fixing the scoping rules is a significant obstacle to adoption among CS and non-CS folks alike) cannot be implemented in any sort of reasonable timeframe - not because a solution doesn’t exist, but because we’re worried about the negative implications of releasing a new major version so soon after the 1.0 release.
I get it; we’re struggling with this in JuliaGraphs. My thought right now is that we’re imparting significance to major versions that either wasn’t anticipated by, or was rejected by, the SemVer standard. This is causing us to tie our own hands with respect to getting code out there that can actually drive adoption of this great language.
That’s true, but it’s an undeniable psychological reality. Can you picture the blog post? “Julia 2.0 is here: see what’s in store!” followed by a single line of release notes saying “global scope thingy changed back”. It’s completely laughable.
Also, doesn’t changing the behavior in the REPL cover most of it? Nobody seems to disagree that can be done in 1.x.
I know I already made a comment advocating not breaking semver, but I wanted to directly address this point and way of framing things. The “cost” talked about here exists whether we call the new version of Julia “1.3” or “2.0”. Either way, both “hard-scope” Julia and “global-scope” Julia exist in the wild, and users and developers have to reckon with that–whether they’re aware of the difference or not. The only difference is that calling it “2.0” is explicit in communicating that a difference exists while calling it “1.3” hides that cost.
I think that the argument is that this change is so unlikely to affect existing code that hiding the “cost” is the course with the highest overall utility. I disagree and think that any positive marginal utility from not forcing users to reckon with that cost is more than offset by the cost/confusion/dishonesty (imo) of having intentional breaking changes within a major release number.
The compromise here would be that we can change the REPL first, then in 2.0 change files to match. But if we want to eventually change file behavior to match, we need to make sure we’re really happy with the way it works and not have it just be a hack only acceptable in the REPL.
I have done just that: we release Julia 1.1 with a slight semantic versioning violation and communicate it clearly by other means than the version number.
I would not find a blog post a la “We realized we made a mistake in a key part of julia 1.0, we have fixed it and are releasing this as julia 2.0. We are sorry, this was not planned and we very much hope this won’t happen again in the future.” laughable at all. In fact, I would find it much more reassuring than some form of “we are following semver, but just not in this case”.
Take this as a data point from one user (me) how he would perceive various communications strategies, not a suggestion what you should do. You know your customer base better than I do, and this might well be the wrong strategy for others.
Ok, I appreciate that, but it’s not happening. The number one issue is the cost/benefit analysis of having more incompatible versions of julia out there just for this one subtle scope thing. The perception stuff is secondary. Yes we may have made a mistake here, and while I’m willing to admit that I’m not willing to make such a big deal out of it. This does not warrant a contrite blog post, as if we’ve leaked millions of credit card numbers or something. I guess if somebody else wants to write a contrite blog post they can, but I’m not going to.
I wonder if the proposed solution will handle all globals the same? It shouldn’t matter whether the global is defined and used in the REPL or inside the file (module). Uniformity (and the attendant simplicity) are in my opinion much preferable to any real or imagined convenience.
The argument applies if we’re not planning to release the change in 1.x, and also not planning to release 2.0 soon. We’d have more time with fewer different versions out there, and after a longer period of time before 2.0 people might be more willing to upgrade again.
Let’s please keep this thread on the merits of the technical solution, not how to get there or recriminations and scolding about what has or has not been done wrong.
Just want to add a +1 to the proposed solution and deprecation path here.
In fact, I would find it much more reassuring than some form of “we are following semver, but just not in this case”.
Don’t get me wrong, I’m a huge proponent of SemVer - especially it’s terminology.
However, the huge practical benefit of SemVer is that it helps clarify what is and what isn’t a backwards-compatible change (by forcing a definition of public API). The whole point is that having that kind of technical clarity makes it way easier to communicate the potential for breakage to downstream projects.
I think it is just as effective from a communication standpoint to say “we’re going to explicitly break from SemVer in this minor case, since doing otherwise would cause more practical harm than good.” Especially when that’s followed up by “here’s an exact description of how we’re going to break from SemVer, and here’s the exact path this nonstandard deprecation will take”. You’re maintaining the same level of technical clarity, just taking a different path in order to minimize potential real-world damage.
Another way to look at it is: having both Julia 1.x and 2.x out there in the world has a cost. People need to spend more time dealing with the existence of incompatible versions. (I don’t want to dwell on it, but of course the python 2/3 split is the canonical example.) To pay that cost, there has to be some balancing benefit: Julia 2.0 has to be significantly better than 1.0 to make it worthwhile.
I, for one, thought that this change would be painful but at the end it wasn’t. Probably because I find the SoftGlobalScope solution sufficient:
1- Prototype/debug interactively and freely in IJulia, not worrying about scope
2- Do IJulia.SOFTSCOPE[] = false to catch any unintended scoping “bugs” that I had overlooked
3- Move things into functions/modules
I agree that some solution is needed, and helpful, for interactive environments. Some solutions are already available, some more will be discussed here.
All in all, asking people about their opinions on a tired Friday afternoon (US time at least) may not be very productive, this scope issue is already blown out of scope
Is there a clear explanation somewhere for why the scoping rules for “children” scopes of global scope must be different for children scopes of local scopes? What edge cases exist that mean we can’t have for blocks within global scopes inherit variables from the global scope while also establishing their own local scope (current behavior of sub-scopes of local scope)? I’m sure examples of these edge cases have been shown before somewhere, but I’m struggling to find them.
They can, if you’re willing to declare local or global on variables inside the loop. If you’re not willing to do that (which people aren’t, which is the source of the controversy here), then the only options are default to global (the proposal here), default to local (1.0 behavior), or make it depend on context somehow (<=0.6).