# Define function with multiple dispatch in terms of another function with same signatures

**URL:** <https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675>\
**Category:** General Usage\
**Tags:** array\
**Created:** [April 3, 2019, 4:26am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675 "2019-04-03T04:26:50Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Alec\_Loudenback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alec_loudenback/32/278_2.png) [@Alec\_Loudenback](https://discourse.julialang.org/u/Alec_Loudenback)\
**Post date:** [April 3, 2019, 4:26am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/1 "2019-04-03T04:26:50Z")

</div>

Say I have a function, call it `q` and it has multiple signatures:

```julia
q(a,b) 
q(b)
...

```

And I have the relationship that `p = 1 - q`

Is there a simpler way to define this other than to list out the same set of signatures?

I.e. not do the following

```julia
p(a,b) = 1 - q(a,b)
p(b) = 1 - q(b)
...

```

I tried just saying `p = 1 - q` but I get a `MethodError: no method matching -(::Int64, ::typeof(q))`

Also tried `p() = 1 - q()` but that’s just defining a function with no arguments, not passing along a variable set to q

---

<div class="post-metadata">

**Author:** ![longemen3000](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/longemen3000/32/7298_2.png) [@longemen3000](https://discourse.julialang.org/u/longemen3000)\
**Post date:** [April 3, 2019, 4:48am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/2 "2019-04-03T04:48:00Z")

</div>

can you try this?

```julia
q(args...) = 1-p(args...)

```

tell me if it works, i will need this in some point in the future

---

<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:** [April 3, 2019, 6:54am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/3 "2019-04-03T06:54:25Z")

</div>

> [@Alec\_Loudenback](#):
>
> I.e. not do the following
> 
> ```julia
> p(a,b) = 1 - q(a,b)
> p(b) = 1 - q(b)
> ...
> 
> ```

Why not? That looks like the right way to do it. Ideally, you expose an interface via a small set of functions, so this should not be cumbersome.

But as @longemen3000 suggested,

```julia
@inline p(args...) = 1 - q(args...)

```

should work fine.

---

<div class="post-metadata">

**Author:** ![Alec\_Loudenback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alec_loudenback/32/278_2.png) [@Alec\_Loudenback](https://discourse.julialang.org/u/Alec_Loudenback)\
**Post date:** [April 3, 2019, 12:36pm UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/4 "2019-04-03T12:36:14Z")

</div>

Yea, I might end up still defining it that way. I was curious because I’m trying to build out [ActuarialScience.jl](https://github.com/alecloudenback/ActuarialScience.jl) and there’s a lot of functions that are useful to export that have the same “name” but different dispatch/signatures (e.g. [life annuities](https://en.wikipedia.org/wiki/Actuarial_notation#Life_annuities)) where often the different signatures really have a simpler relationship (like that in my original example.

Really just looking to build out my understanding of the different things I can do with Julia.

Question on your response though - in this case, what would `@inline` do?

---

<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:** [April 3, 2019, 12:40pm UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/5 "2019-04-03T12:40:15Z")

</div>

> [@Alec\_Loudenback](#):
>
> what would `@inline` do?

See the documentation, eg `?@inline`.

---

<div class="post-metadata">

**Author:** ![non-Jedi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/non-jedi/32/3645_2.png) [@non-Jedi](https://discourse.julialang.org/u/non-Jedi)\
**Post date:** [April 3, 2019, 1:08pm UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/6 "2019-04-03T13:08:08Z")

</div>

The other approach you could take is for the first signature of `q`, wrap `a` and `b` in a struct. Something like:

```julia
struct MyType
    a::SomeType
    b::SomeType
end

q(b) = ...
q(ab::MyType) = ...

p(x) = 1 - q(x)

```

---

<div class="post-metadata">

**Author:** ![Alec\_Loudenback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alec_loudenback/32/278_2.png) [@Alec\_Loudenback](https://discourse.julialang.org/u/Alec_Loudenback)\
**Post date:** [April 17, 2019, 3:26am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/7 "2019-04-17T03:26:32Z")

</div>

Reviving this topic, as now I’m refactoring to use keyword arguments in some cases, but the splat doesn’t work in this case:

```julia
q(a,b) = 0.1
q(b) = 0.2
q(a,b;c=2) = 0.3
p(args...) = 1.0 - q(args...)

```

```julia
p(1,2) # 0.9
p(1) # 0.8
p(1,2,b=3) # function p does not accept keyword arguments

```

---

<div class="post-metadata">

**Author:** ![Ajaychat3](https://avatars.discourse-cdn.com/v4/letter/a/ecd19e/32.png) [@Ajaychat3](https://discourse.julialang.org/u/Ajaychat3)\
**Post date:** [April 17, 2019, 3:45am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/8 "2019-04-17T03:45:09Z")

</div>

Out of curiosity, I tried to run these commands. For p(1,2) I get 0.7 instead of 0.9 once q(a,b;c=2) has been defined.

```julia
julia> q(a,b) = 0.1
q (generic function with 2 methods)

julia> q(b) = 0.2
q (generic function with 2 methods)

julia> q(a,b;c=2) = 0.3
q (generic function with 2 methods)

julia> p(args...) = 1.0 - q(args...)
p (generic function with 1 method)

julia> p(1,2) # 0.9
0.7

julia> p(1) # 0.8
0.8

julia> p(1,2)
0.7

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 17, 2019, 3:48am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/9 "2019-04-17T03:48:10Z")

</div>

```julia
p(args...; kwargs...) = 1.0 - q(args...; kwargs...)

```

---

<div class="post-metadata">

**Author:** ![Ajaychat3](https://avatars.discourse-cdn.com/v4/letter/a/ecd19e/32.png) [@Ajaychat3](https://discourse.julialang.org/u/Ajaychat3)\
**Post date:** [April 17, 2019, 3:52am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/10 "2019-04-17T03:52:39Z")

</div>

I still get p(1,2) as 0.7 even after doing this.

```julia
julia> q(a,b) = 0.1
q (generic function with 1 method)

julia> q(b) = 0.2
q (generic function with 2 methods)

julia> q(a,b;c=2) = 0.3
q (generic function with 2 methods)

julia> p(args...;kwargs...) = 1.0 - q(args...;kwargs...)
p (generic function with 1 method)

julia> p(1,2)
0.7

julia> p(1,2,c=5)
0.7

```

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 17, 2019, 3:58am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/11 "2019-04-17T03:58:23Z")

</div>

`q(a,b;c=2) = 0.3` overwrites `q(a,b) = 0.1`, so that’s to be expected. I was just responding to @Alec_Loudenback.

---

<div class="post-metadata">

**Author:** ![Ajaychat3](https://avatars.discourse-cdn.com/v4/letter/a/ecd19e/32.png) [@Ajaychat3](https://discourse.julialang.org/u/Ajaychat3)\
**Post date:** [April 17, 2019, 4:00am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/12 "2019-04-17T04:00:29Z")

</div>

@tkoolen: Thanks I did understand the same behaviour but was curious to know if there is way out.

---

<div class="post-metadata">

**Author:** ![tkoolen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkoolen/32/1603_2.png) [@tkoolen](https://discourse.julialang.org/u/tkoolen)\
**Post date:** [April 17, 2019, 4:03am UTC](https://discourse.julialang.org/t/define-function-with-multiple-dispatch-in-terms-of-another-function-with-same-signatures/22675/13 "2019-04-17T04:03:23Z")

</div>

Nope, because keyword arguments do not participate in dispatch.
