Paul Eugenio
Paul Eugenio

Reputation: 145

(Julia) What is the difference between explicitly passing an array into a function, and calling that array from within an argument-less function?

Consider the following:

let
    test = [1,2,3]
    
    function testf(test)
        display(test)
        test = "blah"
        display(test)
        end#function
    
    testf(test); display(test)
end

Above I explicitly passed array test into testf(test), then reassigned test to a string; but this does not change the global value of test. The output for me (using Julia 1.4.1) is:

3-element Array{Int64,1}:
 1
 2
 3

"blah"

3-element Array{Int64,1}:
 1
 2
 3

Now consider:

let
    test = [1,2,3]
    
    function testf()
        display(test)
        test = "blah"
        display(test)
        end#function
    
    testf(); display(test)
end

Where here I have not explicitly passed test as an arg. The output:

3-element Array{Int64,1}:
 1
 2
 3

"blah"

"blah"

Such that globally-scoped test has been reassigned to the string.

From the difference b/w these two cases, I get the sense that explicit function arguments are copied into a local variable of the same name but different scope. In other words, I'm guessing the first case is identical to:

let
    test = [1,2,3]
    
    function testf()
        test_copy = copy(test)
        display(test===test_copy) # output: false (Julia 1.4.1)
        display(test_copy)
        test_copy = "blah"
        display(test_copy)
        end#function
    
    testf(); display(test)
end

which I find produces the same output as case #1. Is this the difference b/w these two cases? And are my case #1 and #3 essentially identical, or are there differences not made obvious by this particular example?

Thanks!

Upvotes: 3

Views: 170

Answers (1)

StefanKarpinski
StefanKarpinski

Reputation: 33280

Let's look at the second case first:

let
    test = [1,2,3]
    
    function testf()
        display(test)
        test = "blah"
        display(test)
        end#function
    
    testf(); display(test)
end

Here there is a single test variable that is local to the let block. The same local variable is visible in the body of testf and is assigned when test = "blah" is evaluated. When display(test) is called test therefore has the value "blah".

Now, let's look at the first case:

let
    test = [1,2,3]
    
    function testf(test)
        display(test)
        test = "blah"
        display(test)
        end#function
    
    testf(test); display(test)
end

Here there are two distinct local variables named test:

  1. The variable in the let block
  2. The argument to the testf function

Since these are distinct local variables (the latter "shadows" the former), assigning to one does not affect the other—that's the whole point of scope: when test = "blah" happens inside testf, it reassigns the test variable that is local to testf but has no effect on the test variable that is local to the let block. When display(test) is called at the end, it doesn't matter that the test variable in testf has been chaanged because the call to display(test) occurs outside of the scope of testf.

Upvotes: 4

Related Questions