Thanks for this. I’ll check it out. If SoftGlobalScope.jl does the job, I’ll be back and we’ll have a party. I have to say that in the meantime, I’ve already got a body part or two in the jaws of Mathematica. Wish me luck.
Thanks for the interest. My original problem lives here: Global Scope Confusion
You can run IJulia locally. Don’t confuse IJulia with juliabox or whatever cloud server you are using.
SoftGlobalScope doesn’t work in the REPL. It only works in environments that choose to use it, which so far is just IJulia.
Ah, thanks for the correction. I had thought it did.
Aahhh. That sounds promising. Thanks.
This is slightly off topic, but I never liked much having jupyter notebooks in the middle of my browsing tabs.
I like nteract, which provides an isolated desktop app for jupyter notebooks.
It is beta, though, so you can expect some bugs lurking around.
In Unix plataforms it is able to “self-setup” it to look for installed jupyter kernels. I don’t know if it work as easily on Windows.
One aspect of Julia I enjoy is being able to test code in the REPL, and then examine or plot variables, arrays, or vectors after I run a bit of code to see whether it ran as expected. Sometimes I don’t know which variables I would like to examine, and so having these available in the global scope can help immensely in debugging. Using a “let” closure does not allow me to examine the variables after the fact. Is there some means of, say, returning all variables from a function (or a let block) so that I can see them in global scope?
Hi I read through scope rules. These still don’t make very much sense to me. If someone could please explain.I will give a couple examples below.
Fist the classic example a variable to keep track of iterations
x = 0 for i in 1:5 x+=1 end
Gives an " x not defined" ( out of scope).
Yet I can do the below just fine.
a = [1,2,3,4] b = zeros(Int, 4) for (i, x) in enumerate(a) b[i] = x end
None of these variables are in functions and therefore should be in the global scope. According to docs loops are locally scoped so this shouldn’t work. If the top example doesn’t work I am baffled why the second example would work?
This will change in Julia 1.5 to act like you expected.
The difference between the two examples is that your first one is changing what the name
x is used for, whereas the second is changing what value in stored in
Contrary to appearances, the second example doesn’t involve assignment. Instead it’s lowered to
julia> Meta.@lower b[i] = x :($(Expr(:thunk, CodeInfo( @ none within `top-level scope' 1 ─ Base.setindex!(b, x, i) └── return x ))))
The rule that’s being violated by the first one from the scope section of the manual is:
An explicit global is needed to assign to a global variable
Since no global variable is being assigned to in the second example, the rule doesn’t apply.
As noted above, this is set to change in the REPL for v1.5, but the behavior will still be the same in global scope within scripts and packages, so understanding the difference is still important.
Thank you for the explanation. That makes sense. The confusion arises because the x = 0 being an assignment. I understand it but it is not intuitive. This also leads to more confusion because I can do
x = 0 x # returns the value of x as 0
Yet I cannot mutate x by x = 1. It seems to me you should be able to mutate this since the getindex works. However obviously this not an array. That being the case getindex should not work. Coming from other languages that have separate syntax to denote assignment, makes this ambiguous about what is meant “=” and in this case what is an array and what is not.
getindex does not imply
setindex! — there are immutable arrays. Prominent examples include
and many others.
I am wondering if you misread something, since
julia> x = 0 0 julia> x ERROR: BoundsError Stacktrace:  getindex(::Int64, ::Int64) at ./number.jl:78
The only index that works is
x. That comes from a decision to make numbers iterable containers with a single element — it is controversial, but because of compatibility it won’t be changed before 2.0.
Thanks for the reply. Yes ok its starting to make sense now. I did some more reading based on your reply. It’s been very helpful.
“… changing what the name
x is used for…”
i would disagree, in both cases X is used as a variable, albeit a different kind of variable
distinguishing scope behavior on “kind” of variable is highly surprising
This is an old thread. You should try out Julia 1.5 — there things should “just work” as you want them to.
I personally find the traditional mental model of “variables” — that is, boxes that you put things in and out of — to be quite unhelpful for understanding Julia’s behaviors. It’s much more consistent to simply think of them as names. Re-assignment (
x = 1) is simply stating that you now have a better use for a particular name; it is not a mutation.
Locations in an array, however, are precisely boxes with things in them.
im on a mac, installed via the official process
but, sounds great that the thing should work as explained.
then, can anybody verify this as a bug on their mac / system?
It may be helpful to post a new topic that describes exactly what you’re running into with a minimal example folks can use to understand what’s going on.
Edit: ah, I see you have here: Tips to cope with scoping rules of top level `for` loops etc - #28
i perfectly understand that, and as you outline it it is perfectly true. but that entails a heavy abstraction (or rather, “de-abstracts”) upon what a named-assignable-to-entity is normally understood to be. introducing such mental overload in a language which is a codification of intent i think is problematic.
This depends on the language. C++ assigned names, R places things in boxes. Whether it’s intuitive depends on where you are coming from. I would encourage you to take some more time learning julia and reading the manual, over time the behavior of variable assignment will become more intuitive.