# How do I add a function/method to an already defined module

**URL:** https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699
**Category:** General Usage
**Tags:** question
**Created:** [April 3, 2019, 2:38pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699 "2019-04-03T14:38:09Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 3, 2019, 2:38pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/1 "2019-04-03T14:38:09Z")

</div>

This is a follow up question relating to my question on sub modules:  
[Discourse question on submodules](https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652/2)

Okay. My issues seems to be around circular dependencies. I have an engine that wants to call methods that some “other” code defined outside of the engine. The problem is that that other code also needs to reference “things” defined in the engine. For example, I have an AbstractNode defined in the engine and so my client (aka the game) needs to reference it. The engine—when it is running— will then call these “generic” methods.  
The issue is I don’t want the engine “hard coded” on the game methods because that would negate the generality of the engine. The engine should server **any** game.

Any ideas on how to solve this? 😑

I put together a simple demonstration of attempting to do such a thing. The code is also at [Repl.it code](https://repl.it/@WilliamDeVore/ValidGreenSoftwaresuite).

Naturally I get the _error_:

```julia
ERROR: LoadError: UndefVarError: transition not defined
Stacktrace:
 [1] getproperty(::Module, ::Symbol) at ./sysimg.jl:13
 [2] top-level scope at none:0
 [3] include at ./boot.jl:326 [inlined]
 [4] include_relative(::Module, ::String) at ./loading.jl:1038
 [5] include(::Module, ::String) at ./sysimg.jl:29
 [6] include(::String) at ./client.jl:403
 [7] top-level scope at none:0
in expression starting at /home/runner/main.jl:44

```

Example code:

```julia
# Game is the module I want to augment with a new
# function called `transition()` in which the engine will call
# But I can't define transition yet because AbstractNode isn't
# defined yet, hence the chicken/egg conundrum.
module Game end

module Ranger
  module Nodes
    using ...Game

    # Simple demo node for example ----------
    abstract type AbstractNode end

    mutable struct Node <: AbstractNode
      x::Float64
    end

    crossnode = Node(1.0)
    # -------------------------------------

    function visit()
      Game.transition(crossnode)
    end
  end
end

# Demo engine
module Engine
  using ..Ranger.Nodes:
    visit
    
  function run()
    visit()
  end
end

# ------------------
# Attempt to extend Game module
using .Ranger.Nodes:
  AbstractNode
using .Game

# Attemping to add `new` function to Game module.
function Game.transition(node::AbstractNode) # <-- UndefVarError: transition not defined
  println("game transition")
end

# -------------------------
using .Engine:
  run
  
function go()
  run()
end
  
go()

```

Thanks

---

<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: [April 3, 2019, 2:46pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/2 "2019-04-03T14:46:08Z")

</div>

The answer to your title question is:

```julia
julia> module A
       end
Main.A

julia> A.eval(:(f() = 1))
f (generic function with 1 method)

julia> A.f()
1

```

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 3, 2019, 4:30pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/3 "2019-04-03T16:30:12Z")

</div>

I was afraid I would need to resort to something along the lines of `eval()` 😧

Is there any other idiomatic way?

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [April 3, 2019, 4:33pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/4 "2019-04-03T16:33:39Z")

</div>

As a slight quality of life improvement, you can use the `@eval` macro,

```julia
module A end

@eval A begin
    f() = 1
    g() = 2
end

```

But fundamentally you need to evaluate code in the existing module.

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [April 3, 2019, 4:49pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/5 "2019-04-03T16:49:03Z")

</div>

I suppose the more standard way to do this would maybe be to define an interface in `Engine`, and then have your `AbstractNode` subtypes in `Game` implement that interface (by overloading functions defined in `Engine`), something like

```julia
module Engine
abstract type AbstractNode end

function transition end

function foo(node::AbstractNode)
    # 'generic' behavior here
    transition(node)
    nothing
end
end # module

module Game
using ..Engine

struct GameNode <: Engine.AbstractNode end

Engine.transition(foo::GameNode) = @show foo
end # module

using .Game, .Engine
Engine.foo(Game.GameNode())

```

Alternatively, you could have the ‘generic’ functions in `Engine` take a function argument that acts as a callback for implementation-specific behavior.

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 3, 2019, 5:08pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/6 "2019-04-03T17:08:22Z")

</div>

Nice. I will give that approach a try. Thanks. 🙂

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 4, 2019, 7:43pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/7 "2019-04-04T19:43:58Z")

</div>

I would like to thank **mauro3** , **tkoolen** for helping me solve my issue. Here is the simplified version on [Repl.it](https://repl.it/@WilliamDeVore/ValidGreenSoftwaresuite).

I also experience some _weird_ issues with `import`ing. For example, I have two include files:

```julia
include("splash_scene.jl")
include("game_scene.jl")

```

both perform the same import statements:

```julia
import .Ranger.Nodes:
    transition, get_replacement, visit

```

If I forget to import `visit` in either one of the files I get this warning:

```julia
WARNING: import of Nodes.visit into Main conflicts with an existing identifier; ignored.

```

And as a result, the abstract overload is called instead. This is unexpected and in addition I don’t know why Julia issues this. It is true that I should only have only one import for both files—which is what I did to make sure there isn’t an inconsistency—but still it would be nice if Julia could somehow give a better clue to the problem. It took me 20 minutes to realize what the bug was. Basically, if you have this:

```julia
import .Ranger.Nodes:
    transition, get_replacement, visit

... more code and some includes()

import .Ranger.Nodes:
    transition, get_replacement #<--- missing visit import

```

You will get a warning.

Anyway, I am still learning Julia and I enjoy the language even with a few errors on my part.  
The code-in-progress in on [Github](https://github.com/wdevore/Ranger-Julia-SDL) if you are interested.

Below is a stripped down example with two lines marked `important`:

```julia
module Ranger
  module Nodes
    # This is important piece #1
    function transition end

    # Simple demo node for example ----------
    abstract type AbstractNode end

    mutable struct Node <: AbstractNode
      x::Float64
    end

    crossnode = Node(1.0)
    # -------------------------------------

    function visit()
      transition(crossnode)
    end
  end
end

# Demo engine
module Engine
  using ..Ranger.Nodes:
    visit
    
  function run()
    visit()
  end
end

# ------------------
using .Ranger.Nodes:
  AbstractNode, Node

# This is the important piece #2
import .Ranger.Nodes:
  transition

function transition(node::AbstractNode)
  println("abstract node transition")
end

function transition(node::Node)
  println("node transition")
end

# -------------------------
using .Engine:
  run
  
function go()
  run()
end
  
go()

```

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [April 4, 2019, 9:00pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/8 "2019-04-04T21:00:59Z")

</div>

Could you clarify how the simplified example relates to the problem you were having? The simplified example has only one file and only one `using ..Ranger.Nodes: visit`, and everything seems to be working as intended, no?

By the way, for clarity I personally prefer being very explicit when it comes to adding methods to functions from other modules, i.e.

```julia
import A
A.foo(x::MyType) = x

```

instead of

```julia
import A: foo
foo(x::MyType) = x

```

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 4, 2019, 9:22pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/9 "2019-04-04T21:22:18Z")

</div>

My original issue was a chicken/egg problem. Your example showed how to handle it:

```julia
function transition end

```

I didn’t know you could declare empty functions like that.

The second part of the solution was then importing correctly. I didn’t realize that importing needed to be very specific otherwise what you are trying to extend may not be what you expected.

The other part of your example completed the solution and that was importing the empty function, and as I learned the hard way, you need to make sure you are extending the correct function—which you do explicitly and I do more verbosely. I tend to hang on to particular styles and I admit I should use the more explicit style.

Doesn’t your style import in more than wanted at times?

---

<div class="post-metadata">

### Author: ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)
#### Post date: [April 4, 2019, 9:46pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/10 "2019-04-04T21:46:14Z")

</div>

> [@iPostHuman](#):
>
> Doesn’t your style import in more than wanted at times?

Somewhat confusingly, no. While `using A: foo` is in a sense more conservative than `import A: foo` in that the latter allows you to extend `A.foo` without qualification while the former doesn’t, `import A` is more conservative than `using A`, in that `import A` only makes `A` visible, while `using A` also makes functions exported from `A` visible. See [Modules · The Julia Language](https://docs.julialang.org/en/v1/manual/modules/#Summary-of-module-usage-1).

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 4, 2019, 11:08pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/11 "2019-04-04T23:08:08Z")

</div>

Yeah, I saw the chart and sort of gave it a glance-over when I was learning 😉 But now I have more respect for it.

After thinking about your style question I started thinking about mine and realized that I wouldn’t have experienced my import problem had I used A.foo approach, so I am going back and refactoring based on that realization. 😏

---

<div class="post-metadata">

### Author: ![ayushpatnaikgit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ayushpatnaikgit/32/25229_2.png) [@ayushpatnaikgit](https://discourse.julialang.org/u/ayushpatnaikgit)
#### Post date: [December 1, 2022, 12:37pm UTC](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/12 "2022-12-01T12:37:03Z")

</div>

In the [Survey.jl package](https://github.com/xKDR/Survey.jl), we are defining `mean(x::Symbol, design::SimpleRandomSample)`, in the [design\_update branch](https://github.com/xKDR/Survey.jl/blob/3805768cdcc5ddb52a1752fd7af4b1f85afb375f/src/mean.jl#L39), while we are also importing mean from `StatsBase`. Is this practice acceptable, or we should be using a different name?

In the process, we are importing `mean` from `StatsBase` by doing:

```julia
import StatsBase: mean

```
