# How to make method globally accessible (for interface/protocols/polymorphic types) and avoid "per-module" extension?

**URL:** <https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533>\
**Category:** New to Julia\
**Created:** [July 20, 2022, 1:01pm UTC](https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533 "2022-07-20T13:01:12Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![omnifect](https://avatars.discourse-cdn.com/v4/letter/o/c37758/32.png) [@omnifect](https://discourse.julialang.org/u/omnifect)\
**Post date:** [July 20, 2022, 1:01pm UTC](https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533/1 "2022-07-20T13:01:13Z")

</div>

Hello, I am new to Julia and it’s namespace system. I also don’t know the correct terminology for what I am trying to do (so apologies in advance).

I am trying to see how to one could write “polymorphic” types without having to extend the methods to the namespaces that will use those types. I know that “polymorphism” doesn’t make sense in Julia, but in Python, lets say there some code that takes in an object and does something with that object. I don’t know what the object is, but I know I can do something by calling the `do_something()` method:

```julia
def foo(x):
    x.do_something()

```

And I have to do is ensure that `x` has a `do_something()` method.

In Julia, I can get the same behavior, but only if I extend an existing `do_something()` method in ALL modules that calls this “type-defined” (for lack of a better word) method. Example:

```julia
module Test # Made by Programmer 1
  function do_something end # User-must define this method
  function foo(x)
    do_something(x) # Use user-defined method
  end
end

module TestB # Made by Programmer 2
  function do_something end # User-must define this method
  function foo(x)
    do_something(x) # Use user-defined method
  end
end

module Test2 # Made by Programmer 3 
  import ..Test

  struct MyType
    val
  end

  function do_something(x::MyType) # User is defining do_something (how to do this globally?)
    print(x.val)
  end
end

# Written by Programmer 4

# do_something implementation must be extended for EACH module expecting an implementation of do_something.
# How can I avoid the need to do per-module extension (next 7 lines) and instead just extend so that all modules can see "do_something(x::MyType)" without manual extension?
# Extending in Base doesn't work since "do_something" is not defined in that namespace.
function Test.do_something(x::Test2.MyType) 
  print(x.val)
end

function TestB.do_something(x::Test2.MyType) 
  print(x.val)
end

Test.foo(Test2.MyType("Hello World!\n"))
TestB.foo(Test2.MyType("Hello Universe!\n"))

```

How can I make the `do_something` function available globally, so that I don’t have to extend the function for multiple namespaces that might use it? Is something like that possible in Julia? Is it bad practice? Is there a central/global names space where I can define/extend functions only once, and then those functions are accessible everywhere?

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [July 20, 2022, 1:52pm UTC](https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533/2 "2022-07-20T13:52:14Z")

</div>

What you describe is typically called an `Interface`.  
You can find examples for interfaces here [Interfaces · The Julia Language](https://docs.julialang.org/en/v1/manual/interfaces/)

It could look like this

```julia
module SolverInterface
     abstract type AbstractSolver end;
     solve(solver::AbstractSolver) = nothing
     export AbstractSolver
     export solve
end

```

then users could use this template to define their own solvers

```julia
using SolverInterface

struct MySolver <: AbstractSolver
      solution::Int64
end

function SolverInterface.solve(solver::MySolver)
    return solver.solution
end

solver = MySolver(42)
solve(solver)

```

In this way it is clear that everyone has to extend the function from `SolverInterface`, that resolves the problem you pointed out that people would have to overwrite the functions for each other’s modules.

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [July 20, 2022, 2:20pm UTC](https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533/3 "2022-07-20T14:20:31Z")

</div>

> [@SteffenPL](#):
>
> ```julia
> function solve(solver::MySolver)
> 
> ```

This should be

```julia
function SolverInterface.solve(solver::MySolver)

```

otherwise a new function `CurrentModule.solve` will be created.

Alternatively, `solve` could be explicitly imported: `import SolverInterface: solve`

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [July 20, 2022, 2:21pm UTC](https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533/4 "2022-07-20T14:21:08Z")

</div>

Take a look at something like [DataAPI.jl](https://github.com/JuliaData/DataAPI.jl) which solves this problem.

Have a third package which defines the core functions, everything else extends them.

---

<div class="post-metadata">

**Author:** ![SteffenPL](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/steffenpl/32/206270_2.png) [@SteffenPL](https://discourse.julialang.org/u/SteffenPL)\
**Post date:** [July 20, 2022, 2:26pm UTC](https://discourse.julialang.org/t/how-to-make-method-globally-accessible-for-interface-protocols-polymorphic-types-and-avoid-per-module-extension/84533/5 "2022-07-20T14:26:02Z")

</div>

Thanks, I edited it.
