# Declaring a structure as a subtype?

**URL:** https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917
**Category:** New to Julia
**Created:** [February 20, 2020, 5:00pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917 "2020-02-20T17:00:46Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![squirrel](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@squirrel](https://discourse.julialang.org/u/squirrel)
#### Post date: [February 20, 2020, 5:00pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917/1 "2020-02-20T17:00:46Z")

</div>

So I have an algorithm that has several different steps to perform on matrices. I started declaring new types to ensure that matrices aren’t passed prematurely to the next step, or redundantly to a previous one.

For example, the function for step 1 might accept any old matrix,

```julia
function step_1_foo(M::Matrix)

```

but step 2 might want a matrix that is specifically in reduced row echelon form. For this I declared a structure that has one field that’s a sparse matrix.

```julia
struct SparseRREF
    R::SparseMatrixCSC
end

```

I then would have `step_1_foo` return type `SparseRREF` and make the next function take `SparseRREF` as its argument.

```julia
function step_2_foo(S::SparseRREF)
    M = S.R
    # etc...
end

```

This is a little annoying because when I want to use the sparse matrix, I have to grab it from the struct first. Which leads me to my question.

Is there a better way of declaring these types? I don’t really want to add any functionality to the structure, other than to specify that it has been processed by a certain step. I don’t want to make an alias, because I don’t want any `Matrix` to be seen accepted as a `SparseRREF` type. Could I declare it as a type that inherits Matrix?

---

<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 20, 2020, 6:22pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917/2 "2020-02-20T18:22:18Z")

</div>

> [@squirrel](#):
>
> Is there a better way of declaring these types?

This looks fine to me, and may be the solution with the lowest cost: just one extra line in each function.

> [@squirrel](#):
>
> Could I declare it as a type that inherits Matrix?

There is no mechanism to automatically forward all methods to a field (it’s not really a good idea, you can find many discussions about this). The best strategy is to keep APIs small, and then just forward the [relevant methods](https://docs.julialang.org/en/v1/manual/interfaces/#man-interface-array-1).

FWIW, I think that using wrappers just to ensure the right order in what is otherwise not exposed library code (ie an implementation of an algorithm _inside_ the package) may be overkill. I would just rely on unit tests to make sure the code is correct. Of course if the steps of the algorithm are exposed then this may be way to do it.

---

<div class="post-metadata">

### Author: ![squirrel](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@squirrel](https://discourse.julialang.org/u/squirrel)
#### Post date: [February 20, 2020, 6:55pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917/3 "2020-02-20T18:55:06Z")

</div>

Thanks!

You may be right that it’s overkill, but since I’m coding all by my lonesome (with the exception of you fine folks 🙂) and don’t really plan on distributing my code, I like having the extra protection to make sure I’m not screwing up.

---

<div class="post-metadata">

### Author: ![Non-Contradiction](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-contradiction/32/2208_2.png) [@Non-Contradiction](https://discourse.julialang.org/u/Non-Contradiction)
#### Post date: [February 20, 2020, 11:52pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917/4 "2020-02-20T23:52:16Z")

</div>

If only step is needed, then you can declare one type instead of many, and write one extra line in each function like this:

```julia
struct MatrixWithStep{T,S}
    mat::T
    step::S
end

@inline MatrixWithStep(x, s::Int) = MatrixWithStep(x, Val{s}())

@inline function makesure(x::MatrixWithStep{T,S}, ::S) where {T,S}
    x.mat
end

@inline makesure(x, s::Int) = makesure(x, Val{s}())

function step1(x)
    MatrixWithStep(x.+1, 1)
end

function step2(x)
    m = makesure(x, 1)
    MatrixWithStep(m.+2, 2)
end

function step3(x)
    m = makesure(x, 2)
    MatrixWithStep(m.+3, 3)
end

```

Things like `@inline` and `Val{s}()` is to make sure that things like `makesure` can be compiled away when using in the correct order so there will be no performance penalty after compilation. For example, if we further have

```julia
f1(x) = step2(step1(x))
f2(x) = step3(step1(x))

```

then `makesure` check in both `f1` and `f2` will be compiled away:

```julia
julia> @code_warntype(f1(1))
Body::MatrixWithStep{Int64,Val{2}}
1 ── goto #3 if not true
2 ── nothing
3 ┄─ %3 = (Base.add_int)(x, 1)::Int64
└─── goto #4
4 ── goto #5
5 ── goto #6
6 ── goto #7
7 ── goto #9 if not true
8 ── nothing
9 ┄─ %10 = (Base.add_int)(%3, 2)::Int64
└─── goto #10
10 ─ goto #11
11 ─ goto #12
12 ─ %14 = %new(MatrixWithStep{Int64,Val{2}}, %10, $(QuoteNode(Val{2}())))::MatrixWithStep{Int64,Val{2}}
└─── goto #13
13 ─ return %14

julia> @code_warntype(f2(1))
Body::Union{}
1 ─ goto #3 if not true
2 ─ nothing
3 ┄ %3 = (Base.add_int)(x, 1)::Int64
└── goto #4
4 ─ goto #5
5 ─ goto #6
6 ─ %7 = %new(MatrixWithStep{Int64,Val{1}}, %3, $(QuoteNode(Val{1}())))::MatrixWithStep{Int64,Val{1}}
└── goto #7
7 ─ invoke Main.step3(%7::MatrixWithStep{Int64,Val{1}})
└── $(Expr(:unreachable))

```

---

<div class="post-metadata">

### Author: ![squirrel](https://avatars.discourse-cdn.com/v4/letter/s/96bed5/32.png) [@squirrel](https://discourse.julialang.org/u/squirrel)
#### Post date: [February 21, 2020, 4:30pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917/5 "2020-02-21T16:30:51Z")

</div>

That’s a cool idea I hasn’t considered. It’s not the best choice for my particular situation, though, because my steps aren’t necessarily ordered. This reminds me a lot of `enum` in Java. Does Julia have any sort of `enum` equivalent?

---

<div class="post-metadata">

### Author: ![Non-Contradiction](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-contradiction/32/2208_2.png) [@Non-Contradiction](https://discourse.julialang.org/u/Non-Contradiction)
#### Post date: [February 21, 2020, 4:43pm UTC](https://discourse.julialang.org/t/declaring-a-structure-as-a-subtype/34917/6 "2020-02-21T16:43:33Z")

</div>

Yes, julia has `enum`, see [https://docs.julialang.org/en/v1/base/base/#Base.Enums.@enum](https://docs.julialang.org/en/v1/base/base/#Base.Enums.@enum).  
And you can also use symbols like `:step1`, `:step2`, `:stepsparse` in my example instead of `Int` if the steps are not ordered.
