# Overwriting functions in another module

**URL:** <https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984>\
**Category:** New to Julia\
**Created:** [February 19, 2019, 7:10pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984 "2019-02-19T19:10:49Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Egwene\_al\_Vere](https://avatars.discourse-cdn.com/v4/letter/e/df788c/32.png) [@Egwene\_al\_Vere](https://discourse.julialang.org/u/Egwene_al_Vere)\
**Post date:** [February 19, 2019, 7:10pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/1 "2019-02-19T19:10:49Z")

</div>

Redefining some module’s values/functions directly is not allowed:

```julia
module testm

s = 1

function f(x)
    x/2
end

end

```

`testm.s = 3`

> ERROR: cannot assign variables in other modules

```julia
g = x -> x/10

testm.f = g

```

> ERROR: cannot assign variables in other modules

However, this works:  
`testm.f(x) = g(x)`

`testm.f(1)`

> 0.1

What is the reasoning behind such behavior? Thanks!

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [February 19, 2019, 7:29pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/2 "2019-02-19T19:29:04Z")

</div>

I filed an issue about it [https://github.com/JuliaLang/julia/issues/23295](https://github.com/JuliaLang/julia/issues/23295). I find globals occasionally convenient.

There’s two work-arounds, either you use

```julia
const my_flag = Ref(false)

```

like [Revise.jl does](https://github.com/timholy/Revise.jl/blob/fad8ce53f650c486ed066b27803e6b247749c62f/src/Revise.jl#L31) or you use `@eval ThatModule some_global = 10`.

Regarding `testm.f = g`, there’s a technical reason for not allowing assigning to a function. Julia has multiple dispatch, and it would make the compiler’s job much harder/impossible if it gave you the option to redefine functions like that.

---

<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:** [February 19, 2019, 7:36pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/3 "2019-02-19T19:36:49Z")

</div>

You can also use setter functions:

```julia
julia> module A
       glob = 1
       change_glob(v) = global glob = v
       end

julia> A.glob
1

julia> A.change_glob(4)
4

julia> A.glob
4

```

---

<div class="post-metadata">

**Author:** ![Egwene\_al\_Vere](https://avatars.discourse-cdn.com/v4/letter/e/df788c/32.png) [@Egwene\_al\_Vere](https://discourse.julialang.org/u/Egwene_al_Vere)\
**Post date:** [February 19, 2019, 7:47pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/4 "2019-02-19T19:47:45Z")

</div>

Thanks! I’m still trying to understand the reason for how `testm.f(x) = g(x)` actually work as “redefine test.f” though.

---

<div class="post-metadata">

**Author:** ![favba](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/favba/32/2735_2.png) [@favba](https://discourse.julialang.org/u/favba)\
**Post date:** [February 19, 2019, 7:49pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/5 "2019-02-19T19:49:28Z")

</div>

> [@Egwene\_al\_Vere](#):
>
> However, this works:  
> `testm.f(x) = g(x)`
> 
> `testm.f(1)`
> 
> > 0.1
> 
> What is the reasoning behind such behavior? Thanks!

You’re not allowed to change variables in other modules, but you are allowed to add/modify methods for functions defined in other modules.

see [Methods · The Julia Language](https://docs.julialang.org/en/v1/manual/methods/#Methods-1)

---

<div class="post-metadata">

**Author:** ![Egwene\_al\_Vere](https://avatars.discourse-cdn.com/v4/letter/e/df788c/32.png) [@Egwene\_al\_Vere](https://discourse.julialang.org/u/Egwene_al_Vere)\
**Post date:** [February 19, 2019, 7:59pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/6 "2019-02-19T19:59:36Z")

</div>

Got it. Thanks!

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [February 19, 2019, 8:24pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/7 "2019-02-19T20:24:12Z")

</div>

You can’t write `testm.f(x) = g(x)` inside of a function, to redefine it at runtime. This restriction allows the compiler to assume that, once you’re pressed Enter at the REPL, `f(x) = g(x)` will be true until the computation finishes (barring some technicality with `@eval` and the world age).

Globals can be changed at runtime anywhere, so the compiler can’t assume anything about them, and their performance is terrible.

That’s why functions and globals are separate concepts in Julia, whereas in Python function definitions are (basically) implemented as global variables.

---

<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:** [February 20, 2019, 8:12am UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/8 "2019-02-20T08:12:30Z")

</div>

> [@Egwene\_al\_Vere](#):
>
> What is the reasoning behind such behavior? Thanks!

I am not sure what the original design reason was, but I like it this way. I consider globals as internal to a module, mostly an implementation detail, which should only be exposed via accessor functions outside the module.

Eg suppose I have a package for managing some templates, and have a setup like

```julia
module TemplateManager

export default_template_dir

DEFAULT_TEMPLATE_DIR = expanduser("~/templates")

default_template_dir() = DEFAULT_TEMPLATE_DIR

end

```

Later on I can decide to make the global a `Ref`, fixing the type, or allow the user to set it via an environment variable and just provide a fallback, eg

```julia
function default_template_dir()
    get(ENV, "DEFAULT_TEMPLATE_DIR", DEFAULT_TEMPLATE_DIR)
end

```

without changing the API. Similarly, I can make a setter function

```julia
function default_template_dir!(path)
    isdir(path) || @warn "setting non-existent path for templates"
    DEFAULT_TEMPLATE_DIR = path
end

```

that validates the input.

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [February 22, 2019, 9:27am UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/9 "2019-02-22T09:27:02Z")

</div>

I’ve been experimenting a lot with similar issues related to dependency injection, and my current preferred approach is to `eval` within the scope of the targeted module. So if you’re looking for a way to actually do what you tried, this works:

```julia
julia> Core.eval(testm, :(s = 3))
3

julia> testm.s
3

```

---

<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:** [February 22, 2019, 9:47am UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/10 "2019-02-22T09:47:42Z")

</div>

Or `TestModule.eval(:(s = 3))` (note that `A.@eval s=3` does not work).

---

<div class="post-metadata">

**Author:** ![essenciary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/essenciary/32/210469_2.png) [@essenciary](https://discourse.julialang.org/u/essenciary)\
**Post date:** [February 22, 2019, 10:48am UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/11 "2019-02-22T10:48:24Z")

</div>

Nice, shorter.

---

<div class="post-metadata">

**Author:** ![jonathanBieler](https://avatars.discourse-cdn.com/v4/letter/j/82dd89/32.png) [@jonathanBieler](https://discourse.julialang.org/u/jonathanBieler)\
**Post date:** [February 22, 2019, 1:01pm UTC](https://discourse.julialang.org/t/overwriting-functions-in-another-module/20984/12 "2019-02-22T13:01:29Z")

</div>

Or if you want to write more complex expressions:

```julia
@eval TestModule begin
    s = 3
end

```
