# Dispatch on function itself

**URL:** <https://discourse.julialang.org/t/dispatch-on-function-itself/82449>\
**Category:** New to Julia\
**Created:** [June 8, 2022, 5:29pm UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449 "2022-06-08T17:29:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian1](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brian1/32/49250_2.png) [@Brian1](https://discourse.julialang.org/u/Brian1)\
**Post date:** [June 8, 2022, 5:29pm UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449/1 "2022-06-08T17:29:10Z")

</div>

Can Julia dispatch on the function itself?

```julia
test_func1(i::Int)=i+1
test_func2(i::Int)=i-1
(x::U{typeof(test_func1),typeof(test_func2)})(g::V)=println("ddd")

```

So the twos functions can do this:

```julia
test_func1([1,2,3])

"ddd"

test_func2([1,2,3])

"ddd"

```

---

<div class="post-metadata">

**Author:** ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)\
**Post date:** [June 8, 2022, 5:38pm UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449/2 "2022-06-08T17:38:15Z")

</div>

I’m not sure what you trying to accomplish, but the following code works:

```julia
julia> struct F{T} <: Function
           f::T
       end

julia> (self::F)(x) = self.f(x)

julia> test_func1 = F(i::Int -> i + 1)
(::F{var"#3#4"}) (generic function with 1 method)

julia> test_func2 = F(i::Int -> i - 1)
(::F{var"#5#6"}) (generic function with 1 method)

julia> test_func1(1)
2

julia> test_func2(1)
0

julia> (self::F)(x) = println("ddd")

julia> test_func1([1, 2, 3])
ddd

julia> test_func2([1, 2, 3])
ddd

julia>

```

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [June 8, 2022, 6:51pm UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449/3 "2022-06-08T18:51:59Z")

</div>

I’m also not sure what you mean, but to answer your question:

> [@Brian1](#):
>
> Can Julia dispatch on the function itself?

Yes, Julia can dispatch on functions:

```julia
julia> f() = "f"
f (generic function with 1 method)

julia> g(::typeof(f)) = "I called $(f())"
g (generic function with 1 method)

julia> g(::Any) = "hello"
g (generic function with 2 methods)

julia> g(1)
"hello"

julia> g(f)
"I called f"

```

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [June 8, 2022, 6:56pm UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449/4 "2022-06-08T18:56:51Z")

</div>

Or maybe you’re trying to add a common method to two different functions, but you want to avoid redundant typing? In that case you could use `@eval`:

```julia
julia> test_func1(i::Int) = i + 1
test_func1 (generic function with 1 method)

julia> test_func2(i::Int) = i - 1
test_func2 (generic function with 1 method)

julia> for f in (:test_func1, :test_func2)
       @eval ($f)(g) = println("ddd")
       end

julia> test_func1([1,2,3])
ddd

julia> test_func2([1,2,3])
ddd

```

---

<div class="post-metadata">

**Author:** ![lawless-m](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lawless-m/32/30869_2.png) [@lawless-m](https://discourse.julialang.org/u/lawless-m)\
**Post date:** [June 9, 2022, 5:02am UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449/5 "2022-06-09T05:02:13Z")

</div>

Sort of. But the type of a function is not the same as the function signature, like it would be in C where you can supply a pointer to any function so long as the signature matches. Each individual function is a specific subtype of Function.

Multiple dispatch code selection happens when you _call_ the supplied function, not when you call _with_ it (although that sentence probably makes more sense in my head!).

However, you can despatch on the specific function

```julia
julia> f1(a::Int)::String = "f1"
f1 (generic function with 1 method)

julia> isa(f1, Function)
true

julia> typeof(f1)
typeof(f1)

julia> typeof(f1) in subtypes(Function)
true

julia> ff(f::typeof(f1), a::Int) = f1(a)
ff (generic function with 1 method)

julia> ff(f1, 1)
"f1"

julia> f2(a::Int)::String = "f2"
f2 (generic function with 1 method)

julia> typeof(f1) == typeof(f2)
false

julia> ff(f2, 2)
ERROR: MethodError: no method matching ff(::typeof(f2), ::Int64)
Closest candidates are:
  ff(::typeof(f1), ::Int64) at REPL[17]:1
Stacktrace:
 [1] top-level scope
   @ REPL[22]:1

julia> ff(f::Function, a::Int) = "f(a) = $(f(a))"
ff (generic function with 2 methods)

julia> ff(f2, 1)
"f(a) = f2"

julia> ff(f1, 1)
"f1"

```

and it gets more interesting if there are multiple methods of `f1`

```julia
julia> f1(a::Int, b::Int)::String = "f1 a b"
f1 (generic function with 2 methods)

julia> ff(f1::typeof(f1), a::Int, b::Int) = "f1(a,b) = $(f1(a, b))"
ff (generic function with 3 methods)

julia> ff(f1, 1)
"f1"

julia> ff(f1, 1, 2)
"f1(a,b) = f1 a b"

```

I’ve not encountered situations where this was useful, but I am sure there are occasions where specialising on supplied functions might be useful, due to implementation differences, e.g. thread safety or some sort of Abstract Type interface.

---

<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:** [June 9, 2022, 7:29am UTC](https://discourse.julialang.org/t/dispatch-on-function-itself/82449/6 "2022-06-09T07:29:15Z")

</div>

while not exactly the same, you could do:

```julia
for f in (:test_func1,:test_func2)
  @eval $f(g::Vector) = println("ddd")
end

```

in this case, `:test_func1` is a symbol, not the function itself.
