# Understand Main and Base module behavior

**URL:** <https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713>\
**Category:** New to Julia\
**Created:** [February 12, 2019, 5:26pm UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713 "2019-02-12T17:26:54Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomf/32/6995_2.png) [@tomf](https://discourse.julialang.org/u/tomf)\
**Post date:** [February 12, 2019, 5:26pm UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713/1 "2019-02-12T17:26:54Z")

</div>

I’ve read the Julia reference section on modules carefully but I still don’t understand exactly what’s going on below. These are two separate sessions.

* * *

**First session**

```julia

# Create a simple type and define show() for it.
julia> struct Foo <: Integer x end

julia> show(z::Foo) = print(z)
show (generic function with 1 method)

julia> show(0)
ERROR: MethodError: no method matching show(::Int64)
You may have intended to import Base.show
Closest candidates are:
  show(::Foo) at REPL[2]:1
Stacktrace:
 [1] top-level scope at none:0

julia>

```

* * *

**Second run**

```julia

julia> show(0)
0
julia> struct Foo <: Integer x end

julia> show(0)
0
julia> show(z::Foo) = print(z)
ERROR: error in method definition: function Base.show must be explicitly imported to be extended
Stacktrace:
 [1] top-level scope at none:0

julia>

```

* * *

I understand that if I want to extend `Base.show` I should import it, but I don’t understand exactly what’s going on here. The manual says that in all Julia sessions `using Base` is done implicitly to make Base’s methods available, and that Base’s methods are available for extension. In the first session I can define show on my type without conflict but Base.show is not available via default. In the second session, invoking show(0) seems to have bound show() to Base.show such that extending it with my type causes an error. Can someone explain in more detail the process?

Thanks,  
-Tom

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [February 12, 2019, 5:39pm UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713/2 "2019-02-12T17:39:44Z")

</div>

What happens is you created a new `Main.show` which is not the same as `Base.show`.

```nohighlight
julia> Main.show == Base.show
false

```

Instead, you need to define `Base.show(z::Foo) = print(z)` so the `show` method is the same.

If you want to extend an existing method, you need to be more specific, otherwise you create a completely new function. You can only have one `show` method name in your scope.

Finally, the behavior also depends on whether you called the `Base.show` before making your new definition to replace it. If you dont call it first, you can create a new `show`.

I encountered a similar issue when i created the [ForceImport.jl](https://github.com/chakravala/ForceImport.jl) package.

---

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [February 12, 2019, 7:46pm UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713/3 "2019-02-12T19:46:23Z")

</div>

A quick question then. If you do define a new function i.e. `Main.show()` why dosn’t it use that one given that you are working within `Main`?

> [@tomf](#):
>
> julia\> struct Foo \<: Integer x end
> 
> julia\> show(z::Foo) = print(z)  
> show (generic function with 1 method) julia\>  
> show(0) ERROR: MethodError: no method matching show(::Int64)

Shouldn’t that still run when calling `show` from Main? Alternatively put, why does Julia call `Base.show` when calling a `show` function from `Main`?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [February 12, 2019, 8:09pm UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713/4 "2019-02-12T20:09:07Z")

</div>

By defining `show(z::Foo)` you’re hiding the Base.show method for `Int64`. After running the code by @tomf without first printing/showing something else (i.e. using Base.show in some way), there quite literally is no method available accepting an `Int64` for the function `show`:

```julia
julia> struct Foo <: Integer
              x
       end

julia> show(z::Foo) = print(z)
show (generic function with 1 method)

julia> methods(show)
# 1 method for generic function "show":
[1] show(z::Foo) in Main at REPL[2]:1

```

Compare with an invocation of `methods(show)` in a new session:

```julia
julia> methods(show)
# 295 methods for generic function "show":
[1] show(io::IO, opt::Base.JLOptions) in Base at options.jl:54
[2] show(io::IO, r::LinRange) in Base at range.jl:383
[3] show(io::IO, r::UnitRange) in Base at range.jl:693
[4] show(io::IO, r::Base.OneTo) in Base at range.jl:694
[...]

# you get the idea                

```

---

<div class="post-metadata">

**Author:** ![tomf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomf/32/6995_2.png) [@tomf](https://discourse.julialang.org/u/tomf)\
**Post date:** [February 13, 2019, 2:39am UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713/5 "2019-02-13T02:39:01Z")

</div>

Thanks for the answers. This takes some getting used to. I can import show’s methods from Base and then extend show with my definition, but I can’t define Main.show first then import the other methods from Base to extend it.  
I can accept that but I don’t understand it.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [February 13, 2019, 8:54pm UTC](https://discourse.julialang.org/t/understand-main-and-base-module-behavior/20713/6 "2019-02-13T20:54:12Z")

</div>

You can still extend it, you just have to qualify which show you want to extend. In this case like this: `Base.show(x::Foo) = print("Hello")`. Dispatch will still choose the right method when calling with a `Foo`.

In general, when extending it’s a good idea to explicitly qualify which function you’re extending in order to prevent ambiguities based on the history of the runtime.
