# Type alias or newtype wrapper?

**URL:** <https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770>\
**Category:** New to Julia\
**Created:** [September 17, 2020, 11:15am UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770 "2020-09-17T11:15:59Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/matklad/32/17976_2.png) [@matklad](https://discourse.julialang.org/u/matklad)\
**Post date:** [September 17, 2020, 11:15am UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/1 "2020-09-17T11:15:59Z")

</div>

Hi! I am writing a small from-scratch ray tracer to get myself acquainted with julia.

I’ve defined a color type as

```julia
struct Color
    r::UInt8
    g::UInt8
    b::UInt8
end

```

What would be the most idiomatic definition for the image type?

```julia
const Image = Array{Color, 2}

```

or

```julia
struct Image
  data::Array{Color, 2}
end

```

?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 17, 2020, 11:35am UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/2 "2020-09-17T11:35:41Z")

</div>

Either one could make sense, although if you go with the second, I’d go with

```julia
struct Image <: AbstractMatrix{Color}
  data::Matrix{Color}
end

```

And then implement the rest of the relevant `AbstractArray` interface (see the manual section on it) to get the most out of the type (iteration, broadcast, promotion, etc.).

`Images.jl` does not define an Image type (just operations on arrays of Colors), but that’s a perfectly valid approach! You can take a look at that ecosystem of packages for inspiration.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 17, 2020, 12:06pm UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/3 "2020-09-17T12:06:02Z")

</div>

One thing to think about is whether you want to use `Image` for dispatch. If you really just want to treat image as a regular array, the first option is probably the way to go, but if you wanted to overload `inv` to invert the colors of the image for example, you should definitely go with the second option, because otherwise, you are commiting type piracy.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 17, 2020, 12:29pm UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/4 "2020-09-17T12:29:11Z")

</div>

> [@simeonschaub](#):
>
> if you wanted to overload `inv` to invert the colors of the image for example, you should definitely go with the second option, because otherwise, you are commiting type piracy.

I wouldn’t say so. Since @matklad defined `Color` himself, extending Base functions to `Matrix{Color}` isn’t piracy.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 17, 2020, 1:15pm UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/5 "2020-09-17T13:15:30Z")

</div>

I would still call it type piracy, since it still has a lot of the same problems:

1. Functions written for `Matrix` assume a very specific meaning of `inv` in the linear algebra sense and may rely closely on the mathematical and programmatical properties of `inv(::Matrix)`. So at first sight unrelated functions may now silently return nonsensical results.
2. This is a bit technical, but if a function calls `inv(::Matrix)`, type inferences tries its best to analyze `inv` and optimize as much as it can. Since the element type may sometimes only be partially inferred, the compiler may still look at all methods that could possibly get called (at least if there aren’t too many) and can try to specialize on that. If you are now adding another method to `inv` for a subtype of `Matrix`, it can break assumptions the compiler previously made about those methods that could get called, therefore previous specializations may not be valid anymore, so the function that called `inv(::Matrix)` needs to be recompiled once it is called again. These are called method invalidations and can cause large compiler latencies. (I probably missed some nuances here, you should really read @timholy’s great blog post: [Analyzing sources of compiler latency in Julia: method invalidations](https://julialang.org/blog/2020/08/invalidations/))

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 17, 2020, 1:25pm UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/6 "2020-09-17T13:25:08Z")

</div>

While the point on invalidations is definitely an important and topical one (although not at all where I would start if I were familiarizing myself with the language), the one on extending `inv` in a nonsensical way, I think, is not as clear cut. For example, Images does exactly what you are advocating against, e.g. [here](https://github.com/JuliaImages/Images.jl/blob/de7d11fab7937efaa461874f2fa957dc0a31e602/src/algorithms.jl#L84). Obviously, if the purpose of the newly extended method doesn’t make sense with the function it’s extending, that’s bad design, but otherwise, I’d still say this is valid.

---

<div class="post-metadata">

**Author:** ![magister-ludi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/magister-ludi/32/4003_2.png) [@magister-ludi](https://discourse.julialang.org/u/magister-ludi)\
**Post date:** [September 17, 2020, 1:27pm UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/7 "2020-09-17T13:27:40Z")

</div>

> [@simeonschaub](#):
>
> One thing to think about…

Another thing to think about is that [Images.jl](https://github.com/JuliaImages/Images.jl), together with other packages, already uses this kind of definition. It might be a good starting point to piggyback on that.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [September 17, 2020, 1:34pm UTC](https://discourse.julialang.org/t/type-alias-or-newtype-wrapper/46770/8 "2020-09-17T13:34:37Z")

</div>

That’s definitely type piracy to me as well, but I am not advocating against all uses of type piracy, I am only saying that you should be careful and consider the dangers. Even Base commits quite a bit of type piracy: [https://github.com/JuliaLang/julia/pull/37404#discussion\_r483803996](https://github.com/JuliaLang/julia/pull/37404#discussion_r483803996).
