# How does scope work for declaring functions

**URL:** <https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474>\
**Category:** General Usage\
**Tags:** scope\
**Created:** [January 19, 2018, 2:20pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474 "2018-01-19T14:20:48Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [January 19, 2018, 2:20pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/1 "2018-01-19T14:20:48Z")

</div>

I have not found any good resources on this. I cannot find anything helpful in the Julia docs entry on scopes. However I have had problems with it and found enough instances were I have no idea what is going on and would be happy if someone could help me:

Example 1:  
The code:

```julia
fun = 1
for i = 1:3
    fun = i
    print(fun, " ")
end

```

generates the output  
`1 2 3`  
But if I use a function instead:

```julia
fun(x) = 1
for i = 1:3
    fun(x) = i
    print(fun(0), " ")
end

```

It generates the output  
`1 1 1`  
What is the difference between a function and a normal variable here? Shouldn’t they work the same?

The next example (closer to my real application) is:

```julia
ar = []
for i = 1:3
  eval(:(f() = i))
  println(f())
  push!(ar,f)
end
println(ar[1]()," ", ar[2]()," ", ar[3]()," ",)

```

this generates

```julia
1
2
3
3 3 3

```

Here I would want to have three different functions in my array, which I can fetch and which yields different values. However the later function declarations seems to overwrite the old ones. Again if I work with a numeric variables it works like expected:

```julia
ar = []
for i = 1:3
  eval(:(xx = i))
  println(xx)
  push!(ar,xx)
end
println(ar[1]," ", ar[2]," ", ar[3]," ",)

```

gives

```julia
1
2
3
1 2 3 

```

Obviously there is something I do not get here, but what?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 19, 2018, 2:32pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/2 "2018-01-19T14:32:12Z")

</div>

Try

```julia
fun(x) = 1
for i = 1:3
    local fun(x) = i
    print(fun(0), " ")
end

```

You will find the documentation under `local`.

But generally, this may not be good style. Consider closures (or an equivalent callable structure). Eg

```julia
julia> fs = [() -> i for i in 1:3];

julia> (fs[1](), fs[2](), fs[3]())
(1, 2, 3)

```

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [January 19, 2018, 2:47pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/3 "2018-01-19T14:47:52Z")

</div>

I find very little on closures in the documentation. Is there some place were I can read on what they are? I need it for a part of the DifferentialEquation package were I need to input functions, would closures count as that.

I tried using local and it worked for the first one, but not the second were I used eval. I tried looking closer but now the same code generates an error:

```julia
ar = []
for i = 1:3
  eval(:(f() = i))
  println(f())
  push!(ar,f)
end

```

`UndefVarError: i not defined` (at the line `println(f())`)  
The code is the same as worked before, but now it seems not to work at all, which makes me very confused. I tried exiting and restarting Juno, but that seems to have no effect.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 19, 2018, 2:57pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/4 "2018-01-19T14:57:39Z")

</div>

There is not much more to the _documentation_ of closures than what’s [already there](https://docs.julialang.org/en/stable/devdocs/functions/#Closures-1).

Don’t use `eval`. Generally, besides a few corner cases, using `eval` routinely is a sign that your are doing something that could be done much easier using the standard idioms of the language.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 19, 2018, 2:59pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/5 "2018-01-19T14:59:48Z")

</div>

I think in your example above the argument of `eval` gets evaluated in global scope and that this is always true, hence why it fails. As @tamas_papp said, you should generally avoid using it. It’s really just for code generation. You really don’t want to deliberately invoke the compiler in the middle of your runtime anyway.

We might be able to be more helpful if you give us some idea of what you’re trying to do.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [January 19, 2018, 3:10pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/6 "2018-01-19T15:10:25Z")

</div>

Eval being evaluated on the global scope explains it then. Thank you. I am not sure whenever I can avoid it though, I am building a macro which takes input in a simple format and generates differential equations and other similar structures for me automatically.

I have been able to create the entire function expressions, but then I want to turn those into real function which I can then start doing stuff with. My code reads basically:

```julia
func_expressions = []
for i = 1:n
    func_expr = generate_function_expression(data[i])
    eval(:(function func(input); $func_expr end))
    push!(func_expressions,func)
end

```

the functions in `func_expressions` are then used as input to an external package.

Is there some way of coverting my expressions into functions without using eval, or am I simply in a very messy part of programming and things are unavoidably difficult?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 19, 2018, 3:23pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/7 "2018-01-19T15:23:20Z")

</div>

> [@Torkel](#):
>
> Is there some way of coverting my expressions into functions without using eval

What you should try to do is to perform any manipulation of expressions that you need in the body of the macro and the plug the results into your output expression. For example

```julia
macro diffeq(equation::Expr)
    # here is where you manipulate `equation` and create an expression
    esc(quote
        # here you place the completed expression which will evaluate at runtime
    end)
end

```

The only exception is cases where you need information generated at runtime in order to know how to manipulate your expression. In that case you have no choice but to invoke the compiler somehow, but you should try hard to avoid this; if you write the appropriate functions it shouldn’t be necessary.

Also, in case you are not aware [MacroTools.jl](https://github.com/MikeInnes/MacroTools.jl) makes writing macro code far less painful (really should have been in `Base` in my opinion).

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [January 19, 2018, 4:00pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/8 "2018-01-19T16:00:42Z")

</div>

Thanks for the help, I will see what I can do.

The MacroTools seems like very useful stuff as well, I will have a look there.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [January 19, 2018, 4:29pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/9 "2018-01-19T16:29:19Z")

</div>

Macros are an advanced concept. Julia is in a strange position of having really powerful metaprogramming facilities, while at the same time these can be difficult to use until you get used to them.

Given that you had problems with closures, I would suggest that you hold off metaprogramming for a while and try to do what you want with functions. Perhaps if you gave an MWE, you could get more specific help.

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [January 19, 2018, 4:51pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/10 "2018-01-19T16:51:13Z")

</div>

Even once you are comfortable writing macros, usually a good rule of thumb is to get everything that the macro relies on fully designed and working before you start writing the macro at all. I’ve done a fair amount of meta-programming now and I still find it can be quite a pain in the ass, even though the results are spectacular.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [January 19, 2018, 6:13pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/11 "2018-01-19T18:13:43Z")

</div>

Thanks for the advice. I think I’ve gotten the most important functionalities working now, but it is indeed really messy.

---

<div class="post-metadata">

**Author:** ![swissr](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/swissr/32/208_2.png) [@swissr](https://discourse.julialang.org/u/swissr)\
**Post date:** [January 20, 2018, 3:19pm UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/12 "2018-01-20T15:19:06Z")

</div>

> [@Torkel](#):
>
> … But if I use a function instead:
> 
> ```
> fun(x) = 1
> for i = 1:3
> fun(x) = i
> print(fun(0), " ") # [Edit: output gives 1 1 1]
> end
> print(fun(0), " ") # [Edit: added by me, output gives 3] ...
> 
> ```

I’m not 100 % sure but I think the observed effects in this snippet have more to do with [redefining methods](https://docs.julialang.org/en/stable/manual/methods/#Redefining-Methods-1) and ‘world-age’ than scope. The last line (added by me) gives 3 as output; and this were not possible if the global function `fun` wouldn’t have been modified. - To hopefully understand what happens I used the following code:

```julia
println("WORLD_COUNTER at start: $(ccall(:jl_get_world_counter, UInt,()))")
if isdefined(:foo)
    println("normal/latest foo(10) as defined: $(foo(10))/$(Base.invokelatest(foo, 10))")
else
    println("foo not defined")
end
foo(x) = (999, x)
println("\nWORLD_COUNTER after foo (re)definition: $(ccall(:jl_get_world_counter, UInt,()))")
println("normal/latest foo(20) after (re)definition: $(foo(20))/$(Base.invokelatest(foo, 20))\n")
for i = 1:3
    # local foo(x) = (i, x) # def./upd. foo; after loop exit, global foo(x) = (99,x) is visible again 
    foo(x) = (i, x) # only update latest defined foo; after exit, foo(x) = (3,x) remains
    println(" WORLD_COUNTER after forloop foo redefinition: $(ccall(:jl_get_world_counter, UInt,()))")
    println(" normal/latest foo(30+$i) within forloop: $(foo(30 + i))/$(Base.invokelatest(foo, 30 + i))")
end
println("\nWORLD_COUNTER after for block: $(ccall(:jl_get_world_counter, UInt,()))")
println("normal/latest foo(40) after for block: $(foo(40))/$(Base.invokelatest(foo, 40))")

```

```c
(--- output)

WORLD_COUNTER at start: 22146                                                                                                                
foo not defined                                                                                                                              
                                                                                                                                             
WORLD_COUNTER after foo (re)definition: 22147                                                                                                
normal/latest foo(20) after (re)definition: (999, 20)/(999, 20)                                                                              
                                                                                                                                             
    WORLD_COUNTER after forloop foo redefinition: 22148                                                                                       
    normal/latest foo(30+1) within forloop: (999, 31)/(1, 31)                                                                                        
    WORLD_COUNTER after forloop foo redefinition: 22149                                                                                       
    normal/latest foo(30+2) within forloop: (999, 32)/(2, 32)                                                                                        
    WORLD_COUNTER after forloop foo redefinition: 22150                                                                                       
    normal/latest foo(30+3) within forloop: (999, 33)/(3, 33)                                                                                        
                                                                                                                                             
WORLD_COUNTER after for block: 22150                                                                                                         
normal/latest foo(40) after for block: (3, 40)/(3, 40) 

```

The output of the ‘normal’ and the ‘latest defined’ `foo` call shows that the ‘latest foo’ _does_ get updated in the for loop. I suppose that the loop simply cannot replace a method received from the outside. The method gets replaced after the loop though. When you write `local foo(x) = i`, then there is a locally defined `foo` method which can be replaced in every loop iteration. After the loop, the global `foo` method is visible again.

---

<div class="post-metadata">

**Author:** ![Torkel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/torkel/32/5030_2.png) [@Torkel](https://discourse.julialang.org/u/Torkel)\
**Post date:** [January 22, 2018, 10:37am UTC](https://discourse.julialang.org/t/how-does-scope-work-for-declaring-functions/8474/13 "2018-01-22T10:37:54Z")

</div>

Thank you swissr, that is really helpful. I did not know about that at all before.
