Syntax sugar for Union{T, Void}

I found myself writing Union{T, Void} a lot in the function default arguments, e.g.

function integers{T}(
        ::Type{T};
        min_value::Union{Integer, Void}=nothing,
        max_value::Union{Integer, Void}=nothing
    )
    min_value::T = min_value == nothing ? typemin(T) : min_value
    max_value::T = max_value == nothing ? typemax(T) : max_value
    @assert min_value <= max_value
    
    rand(min_value:max_value)
end

Is there any better way to do it?
Normally I would make a typealias Voidable{T} Union{T, Void}

Would it be useful, if there is a syntax like T? is expanding to Union{T, Void}?

There’s the Nullable{T} type. I usually alias it to Maybe{T}.

It is a bit clumsy to ask the caller to pass in min_value=Nullable(123) instead of min_value=123

Maybe sounds a monad to me.

At least in this case, you can just use typemin(T) and typemax(T) as default arguments:

function integers{T}(::Type{T}, min_value::T = typemin(T), max_value::T = typemax(T))
    @assert min_value <= max_value
    rand(min_value:max_value)
end
1 Like

For specifying optional values, you can always convert(Nullable, value) to ensure it is a Nullable.

I sometimes wonder about having get(x)=x as a fallback. Then I could always use the semantics of Nullable for optional arguments, whether they are actually Nullable or not. But I am sure I have not thought about all the ramifications.

2 Likes

This isn’t universally applicable, but you can shorten your example to:

function integers{T}(
        ::Type{T};
    min_value::Integer=typemin(T),
    max_value::Integer=typemax(T)
    )
    @assert min_value <= max_value
    
    rand(min_value:max_value)
end