Allow me to summarize the findings of my research so far:
- Julia is able to automatically infer the return type
- from: Do you put return type in function definitions?
This is true, however I do not see that this is a reason to prefer not to explicitly define the return type for a function.
- Specifying the return type can result in a performance penalty
- from: A function return type of `::AbstractArray{AbstractString}` causes a performance penalty?
Actually, this is not quite correct. The above linked post specifies the type of the return value incorrectly, and it is this incorrectly specified return type which results in a type conversion taking place resulting in a performance penalty. If the return type is specified incorrectly, we should not be surprised if runtime performance degrades. From this, I concluded that this is not a reason to not specify the return type.
- Julia does not dispatch on the return type
- from: Multiple-dispatch depending on output type? - #3 by xiaodai
This is true, however I don’t think that implies that the return type should not be specified. It is just a statement that Julia doesn’t dispatch on return types in the same way that it does dispatch on argument types.
Possible advantages of including the return type information:
- Specifying the return type is a good way to provide documentation to users of your API (aka functions)
While it is possible to write the type of the return value in a docstring, this does not have the same effect of using the type system to specify it, which is harder to ignore.
A discussion about specifying the types of arguments to functions:
In contrast to the above, I do not think that the types of arguments to functions should be explicitly specified, because this limits the scope of application for your algorithm (aka function). (But this could be behavior you want - see below.)
There are two exceptions to the above, as far as I can see:
1
- Multiple dispatch. If a function implementation should have different logic depending on the type of the argument(s), then the types need to be specified.
- This is nothing new or special. It is simply a statement as to what methods are in Julia. It’s just the multiple dispatch system.
2
- To restrict the range of types which can be used when calling a function
- To provide documentation to the user of your API
It seems kind of obvious that a generic algorithm (function implementation) will not work for all types.
For example, some function which performs math operations (like taking the sin
of something, or something involving multiplications) is unlikely to be valid when a DateTime
type is passed in.
You might argue in order to increase robustness and make it easier for clients to understand how to use your API, the type should be documented. Just as before, it would be better to document this information in the type system rather than a documentation comment, because it is harder to ignore.
This argument is very similar to the argument for specifying the return type.
Do consider there may be less obvious cases. For example, almost anything can be represented using a String
type. You can serialize most things, and create most things by parsing a String
. Things involving dates and durations can also be a bit tricky. What units of time should the duration be? Is it seconds? Something like CompoundPeriod
or Period
? If this code is close to some code which reads/writes to file, should the string representation of a duration be used?
Does anyone disagree with anything I have written here. I would be quite happy to be proven wrong if my reasoning is not sound…