# Dispatch function based on values of a parametric structure

**URL:** <https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681>\
**Category:** General Usage\
**Created:** [March 29, 2020, 4:10pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681 "2020-03-29T16:10:48Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 29, 2020, 4:10pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/1 "2020-03-29T16:10:48Z")

</div>

Hello everyone,

I am using a parametric structure parameterized by an integer parameter `p`.

Depending on the value of `p`, the function `f` will have different behaviors.  
What is the best solution: write an if elseif else structure inside the function `f` or dispatch f according to the value of `p`.

If I choose this second option, how should I write the dispatch? I have something like this in mind but this is not the right syntax.

```julia
struct mystruct{p}
A::Array{Float64,2}
end

f(m::mystruct{p}) where {p==0}
# do operations
end

f(m::mystruct{p}) where {p>0}
# do different operations
end

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 29, 2020, 5:49pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/2 "2020-03-29T17:49:48Z")

</div>

Just write the conditional inside `f`.

What is the reason to parameterized on `p` instead of not just storing it in the struct?

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [March 29, 2020, 8:01pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/3 "2020-03-29T20:01:58Z")

</div>

Sorry to digress slightly: I was under the impression that the `p` in the `struct` definition must be a `DataType`. Yet

`p1 = mystruct{1}([1.0 2.0])`

does not throw an error. Since dispatch on `p==1` is not possible, what would be a use case (and is it documented somewhere; I could not find it)?

Thanks.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [March 29, 2020, 8:34pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/4 "2020-03-29T20:34:42Z")

</div>

> [@hendri54](#):
>
> Since dispatch on `p==1` is not possible, what would be a use case (and is it documented somewhere; I could not find it)?

What do you mean? It is definitely possible. Just look at e.g. StaticArrays.jl

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [March 29, 2020, 9:04pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/5 "2020-03-29T21:04:59Z")

</div>

I had not seen that type of dispatch before. Thanks.

---

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 30, 2020, 4:57am UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/6 "2020-03-30T04:57:13Z")

</div>

I just give this configuration with one parameter as a toy problem. In reality, I have 3 parameters to parameterize my structure.  
Instead of making a long function with all the different possible combinations, I ‘ve thought that creating a function dispatched according to these cases will be more efficient than nested if conditions.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 30, 2020, 5:20am UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/7 "2020-03-30T05:20:45Z")

</div>

Surely you’ve seen dispatch on `Array{., 1}` vs `Array{., 2}`?

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [March 30, 2020, 5:51am UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/8 "2020-03-30T05:51:21Z")

</div>

> [@mleprovost](#):
>
> I ‘ve thought that creating a function dispatched according to these cases will be more efficient than nested if conditions.

It’s not really about efficiency, but about convenience. You can write it whichever way you want, just do it whichever way you think is nicer and gives cleaner, more readable code.

If methods for different parameters share a lot of code, maybe it’s easier to write them in a single function body. If not, it may be better to write different methods.

> [@mleprovost](#):
>
> ```julia
> f(m::mystruct{p}) where {p==0} 
> # do operations 
> end 
> 
> f(m::mystruct{p}) where {p>0} 
> # do different operations
> end
> 
> ```

You can do it like this (note that typenames should be CamelCase, not lowercase):

```julia
function f(m::MyStruct{0}) # method 1
    # do operations
end

function f(m::MyStruct{p}) where {p} # method 2
    # do operations
end

```

You cannot do arithmetic or comparisons such as `p > 0` on the type parameter in the function signature, that has to happen inside the function body. Here, `p==0` dispatches to method 1, and then _every other value_ for `p` dispatches to method 2.

---

<div class="post-metadata">

**Author:** ![Elrod](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/elrod/32/22461_2.png) [@Elrod](https://discourse.julialang.org/u/Elrod)\
**Post date:** [March 30, 2020, 6:49am UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/9 "2020-03-30T06:49:47Z")

</div>

> [@hendri54](#):
>
> I had not seen that type of dispatch before. Thanks.

Perhaps the most common use is for `AbstractArray`s:

```julia
foo(A::AbstractArray{T,1}) = # definition for vectors
foo(A::AbstractArray{T,2}) = # definition for matrices

```

Regarding efficiency, because these numbers are known at compile time, the compiler will get rid of all the branches like `if p > 0` (leaving only the code for the branch it would’ve taken).

Meaning they should perform identically if you’ve avoided all dynamic dispatches.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [March 30, 2020, 7:40am UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/10 "2020-03-30T07:40:08Z")

</div>

> [@hendri54](#):
>
> I was under the impression that the `p` in the `struct` definition must be a `DataType`

It is always recommended to check the [docs](https://docs.julialang.org/en/v1/manual/types/#man-types-1) first:

> Both abstract and concrete types can be parameterized by other types. They can also be parameterized by symbols, by values of any type for which [`isbits`](https://docs.julialang.org/en/v1/base/base/#Base.isbits) returns true (essentially, things like numbers and bools that are stored like C types or `struct` s with no pointers to other objects), and also by tuples thereof. Type parameters may be omitted when they do not need to be referenced or restricted.

---

<div class="post-metadata">

**Author:** ![hendri54](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hendri54/32/9621_2.png) [@hendri54](https://discourse.julialang.org/u/hendri54)\
**Post date:** [March 30, 2020, 11:29am UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/11 "2020-03-30T11:29:23Z")

</div>

Yes - I clearly failed to connect some dots here. I thought of array dimensions as a special case, but had not seen a `struct` parameterized by just a number.

I don’t want to divert the topic from the original question. Thanks for all the responses though.

---

<div class="post-metadata">

**Author:** ![mleprovost](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mleprovost/32/7166_2.png) [@mleprovost](https://discourse.julialang.org/u/mleprovost)\
**Post date:** [March 30, 2020, 8:08pm UTC](https://discourse.julialang.org/t/dispatch-function-based-on-values-of-a-parametric-structure/36681/12 "2020-03-30T20:08:44Z")

</div>

Thank you for all your answers, this helps me a lot.
