# Overwriting functions

**URL:** <https://discourse.julialang.org/t/overwriting-functions/404>\
**Category:** General Usage\
**Tags:** faq\
**Created:** [November 18, 2016, 8:00am UTC](https://discourse.julialang.org/t/overwriting-functions/404 "2016-11-18T08:00:36Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![akis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akis/32/156_2.png) [@akis](https://discourse.julialang.org/u/akis)\
**Post date:** [November 18, 2016, 8:00am UTC](https://discourse.julialang.org/t/overwriting-functions/404/1 "2016-11-18T08:00:36Z")

</div>

**Note:** This post is intended as a **FAQ** entry in **wiki** format to get improved by the community.

Relevant pages of the Julia **Documentation** : [Functions](http://docs.julialang.org/en/release-0.5/manual/functions/), [Methods](http://docs.julialang.org/en/release-0.5/manual/methods/)

Relevant Julia **principles** _by design_:

- Different **_types_** get different treatment.
- _Special_ gets **priority** over _generic_.
- Julia is not an interpreter able to compile code, but a **compiler** able to execute arbitrary code ([read more](http://docs.julialang.org/en/release-0.5/manual/modules/#module-initialization-and-precompilation)).
- Julia’s compiler is a **Just-In-Time** (_JIT_) compiler ([read more](http://docs.julialang.org/en/release-0.5/devdocs/eval/#jit-code-generation)).

**Note:** The last two principles are simplified descriptions of a sophisticated multistage system, which in most cases operates transparently to the programmer. For the needs of this post, the simplified descriptions are enough. The details can be explored by following the provided links.

## Demonstration

**Important:** All code sections in this post constitute a **single session** , the next ones logically following and often depending on the previous ones.

### Defining a _function_

We are going to define a _function_ named `myfun`. Before naming something, it is a good idea to check if the name is already in use:

```julia-auto
julia> myfun
ERROR: UndefVarError: myfun not defined

```

_Functions_ get usually defined implicitly, together with the definition of their first _method_. To [explicitly define a function](http://docs.julialang.org/en/release-0.5/manual/methods/#empty-generic-functions):

```julia-auto
julia> function myfun end
myfun (generic function with 0 methods)

```

The phrase “generic function” in REPL’s answer refers to a [different concept](https://en.wikipedia.org/wiki/Generic_function) than the one used here. For the purposes of this post, only one _function_ (a generic _function_) is used and its various methods may compare to each other as more/less _generic_ or more/less _special_.

The new _function_ cannot be called, because it has no _methods_:

```julia-auto
julia> myfun()
ERROR: MethodError: no method matching myfun()

```

However, it is as real as any other _function_ and can be referenced by other code:

```julia-auto
julia> f = myfun # assign to a variable
myfun (generic function with 0 methods)

julia> g = (function myfun end) # attempt to redefine
myfun (generic function with 0 methods)

julia> f === g # equivalent to is(f, g)
true

```

Therefore, overwriting a _function_ in Julia is empty of meaning. Actually, the whole Functions page of the Julia Documentation is about _methods_. The reason for using “functions” in the title of that page (as well as in the title of the present topic) is to help people coming to Julia from other languages. **Overwriting** in Julia is fully possible, but it takes place **per _method_** and it needs a different perspective to avoid surprises:

### Defining _methods_

Next we are going to define various _methods_ for the `myfun` _function_ and notice that overwriting is rare in practice, because of Julia’s key feature of [multimethods](https://en.wikipedia.org/wiki/Multiple_dispatch):

```julia-auto
julia> myfun() = "no arguments" # define a method of myfun function without arguments
myfun (generic function with 1 method)

julia> myfun() # call the new method
"no arguments"

julia> myfun(x) = "single argument: $x" # define a second method for an arbitrary argument
myfun (generic function with 2 methods)

julia> myfun(1) # call method myfun(x) passing an Int
"single argument: 1"

julia> myfun("a") # call method myfun(x) passing a String
"single argument: a"

julia> myfun() # method myfun() not overwritten by method myfun(x)
"no arguments"

julia> myfun("a", "b") # call a not-yet-defined method
ERROR: MethodError: no method matching myfun(::String, ::String)

julia> myfun(::String, ::String) = "too many strings" # define a special fix
myfun (generic function with 3 methods)

julia> myfun("a", "b") # try again previously failed call
"too many strings"

julia> myfun("a") # myfun(x) not overwritten by myfun(::String, ::String)
"single argument: a"

julia> myfun(x1, x2) = "too many arguments: $x1, $x2" # define a generic fix
myfun (generic function with 4 methods)

julia> myfun(1, 2) # generic fix works
"too many arguments: 1, 2"

julia> myfun("a", "b") # myfun(::String, ::String) not overwritten by myfun(x1, x2)
"too many strings"

julia> methods(myfun) # review the defined methods of function myfun
# 4 methods for generic function "myfun":
[...]

```

Here a programmer may complain that the last definition should overwrite the previous one, as they both have the **same number of arguments** (two). But that would be against Julia’s principle: “Different _types_ get different treatment.” That principle allows [overloading](https://en.wikipedia.org/wiki/Function_overloading) beyond [arity](https://en.wikipedia.org/wiki/Arity) and enables Julia to optimize code based on each _type_’s _special_ characteristics, resulting in **high performance**.

Still the programmer could suggest that at least the _generic_ fix should get priority over the _special_ one, for being **more _generic_**. But that would be against Julia’s principle: “_Special_ gets priority over _generic_.” That principle (which extends beyond Julia’s boundaries) allows programmers to have code for their _special_ custom _types_ take priority over the _generic_ or default/fall-back functionality provided by Julia packages or other libraries, preventing surprising conflicts and resulting in **high flexibility**.

Still the programmer could argue that such conflicts could get resolved instead by each time giving priority to whatever _method_ got **defined last**. That way programmers could decide priority for themselves, based on their personal needs. However, although that would free the programmer from previous definitions, it could easily alter the functionality of loaded packages in ways unpredictable by someone who doesn’t know their internals. One of the reasons that packages created by unrelated people are able to work together smoothly, is that priority is governed by the “_special_ over _generic_” principle, acting like a **contract** which people can trust to code independently.

Still the programmer in the above session has a specific intent, that all two-argument calls of the `myfun` _function_ to return the result defined by the code of the `myfun(x1, x2)` _method_. Outside **interactive coding** , that could be achieved simply by removing the code of the _special_ definition, effectively directing all potential calls to the remaining _generic_ _method_. But when coding interactively (like in Julia’s REPL), past actions remain in effect to the end of the session. In that case, there are **various options** presented right below.

### Overwriting _methods_

**Redefine/overwrite** the _special_ _method_ to make it like the _generic_ one or **_specialize_** upon it:

```julia-auto
julia> myfun(s1::String, s2::String) = "too many strings: $s1, $s2" # overwrite
WARNING: Method definition myfun(String, String) [...] overwritten

julia> myfun("a", "b") # call the redefined method
"too many strings: a, b"

```

**Redefine/overwrite** the _special_ _method_ to explicitly [invoke](http://docs.julialang.org/en/release-0.5/stdlib/base/#Base.invoke) the _generic_ one:

```julia-auto
julia> myfun(s1::String, s2::String) = myfun(s1, s2) # overwrite, the wrong way
WARNING: Method definition myfun(String, String) [...] overwritten

julia> myfun("a", "b") # call the redefined method, which calls itself forever
ERROR: StackOverflowError:

julia> myfun(s1::String, s2::String) = invoke(myfun, tuple(Any, Any), s1, s2) # overwrite
WARNING: Method definition myfun(String, String) [...] overwritten

julia> myfun("a", "b") # call the redefined method, but get the result of the generic method
"too many arguments: a, b"

```

**Start over** by calling the interactive [workspace()](http://docs.julialang.org/en/release-0.5/stdlib/base/#Base.workspace) _function_, without exiting Julia’s REPL:

```julia-auto
julia> workspace()

julia> myfun # all user definitions are gone
ERROR: UndefVarError: myfun not defined

julia> myfun(x1, x2) = "too many arguments: $x1, $x2" # both function and method defined at once
myfun (generic function with 1 method)

julia> myfun("a", "b") # only a single candidate method now
"too many arguments: a, b"

```

### _JIT_ compiler implications

In both overwriting cases, a warning was raised. There is good reason for that, as overwriting a _method_ directs all its future calls to the new definition, except of those which are **already compiled** :

```julia-auto
julia> myfun(x) = myfun(x, "b") # purposely define myfun(x) so as to call myfun(x1, x2)
myfun (generic function with 2 methods)

julia> myfun("a") # here myfun(x) gets JIT compiled to depend on myfun(x1, x2)
"too many arguments: a, b"

julia> myfun(x1, x2) = "2: two arguments are fine: $x1, $x2" # overwrite with a new (2nd) version
WARNING: Method definition myfun(Any, Any) [...] overwritten

julia> myfun("a", "b") # the 2nd version of method myfun(x1, x2) works fine
"2: two arguments are fine: a, b"

julia> myfun("a") # but method myfun(x) is still compiled to call the 1st version
"too many arguments: a, b"

julia> myfun(x) = myfun(x, "b") # redefine myfun(x) exactly as before
WARNING: Method definition myfun(Any) [...] overwritten

julia> myfun("a") # now method myfun(x) gets JIT compiled to call the 2nd version
"2: two arguments are fine: a, b"

julia> myfun(x) = myfun(x, x) # overwrite to hopefully call 2nd version before next change
WARNING: Method definition myfun(Any) [...] overwritten

julia> myfun(x1, x2) = "3: two arguments are mysterious: $x1, $x2" # overwrite with 3rd version
WARNING: Method definition myfun(Any, Any) [...] overwritten

julia> myfun("a") # but method myfun(x) gets JIT compiled to call the 3rd version
"3: two arguments are mysterious: a, a"

julia> myfun(x) = invoke(myfun, tuple(Any, Any), x, x) # overwrite to depend on function myfun
WARNING: Method definition myfun(Any) [...] overwritten

julia> myfun(x1, x2) = "4: two arguments ought to be enough: $x1, $x2" # overwrite with 4th version
WARNING: Method definition myfun(Any, Any) [...] overwritten

julia> myfun("a") # 4th version works fine, as function myfun never gets overwritten
"4: two arguments ought to be enough: a, a"

julia> myfun(x1, x2) = "5: two arguments final offer: $x1, $x2" # overwrite with 5th version
WARNING: Method definition myfun(Any, Any) [...] overwritten

julia> myfun("a") # 5th version works fine, myfun(x) always calls latest version
"5: two arguments final offer: a, a"

julia> myfun(x) = eval( :( myfun($x, $x) ) ) # overwrite to enforce recompilation of the call
WARNING: Method definition myfun(Any) [...] overwritten

julia> myfun(x1, x2) = "4: two arguments ought to be enough: $x1, $x2" # back to 4th version
WARNING: Method definition myfun(Any, Any) [...] overwritten

julia> myfun("a") # 4th version works fine, as eval() recreates the call every time
"4: two arguments ought to be enough: a, a"

julia> myfun(x1, x2) = "5: two arguments final offer: $x1, $x2" # forward to 5th version
WARNING: Method definition myfun(Any, Any) [...] overwritten

julia> myfun("a") # 5th version works fine, myfun(x) always calls latest version
"5: two arguments final offer: a, a"

julia> map(myfun, 1:2) # higher-order function map gets JIT compiled to call current myfun(x)
2-element Array{String,1}:
 "5: two arguments final offer: 1, 1"
 "5: two arguments final offer: 2, 2"

julia> myfun(x) = "single argument: $x" # overwrite with initial definition
WARNING: Method definition myfun(Any) [...] overwritten

julia> map(myfun, 1:2) # but map is still compiled to call the previous definition
2-element Array{String,1}:
 "5: two arguments final offer: 1, 1"
 "5: two arguments final offer: 2, 2"

julia> map( (x)-> myfun(x) , 1:2) # use an anonymous function to recompile on every call
2-element Array{String,1}:
 "single argument: 1"
 "single argument: 2"

```

The above should clear up that, as Julia is not an interpreter but a **compiler** , overwriting a _method_ **doesn’t update** already compiled definitions. And also that, as Julia’s compiler is a **_JIT_** compiler, new definitions get normally compiled **not before** their first actual usage ([precompilation](http://docs.julialang.org/en/release-0.5/manual/modules/#man-modules-initialization-precompilation) is not examined in this post).

- The `invoke()` _function_ is **slower** than a compiled call, so it should be avoided under usual conditions.
- The [eval()](http://docs.julialang.org/en/release-0.5/stdlib/base/#Base.eval) _function_ is **even slower** , for providing more flexibility.
- The repeated creation of anonymous _functions_ adds its own **overhead** , but it works well for interactive calling of [higher-order](https://en.wikipedia.org/wiki/Higher-order_function) _functions_.
- Another work-around in various coding scenarios is to put compiled _methods_ inside **modules** and reload the latter whenever an update is needed, as described in official [Workflow Tips](http://docs.julialang.org/en/release-0.5/manual/workflow-tips/).

## Final considerations

The previous demonstration covers the **most usual cases**. But the implications are more complicated and there are **edge cases** of undefined behavior, not mentioned here. There is an [open issue](https://github.com/JuliaLang/julia/issues/265) on Julia’s repository which aims to remove compiler implications from future releases of Julia. The intended behavior is that, every time a _method_ gets redefined, it will recursively invalidate all compiled calls to it, so as on their next execution they get recompiled to call the latest definition. However, that won’t change the **principles** stated here and every programmer in Julia should be aware of them, no matter if coding interactively or not.

---

<div class="post-metadata">

**Author:** ![ArchieCall](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/archiecall/32/206_2.png) [@ArchieCall](https://discourse.julialang.org/u/ArchieCall)\
**Post date:** [November 18, 2016, 3:21pm UTC](https://discourse.julialang.org/t/overwriting-functions/404/2 "2016-11-18T15:21:51Z")

</div>

akis,

Your thought process in describing the following is very enlightening to more casual users of Julia like myself

- compilers vs. interpreters
- functions vs. methods
- overwriting methods
- pre compilation and JIT implications

Unless one digs down to a certain level in Julia these concepts can easily go right over your head.

Thanks for your efforts in documentation…Archie

.

---

<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:** [November 19, 2016, 10:44am UTC](https://discourse.julialang.org/t/overwriting-functions/404/3 "2016-11-19T10:44:23Z")

</div>

My understanding is that fixing #265 **would** change the principles you demonstrate in the last part: redefining functions will for all intents and purposes be equivalent to recompiling the functions which call them.

---

<div class="post-metadata">

**Author:** ![akis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akis/32/156_2.png) [@akis](https://discourse.julialang.org/u/akis)\
**Post date:** [November 19, 2016, 5:34pm UTC](https://discourse.julialang.org/t/overwriting-functions/404/4 "2016-11-19T17:34:24Z")

</div>

> [@Tamas\_Papp](#):
>
> My understanding is that fixing #265 would change the principles you demonstrate in the last part: redefining functions will for all intents and purposes be equivalent to recompiling the functions which call them.

The post mentions four principles, listed in the beginning for convenience. The last two principles are demonstrated near the end:

> [@akis](#):
>
> as Julia is not an interpreter but a **compiler** ,  
> […]  
> as Julia’s compiler is a **_JIT_** compiler,

The rest of the text contains no principles. Would you suggest some rephrasing to make that clear?

---

<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:** [November 19, 2016, 6:32pm UTC](https://discourse.julialang.org/t/overwriting-functions/404/5 "2016-11-19T18:32:49Z")

</div>

My understanding is that what you demonstrate in the part “JIT compiler implications” is not a consequence of any principle, but the infamous issue #265. This is the way things currently are, and it’s good that you address this in a FAQ item because many people run into it, but it will (hopefully) change soon.

The way I see it, once #265 is fixed, the fact that Julia is a JIT compiler should be irrelevant for function redefinitions.

---

<div class="post-metadata">

**Author:** ![akis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akis/32/156_2.png) [@akis](https://discourse.julialang.org/u/akis)\
**Post date:** [November 19, 2016, 7:54pm UTC](https://discourse.julialang.org/t/overwriting-functions/404/6 "2016-11-19T19:54:24Z")

</div>

Principles don’t change, but I updated the post to state what should be expected from fixing issue #265. Thanks for the suggestion.

---

<div class="post-metadata">

**Author:** ![Ralph\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ralph_smith/32/10344_2.png) [@Ralph\_Smith](https://discourse.julialang.org/u/Ralph_Smith)\
**Post date:** [November 19, 2016, 11:49pm UTC](https://discourse.julialang.org/t/overwriting-functions/404/7 "2016-11-19T23:49:52Z")

</div>

A common work-around for the problem of obsolete cached compiled methods (issue 265) is to put volatile method definitions in a module, then reload the module after editing, as described in [the workflow section of the manual](http://docs.julialang.org/en/release-0.5/manual/workflow-tips/). You should be reminded to also reload any modules using the changed one by a single warning (rather than the cascade you get when reloading a file of bare functions). This is not quite as robust as `workspace()`, but suffices for typical iterative development in Julia v0.5 (and can save a lot of time in a large project).

---

<div class="post-metadata">

**Author:** ![akis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/akis/32/156_2.png) [@akis](https://discourse.julialang.org/u/akis)\
**Post date:** [November 22, 2016, 11:53pm UTC](https://discourse.julialang.org/t/overwriting-functions/404/8 "2016-11-22T23:53:13Z")

</div>

Wiki updated to include three more user suggestions and extra code. Much appreciated.
