# Simple sum types

**URL:** <https://discourse.julialang.org/t/simple-sum-types/121048>\
**Category:** General Usage\
**Tags:** package\
**Created:** [October 8, 2024, 5:59am UTC](https://discourse.julialang.org/t/simple-sum-types/121048 "2024-10-08T05:59:23Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [October 8, 2024, 5:59am UTC](https://discourse.julialang.org/t/simple-sum-types/121048/1 "2024-10-08T05:59:23Z")

</div>

There are quite a few julia packages for sum types:

- [SumTypes.jl](https://github.com/MasonProtter/SumTypes.jl)
- [Unityper.jl](https://github.com/YingboMa/Unityper.jl)
- [LightSumTypes.jl](https://github.com/JuliaDynamics/LightSumTypes.jl)
- [Moshi.jl](https://github.com/Roger-luo/Moshi.jl)

Probably more. For my usecase, I am looking for a sum types package with the following tradeoffs:

- I don’t need parametric types
- I don’t need recursion
- There should be as little performance gotchas as possible. It should be hard to accidentally write slow code with sum types
- There should be a pattern matching macro that checks that all cases are handled.
- The package implementation should be simple and easy to maintain.

Are there good options with these specific goals?

---

<div class="post-metadata">

**Author:** ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)\
**Post date:** [October 8, 2024, 6:04am UTC](https://discourse.julialang.org/t/simple-sum-types/121048/2 "2024-10-08T06:04:48Z")

</div>

Yup, the latest and greatest for most is:

> **[Welcome to Moshi](https://rogerluo.dev/Moshi.jl/)**
>
> Pattern match with & without generic algebraic data types in Julia!

(on GitHub: [GitHub - Roger-luo/Moshi.jl: nextgen MLStyle: Generic Algebraic Data Type + Pattern Match](https://github.com/Roger-luo/Moshi.jl))

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [October 8, 2024, 6:20am UTC](https://discourse.julialang.org/t/simple-sum-types/121048/3 "2024-10-08T06:20:53Z")

</div>

Thanks, I will add it to the list. It looks like it is much more featureful and complex than what I was looking for.

---

<div class="post-metadata">

**Author:** ![nandoconde](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nandoconde/32/19497_2.png) [@nandoconde](https://discourse.julialang.org/u/nandoconde)\
**Post date:** [October 8, 2024, 8:08am UTC](https://discourse.julialang.org/t/simple-sum-types/121048/4 "2024-10-08T08:08:04Z")

</div>

I really don’t think it is complex at all. It is way less than what SumTypes originally was. And the available features are only as many as you want.

If you still want a simpler approach, albeit with less features and no exhaustive match, I’d go for LightSumTypes.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [October 8, 2024, 1:01pm UTC](https://discourse.julialang.org/t/simple-sum-types/121048/5 "2024-10-08T13:01:10Z")

</div>

LightSumTypes looks pretty nice, just missing a match macro.

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 8, 2024, 1:26pm UTC](https://discourse.julialang.org/t/simple-sum-types/121048/6 "2024-10-08T13:26:25Z")

</div>

Part of what makes it so “light” is that you can just use dispatch, i.e.

```julia
f(::A) = 1
f(::B) = 2
f(variant(x))

```

Could probably turn that into a macro pretty easily though. You’d then just use JET.jl to check for completeness by checking for the possibility of method errors.

---

<div class="post-metadata">

**Author:** ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)\
**Post date:** [October 8, 2024, 1:33pm UTC](https://discourse.julialang.org/t/simple-sum-types/121048/7 "2024-10-08T13:33:36Z")

</div>

Does dispatch always have good performance or is there a cliff once you have 32 variants say?

---

<div class="post-metadata">

**Author:** ![Mason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mason/32/2423_2.png) [@Mason](https://discourse.julialang.org/u/Mason)\
**Post date:** [October 8, 2024, 1:47pm UTC](https://discourse.julialang.org/t/simple-sum-types/121048/8 "2024-10-08T13:47:35Z")

</div>

I’ve done some light testing previously and it seems to work fine even with very large numbers of variants. E.g. here’s a benchmark on a sum type with 64 variants and the numbers indicate that it’s spending only one clock cycle per application of `f`:

```julia-repl
julia> using LightSumTypes, Random

julia> var_vec = let variants = [Symbol(:A, i) for i ∈ 1:64]
           for (i, var) ∈ enumerate(variants)
               @eval begin
                   struct $var end
                   f(::$var) = $i
               end
           end
           @eval begin
               @sumtype S($(variants...),)
               f(s::S) = f(variant(s))
           end
           shuffle!([S(getproperty(Main, var)()) for var ∈ variants])
       end;

```

```julia-repl
julia> @benchmark sum(f, $var_vec)
BenchmarkTools.Trial: 10000 samples with 990 evaluations.
 Range (min … max): 42.151 ns … 378.326 ns ┊ GC (min … max): 0.00% … 0.00%
 Time (median): 43.466 ns ┊ GC (median): 0.00%
 Time (mean ± σ): 44.029 ns ± 9.632 ns ┊ GC (mean ± σ): 0.00% ± 0.00%

        ▃█▅                                                     
  ▂▄▂▂▃▆███▇▅▃▃▂▂▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▁▂▂ ▃
  42.2 ns Histogram: frequency by time 52.3 ns <

 Memory estimate: 0 bytes, allocs estimate: 0.

```
