Using multiple dispatch in packages

I need some clarification on how multiple dispatch (or “inheritance”) is working between packages. Let’s take CSVFiles for example.

I can run load("file.csv") and it returns a table. In the source code, we have export load, save yet I don’t see the load function defined anywhere. There are

function fileio_load(f::FileIO.File{FileIO.format"CSV"}, delim=','; args...)
    return CSVFile(f.filename, delim, args)
end

function fileio_load(f::FileIO.File{FileIO.format"TSV"}, delim='\t'; args...)
    return CSVFile(f.filename, delim, args)
end

and
function _loaddata(file) which i suppose is a helper function.

The homepage of CSVFiles says something about FileIO. I suspect the load() is defined somewhere in there… so what is the exact sequence of functions that are run when I type in load.

Moreover, suppose I am developing a package that can read a particular file and would also like to use load() in my package. Can I just have a signature load(::MyType)? Will this automatically “hook” into FileIO?

load is defined in FileIO. It’s one of the stranger examples of multiple dispatch, because we explicitly urge people not to extend this function, instead having FileIO call the module-specific version by scoping (e.g., CSV.load(args...)), so that the only methods defined for load are in FileIO itself and CSV.load is a nominally-unrelated function.

This is not how it typically works (in FileIO it seems necessary to allow multiple packages to implement different approaches for a single file format), so I’m not sure this is the best model for understanding how this typically works.

2 Likes