Julia type conversion best practices

240 Views Asked by At

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:

  1. 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
  1. 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
  1. 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?

1

There are 1 best solutions below

0
cbk On

The answer in the comments is correct that, ideally, you would write your ofdatetime function such that all operations on dt within your function body are general to any AbstractDateTime; in any case where the the difference between DateTime and ZonedDateTime would matter, you can use dispatch at that point within your function to take care of the details.

Failing that, either of 2 or 3 is generally preferable to 1 in your question, since for either of those, the branch can be elided in the case that the type of df is known at compile-time. Of the latter two, 2 is probably preferable to 3 as 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, then 3 could 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.