# Best practice to support multiple implementations

**URL:** <https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240>\
**Category:** New to Julia\
**Tags:** multidispatch\
**Created:** [January 8, 2022, 1:58pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240 "2022-01-08T13:58:14Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![roh\_codeur](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@roh\_codeur](https://discourse.julialang.org/u/roh_codeur)\
**Post date:** [January 8, 2022, 1:58pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/1 "2022-01-08T13:58:14Z")

</div>

Hi

I am a newbie to the language, coming from an OOP background. I have a method as below:

```julia
function run(downloader)
       downloader.download()
end

```

the downloader can have several implementations, for instance, could be downloading from internet or getting data from csv etc.

I am looking for advice on how Julia supports this. keeping in view, type safety, multiple dispatch etc.  
In other languages, such as Java, this would be supported by creating an interface

Java example

```julia
void run(IDownloader downloader)
       downloader.download()
end

interface IDownloader {
         void download();
}

class CsvDownloader implements IDownloader{
         void download(){}
}

```

Thanks!  
Roh

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 8, 2022, 2:49pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/2 "2022-01-08T14:49:13Z")

</div>

In this case, it sounds like you could just pass a function:

```julia
function run(download)
    download()
end

```

For more general cases, the analogue of OOP’s `object.method(args...)` in Julia is `method(object, args...)`. Just like how in OOP you can overload a method for an object, in the same way for Julia you can overload functions for particular argument types (based on any/all of the argument types — this is called “multiple dispatch”, whereas traditional OOP is “single dispatch” because the `method` called only depends on the type of `object` and not on the other arguments).

For example, if you write

```julia
sqr(a) = a * a

```

in Julia, then it will work on any type of `a` object that has implemented a method for the function `(*)(a, a)`, i.e. `*` with two arguments of the type of `a`.

---

<div class="post-metadata">

**Author:** ![roh\_codeur](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@roh\_codeur](https://discourse.julialang.org/u/roh_codeur)\
**Post date:** [January 8, 2022, 3:00pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/3 "2022-01-08T15:00:58Z")

</div>

thanks for your elaborate response. this is indeed a wonderful community.

_“Julia you can overload functions for particular argument types (based on any/all of the argument types”_

in my case, the arguments are the same for multiple implementations of the download function.

Also, not sure:

1. Does this impact performance? not specifying the arguments with function passed in as an arg. Also, please consider the scenario where run() takes in multiple functions as args.
2. Can this be solved using traits? I am reading about them as I write.

ta!

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 8, 2022, 3:06pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/4 "2022-01-08T15:06:20Z")

</div>

> [@roh\_codeur](#):
>
> in my case, the arguments are the same for multiple implementations of the download function.

No, they’re not. The analogue of `downloader.download(args...)` in Julia would be `download(downloader, args...)`, so the type of `downloader` (the `self` object in Python or `this` in C++) is different and you can dispatch on that.

> [@roh\_codeur](#):
>
> Does this impact performance?

Not for properly written (type-stable/type-inferrable) Julia code — the Julia complier compiles a type-specialized version of `run` based on the type of the argument (`downloader`) at the call site. This is called “devirtualization” in C++, and is commonplace in Julia because all concrete types are “final” (in C++ parlance).

> [@roh\_codeur](#):
>
> Can this be solved using traits?

Traits are essentially a way to get benefits analogous to multiple inheritance / mix-in interfaces. It doesn’t sound like you need that here, and in general you should learn the basics (how dispatch and generic programming works) before you learn fancier techniques.

---

<div class="post-metadata">

**Author:** ![roh\_codeur](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@roh\_codeur](https://discourse.julialang.org/u/roh_codeur)\
**Post date:** [January 8, 2022, 3:10pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/5 "2022-01-08T15:10:04Z")

</div>

Got it! thanks a lot for your comments and feedback. I will give this a shot.

---

<div class="post-metadata">

**Author:** ![roh\_codeur](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@roh\_codeur](https://discourse.julialang.org/u/roh_codeur)\
**Post date:** [January 8, 2022, 3:23pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/6 "2022-01-08T15:23:36Z")

</div>

@stevengj Looks like I do need to read a bit more on Julia docs. May I ask you another question please? Do you think this would be a good solution in my case:

```julia
function downloader()
... download some data
end

function run(downloader)
downloader()
end

```

I haven’t enforced any types downloader function when I passed it in as an arg. Does this matter? if it does, how can I enforce types on functions? I tried the below and it didn’t work.

```julia
function run(downloader::Function{String, Number})
    # download data
    downloader()
end

```

---

<div class="post-metadata">

**Author:** ![melonedo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/melonedo/32/15503_2.png) [@melonedo](https://discourse.julialang.org/u/melonedo)\
**Post date:** [January 8, 2022, 3:58pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/7 "2022-01-08T15:58:32Z")

</div>

Julia currently does not support typing functions, because unlike c, a function is a set of different methods. It is like the visitor pattern in Java where you pass a set of methods to be dispatched.

For example, this is possible in Julia:

```julia
function run(downloader, source)
    downloader(source)
end
run(downloader, ip) # ip of type IPv4
run(downloader, "http://julialang.org")

```

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [January 8, 2022, 4:00pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/8 "2022-01-08T16:00:29Z")

</div>

this isn’t quite true. Julia stores support young functions, it’s just that every function has a unique type and the type isn’t determinedby the argument tropes.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 8, 2022, 4:35pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/9 "2022-01-08T16:35:18Z")

</div>

> [@roh\_codeur](#):
>
> I haven’t enforced any types downloader function when I passed it in as an arg. Does this matter?

No, it’s not a problem.

See also [Argument-Type Declarations](https://docs.julialang.org/en/v1/manual/functions/#Argument-type-declarations) in the Julia manual.

---

<div class="post-metadata">

**Author:** ![roh\_codeur](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@roh\_codeur](https://discourse.julialang.org/u/roh_codeur)\
**Post date:** [January 9, 2022, 11:38am UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/10 "2022-01-09T11:38:45Z")

</div>

Thanks to everyone who pitched in. this is the solution I came up with:

```julia
using BenchmarkTools

abstract type Downloader end

function downloadFromUrl(url::String)
    # println("downloading from url $url")
    # some operation
    count = 0.
    for i in rand(100000)
        count+=i
    end
end

function downloadFromCsv(filepath::String)
    # println("downloading from url $url")
    # some operation
    count = 0.
    for i in rand(100000)
        count+=i
    end
end

Base.@kwdef struct UrlDownloader <: Downloader
    url::String = "some--url"
    token::String = "my-token"
    process::Function = () -> downloadFromUrl(url)
end

Base.@kwdef struct CsvDownloader <: Downloader
    filePath::String = "file-path"
    process::Function = () -> downloadFromCsv(filePath)
end

function run(downloader::Downloader)
    println("Running $(typeof(downloader))")
    downloader.process()
end

# call run with url downloader
run(UrlDownloader())
# call run with csv downloader
run(CsvDownloader())

println("Calling methods directly")
@btime downloadFromUrl("some url")
@btime downloadFromCsv("some file path")

println("Calling methods from struct")
@btime UrlDownloader().process()
@btime CsvDownloader().process()

```

Output:

```julia
Running UrlDownloader
Running CsvDownloader
Calling methods directly
  66.208 μs (2 allocations: 781.30 KiB)
  66.167 μs (2 allocations: 781.30 KiB)
Calling methods from struct
  66.208 μs (2 allocations: 781.30 KiB)
  66.167 μs (2 allocations: 781.30 KiB)

```

1. I can call run with any implementation of the downloader.
2. I have checked that calling the method directly vs calling a method referenced from inside a struct does not have any performance penalties (I didn’t expect any, this is just a learning exercise)
3. It allows me to pass in a struct to run() function. the struct has the params and the method specified, which I feel fits nicely together. the alternative was that I don’t use structs and pass in the functions as args to run. the functions can get very complicated and have multiple args, so I feel this pattern fits better

I look forward to everyone’s comments and suggestions. Please do let me know if there is a better approach. ta!

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [January 9, 2022, 1:56pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/11 "2022-01-09T13:56:23Z")

</div>

> [@roh\_codeur](#):
>
> ```julia
> Base.@kwdef struct UrlDownloader <: Downloader
> url::String = "some--url"
> token::String = "my-token"
> process::Function = () -> downloadFromUrl(url)
> end
> 
> ```

Don’t try to emulate OOP syntax this way. The `process` [field is abstractly typed](https://docs.julialang.org/en/v1/manual/performance-tips/#man-performance-abstract-container), which basically prevents the compiler from doing type inference or inlining anything when you call this function. It’s also not idiomatic Julia style.

(Function-call performance may not matter in this particular example, or in any example where the body of the function takes so much time that everything else is negligible, but it’s a bad habit.)

As I said, the analogue of OOP’s `downloader.process()` [UFC](https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax) syntax in Julia is `process(downloader)`. i.e. write:

```julia
function process(x::UrlDownloader)
    # do something
end

function process(x::CsvDownloader)
    # do something else
end

function run(downloader::Downloader)
    println("Running $(typeof(downloader))")
    process(downloader)
end

```

See also [Allowing the object.method(args...) syntax as an alias for method(object, args ...)](https://discourse.julialang.org/t/allowing-the-object-method-args-syntax-as-an-alias-for-method-object-args/62051)

---

<div class="post-metadata">

**Author:** ![roh\_codeur](https://avatars.discourse-cdn.com/v4/letter/r/ce73a5/32.png) [@roh\_codeur](https://discourse.julialang.org/u/roh_codeur)\
**Post date:** [January 9, 2022, 2:22pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/12 "2022-01-09T14:22:40Z")

</div>

@stevengj : thanks a lot for your patience and review comments. I will keep those in mind and have changed the code as below

```julia
abstract type Downloader end

Base.@kwdef struct UrlDownloader <: Downloader
    url::String = "some--url"
    token::String = "my-token"
end

Base.@kwdef struct CsvDownloader <: Downloader
    filePath::String = "file-path"
end

function process(x::UrlDownloader)
    println("downloading from url $(typeof(x))")
end

function process(x::CsvDownloader)
    println("downloading from csv $(typeof(x))")
end

function run(downloader::Downloader)
    process(downloader)
end

# call run with url downloader
run(UrlDownloader())
# call run with csv downloader
run(CsvDownloader())

```

ta!

---

<div class="post-metadata">

**Author:** ![RonBackal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronbackal/32/32425_2.png) [@RonBackal](https://discourse.julialang.org/u/RonBackal)\
**Post date:** [January 14, 2022, 1:06pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/13 "2022-01-14T13:06:51Z")

</div>

though C++ has multiple dispatch too. I just always get discouraged to keep learning it sometime because it has so many subtleties 🙂

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [January 14, 2022, 1:13pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/14 "2022-01-14T13:13:34Z")

</div>

no it doesn’t. operator overloading and templating are both different from multiple dispatch.

---

<div class="post-metadata">

**Author:** ![RonBackal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronbackal/32/32425_2.png) [@RonBackal](https://discourse.julialang.org/u/RonBackal)\
**Post date:** [January 14, 2022, 1:25pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/15 "2022-01-14T13:25:41Z")

</div>

Okay good to know. What are the main difference?(I do remember from C++ book the mention of templates and overloading, I was thinking I saw multiple dispatch too, but now I see I was wrong). Because in overloading you make two function with same name, and template is to allow things like “T integrate(T,T)” for any number, so what is different in dispatch?  
Thanks for help

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [January 14, 2022, 1:28pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/16 "2022-01-14T13:28:48Z")

</div>

The difference is that both templates and overloading must know all the types of a program if you don’t want to call fallback implementations. [JuliaCon 2019 | The Unreasonable Effectiveness of Multiple Dispatch | Stefan Karpinski - YouTube](https://www.youtube.com/watch?v=kc9HwsxE1OY) has a good description of the differences.

---

<div class="post-metadata">

**Author:** ![RonBackal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronbackal/32/32425_2.png) [@RonBackal](https://discourse.julialang.org/u/RonBackal)\
**Post date:** [January 14, 2022, 1:34pm UTC](https://discourse.julialang.org/t/best-practice-to-support-multiple-implementations/74240/17 "2022-01-14T13:34:57Z")

</div>

thanks.
