# A generic function (using higher order functions) with special implementation for specific functions (as input)?

**URL:** <https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213>\
**Category:** General Usage\
**Created:** [May 21, 2025, 11:58am UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213 "2025-05-21T11:58:30Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel\_Lincke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daniel_lincke/32/206206_2.png) [@Daniel\_Lincke](https://discourse.julialang.org/u/Daniel_Lincke)\
**Post date:** [May 21, 2025, 11:58am UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/1 "2025-05-21T11:58:30Z")

</div>

Hi,

I have the following situation: A complicated algorithm that works with a function as input parameter:

```julia
function cool_stuff(f :: Function, a::Real, b::Real) 
   ... 
end

```

cool\_stuff could be something like integration or some optimization which is numerically complicated. For some functions (like f(x) = sin(x) or f(x) = x + 1) I have done all the math and can provide very efficient code. I nevertheless want to have one function cool\_stuff with several methods. So a function cool\_stuff\_for\_sin is not the desired solution. Question: How can I do multiple dispatch for a special function? So I guess that’s equivalent to the question if I can define subtypes of the function type?

Thanks

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [May 21, 2025, 12:11pm UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/2 "2025-05-21T12:11:09Z")

</div>

You can say something like

```julia
cool_stuff(f::typeof(sin), a::Real, b::Real) = cos(a+b)

```

Apart from that, I would say it’s not a good idea to restrict `f` to `Function`. You (or somebody else) may want to use some object `a::A` with a callable method `a(x)` instead. That wouldn’t work if `A` is not a subtype of `Function`.

---

<div class="post-metadata">

**Author:** ![Daniel\_Lincke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daniel_lincke/32/206206_2.png) [@Daniel\_Lincke](https://discourse.julialang.org/u/Daniel_Lincke)\
**Post date:** [May 21, 2025, 12:15pm UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/3 "2025-05-21T12:15:46Z")

</div>

Thanks - what would be the way to restrict the argument to types that are callable?

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 21, 2025, 12:27pm UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/4 "2025-05-21T12:27:00Z")

</div>

Anything can be callable, so there’s no way to do that within the type system, basically. If reflection is a viable solution, `hasmethod` or `applicable` might be useful, but that’s easy to abuse.

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [May 21, 2025, 12:28pm UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/5 "2025-05-21T12:28:23Z")

</div>

There is no real way – any type can have callable methods. There is a type `Callable`, but it’s internal. Moreover, like `Function`, you can subtype it for any type. So it’s not helpful.

I wouldn’t restrict the type of `f` at all. If `f` doesn’t have a callable method (or rather not one with the signature you are using), then you get an error. If you pass `f` on as an argument to some other function, then it’s best to use a type parameter as in

```julia
cool_stuff(f::F, a::Real, b::Real) where F = sum(f, (a, b))

```

see [here](https://docs.julialang.org/en/v1/manual/performance-tips/#Be-aware-of-when-Julia-avoids-specializing).

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 21, 2025, 12:28pm UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/6 "2025-05-21T12:28:47Z")

</div>

> [@Daniel\_Lincke](#):
>
> the question if I can define subtypes of the function type

It’s not really relevant to the rest of the topic, but, just to be clear, defining subtypes of `Function` is done in the usual manner: `struct Func <: Function end`.

---

<div class="post-metadata">

**Author:** ![Daniel\_Lincke](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daniel_lincke/32/206206_2.png) [@Daniel\_Lincke](https://discourse.julialang.org/u/Daniel_Lincke)\
**Post date:** [May 21, 2025, 1:14pm UTC](https://discourse.julialang.org/t/a-generic-function-using-higher-order-functions-with-special-implementation-for-specific-functions-as-input/129213/7 "2025-05-21T13:14:56Z")

</div>

Thanks - I think using a subtype of Function is reletad as the following works fine:

```julia
struct AddSomething <: Function 
  to_add :: Real
end;

(my_f::AddSomething)(x::Real) = x + my_f.to_add

function cool_thing(f::Function, a::Real, b::Real) println("fallback") end

function cool_thing(f::AddSomething, a::Real, b::Real) println("special, parameter = ",f.to_add) end

my_func = AddSomething(3)

julia> cool_thing(x -> x+1, 0, 1)
fallback

julia> cool_thing(my_func, 0, 1)
special, parameter = 3

```
