# Attempting to assign to a pre-existing function name inside a function returns an UndefVarError

**URL:** <https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199>\
**Category:** General Usage\
**Created:** [January 28, 2019, 11:42pm UTC](https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199 "2019-01-28T23:42:13Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [January 28, 2019, 11:42pm UTC](https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199/1 "2019-01-28T23:42:13Z")

</div>

If I try to assign to a pre-existing function name in the global scope, I get a reasonable error:

```julia
function foo(x)
    x
end
foo = foo(7)
# ERROR: invalid redefinition of constant foo
# Stacktrace:
# [1] top-level scope at none:0

```

But if I do the same inside a function, I get an `UndefVarError` exception:

```julia
function bar(x)
    foo = foo(x)
    x
end
bar(7)
# ERROR: UndefVarError: foo not defined
# Stacktrace:
# [1] bar(::Int64) at ./REPL[3]:2
# [2] top-level scope at none:0

```

`"UndefVarError: foo not defined"` does not make much sense to me, and makes the cause of the above exception much less obvious. Is this the expected exception here? If so, can someone explain to me why that’s the expected exception, instead of something like `"ERROR: invalid redefinition of constant foo"`?

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [January 29, 2019, 2:10am UTC](https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199/2 "2019-01-29T02:10:08Z")

</div>

I think the confusion here is because the name `foo` on the _right hand side_ of `foo = foo(x)` is resolved in local scope because `foo` is an implicit local variable due to being assigned within the function block. Implicit local variables are resolved during lowering, so you can see which scope is chosen by using `@code_lowered`:

```julia
julia> function bar(x)
           foo = foo(x)
           x
       end

julia> function baz(x)
           foo = qux(x)
           x
       end

julia> @code_lowered bar(7)
CodeInfo(
1 ─ foo = (foo)(x) # Here foo is looked up in local scope
└── return x
)

julia> @code_lowered baz(7)
CodeInfo(
1 ─ foo = (Main.qux)(x) # Here qux is looked up in module scope
└── return x
)

```

(See [https://github.com/JuliaLang/julia/blob/8b7c88c650bb20d2b45bebfeb51a0ad8a4856175/src/julia-syntax.scm#L2491](https://github.com/JuliaLang/julia/blob/8b7c88c650bb20d2b45bebfeb51a0ad8a4856175/src/julia-syntax.scm#L2491) for nitty gritty details.)

I think this is required behavior to allow recursive (or mutually recursive) closures to be defined in local scope. For example, what does the `foo` on the right hand side of the following expression refer to?

```julia
julia> function asdf(x)
           foo(x) = x > 1 ? x*foo(x-1) : 1
           foo(x)
       end

```

It seems tricky to give a clearer error message for your example, as more evil examples such as the following are permitted and syntactically rather similar to your original function `bar`.

```julia
julia> function asdf(x)
           foo = (x) -> x > 1 ? x*foo(x-1) : 1
           foo(x)
       end

```

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [January 29, 2019, 5:39am UTC](https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199/3 "2019-01-29T05:39:17Z")

</div>

Ok, thanks! I’ll have to mull that over a bit. It sounds like you’re saying that any assignment to `foo` within the function block (no matter where in the block it occurs!) causes `foo` to be treated as a local variable, and since `foo` hasn’t been defined yet in line 2 of `bar`, it throws an `UndefVarError`.

I think this example is a little better:

```julia
foo(x) = x

function bar(x)
    y = foo(x)
    foo = 11
    return "hello"
end
# ERROR: UndefVarError: foo not defined
# Stacktrace:
# [1] bar(::Int64) at /Users/cameron/Julia/test.jl:4
# [2] top-level scope at none:0

```

In this case, `foo` is assigned to _after_ it’s used as a function, and yet this assignment in line 3 of `bar` changes the behavior of line 2 in `bar`! This messes with my conception of imperative/procedural programming where lines of code are executed one at a time, in order.

I just tried this example in R and Python. The analogous `bar` function in R returns `"hello"`, but the Python `bar` throws an exception similar to the Julia exception (though the error message is more informative).

Here’s the analogous R code:

```julia
foo <- function(x) x

bar <- function(x) {
    y <- foo(x)
    foo <- 11
    "hello"
}

bar(7)
# [1] "hello"

```

And here’s the analogous Python code:

```julia
def foo(x):
    return x

def bar(x):
    y = foo(x)
    foo = 11
    return "hello"

bar(7)
# Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
# File "<stdin>", line 2, in bar
# UnboundLocalError: local variable 'foo' referenced before assignment

```

I guess R programming has either pampered me or taught me bad habits.

---

<div class="post-metadata">

**Author:** ![c42f](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/c42f/32/52842_2.png) [@c42f](https://discourse.julialang.org/u/c42f)\
**Post date:** [January 29, 2019, 6:50am UTC](https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199/4 "2019-01-29T06:50:23Z")

</div>

> [@CameronBieganek](#):
>
> In this case, `foo` is assigned to _after_ it’s used as a function, and yet this assignment in line 3 of `bar` changes the behavior of line 2 in `bar` ! This messes with my conception of imperative/procedural programming where lines of code are executed one at a time, in order.

Good example! I agree this seems odd at first sight. Again, I think it’s to allow the definition mutually recursive inner functions:

```julia
julia> function bar(u)
           F(n) = (n > 0) ? n - M(F(n-1)) : 1 # M used before definition
           M(n) = (n > 0) ? n - F(M(n-1)) : 0
           F(u)
       end

```

The manual section on [local scope](https://docs.julialang.org/en/v1/manual/variables-and-scoping/index.html#Local-Scope-1) has this to say:

> An assignment introducing a variable used inside a function, type or macro definition need not come before its inner usage:

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [January 29, 2019, 4:56pm UTC](https://discourse.julialang.org/t/attempting-to-assign-to-a-pre-existing-function-name-inside-a-function-returns-an-undefvarerror/20199/5 "2019-01-29T16:56:53Z")

</div>

Great, thanks for your help!
