# Question about scoping inside a function

**URL:** https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709
**Category:** General Usage
**Created:** [December 3, 2016, 1:07pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709 "2016-12-03T13:07:42Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 3, 2016, 1:07pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/1 "2016-12-03T13:07:42Z")

</div>

Below are two functions that are slightly different in the names of the functions defined in them:

```nohighlight
function f()
    h(x) = x
    b(x) = x
    q(x::Vector{Float32}) = foo(h, b)
end

function g()
    h(x) = x
    b(x) = x
    h(x::Vector{Float32}) = foo(h, b)
end

f()
g()

```

The call to `g` fails with `UndefVarError: b not defined` I think I am missing some scoping rules because both of the functions work fine if I just paste their bodies in the REPL.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [December 3, 2016, 2:16pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/2 "2016-12-03T14:16:22Z")

</div>

It’s not related to scope. It’s a lowering bug similar (/dup of) [https://github.com/JuliaLang/julia/issues/18621](https://github.com/JuliaLang/julia/issues/18621)

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 3, 2016, 6:29pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/3 "2016-12-03T18:29:01Z")

</div>

This works:

```julia
julia> function g()
           h(x) = x
           b(x) = x
           (::typeof(h))(x::Vector{Float32}) = foo(h, b)
           h # this is necessary as above line does not evaluate to the function
       end
g (generic function with 1 method)

julia> g()
(::h) (generic function with 2 methods)

```

Related: This is also what is needed to add a method to a function passed into a function:

```julia
julia> f1(f) = f(x) = 1
ERROR: syntax: cannot add method to function argument f

julia> f1(f) = (::typeof(f))(x) = 1
f1 (generic function with 1 method)

julia> ff() = 1
ff (generic function with 1 method)

julia> f1(ff)

julia> ff(2)
1

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 3, 2016, 6:56pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/4 "2016-12-03T18:56:09Z")

</div>

Thanks mauro, I will try it.

To give some context, this is what I am doing: [https://github.com/JuliaDiff/ForwardDiff.jl/pull/165](https://github.com/JuliaDiff/ForwardDiff.jl/pull/165)

I basically want to add a method to a user defined function with a macro. Both the user defined function and the macro should be able to itself be executed within a function.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 3, 2016, 7:13pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/5 "2016-12-03T19:13:20Z")

</div>

That be excellent to have! Looking at the example, probably better like so then:

```julia
julia> f2{F}(f::F) = ((::F)(x) = 1; f(5) )
f2 (generic function with 1 method)

julia> Base.Test.@inferred f2(ff)
WARNING: Method definition ff(Any) in module Main at REPL[1]:1 overwritten at REPL[5]:1.
1

```

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 4, 2016, 9:03pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/7 "2016-12-04T21:03:52Z")

</div>

Still having some problem. Being a bit more explicit now:

In global scope, the following works fine:

```nohighlight
using ForwardDiff

import ForwardDiff: value, partials, Dual

h(x) = 3*x
dh(x) = (println("Called"); 3 * one(x))

h(x::Dual) = Dual(h(value(x)), partials(x) * dh(value(x)))
ForwardDiff.derivative(h, 2.0)

```

This has the output:

```nohighlight
julia> ForwardDiff.derivative(h, 2.0)
Called
3.0

```

which shows that my custom derivative is being called. However, for automatic differentiation, users frequently use closures.

My attempt as in the OP was:

```nohighlight
function closure(a)
    h(x) = a*x
    dh(x) = (println("Called"); a * one(x))

    h(x::Dual) = Dual(h(value(x)), partials(x) * dh(value(x)))
    ForwardDiff.derivative(h, 2.0)
end

```

As been said, this fails with `UndefVarError: dh not defined`. (This just feels like a straight up bug, `dh` is defined!).

Just copy pasting the function bodies into the `::Dual` function works (but this is of course not really user friendly):

```julia
julia> function closure2(a)
          h(x::Dual) = (println("Called"); Dual(a * value(x), partials(x) * a * one(value(x))))
          ForwardDiff.derivative(h, 2.0)
        end
closure2 (generic function with 1 method)

julia> closure2(1.0)
Called
1.0

julia> closure2(2.0)
Called
2.0

```

Trying to do it @mauro3 style:

```nohighlight
function closure3(a)
    h(x) = a*x
    dh(x) = (println("Called"); a * one(x))

    (::typeof(h))(x::Dual) = Dual(h(value(x)), partials(x) * dh(value(x)))
    ForwardDiff.derivative(h, 2.0)
end

```

Doing it like this, the custom derivative function is actually never called. Moreover this leads to method redefinition warnings when calling it multiple times.

```nohighlight
julia> closure3(2.0)
2.0

julia> closure3(2.0)
WARNING: Method definition (::Main.#h#15{Float64})(ForwardDiff.Dual) in module Main at REPL[3]:5 overwritten at REPL[3]:5.
2.0

```

I’m kinda out of ideas now. It feels like this should just work.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 4, 2016, 9:52pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/8 "2016-12-04T21:52:36Z")

</div>

Part of this certainly seems like a bug. Here a more minimal repo:

```julia
julia> function cl(a)
       g(x) = a*x
       h(x) = 7
       (::typeof(g))(x::Int) = (println("here"); g(Float64(x)) + h(x))
       sin(g(5))
       end
cl (generic function with 1 method)

julia> cl(5)
-0.13235175009777303 # this is sin(25)

julia> function cll(a)
       g(x) = a*x
       h(x) = 7
       (::typeof(g))(x::Int) = (println("here"); g(Float64(x)) + h(x))
       g
       end
cll (generic function with 1 method)

julia> gg = cll(5)
(::g) (generic function with 2 methods)

julia> sin(gg(5))
here
0.5514266812416906

```

I would expect those to be the same.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [December 4, 2016, 11:01pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/9 "2016-12-04T23:01:28Z")

</div>

This is #265 but it will also be the expected behavior after #265 is fixed.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 7:03am UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/10 "2016-12-05T07:03:12Z")

</div>

Why is this #265? I just want to add a method to a function. Everything works as I want it in global scope.

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 5, 2016, 7:40am UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/11 "2016-12-05T07:40:57Z")

</div>

[Here](https://github.com/JuliaLang/julia/issues/14910#issuecomment-178662102) Jeff states: “It’s an increasingly official rule that method changes aren’t guaranteed to take effect until you return to the top level (see e.g. #4688).” I think that is what’s hit here.

Also somewhat related to: [https://github.com/JuliaLang/julia/issues/11808](https://github.com/JuliaLang/julia/issues/11808).  
Although translating above to match Jeff’s [comment](https://github.com/JuliaLang/julia/issues/11808#issuecomment-114167311), does not lead to unexpected behavior:

```julia
julia> let
       g(x) = (println("here 1"); pi/2)
       h(x) = pi/2
       # the typeof trick is needed here too:
       (::typeof(g))(x::Int) = (println("here 2"); g(Float64(x)) + h(x)) 
       sin(g(5))
       end
here 2
here 1
1.2246467991473532e-16

```

I’m not sure how that is all reconcilable with above quote by Jeff. I would have thought the last code snippet shouldn’t work either.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 7:47am UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/12 "2016-12-05T07:47:16Z")

</div>

I don’t see what is different with what I am trying to do and the following:

```nohighlight
function f()
    g(x::Int) = println("Here 1")
    g(x::Float64) = println("Here 2")
    g(1)
    g(2.0)
end

```

```julia
julia> f()
Here 1
Here 2

```

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [December 5, 2016, 8:01am UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/13 "2016-12-05T08:01:09Z")

</div>

To trigger the odd behavior, you need to call a method (or function?) which was also defined inside the outer function (`h` above). I guess the key part of Jeff’s statement is “guaranteed”: method updates may take effect or may not, i.e. undefined behavior. Nonetheless, I think we should file an issue for this. You or I?

Concerning your problem: it does seem a bit odd to define, evaluate and throw away generic functions within a method. Is there no other way to do what you want?

Otherwise, you could do something like this:

```julia
julia> function cl(a)
              global g(x) = a*x
              global h(x) = 7
              # the typeof trick is not needed:
              g(x::Int) = (println("here"); g(Float64(x)) + h(x))
              sin(g(1))
              end
cl (generic function with 1 method)

julia> cl(1)
here
0.9893582466233818

```

I think you’re generating this with macros, thus you could use `gensym` to avoid name-collisions.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 12:31pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/14 "2016-12-05T12:31:21Z")

</div>

> [@mauro3](#):
>
> it does seem a bit odd to define, evaluate and throw away generic functions within a method.

Isn’t this what any closure defined in a function is though? Defined, evaluated and thrown away.  
Is the conclusion here that multiple dispatch is not allowed for closures created inside a function?

What I want is for the user, at any point, to give me a function `h(x::Vector)` and I then want to create the method `h{T <: ForwardDiff.Dual}(x::Vector{T})` such that function will be called for eltypes of `ForwardDiff.Dual`. In the new method I need to be able to call the original `h(x::Vector)` function.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [December 5, 2016, 1:14pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/15 "2016-12-05T13:14:44Z")

</div>

> [@kristoffer.carlsson](#):
>
> I don’t see what is different with what I am trying to do and the following:

It’s very different since using `(::typeof(g))(...) = ...` you are adding a method at runtime.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 1:17pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/16 "2016-12-05T13:17:37Z")

</div>

But the only reason for that is because the original code which did not use `typeof` did not work and threw an error about an undefined variable which actually is defined.

Again:

```nohighlight
function cll(a) # works
    g(x) = a*x
    g(x::Int) = g(Float32(x))
    g(3)
end

function cll2(a) # doesnt work
    g(x) = a*x
    h(x) = 2.0
    g(x::Int) = (g(Float32(x)), h(x))
    g(3)
 end

```

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [December 5, 2016, 1:41pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/17 "2016-12-05T13:41:05Z")

</div>

As I said in the very beginning, this is a lowering bug.

The “work around” does not do the same thing as the original code.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 1:53pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/18 "2016-12-05T13:53:34Z")

</div>

Ok, thank you. Is there a workaround that does the same (or with the same intention) as the original code.

---

<div class="post-metadata">

### Author: ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)
#### Post date: [December 5, 2016, 2:01pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/19 "2016-12-05T14:01:31Z")

</div>

define `h` before the first `g` or after the second `g` might be ok.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 2:04pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/20 "2016-12-05T14:04:42Z")

</div>

Oh, defining `h` before `g` seems to work! Not super user friendly but better than nothing. Thanks!

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 5, 2016, 3:15pm UTC](https://discourse.julialang.org/t/question-about-scoping-inside-a-function/709/21 "2016-12-05T15:15:43Z")

</div>

Only problem now is that `g` turns into a `Box`.
