I love thinking visually by drawing doodles and schematics for my work. It’s one of my favorite things to do, next to coding. When working with the Julia language, one visualization I enjoy is seeing the type space of a method that you are dispatching on. Normally I do this in my mind’s eye, but let me clarify this by drawing some actual figures.
To start with the basics; Julia has functions and methods. A function is simply the name, like push!
or read
. Methods are specific definitions of a function, for certain types of arguments. Take for example push!(s::Set, x)
or read(io::IO)
. From an object-oriented perspective you could say that methods are instances of functions.
For any given method you can consider the dispatching as slicing a part of the entire possible type space of that given function. For a given set of arguments of course. If you increase the number of arguments in the function definition, then more dimensions get added to the type space. I don’t even know how to find the best written words for this, the visualization above just feels intuitive to me.
Let’s take the function f
and imagine for a moment that there are only 3 types in the whole Julia type universe: the Float64
, Int64
and the String
. The Float64
and the Int64
are a subtype of Number
, which is obvious I hope. By default in Julia if you specify no type in your function argument, then it will be assumed you mean the Any
type, of which every other type is a subtype.
A method f(::Any, ::Any)
thus describes the entire space of all possible types for the function named f
. On the other hand, a method like f(::Int64, ::String)
is super concrete, it’s a singular point in the type space.
You can use abstract types like Number
or unions like Union{Float64, Int64}
to capture a subset of the discrete type space. This way you can choose which part you want to define for your function, with the chosen set of types you will be dispatching on at runtime. Abstract types in Julia exist only for this dispatching purpose, to dispatch on a set of