Search code examples
juliaglobal-variablespass-by-referenceglobal

to be global, or not to be


in Julia 1.6.1 [VScode 1.57.1 with Julia Extension 1.2.5] : two trivial functions, two variables, one being g1 (of type {Int64}) and the other g2 (of type Vector{Int64} obviously). the enormously elaborate code on a Proust'ian scale in full is :

function set_g1(_a)
    _a = 0
end

function set_g2(_a)
    _a[length(_a)] = _a[begin]
end

g1 = 279
g2 = [1, 2, 3, 4]

set_g1(g1)
set_g2(g2)

println(g1)
println(g2)

-- output :

279
[1, 2, 3, 1]

that's it. g1 is passed on to set_g1() 'by value' only and, of course, not 'by reference' -- as Pascal'ians might put it

but g2 isn't ? but then it is what exactly ?

functionally it might well be a 'global' variable (tho not declared as such and that 'global' declaration would anyway be required in a function if it were meant to be a global var. it's doesn't matter). nevermind local/gobal, set_g2 in any event acts on g2 by reference -- in effect.

'logical optics', so to speak, suffering from myopia here ?

however, me is myopic so perhaps it's me .. and then one has to live with one's deficits, ' tries to cope and this 'by reference'-behaviour does come in quite handy (given i have to deal with -- tho not liking it a bit -- loads of global variables)

but then i can't figure out how to pass g1 on to set_g1() 'by reference' [still like that antiquated Pascal method; but passing the var on and then, once functionally digested, returning it, visuo-logically looks not quite myopic, it looks somewhat clumsy]


Solution

  • set_g2 does not work "by reference" in your terminology, no. In the body of the function, you are not changing _a -- you are changing its contents.

    "By reference" is like: you give me an apple; I take another apple and give it back to you. What happens in set_g2, though, is: you give me a box of apples. I swap one one of the apples and give you back the box. I didn't change the box.

    You can pass values by reference, though, by wrapping them in the Ref type (which behaves like a rank zero array, almost like a pointer):

    function set_g1!(_a::Ref{Int})
        _a[] = 0
    end
    
    g1 = Ref(234)
    set_g1(g1)
    @assert g1[] == 0
    

    Locality does not have anything to do with it; by-reference is about values, not names. (Also, you are not even shadowing anything.)