# Parametric types & multiple dispatch

**URL:** https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650
**Category:** General Usage
**Tags:** question, parametric-types, multiple-dispatch
**Created:** [November 24, 2023, 1:12am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650 "2023-11-24T01:12:00Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)
#### Post date: [November 24, 2023, 1:12am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/1 "2023-11-24T01:12:00Z")

</div>

Method choice can be determined by a parametric type

```julia
struct X{x} end

f(::X{:x1}) = 1
f(::X{:x2}) = 2

f(X{:x1}()) # 1
f(X{:x2}()) # 2

```

Why not allow it to be determined just with the parameter ?

```julia
f({:x1}) = 1
f({:x2}) = 2

f({:x1}) # 1
f({:x1}) # 2

```

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [November 24, 2023, 1:51am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/2 "2023-11-24T01:51:52Z")

</div>

Strictly speaking, it’s no longer a parameter because there is nothing to parameterize. It’s not consistent with the language to use curly braces for anything besides parameterizing types and related `where` clauses, nor to dispatch methods by instances instead of types. This is more like a feature of pattern-matching ([Haskell example](https://en.wikipedia.org/wiki/Pattern_matching#Primitive_patterns)) than type-based polymorphism. (Incidentally, you [can use type classes](https://stackoverflow.com/questions/26303353/can-multiple-dispatch-be-achieved-in-haskell-with-pattern-matching-on-type-class) to slightly do multiple dispatch in Haskell, but without the convenient syntax or subtyping that we’re familiar with in Julia. Different language designs, different tradeoffs.)

As for a practical reason, dispatching on instances instead of types either invites more performance-ruining compilation bloat or optimization-impeding runtime dispatch, you don’t want this very often. As you know already, the standard `Val(x)::Val{x}` can be used for this purpose. The proposed curly brace syntax could only be dubious shorthand for that, not actually omit a type.

---

<div class="post-metadata">

### Author: ![tverho](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tverho](https://discourse.julialang.org/u/tverho)
#### Post date: [November 24, 2023, 7:52am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/3 "2023-11-24T07:52:41Z")

</div>

Funnily enough it’s possible to abuse the constructor syntax to do pretty much what you describe:

```julia
struct f{T} end

f{:x1}() = 1
f{:x2}() = 2

julia> f{:x1}()
1

julia> f{:x2}()
2

```

This works because constructors seem to be permitted to return any value.

I wonder if it’d make any sense to allow this syntax for any function, not just constructors?

---

<div class="post-metadata">

### Author: ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)
#### Post date: [November 24, 2023, 10:02am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/4 "2023-11-24T10:02:41Z")

</div>

So for a given function `f` you add `struct f{T} end`  
You can then create additional methods of `f` that you can call specifically

f{“specific\_method\_1”}( args… )  
f{“specific\_method\_2”}( args… )

The selector has to be hard coded. i.e. this doesn’t work

```julia
f{:x}()=1
X = :x
f{X}()

```

So you could instead just create different functions  
f\_specific\_method\_1( args… )  
f\_specific\_method\_2( args… )

I like it though. I’d prefer to have one function with different tags rather than different functions. But I’m not an expert.

---

<div class="post-metadata">

### Author: ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)
#### Post date: [November 24, 2023, 10:28am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/5 "2023-11-24T10:28:03Z")

</div>

> [@tverho](#):
>
> I wonder if it’d make any sense to allow this syntax for any function, not just constructors?

It doesn’t make sense for the language to turn curly braces into bonus arguments in a hypothetical parametric function call (not to be confused with parametric methods), nor does it make sense to parameterize non-types. Type-based multimethods and parametric types shouldn’t be misappropriated for the syntax of very limited pattern-matching.

> [@Lincoln\_Hannah](#):
>
> So for a given function `f` you add `struct f{T} end`

This isn’t a function, even if you do `struct f{T} <: Function end`. Types are _callable_ (the methods being the type constructors), but functions are instances of `Function`, not subtypes.

> [@Lincoln\_Hannah](#):
>
> I’d prefer to have one function with different tags rather than different functions.

Let alone a function, you’re not working with even one type, but an iterated union of infinitely many types. You would not want to nest calls like `f{X}()` instead of `f(X)` because of the type instability. Type-based dispatch is only one specific way of branching, it’s not suitable for everything. In this example I’d much prefer indexing a `Dict{Symbol, Int}`, and in general with a few fixed paths I’d prefer an `if`-statement or try proper pattern-matching like Match.jl.

> [@Lincoln\_Hannah](#):
>
> The selector has to be hard coded. i.e. this doesn’t work
> 
> ```julia
> f{:x}()=1
> X = :x
> f{X}()
> 
> ```

It works for me, where does it throw the error and what is it?

---

<div class="post-metadata">

### Author: ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)
#### Post date: [November 24, 2023, 10:33am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/6 "2023-11-24T10:33:08Z")

</div>

You’re right. It does work.

---

<div class="post-metadata">

### Author: ![tverho](https://avatars.discourse-cdn.com/v4/letter/t/839c29/32.png) [@tverho](https://discourse.julialang.org/u/tverho)
#### Post date: [November 24, 2023, 11:26am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/7 "2023-11-24T11:26:48Z")

</div>

I think the recommended way to do dispatch based on values is using `Val` like Benny mentioned

```julia
f(::Val{:x1}) = 1
f(::Val{:x2}) = 2

f(Val(:x1))

```

Whether this is the best approach depends on what you’re trying to do, I guess.

---

<div class="post-metadata">

### Author: ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)
#### Post date: [November 27, 2023, 9:30am UTC](https://discourse.julialang.org/t/parametric-types-multiple-dispatch/106650/8 "2023-11-27T09:30:34Z")

</div>

Thanks for all your help.  
I see now how Val(x) works. I’d missed it before.  
So tuukka’s answer above is the best way to dispatch on parameter.  
I’ll use this from now on.

Re Match.jl  
I love this package but only when the result of each match is one or two lines.  
If its 20 lines, multiple methods seems cleaner.
