Implementing a function from an interface, multiple dispatch


#1

I am reading the source of CSVFiles.jl and I see it implements the TableTraits interface, which in Julia, is the defacto way of describing table data. I see functions like

function TableTraits.getiterator(file::CSVFile)
    res = _loaddata(file)
    it = TableTraitsUtils.create_tableiterator([i for i in res[1]], [Symbol(i) for i in res[2]])
    return it
end 

I noticed TableTraits.getiterator rather than just getiterator. I am a bit confused on why the name is prepended with TableTraits. I thought multiple dispatch didn’t require this? And that it would pick the right getiterator based on the types it gets. In this particular case, if someone was to call getiterator(mycsvfile::CSVFile), this function should be called. Do we need the prepend, and if so why?

Follow up question… suppose I have my own custom type and that I’d like a “pretty print” of this type in the repl. Would It not be sufficient to define show(io, MyType) or do I have to define Base.show(io, MyType)?


#2

In Julia, there may be many functions with the same name in different modules, and each function may have multiple methods. As motivation for this, imagine 2 functions - Databases.connect(), which is responsible for connecting to various databases (via different methods that implement this function) and another function Graphs.connect() which is responsible for connecting nodes in a graph, and may also have multiple implementing methods.

Prepanding method name with a module name (or alternatively importing function name explicitely) tells Julia to extend existing function instead of creating a new one in current module.


#3

define Base.show(io::IO, x::MyType)


#4

or, alternatively,

import Base: show

show(io::IO, x::MyType) = ...

However, I typically prefer Base.show.