# Define sub-types or not?

**URL:** <https://discourse.julialang.org/t/define-sub-types-or-not/34183>\
**Category:** General Usage\
**Tags:** type\
**Created:** [February 4, 2020, 6:08pm UTC](https://discourse.julialang.org/t/define-sub-types-or-not/34183 "2020-02-04T18:08:48Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mthelm85](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mthelm85/32/224164_2.png) [@mthelm85](https://discourse.julialang.org/u/mthelm85)\
**Post date:** [February 4, 2020, 6:08pm UTC](https://discourse.julialang.org/t/define-sub-types-or-not/34183/1 "2020-02-04T18:08:48Z")

</div>

Consider the following contrived example:

Suppose I wanted to implement my own custom `Weight` types and let’s say that some of them can be converted to standard units (pounds, kilograms, etc.) while others (for some strange reason) are not convertible to other units at all. What’s the recommended way to define the types in this scenario? I could define a `Weight` type that has an `isconvertible` field and then in my `convert_to(w::Weight, units)` function just check to see if it’s convertible, throwing an Error if not.

```julia
struct Weight
    value::Real
    isconvertible::Bool
end

function convert_to(w::Weight, units)
    w.isconvertible == false && throw(ArgumentError("Sorry, this weight is not convertible to other units"))
end

```

Or, I could just define `Weight` as an abstract type and then have `ConvertibleWeight` and `NonConvertibleWeight` as subtypes. Is there a preferred/recommended way to deal with this kind of situation?

---

<div class="post-metadata">

**Author:** ![JeffreySarnoff](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeffreysarnoff/32/1980_2.png) [@JeffreySarnoff](https://discourse.julialang.org/u/JeffreySarnoff)\
**Post date:** [February 4, 2020, 11:24pm UTC](https://discourse.julialang.org/t/define-sub-types-or-not/34183/2 "2020-02-04T23:24:56Z")

</div>

Either approach is OK. I prefer the " Or, I could just define `Weight` as an abstract type and then have `ConvertibleWeight` and `NonConvertibleWeight` as subtypes." approach as it does not carry an extra field in the struct (though it duplicates structs – but that’s ok here, as the functionality is well coordinated). A third approach to make convertibility a trait (perhaps using [SimpleTraits.jl](https://github.com/mauro3/SimpleTraits.jl) as you are new to this).

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 5, 2020, 7:08am UTC](https://discourse.julialang.org/t/define-sub-types-or-not/34183/3 "2020-02-05T07:08:04Z")

</div>

It depends on two things, mostly:

1. do you want to dispatch on a weight being convertible?

2. can you fit into a type hierarchy with single inheritance?

For (1), you need either subtypes or traits. If (2) does not hold, traits are your only option.

I would go with subtypes in the first iteration but _expose that via a function like `is_convertible`_, so that refactoring is easy.
