The backdrop: I’m starting to learn the language and am playing around with both JuliaBox and locally installed JuliaPro.
Here’s a silly way to create 3x3 array of three 0s, 1s and 2s arranged randomly:
using Random
myvec = shuffle([fill(0,3); fill(1,3); fill(2,3)])
mymat = myvec[1:3]
for i = 2:3
mymat = hcat(mymat, myvec[fill(3*(i-1),3)+(1:3)])
end
This code snippet works without complaint on JuliaBox running Julia 1.0.3 and fails on JuliaPro running 1.0.2. The error is:
UndefVarError: mymat not defined
in top-level scope at base/none
in top-level scope at untitled:5
So it seems that the definition of mymat at line 3 is not available within the for loop in my JuliaPro but is available within the loop when using JuliaBox.
Can someone enlighten me as to what’s going on?
Thanks - and please tell me if this is the wrong place for very basic questions like this.
Thanks for that. So, if I want to use a proper IDE and therefore choose to use JuliaPro locally then must I declare globals explicitly, or can I just add and use the SoftGlobalScope package to make code that works on JuliaBox work w/o modification on JuliaPro?
Yes, if you add and use SoftGlobalScope then the REPL will work the same as IJulia. There’s also a potential change being worked on for base Julia that would make the global annotation unnecessary in such usages.
Yup, I tried the three basic SoftGlobalScope calls in JuliaPro already. As Steven said, no such luck… I think I can preface loops with SoftGlobalScope macros but that’s not really any easier than just declaring globals. It’s too bad that JuliaPro and JuliaBox cannot be (easily) made fully interoperable. You guys should highlight that code can’t simply be ported from JB to JP w/o modification. Or perhaps highlight that you’re not kidding about the “Pro” part… Still, channeling (and probably mangling) Aristotle: “The roots of education are bitter, but the fruit is sweet”
The REPL hooks are easy enough to add in with SoftGlobalScope, it’s just a case of running the code in this gist. The only problem is that running it blindly (i.e., without considering whether you’re using Revise or not) can mess up Revise.
It should be possible to do something with Requires to automate this but I’ve never got around to it.
I would recommend wrapping such code (and most code) in functions almost always, without thinking about it. Combined with Revise.jl, it leads to a very convenient and efficient workflow.
Production code in Julia uses globals very sparingly, if at all. Mostly they are used in a pedagogical setting.
So what’s the best-practice suggestion for iteratively updating a variable? I’m used to writing something like
var2update = initial_value
for i=range2iterate
var2update = some path dependent fn of i and inital_value
end
To avoid the bad practice of using globals does the hard scoping force me to wrap every loop in a function? E.g., are you suggesting that I write
loopFn1 = function(var1, numIter)
for i in 1:numIter
var1 += 1
print(var1,“\n”)
end
end
loopFn1(0,5)
instead of
var1=0
for i=1:5
var1+=1
print(var1,“\n”)
end
I can certainly do this, but it seems cumbersome. I understand how hard scoping helps me avoid hard to diagnose bugs, though, so maybe I should just change my coding habits in other more permissive languages, too.