I have the following situation: A complicated algorithm that works with a function as input parameter:
function cool_stuff(f :: Function, a::Real, b::Real)
...
end
cool_stuff could be something like integration or some optimization which is numerically complicated. For some functions (like f(x) = sin(x) or f(x) = x + 1) I have done all the math and can provide very efficient code. I nevertheless want to have one function cool_stuff with several methods. So a function cool_stuff_for_sin is not the desired solution. Question: How can I do multiple dispatch for a special function? So I guess that’s equivalent to the question if I can define subtypes of the function type?
Apart from that, I would say it’s not a good idea to restrict f to Function. You (or somebody else) may want to use some object a::A with a callable method a(x) instead. That wouldn’t work if A is not a subtype of Function.
Anything can be callable, so there’s no way to do that within the type system, basically. If reflection is a viable solution, hasmethod or applicable might be useful, but that’s easy to abuse.
There is no real way – any type can have callable methods. There is a type Callable, but it’s internal. Moreover, like Function, you can subtype it for any type. So it’s not helpful.
I wouldn’t restrict the type of f at all. If f doesn’t have a callable method (or rather not one with the signature you are using), then you get an error. If you pass f on as an argument to some other function, then it’s best to use a type parameter as in
cool_stuff(f::F, a::Real, b::Real) where F = sum(f, (a, b))
It’s not really relevant to the rest of the topic, but, just to be clear, defining subtypes of Function is done in the usual manner: struct Func <: Function end.