# What is the triangle in "triangular dispatch"?

**URL:** <https://discourse.julialang.org/t/what-is-the-triangle-in-triangular-dispatch/18817>\
**Category:** Internals & Design\
**Created:** [December 19, 2018, 2:00am UTC](https://discourse.julialang.org/t/what-is-the-triangle-in-triangular-dispatch/18817 "2018-12-19T02:00:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [December 19, 2018, 2:00am UTC](https://discourse.julialang.org/t/what-is-the-triangle-in-triangular-dispatch/18817/1 "2018-12-19T02:00:03Z")

</div>

More than 5 year ago Tim Holey [wished he could write](https://github.com/JuliaLang/julia/issues/3766)

```julia
colorspace{C<:ColorValue,A<:AbstractArray{C}}(img::A) = string(C)

```

He called such a feature “triangular dispatch (left-to-right template parameter chaining)”.

Today Julia does support such “triangular” dispatch and Tim’s example can be written as

```julia
colorspace(img::A) where A<:AbstractArray{C} where C<:ColorValue = string(C)

```

I understand the “left-to-right template parameter chaining” part, but what makes this kind of dispatch triangular? What are the vertices of that triangle?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [December 19, 2018, 4:26am UTC](https://discourse.julialang.org/t/what-is-the-triangle-in-triangular-dispatch/18817/2 "2018-12-19T04:26:14Z")

</div>

> <https://stackoverflow.com/questions/30746405/can-i-use-a-subtype-of-a-function-parameter-in-the-function-definition>

> The ability to define a function `g{T, S<:T}(::Vector{T}, ::S)` has been referred to as “triangular dispatch” as an analogy to diagonal dispatch: `f{T}(::Vector{T}, ::T)` . (Imagine a table with a type hierarchy labelling the rows and columns, arranged such that the super types are to the top and left. The rows represent the element type of the first argument, and the columns the type of the second. Diagonal dispatch will only match the cells along the diagonal of the table, whereas triangular dispatch matches the diagonal and everything below it, forming a triangle.)

---

<div class="post-metadata">

**Author:** ![jandehaan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jandehaan/32/6805_2.png) [@jandehaan](https://discourse.julialang.org/u/jandehaan)\
**Post date:** [December 19, 2018, 5:17am UTC](https://discourse.julialang.org/t/what-is-the-triangle-in-triangular-dispatch/18817/3 "2018-12-19T05:17:57Z")

</div>

Edit: the following is wrong. It is backwards. See the correct version below this entry.

@Gnimuc, I interpret that to mean  
`R <: S <: T`

Triangular:

```julia
          | T | S | R 
----------+---+---+---
Vector{T} | X | |
Vector{S} | X | X |
Vector{R} | X | X | X

```

Diagonal:

```julia
          | T | S | R 
----------+---+---+---
Vector{T} | X | |
Vector{S} | | X |
Vector{R} | | | X

```

Where `X` marks the combination that will cause the function `g{T, R<:T}(::Vector{T}, ::R)` to be dispatched.

Correct?

---

<div class="post-metadata">

**Author:** ![Gnimuc](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gnimuc/32/2194_2.png) [@Gnimuc](https://discourse.julialang.org/u/Gnimuc)\
**Post date:** [December 19, 2018, 5:41am UTC](https://discourse.julialang.org/t/what-is-the-triangle-in-triangular-dispatch/18817/4 "2018-12-19T05:41:31Z")

</div>

It should be:

| | T | S |
| --- | --- | --- |
| Vector{T} | ✅ | ✅ |
| Vector{S} | x | ✅ |

```julia
julia> g(t::Vector{T}, s::S) where {T, S<:T} = "dispatch!"

julia> g(Integer[1], Integer(1)) # Vector{T} T
"dispatch!"

julia> g(Integer[1], Unsigned(1)) # Vector{T} S
"dispatch!"

julia> g(Unsigned[1], Integer(1)) # Vector{S} T
ERROR: MethodError: no method matching g(::Array{Unsigned,1}, ::Int64)

julia> g(Unsigned[1], Unsigned(1)) # Vector{S} S
"dispatch!"

```
