# Usage of "empty" structs

**URL:** <https://discourse.julialang.org/t/usage-of-empty-structs/18968>\
**Category:** General Usage\
**Created:** [December 25, 2018, 12:20am UTC](https://discourse.julialang.org/t/usage-of-empty-structs/18968 "2018-12-25T00:20:24Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)\
**Post date:** [December 25, 2018, 12:20am UTC](https://discourse.julialang.org/t/usage-of-empty-structs/18968/1 "2018-12-25T00:20:24Z")

</div>

Often in packages and Julia source code, I see `structs` that have no field. For example,

```julia
abstract type RangeStepStyle end
struct RangeStepRegular &lt;: RangeStepStyle end # range with regular step
struct RangeStepIrregular &lt;: RangeStepStyle end # range with rounding error

```

What’s the point of creating a `type` without any fields. How do you use these and how does this relate to type stability of the code?

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [December 25, 2018, 12:28am UTC](https://discourse.julialang.org/t/usage-of-empty-structs/18968/2 "2018-12-25T00:28:47Z")

</div>

It’s often used for multiple dispatch. Example:

```julia
abstract type RangeStepStyle end

struct RangeStepRegular <: RangeStepStyle end
struct RangeStepIrregular <: RangeStepStyle end

range_step(n, ::Type{RangeStepRegular}) = println("regular step: $n")
range_step(n, ::Type{RangeStepIrregular}) = println("not a normal step: $n")

range_step(3, RangeStepRegular)
range_step(6, RangeStepIrregular)

```

Result:

```julia
regular step: 3
not a normal step: 6

```

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [December 25, 2018, 12:37am UTC](https://discourse.julialang.org/t/usage-of-empty-structs/18968/3 "2018-12-25T00:37:07Z")

</div>

Also, by making it a subtype of `RangeStepStyle`, you can enforce the argument in non-specialized methods, e.g.:

```julia
struct InvalidStep end

step_forward(n, style::Type{<:RangeStepStyle}) = range_step(n, style)

step_forward(3, RangeStepRegular)
step_forward(6, RangeStepIrregular)
step_forward(4, InvalidStep)

```

Result:

```julia
regular step: 3
not a normal step: 6
ERROR: LoadError: MethodError: no method matching step_forward(::Int64, ::Type{InvalidStep})

```

---

<div class="post-metadata">

**Author:** ![chakravala](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chakravala/32/6832_2.png) [@chakravala](https://discourse.julialang.org/u/chakravala)\
**Post date:** [December 25, 2018, 4:23am UTC](https://discourse.julialang.org/t/usage-of-empty-structs/18968/4 "2018-12-25T04:23:32Z")

</div>

You can also use type parameters like `f(::NoFields{N}) where N = N == 0` will specialize the function on the type parameter. Because `N` is a type parameter, the value of `N == 0` can be evaluated ahead of time during compilation before the function is actually called, thus eliminating the calculation at run time.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [December 25, 2018, 4:36am UTC](https://discourse.julialang.org/t/usage-of-empty-structs/18968/5 "2018-12-25T04:36:55Z")

</div>

This is discussed in the manual btw:

[https://docs.julialang.org/en/v1/manual/methods/#Trait-based-dispatch-1](https://docs.julialang.org/en/v1/manual/methods/#Trait-based-dispatch-1)
