# Function definition (unexpected functionality)

**URL:** <https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202>\
**Category:** General Usage\
**Created:** [February 21, 2017, 3:59am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202 "2017-02-21T03:59:18Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![vitalishe](https://avatars.discourse-cdn.com/v4/letter/v/ebca7d/32.png) [@vitalishe](https://discourse.julialang.org/u/vitalishe)\
**Post date:** [February 21, 2017, 3:59am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/1 "2017-02-21T03:59:18Z")

</div>

Consider the following simple example. This behavior seams rather strange to me. I would have expected the output of myF(1) stay the same regardless of redefinition of ‘a’, or at the very least not be impacted by the last redefinition.

a = vec([1 2 3]);  
myF(t) = t\*a[2];  
myF(1)

> 2  
> a[2] = 1;  
> myF(1)  
> 1  
> a = 0;  
> myF(1)  
> BoundsError

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 21, 2017, 4:00am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/2 "2017-02-21T04:00:00Z")

</div>

Please quote your code using backticks (`) or the “\</\>” button.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 21, 2017, 4:00am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/3 "2017-02-21T04:00:54Z")

</div>

It is also not clear what is input and what is output. You can just post the complete content of a Julia REPL (terminal) session.

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [February 21, 2017, 4:02am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/4 "2017-02-21T04:02:26Z")

</div>

This happens because `a` is a global variable that is being looked up each time you call `myF`.

---

<div class="post-metadata">

**Author:** ![vitalishe](https://avatars.discourse-cdn.com/v4/letter/v/ebca7d/32.png) [@vitalishe](https://discourse.julialang.org/u/vitalishe)\
**Post date:** [February 21, 2017, 6:30am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/5 "2017-02-21T06:30:31Z")

</div>

Here is the attempt to present the code as you asked:

> [@vitalishe](#):
>
> ‘a = vec([1 2 3]);’  
> ‘myF(t) = t\*a[2];’  
> ‘myF(1)’  
> output: 2
> 
> ‘a[2] = 1;’  
> ‘myF(1)’  
> output: 1
> 
> ‘a = 0;’  
> ‘myF(1)’  
> output: BoundsError

Here is the part I don’t understand. I can pass the function ‘myF’ to other parts of the code that may have no information about ‘a’. So the function will not be computeable there, right? This behavior is very counter-intuitive.

This is especially counter-intuitive due to the concept of object types not being associated with the variables but rather with instances themselves. So the function ‘myF’ will have completely unpredictable behavior depending on what ‘a’ happens to be bound to at the moment. And ‘a’ is not even a part of explicit argument of ‘myF’.

Now, assuming that this weirdness is a part of life. What would be a good modification of the function definition if I want it to depend on the value that is sitting in ‘a[2]’ at the moment of function declaration?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [February 21, 2017, 7:18am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/6 "2017-02-21T07:18:20Z")

</div>

It’s interesting to play around with `@code_*` macros. For example, `@code_lowered` gives you:

```julia
julia> @code_lowered myF(1)
CodeInfo(:(begin 
        nothing
        return t * (Main.getindex)(Main.a, 2)
    end))

```

Note `Main.a` part - Julia identified that `a` belongs to module `Main` (current module), so wherever you pass this function later, `a` will refer to `Main.a`, not something else.

Now take a look at the output of `@code_warntype`:

```julia
julia> @code_warntype myF(1)
Variables:
  #self#::#myF
  t::Int64

Body:
  begin 
      return (t::Int64 * (Main.getindex)(Main.a, 2)::Any)::Any
  end::Any

```

You see these `Any`? In the REPL, they are even colored in red because you have introduced type instability - one of the major reasons for code slowdown. Julia doesn’t restrict you, but usually, you don’t want/need to have variables with variable type.

The solution is to try to avoid using variables from the global scope, and if really needed, make them `const`.

---

<div class="post-metadata">

**Author:** ![vitalishe](https://avatars.discourse-cdn.com/v4/letter/v/ebca7d/32.png) [@vitalishe](https://discourse.julialang.org/u/vitalishe)\
**Post date:** [February 21, 2017, 7:41am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/7 "2017-02-21T07:41:26Z")

</div>

Thank you! Very much appreciate the details.

How should I change the code to use the present value stored in ‘a[2]’ (at the time of declaration of function) vs looking up what will be stored there at the time the function is called?

---

<div class="post-metadata">

**Author:** ![dfdx](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dfdx/32/120_2.png) [@dfdx](https://discourse.julialang.org/u/dfdx)\
**Post date:** [February 21, 2017, 8:47am UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/8 "2017-02-21T08:47:34Z")

</div>

One way is to use closures, e.g.:

```julia
julia> a = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> makeMyF(x) = t -> x * t
makeMyF (generic function with 1 method)

julia> myF = makeMyF(a[2]) # we capture current _value_ of `a[2]`, no binding to _variable_ `a` is preserved
(::#1) (generic function with 1 method)

julia> myF(1)
2

julia> a[2] = 42
42

julia> myF(1)
2

```

---

<div class="post-metadata">

**Author:** ![vitalishe](https://avatars.discourse-cdn.com/v4/letter/v/ebca7d/32.png) [@vitalishe](https://discourse.julialang.org/u/vitalishe)\
**Post date:** [February 21, 2017, 4:26pm UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/9 "2017-02-21T16:26:17Z")

</div>

> [@dfdx](#):
>
> myF = makeMyF(a[2])

This works! Now I just need to figure out what exactly is happening here that makes it work different for closures than for the outer functions.

Also, I would expect there to be a more straightforward/elegant solution here that does not require creating a dummy internal function just to capture a present value of ‘a[2]’. An in-line solution (inside definition of the function myF) would be ideal. This is both a theoretical and a practical question, since I anticipate using this solution often.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [February 21, 2017, 5:17pm UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/10 "2017-02-21T17:17:17Z")

</div>

The fact that this is happening for you with a closure is actually a bit of a red herring. This is just the normal way that variables are bound in Julia. As you might already know, assigning a variable doesn’t create a copy, just a new name for the same object. So we can do:

```julia
julia> a = [1, 2, 3]
3-element Array{Int64,1}:
b = 1
 2
 3

julia> b = a
3-element Array{Int64,1}:
 1
 2
 3

julia> a[1] = 5
5

julia> b
3-element Array{Int64,1}:
 5
 2
 3

```

The value in `b` changes because `b` is just another binding for the same data as `a`. Compare this with:

```julia
julia> a = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> c = a[1]
1

julia> a[1] = 5
5

julia> c
1

```

In that case, `c` is bound to whatever was originally in `a[1]` (the value `1` in this case). Changing `a[1]` has no effect on `c` because `c` just points to the value `1` regardless of what `a` happens to contain right now.

The reason this is confusing in your particular case is that the closure `myF(t) = t * a[2]` creates a local binding for `a` (like the first case) not a local binding for `a[2]` (like the second case). That’s why changing `a` changes the value returned by `myF`.

The code from @dfdx works because calling the `makeMyF` function creates a new local variable bound to `a[2]`, and your closure captures that variable instead of capturing the entire `a` array. If you don’t want to introduce a special `makeMyF` function, you can also get the behavior you want with a `let` block like this:

```julia
julia> a = [1, 2, 3]
3-element Array{Int64,1}:
 1
 2
 3

julia> myF = let
       y = a[2]
       t -> t * y
       end
(::#1) (generic function with 1 method)

julia> myF(1)
2

julia> a[2] = 1
1

julia> myF(1)
2

julia> a = 0
0

julia> myF(1)
2

```

Note that the `y` created inside the `let` block just lives inside that block and doesn’t escape or interfere with any other variable named `y`. Even creating a new variable that happens to also be called `y` won’t break `myF`:

```julia
julia> y = 10
10

julia> myF(1)
2

```

---

<div class="post-metadata">

**Author:** ![vitalishe](https://avatars.discourse-cdn.com/v4/letter/v/ebca7d/32.png) [@vitalishe](https://discourse.julialang.org/u/vitalishe)\
**Post date:** [February 21, 2017, 6:06pm UTC](https://discourse.julialang.org/t/function-definition-unexpected-functionality/2202/11 "2017-02-21T18:06:46Z")

</div>

> [@rdeits](#):
>
> julia\> myF = let  
> y = a[2]  
> t -\> t \* y  
> end

Thank you! This is perfect!

> As you might already know, assigning a variable doesn’t create a copy, just a new name for the same object.

Yes, I knew that. The part that I did not quite understand was how my original definition of ‘myF’ is interpreted.
