I had no idea this was possible! Looking at another post here on Discourse I found how to implement it with this syntax:
function (a::MyStruct)(param1, param2)
...
end
It clearly works, but I’m having a hard time understanding how. How does the above allow for dispatching on the MyStruct type without it being one of the parameters? It even allows you to access the MyStruct fields as a.foo
To be precise, you are calling an instance of a struct. This is documented in the Function-like objects section. A function call f(a, b, c) dispatches a method based on the types of the called functionf and the arguments a, b, c. It’s just that a function is an instance of a singleton type; that’s why typeof(f) is simply printed as typeof(f). A function definition can also make a method that is dispatched based on a non-singleton type of called instances. Despite the definition name, the type is not necessarily a function type; that depends on if it subtypes Function.
Unlike arguments, there are restrictions on what you can annotate the called instance in the method definition. As you know, no annotations function f(... makes a singleton function type. Concrete annotations function (m::Int)(... are okay. Some abstract annotations, like types you defined, function (m::Number)(... are okay. Overly general annotations like ::Function, ::Any, ::Type, or ::DataType will throw an error or cause bugs; I don’t know the exact criteria or an exhaustive list.
About calling a type, e.g. DistanceType(options). Many types, like struct types, are instances of DataType, but Julia specializes on the abstract singleton Type{T} in many circumstances for type stability. I’m not really sure how to describe the circumstances.
This: Methods · The Julia Language part of the Julia documentation deals with such definitions, which are often called “functors”. Searching for “Julia functors” will lead to many more explanations of the syntax and its uses.
Thank you both! The Julia documentation and the term “functors” will help me dig further.
@Benny ah ok, right, the methods themselves are also typed this makes sense. So its all rolled under the big multiple dispatch umbrella. Excuse me while my brain stretches in new directions to understand.