# Allow redefining functions names of outer scope? ERROR: UndefVarError: f not defined

**URL:** <https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [March 9, 2019, 1:42pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676 "2019-03-09T13:42:10Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [March 9, 2019, 1:42pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/1 "2019-03-09T13:42:10Z")

</div>

It seems we have to use reflections in order to overwrite a function from an outer scope.

Please look at the following minimal example

```julia
module MyModule
  f(a) = a

  function f2()
    h = getfield(MyModule, :f)
    #= if you uncomment the following
    you get an `ERROR: UndefVarError: f not defined` 
    pointing to exactly this assignment `h = f` =#

    # h = f # PLEASE UNCOMMENT THIS
    f(args...; kwargs...) = h(2, args...; kwargs...)
    f()
  end
end

MyModule.f2() # 2

```

If we know the outer scope is just module, we can use simple `getfield(MyModule, :myfunc)` to refer to the function which we want to overwrite locally (as used in the example), however if you have nested functions I even don’t know a way to do that.

Is this restriction needed? or could julia just correctly infer that the first `f` in `h = f` is pointing correctly to the outer scope?

I am using julia 1.1

---

<div class="post-metadata">

**Author:** ![wsrinin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wsrinin/32/7676_2.png) [@wsrinin](https://discourse.julialang.org/u/wsrinin)\
**Post date:** [March 9, 2019, 2:31pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/2 "2019-03-09T14:31:20Z")

</div>

If I understand you correctly, what are you looking for is Revise workflow.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 9, 2019, 4:21pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/3 "2019-03-09T16:21:10Z")

</div>

Assigning to a name from inside a function causes it to be a local variable. If you want it to be global you have to declare it `global`. And you can’t have it both ways: the name `f` is either local or global.

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [March 10, 2019, 9:15am UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/4 "2019-03-10T09:15:42Z")

</div>

Is there a design decision which explains why this is done?

It looks so unintuitive and unneeded to me

---

<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:** [March 10, 2019, 1:52pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/5 "2019-03-10T13:52:24Z")

</div>

Please be specific about what you have an issue with: the idea of scoping, the distinction between local and global, or the fact that these are disjoint categories for specific variables?

Also, note that scoping rules are a very fundamental building block of the language, and have usually received a lot of attention. This is also the case for Julia. When you are learning a new language, consider the possibility that you may need to invest in understanding how it works before labeling fundamental features “unneeded”.

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [March 10, 2019, 1:55pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/6 "2019-03-10T13:55:35Z")

</div>

that is exactly what I am doing right here - trying to understand why it is needed.

But apparently that is not easy to understand, at least no one could help so far (of course some answers already pointed out that julia currently is designed this way, but the more important question to me is to understand why)

---

<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:** [March 10, 2019, 2:12pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/7 "2019-03-10T14:12:51Z")

</div>

Again, it is unclear _what_ you are referring to as a “design choice” — even though it is short, the example you included involves multiple ones. Reading about [scoping](https://docs.julialang.org/en/v1/manual/variables-and-scoping/) would be a good start.

Also, instead of delving into the design of the language, it may be easier to just explain _what_ you want, not _how_ you tried to get it. Eg do you want the behavior of the API function `f` to depend on some global state, and have the function recompiled? Then

```julia
module MyModule

export f

_f(a) = a

f(a) = _f(a)

function toggle()
    @eval f(a) = 2 * _f(a)
end

end

```

could work, eg

```julia
julia> MyModule.f(1)
1

julia> MyModule.toggle()
f (generic function with 1 method)

julia> MyModule.f(1)
2

```

though I don’t think you would lose much by just having a global flag (as the above is not ideal coding style).

---

<div class="post-metadata">

**Author:** ![schlichtanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/schlichtanders/32/32145_2.png) [@schlichtanders](https://discourse.julialang.org/u/schlichtanders)\
**Post date:** [March 10, 2019, 2:16pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/8 "2019-03-10T14:16:33Z")

</div>

my usecase is super similar to the simple example I gave above: I would like to fixate one parameter of a function, and use the same name for the new wrapped function.

It is that simple.

I can make a naming convention by just adding underscore to the name, but it looks so natural that the one `f` could refer to outer scope while the next `f` is the new wrapped function.

---

<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:** [March 10, 2019, 2:24pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/9 "2019-03-10T14:24:55Z")

</div>

> [@schlichtanders](#):
>
> fixate one parameter of a function, and use the same name for the new wrapped function

It may help to think of functions in Julia as a table of methods. The `f(...) = ...` syntax _adds_ to this table. The table itself may have global (usually) or local scope, eg

```julia
julia> function f(x)
           g(::Int) = 1
           g(::Float64) = 2
           g(x)
       end
f (generic function with 1 method)

julia> f(1)
1

julia> f(1.0)
2

julia> g(1)
ERROR: UndefVarError: g not defined
Stacktrace:
 [1] top-level scope at REPL[18]:1

```

I would just use a closure for pinning down a parameter. The details of the solution depend on _where_ you would like to use the transformed function (ie inside or outside `f2` and/or `MyModule` in your example).

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [March 10, 2019, 4:53pm UTC](https://discourse.julialang.org/t/allow-redefining-functions-names-of-outer-scope-error-undefvarerror-f-not-defined/21676/10 "2019-03-10T16:53:50Z")

</div>

> [@schlichtanders](#):
>
> but it looks so natural that the one `f` could refer to outer scope while the next `f` is the new wrapped function.

So the same name in the same scope would be global in some places but local in others? That seems confusing and also not how local scope works in any other languages I’m aware of. You could use a let block to introduce a new binding with the same name and still use the outer meaning in the definition.
