I have a function which requires a DateTime argument. A possibility is that a user might provide a ZonedDateTime argument. As far as I can tell there are three possible ways to catch this without breaking:
- Accept both arguments in a single method, and perform a type conversion if necessary via an if... statement
function ofdatetime(dt::AbstractDateTime)
if dt::ZonedDateTime
dt = DateTime(dt, UTC)
end
...
end
- Define a second method which simply converts the type and calls the first method
function ofdatetime(dt::DateTime)
...
end
function ofdatetime(dt::ZonedDateTime)
dt = DateTime(dt, UTC)
return ofdatetime(dt)
end
- Redefine the entire function body for the second method
function ofdatetime(dt::DateTime)
...
end
function ofdatetime(dt::ZonedDateTime)
dt = DateTime(dt, UTC)
...
end
Of course, this doesn't apply when a different argument type implies that the function actually do something different - the whole point of multiple dispatch - but this is a toy example. I'm wondering what is best practice in these cases? It needn't be exclusively to do with time zones, this is just the example I'm working with. Perhaps a relevant question is 'how does Julia do multiple dispatch under the hood?' i.e. are arguments dispatched to relevant methods by something like an if... else/switch... case block, or is it more clever than that?
The answer in the comments is correct that, ideally, you would write your
ofdatetimefunction such that all operations ondtwithin your function body are general to anyAbstractDateTime; in any case where the the difference betweenDateTimeandZonedDateTimewould matter, you can use dispatch at that point within your function to take care of the details.Failing that, either of
2or3is generally preferable to1in your question, since for either of those, the branch can be elided in the case that the type ofdfis known at compile-time. Of the latter two,2is probably preferable to3as written in your example in terms of general code style ("DRY"), but if you were able to avoid the type conversion by writing entirely different function bodies, then3could actually have better performance than if the type conversion is at all expensive.In general though, the best of all worlds is to keep most your code generic to either type, and only dispatch at the last possible moment.