Noob question: why does attached code snippet work on JuliaBox but not JuliaPro?


#1

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.


#2

IJulia automatically uses SoftGlobalScope whereas plain Julia 1.0 in the REPL does not. It is a very good question.


#3

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?


#4

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.


#5

Ok, tx again.


#6

No it won’t. To do this, we would need to hook into the REPL, which we aren’t currently doing because it would conflict with other packages:


#7

Ah, sorry. I was under the impression that this is what SoftGlobalScope did.


#8

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” :smiley:


#9

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.


#10

SoftGlobalScope just provides the transformation tools; it’s up to other packages to use it. Currently only IJulia does AFAIK.

The fact that IJulia does this transformation by default has taken some of the pressure of confused users off, but I still think the REPL needs to do something similar … https://github.com/JuliaLang/julia/issues/28789 still needs to be addressed. There is also the question of whether vscode (https://github.com/JuliaEditorSupport/julia-vscode/issues/540) and Juno (https://github.com/JunoLab/Juno.jl/issues/174) should do it.

(I still haven’t seen any cases in which people are confused by the SoftGlobalScope transformation — they are only confused when it doesn’t happen.)


#11

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.


#12

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.