-
-
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
improve documentation of soft vs. hard scope #9955
Comments
There was some more discussion on julia-users https://groups.google.com/d/msg/julia-users/bQxvNw21hC4/s3wHzRCe9UQJ. There a good reference to an old comment of Stefan was made: #423 (comment) In that julia-users thread, I posted these soft/hard rules:
However, these rules break down for nested functions, which seem to have a soft scope?! Here an old example: #423 (comment): function namespace()
x = 0
function f()
x = 10
end
f()
println(x)
end
namespace() # prints 10, suggesting the inner function has soft-scope!? I think this is a bug, right? Or should it feature in the rules: only outer functions have hard scope. |
Hello mauro3, your rules make sense to me. I have done an notebook illustration based on your rules. You can find it at https://drive.google.com/open?id=0B30Cah_MN0i0TlZfRlBXLWgxbE0&authuser=0 I tested it in IJulia notebook. Behaviors in script remain untested. |
Furthermore, for nested function, only the outermost function should be considered to be a hard scope. The inner functions are soft scope. |
Here is the notebook rendered: http://nbviewer.ipython.org/gist/mauro3/9b92ac4adfb1d845f3fc. Looks like the rules work for your examples, thanks! About the semi-soft scope of inner functions, I filed #10559 for discussion. |
This really ought to be documented. @JeffBezanson, you implemented it and probably understand the subtleties the best of anyone and thus are in the best position to document it. Are you willing to do that? |
I think I now see through it but I can't take care of it until July. See @elextr and @JeffBezanson comments here: #10559 (comment) |
It would be great if someone could add the rationale behind why "Notably missing from this list are begin blocks and if blocks, which do not introduce new scope blocks." But why? What is so special about Making matters even more confusing (though this is probably just a bug) is that there is an exception to the exception when a begin
x = 1
const y = 2
local z = 3
end
println(x) # works because of the exception for begin and if blocks
println(y) # works because of the exception for begin and if blocks
println(z) # fails because of the exception to the exception for begin and if blocks So, what is the rationale/justification behind this complexity? And thank you for the fantastic language you have coming along! |
|
I am aware of my_anon_func = x -> begin
#...
end to be written without adding two new levels of scope (one for my_anon_func = function (x)
#...
end isn't desired for (e.g.) style uniformity in cases where multiple anonymous functions that are mostly one-liners are used. Is there any other use case for And the exception for x, y = if condition
1, 2
else
3, 4
end (adding new lines after commas if needed for longer variable names and/or initialization expressions) in place of # `local x, y` not currently needed here
if condition
x = 1
y = 2
else
x = 3
y = 4
end Was the decision to make |
I highly recommend digging into the source if you're interested in these sorts of questions. In this case, you'll find that almost every usage of As far as discussions of |
Ah yes, I didn't consider the utility of an unscoped As for my question about the code snippet above (shown below for reference), it is not a bug. local z = 3
println(z) # fails (ERROR: UndefVarError: z not defined)
x = 1
local x = 2
println(x) # prints 1, not 2 Original code in question: begin
x = 1
const y = 2
local z = 3
end
println(x) # prints 1
println(y) # prints 2
println(z) # fails (ERROR: UndefVarError: z not defined) |
It would be better to have using |
I believe this thing is that |
To illustrate what I think @StefanKarpinski is referencing (the following at global scope): local x = 1 # currently works, but this `x` can never be used
local y # fails (ERROR: syntax: misplaced "local" declaration)
begin
local z # ok here because `z` is assigned by the end of the block
z = 1 # but `z` can't be used outside of the block
end |
@mauro3 - But On the other hand, Julia (seemingly) has more complex scope rules that vary on a case-by-case basis, which I understand is a trade-off between consistency and pragmatism. It would be nice if Julia's scope rules could be summarized more concisely as is the case with some languages (e.g. Python and Matlab). As it stands, types, functions, loops, let blocks, try-catch-finally blocks, and optionally macros are what introduce new scope. More of a mouthful than One way to make things look more uniform in Julia would be to make the closing keyword e.g. |
@StefanKarpinski, no,
The examples of @asoffa must be bugs, unreported as far as I can tell. Can you file an issue for this? |
It's #10472. |
I thought this issue seemed familiar, but failed to search in the closed issues, thanks! |
Here's another issue (either a bug or missing documentation): x = 1
function f()
x = 2
end
f()
println(x) # prints 1
let
x = 3
end
println(x) # prints 3 <--- desired? The behavior of |
This is soft vs hard scope. Have a read of the overhauled scope section: #12146 (here a semi-rendered version. |
@mauro3 - Thank you for pointing me to the upcoming scope documentation. This is much more complete, and the table at the beginning is really helpful for seeing which language construct introduces which type of scope (or lack thereof in the case of Julia's scope rules now seem more complex than ever, requiring an understanding of the the distinction between global vs. hard local vs. soft local vs. no new scope for each language construct along with how each scope-related declaration ( module-type blocks ---> global scope This would provide a higher-level starting point that would make learning the scope table easier. |
Fixed with #12146, please close. |
See julia-dev discussion here: https://groups.google.com/forum/#!topic/julia-dev/-qIVQGq-f_U
The text was updated successfully, but these errors were encountered: