Here temp is a global variable and in Julia you can read from global variables anywhere (in the same module - here Main) just not assign to them. If you want to assign to a global variable then you need to declare it with a global statement.
OK, I think I see. what is outside the for loop is defaulted to global, but what is defined within the for loop is local so after the loop completes, I cannot get those variables out, but I can get upstream global variables into the for loop to use.
I know there is another whole topic on this, but this is really unintuitive for people coming from other scripting languages.
Not wanting to add more noise to this topic, but just how I think about this.
A function is like a black box so variables go in (through the function arguments) and variables go out through return statements, so that’s makes sense that functions that their own scope.
But for, try, while blocks don’t really have an “input port” and neither do they have an “output port”. It would be different if there were something like a return statement to get stuff processed in those objects out but I don’t think there is, is there (other than setting those variables as global). It’s kind of like creating a black box with only a clear mechanism to get things in but not out.
What about If/else blocks. Why don’t those have local scoping rules similar to for/while/try?
I mentioned, “other than setting variables as global” in my statement. But that feels like a workaround and seems kind of heavy handed. It feels like there should be another way other than resorting to globals.
Anyways, I don’t think I’m going to add anything useful to this discussion. I don’t have enough experience or background on programming languages. I’m just a simple user.
Anyways, thanks for taking the time to reply to this lowly user (me). I guess I’ll figure this out eventually.
I also find the new policy about global scopes and for loops quite complicated and confusing. Sure it can be justified (everything can, in the end), but would really like to change it back to what it was before the big changes of 0.7.0 (my two cents).
Still somebody here pointed out that there is a big thread discussing that… can somebody please tell me which one is it? This forum is quite busy and it is sometimes hard to keep up with everything…
Best regards and thanks,
Ferran.
julia> for i in 1:1
temp = 2 # this is local
for j in 1:1
temp = 3 # this is not defaulted to global!
end
println(temp) # local is changed
end
println(temp) # global is undefined
3
ERROR: UndefVarError: temp not defined
Same if for is inside function body where also inherit function’s local scope.
And maybe this is bug:
julia> temp = 1
for i in 1:1
temp = 2
for j in 1:1
global temp = 3 # you could not reach global `temp` here!
end
println(temp)
end
println(temp)
ERROR: syntax: `global temp`: temp is a local variable in its enclosing scope
You can greatly simplify things by writing functions for everything. Pass in everything the function needs as a parameter ( wrap them in tuples or struct if there are too many. ). For complex return values, use tuples and structs as well.
In general use struct and not mutable struct as much as possible.
I’ve happily never hit the problem with scoping and look on bemusedly at the amazingly long discussions on an issue I didn’t know existed.
Interactively. That’s how I use Julia. I develop extensively using the repl. Julia easily has the nicest repl-based function writing experience I’ve seen.
What do you mean by interactively?
By interactively I’m guessing you mean manipulating global state via expressions instead of functions?
Not sure why you would want to do that. So many pitfalls. There is a wealth of higher order functions available with very nice syntax. Broadcasting for example does an amazing amount. map reduce filter, it’s all there. Super simple anonymous functions. I do most of my work with hof.
Sure every now and then I interactively modify some global state directly, but it’s almost always pretty simple stuff setting up data for a function to process.
Function closures go a long way as well.
function thinkofname()
M[1,1] = 0
M[2,2] = 0
end
if you don’t like thinking of names
(()-> begin
M[1,1] = 0
M[2,2] = 0
whatever expressions block you would normally enter
end)()
use ans immediately to evaluate your lambda expression with a closure mutating.
julia> A = rand(10,2)
10×2 Array{Float64,2}:
0.674215 0.679194
0.946359 0.26367
0.328985 0.119864
0.793516 0.613542
0.0598779 0.407411
0.637759 0.233309
0.172873 0.222074
0.650882 0.91787
0.217435 0.8771
0.141181 0.853914
julia> ()->
for i in 1:10
A[i,1] = i
end
#41 (generic function with 1 method)
julia> ans()
julia> A
10×2 Array{Float64,2}:
1.0 0.679194
2.0 0.26367