# Understanding Julia's type system

**URL:** <https://discourse.julialang.org/t/understanding-julias-type-system/64709>\
**Category:** General Usage\
**Tags:** question\
**Created:** [July 15, 2021, 7:00pm UTC](https://discourse.julialang.org/t/understanding-julias-type-system/64709 "2021-07-15T19:00:01Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![cadojo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cadojo/32/25328_2.png) [@cadojo](https://discourse.julialang.org/u/cadojo)\
**Post date:** [July 15, 2021, 7:00pm UTC](https://discourse.julialang.org/t/understanding-julias-type-system/64709/1 "2021-07-15T19:00:01Z")

</div>

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._

```julia
# 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`._

```julia
# 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`

```

---

<div class="post-metadata">

**Author:** ![jeffreyesun](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreyesun/32/13379_2.png) [@jeffreyesun](https://discourse.julialang.org/u/jeffreyesun)\
**Post date:** [July 15, 2021, 8:33pm UTC](https://discourse.julialang.org/t/understanding-julias-type-system/64709/2 "2021-07-15T20:33:41Z")

</div>

The issue with Option 1 is that `f` will now dispatch on all `LArray`s, 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](https://ahsmart.com/pub/holy-traits-design-patterns-and-best-practice-book/) or something.

---

<div class="post-metadata">

**Author:** ![cadojo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cadojo/32/25328_2.png) [@cadojo](https://discourse.julialang.org/u/cadojo)\
**Post date:** [July 15, 2021, 8:36pm UTC](https://discourse.julialang.org/t/understanding-julias-type-system/64709/3 "2021-07-15T20:36:07Z")

</div>

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