-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function defined in global scope has "hard scope", function in any block has "semi-soft scope" #10559
Comments
👍 I hadn't realized just what was going on, but after reading this, I see that I was bitten by these differences many times already. |
@mauro3 I'd describe it differently with the simple rule: "Functions (and types, didn't check but it makes sense) do not implicitly access globals." This makes sense, a global defined anywhere could accidentally modify the behaviour of those constructs. It applies to those constructs since they are the only ones whose existence can exceed the lifetime of their containing scope, so a global created at any time could affect them, There is not really any change in the behaviour of |
Thanks @elextr, presumably you mean "Functions (and types, didn't check but it makes sense) do not implicitly modify globals.", because reading global certainly happens. If the However, I think all of the above still needs spelling out as deducting this from your rule is far from easy. What are your thoughts on making this explicit by introducing the |
Ahh, I meant to say "assign" not "access", thanks for picking that up. I am not sure about spelling it out, that makes it look complex, but the actual rule is simple. But I suppose spelling out the effects may be useful if the simple rule is also mentioned (after one of the experts confirms it is indeed correct).
Personally I always like explicit over implicit, so specifying captures explicitly could be good, but that would make anonymous functions and one line functions incapable of capturing local variables, since their syntax doesn't allow such a declaration. That is likely to break lots of existing code. The alternative is making anonymous and one-line functions implicitly capture, and functions defined with Neither of those alternatives is very attractive, so I think the status quo is the best. |
I think, if a simple rule has complex effects, as is the case here, then those effects need describing. Concerning introducing a
So I see no reason a |
Rambled on about |
The description in this issue makes it seem more complicated than it is. There aren't really so many different kinds of scope. All variables are inherited by inner scopes for both reading and writing, unless explicitly overridden with If
Would the |
Ok... I think the bugs brought up in #7234 have just been clouding the issues for everybody, making things seem a lot more complicated. Does it look like it will be difficult to fix? |
Thanks Jeff and Lex, you make it sound so easy... Thanks Jeff for confirming Lex' |
In Julia, function-blocks and type-blocks introduce a hard scope (see #9955 for an explanation of hard and soft scope). However the hard scope is only introduced if not nested inside another block. If nested then they become "semi-soft scopes". Example:
Some thoughts:
I think the main reason for semi-soft scope is to make certain types of closures possible. An idiomatic example from base/multi.jl:
This relies on the soft-scoping of
next_pid
. If functions were to get totally hard scope, some way to refer to outer variables but not globals would be needed (see #5331), as writingglobal next_pid
would refer to anext_pid
in the scope outside the let-block:Considering that the current example already needs one
global
statement, a furthernonlocal
statement is not bad in exchange for a lot more consistency.To discuss:
This has come up before: #423 (comment), #5331 and #7234. However, in those issues it is not as clearly documented as here, thus a new issue.
The text was updated successfully, but these errors were encountered: