# Why traits?

**URL:** https://discourse.julialang.org/t/why-traits/105591
**Category:** General Usage
**Tags:** dispatch, traits, type-stability
**Created:** [October 30, 2023, 6:51pm UTC](https://discourse.julialang.org/t/why-traits/105591 "2023-10-30T18:51:47Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [October 30, 2023, 6:51pm UTC](https://discourse.julialang.org/t/why-traits/105591/1 "2023-10-30T18:51:47Z")

</div>

I’ve been trying to teach my students traits, only to realize that there is something I don’t fully understand. Is there any different between these two approaches to dispatch?

```julia
struct A end
struct B end

## Holy trait

trait1(::A) = Val(true)
trait1(::B) = Val(false)
f(x) = f(x, trait1(x))
f(x, ::Val{true}) = π
f(x, ::Val{false}) = "pi"

## Type-inferrable if-else

trait2(::A) = true
trait2(::B) = false
g(x) = trait2(x) ? π : "pi"

```

Both make `@code_warntype` happy, and while I know the first one is more “julianic”, I actually wonder why.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [October 30, 2023, 6:54pm UTC](https://discourse.julialang.org/t/why-traits/105591/2 "2023-10-30T18:54:35Z")

</div>

> [@gdalle](#):
>
> Both make `@code_warntype` happy, and while I know the first one is more “julianic”, I actually wonder why.

The second one relies on compiler inlining and constant propagation (which might not happen if the functions become sufficiently complicated), whereas the first only relies on type inference and specialization (which happen even for very complicated functions).

(Technically, even in the first case you are relying on inlining and constant propagation because you are calling `Val(true)` rather than `Val{true}()`. But for the `Val` function with literal constants the two are equivalent these days; this wasn’t the case in early versions of Julia IIRC.)

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [October 30, 2023, 6:59pm UTC](https://discourse.julialang.org/t/why-traits/105591/3 "2023-10-30T18:59:11Z")

</div>

Thanks!  
Follow up: assuming I do call `Val{true}()` in `trait1`, is there any difference between using value-types and using dummy structs like `TraitSatisfied()`?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [October 30, 2023, 7:01pm UTC](https://discourse.julialang.org/t/why-traits/105591/4 "2023-10-30T19:01:17Z")

</div>

> [@gdalle](#):
>
> is there any difference between using value-types and using dummy structs like `TraitSatisfied()`?

If you define your own types then you can have a hierarchy with subtypes. (There is also a difference in readability by using more descriptive names, of course.)

---

<div class="post-metadata">

### Author: ![gdalle](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gdalle/32/27854_2.png) [@gdalle](https://discourse.julialang.org/u/gdalle)
#### Post date: [October 30, 2023, 7:02pm UTC](https://discourse.julialang.org/t/why-traits/105591/5 "2023-10-30T19:02:23Z")

</div>

That makes sense!  
First-class answers in a matter of seconds: 10/10 would recommend the Julia Discourse

---

<div class="post-metadata">

### Author: ![marco\_menarini](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_menarini/32/46117_2.png) [@marco\_menarini](https://discourse.julialang.org/u/marco_menarini)
#### Post date: [November 19, 2023, 12:30pm UTC](https://discourse.julialang.org/t/why-traits/105591/6 "2023-11-19T12:30:20Z")

</div>

With 2 maybe no, but if you have more you can apply the strategy pattern by modifying only one line (see design patterns and best behavior in Julia)

For example

```julia
abstract type Algo end
struct Fast:<Algo end
struct Slow:< Algo end
...
struct Experimental<:Algo end

Then you can dispatch multiple versions by simply doing different dispatch of

Func(f::Algo,...)

```

This is a great pattern if you want to maintain a growing code without awkwards if else switches inside
