Understanding Julia's type system

I want to describe two kinds of state vectors: CartesianState and KeplerianState. For convenience, I’d like to have these state vectors to be mutable and have labels via LabelledArrays.

Now, I’d like to be able to use methods which work for all state vector types. Without type parameters, I’d like to define abstract type AbstractState end, and have CartesianState and KeplerianState be aliases for LArray.

I understand I can’t have the best of both worlds – to have two new aliases which are also subtypes of a new abstract type, we’d have to insert a supertype above LArray, which is definitely not okay.

My question is – what’s the closest we can come to accomplishing this?

I have two options below, though I’m not sure how advisable they are. I was curious what other folks’ go-to method for this would be. One issue I see with Option 2 is if users make their own NewState type, it wouldn’t be dispatch-able because the Union is already defined.

Option 1

The abstract type is an alias.

# LArray's parameters are {eltype, dimension, vector type, tuple with labels}

const AbstractState{F, V, L} = LArray{F, 1, V, L} # always a vector

const CartesianState{F, V} = AbstractState{F, V, (x=1, y=2, z=3, ẋ=4, ẏ=5, ż=6, r=1:3, v=4:6)}
const KeplerianState{F, V} = AbstractState{F, V, (e=1, a=2, i=3, Ω=4, ω=5, ν=6)}

f(x::AbstractState) = typeof(x) # should dispatch on `CartesianState` or `KeplerianState`

Option 2

The abstract type is a Union.

# LArray's parameters are {eltype, dimension, vector type, tuple with labels}

const CartesianState{F, V} = LArray{F, 1, V, (x=1, y=2, z=3, ẋ=4, ẏ=5, ż=6, r=1:3, v=4:6)}
const KeplerianState{F, V} = LArray{F, 1, V, (e=1, a=2, i=3, Ω=4, ω=5, ν=6)}

const AbstractState = Union{CartesianState, KeplerianState}

f(x<:AbstractState) = typeof(x) # should dispatch on `CartesianState` or `KeplerianState`

The issue with Option 1 is that f will now dispatch on all LArrays, which could have unintended consequences. I think Option 2 is fine. Are you really expecting users to define a new type of state vector? If not, then you can just update the Union definition when you add a new state vector type for yourself. If you are, then you might want to look into Holy Traits or something.

3 Likes

Love the Holy Traits pattern, really cool and hadn’t seen that before. Thanks!

1 Like