Constrained type parameters

When defining a type, is it possible to place a constraint on parameter values? For example, consider the following simple type definition:

struct Orf
   start::Int32
   stop::Int32
   pol::Int8
end

Is there any way to add a hint such as "stop > start" to this definition? In pseudo-code, it might resemble

struct Orf
   start::Int32
   stop::Int32, start > start
   pol::Int8 
end

In this way, data errors could be caught without explicit tests in code.

Check this, the first example is exactly what you need:

https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods

6 Likes

Perfect! Thanks very much for pointing this out.

A pattern that I like is

struct OrderedPair
    x::Real
    y::Real
    function OrderedPair(x, y, ::Val{Checks}=Val(true)) where {Checks}
        if Checks
            x > y || error("out of order")
        end
        new(x, y)
    end
end

This way you can avoid the checks when you are 100% sure that the values you are feeding to the constructor satisfy all the requirements. If you call OrderedPair(x, y, Val(false)), the checks are statically removed.

8 Likes

This seems to be a perfect use case for the macro @assert from the package Parameters.jl, such as:

using Parameters
struct OrderedPair
    x::Real
    y::Real; @assert x <= y
end

Note that @assert is in Base. Perhaps you meant Parameters.@with_kw.

1 Like

Thanks for the correction, Tamas_Papp: I really meant what you said and wanted to call attention to the very useful (at least to me, as a newbie) Parameters.jl package.