Is there any trick to handle optional arguments in Julia? Sometimes I want to setup some of the arguments of a function for the user, however; this setup is not necessarily straightforward that I could just pass a default value in a keyword argument. Consider the function below:
function f(; b=nothing)
if b != nothing
# assertions to make sure b is of the right type
end
println(b)
end
If the user specifies b
, I need to assert its type, but it seems that I am reinventing the wheel here. There is probably a better way of handling this situation? I was thinking of something like Nullable
in Julia v0.6, but I am not very familiar with it. In C++, I would use Boost.Optional.
You can just do b::Union{T, Void}
, with T
the type you would like to assert.
1 Like
If speed is a concern on v0.6, you might also consider using b::Nullable{T} = Nullable{T}()
. I think this the same as an optional in C++.
(Note: the Union
approach will be fast on v0.7/v1.0)
1 Like
Thank you all, could you please elaborate on the differences between Union{T,Void}
and Nullable{T}
? What is the advantage/disadvantage of each approach when modeling optional arguments?
b::Nullable{T}
is a container - you will need to check if it contains data with isnull(b)
and then use get
(or getindex
) to extract the data of type T
. Also, the code calling the function may need to explicitly wrap the data in a Nullable{T}
…
b::Union{T, Void}
will be an “unboxed” T
or else a nothing
. You can check if b === nothing
(or b isa Void
) and if not you can assume that b
is the data (of type T
) you want. Your code example in the OP more-or-less does this already (maybe you want !==
rather than !=
to help inference? not sure…)
Really, it’s just a difference in style. In a static language like C++ the container is quite necessary. In a dynamic language like Julia, both options are available and arguably the Union
approach is somewhat simpler to work with. The upcoming Union
performance improvements (as fast as Nullable
) will mean that Union
s will probably be the preferred approach in the future - but both options will remain open to you. If your function isn’t performance critical (say, called in an inner loop of a numeric algorithm), feel free to use the Union
approach now - it won’t slow you down by that much, really (and inference on v0.6 seems good enough that type instabilities won’t propagate).
3 Likes
Thank you for the very clear explanation @andyferris I personally like the Union
type more and the fact that by using it instead of Nullable
we don’t need to wrap the input in the call site.
1 Like