# I seriously struggle to understand method extension in connection with using, import and export

**URL:** <https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831>\
**Category:** New to Julia\
**Tags:** method-extension\
**Created:** [February 18, 2020, 9:04pm UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831 "2020-02-18T21:04:22Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![wg030](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wg030/32/12944_2.png) [@wg030](https://discourse.julialang.org/u/wg030)\
**Post date:** [February 18, 2020, 9:04pm UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/1 "2020-02-18T21:04:22Z")

</div>

Hi everybody!

I have a hard time to understand how method extension really works and I hope you can help me with that. Let’s look at a concrete example and talk about the DataStructures module with `SortedSet`.

So DataStructures.jl contains

```julia
import Base: show

```

and sorted\_set.jl defines a method by

```julia
function Base.show(io::IO, m::SortedSet{K,Ord}) where {K,Ord <: Ordering}

```

which means that even though `show` is not exported in the DataStructure package, it can be called by `show(mysortedset)`from outside the module after loading the package with `using DataStructures`. What I don’t really understand here is why sorted\_set.jl defines this method with `Base.show` instead of just `show`, which is what I would expect according to section 25.1 of the manual.  
For example DataStructures.jl also contains

```julia
import Base: push!

```

ans sorted\_set.jl defines a method by

```julia
@inline function push!(m::SortedSet, k_)

```

and this method can also be called outside the module by `push!(mysortedset, somestuff)` even tough it is not exported either. So where is the difference in this two cases? Or are they actually aquivalent? Or does this have to do with the `@inline`?

Even more trouble causes the method `setdiff!` for me. There is **NO** line like

```julia
import Base: setdiff!

```

(just `import Base: setdiff`, which I suppose to be a different name), but the method

```julia
function setdiff!(m1::SortedSet, iterable)

```

defined in sorted\_set.jl can be called the same way as `push!`. That’s what I complete don’t understand since the method is not exported neither imported for method extension. From my understaind it should not be possible to call it with just `settdiff!(mysortedset, somestuff)`, but I can confirm it is. My expectation would be, again referring to section 25.1 of the manual, that it must be called by `DataStructures.settdiff!(mysortedset, somestuff)`.

I would really highly appreciate if someone was able to explain me what is going on here and tell me the point that I have missed so far. Thanks a lot!

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [February 18, 2020, 10:09pm UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/2 "2020-02-18T22:09:42Z")

</div>

In the first example, it looks like `Base.show` is redundant. That is, `show` would work as well. Alternatively, you could omit `import Base: show`, and then you would be required to use `Base.show` (to extend the function `show` from `Base` as intended.)

This is probably because `DataStructures` is too large and contains unrelated code that is developed by different people. There has been talk of splitting it.

I prefer to avoid importing from `Base` when possible, and then explicitly writing `Base.show(...`. This seems cleaner, signals intent at the method definition, and avoids redunancy causing the confusion that you are having (because you are not used to seeing this kind of thing.)

---

<div class="post-metadata">

**Author:** ![wg030](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wg030/32/12944_2.png) [@wg030](https://discourse.julialang.org/u/wg030)\
**Post date:** [February 19, 2020, 11:44am UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/3 "2020-02-19T11:44:16Z")

</div>

Thanks for the explanation. That makes a little more sense now:  
So if you do `import Base: show` or `import Base: push!` you could extend these methods without the prefix `Base.`, but you are not required to do so. If you omit the import statement, you must define it with `Base.show(...)` or `Base.push!(...)`. That sounds logical to me now and I totally agree with you that the second version is way better to understand and read.

**HOWEVER** What about `setdiff!`, which contraticts this.  
I mean it is defined with `setdiff!(...)` on the one hand, but there is no `Base: setdiff!` on the other hand. That should not actually work, but it does. Could it be that I am wrong when I assume that `setdiff` and `setdiff!` are different and they are actually somehow considered the same? I mean there is `Base: setdiff` in the package definition, so that would make sense!

---

<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 19, 2020, 11:49am UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/4 "2020-02-19T11:49:37Z")

</div>

> [@wg030](#):
>
> but there is no `Base: setdiff!` on the other hand

It is [imported explicitly](https://github.com/JuliaCollections/DataStructures.jl/blob/98b01d14a1edb9282d91a921cf49c93ef5259e17/src/int_set.jl#L5).

Most packages would put imports in the main source file, but that is merely a style convention.

When in doubt, you can always check these things interactively, eg

```julia
julia> import DataStructures

julia> parentmodule(DataStructures.setdiff!)
Base

```

---

<div class="post-metadata">

**Author:** ![wg030](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wg030/32/12944_2.png) [@wg030](https://discourse.julialang.org/u/wg030)\
**Post date:** [February 19, 2020, 12:54pm UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/5 "2020-02-19T12:54:51Z")

</div>

> [@Tamas\_Papp](#):
>
> It is [imported explicitly](https://github.com/JuliaCollections/DataStructures.jl/blob/98b01d14a1edb9282d91a921cf49c93ef5259e17/src/int_set.jl#L5).
> 
> Most packages would put imports in the main source file, but that is merely a style convention.

😃  
It’s obiously a pretty good idea to stick to that convention. Looking for the command in another files of the package, which are not even related to `SortedSet` is something I would have never done.

But the command `parentmodule` is new to me! Thanks for that one! It should help a lot!

---

<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 19, 2020, 1:15pm UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/6 "2020-02-19T13:15:28Z")

</div>

> [@wg030](#):
>
> Looking for the command in another files of the package, which are not even related to `SortedSet` is something I would have never done.

It is generally a good idea to be able to use a variant of `grep` when learning about the internals of a package. I use [`ag`](https://github.com/ggreer/the_silver_searcher), integrated into [Emacs](https://github.com/syohex/emacs-helm-ag); possibly your IDE has something similar, or you can use the command line.

---

<div class="post-metadata">

**Author:** ![wg030](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/wg030/32/12944_2.png) [@wg030](https://discourse.julialang.org/u/wg030)\
**Post date:** [February 20, 2020, 7:43pm UTC](https://discourse.julialang.org/t/i-seriously-struggle-to-understand-method-extension-in-connection-with-using-import-and-export/34831/7 "2020-02-20T19:43:09Z")

</div>

I will try to find that out! Thanks a lot for your useful advice!
