# Argument type of higher order functions

**URL:** <https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989>\
**Category:** General Usage\
**Created:** [April 2, 2023, 10:59pm UTC](https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989 "2023-04-02T22:59:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![empet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/empet/32/221303_2.png) [@empet](https://discourse.julialang.org/u/empet)\
**Post date:** [April 2, 2023, 10:59pm UTC](https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989/1 "2023-04-02T22:59:10Z")

</div>

If I define:

```julia
function myfunc(f::T, g::T; b=2.5 ) where T<:Function
    #some lines here
    h(t) = b*(f(t) +g(t)^2)
end
f(t; a=2)=a*t
g(t; a=3)=a+exp(t)
h=myfunc(f, g)
h(1.3)

```

it is thrown the error:

```julia
MethodError: no method matching myfunc(::typeof(f), ::typeof(g))
Closest candidates are:
  myfunc(::T, ::T; b) where T<:Function at In[2]:1

Stacktrace:
 [1] top-level scope
   @ In[2]:7

```

but the following two definitions work:

```julia
function myfunc(f::Function, g::Function) 
    #...
    h(t) = f(t) +g(t)^2
end
h=myfunc(f,g)
h(1.3)
function myfunc(f::T) where T<:Function
    #...
    h(t)=exp(f(t))-f(t)
end
k=myfunc(t->-t^2)
k(4)

```

Why the last one works, but the first one doesn’t?

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [April 2, 2023, 11:08pm UTC](https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989/2 "2023-04-02T23:08:43Z")

</div>

First version is enforcing that both functions share 1 unknown type `T`, but `f` and `g` have different types. Try `function myfunc(f::T, g::S; b=2.5 ) where {T<:Function, S<:Function}`

---

<div class="post-metadata">

**Author:** ![PeterSimon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/petersimon/32/25193_2.png) [@PeterSimon](https://discourse.julialang.org/u/PeterSimon)\
**Post date:** [April 2, 2023, 11:50pm UTC](https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989/3 "2023-04-02T23:50:07Z")

</div>

> [@Benny](#):
>
> `f` and `g` have different types

In case it isn’t obvious to you why this is so, as stated [here](https://docs.julialang.org/en/v1/manual/types/#Types-of-functions) in the Julia documentation, every function in Julia has a distinct type.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [April 3, 2023, 8:12am UTC](https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989/4 "2023-04-03T08:12:17Z")

</div>

Technically, the first version could’ve worked with `T == Function`. Then, both `f::T` and `g::T`, and `T <: Function`.  
The reason why it doesn’t actually work is that Julia implicitly constrains `T` to be a concrete type in this case.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [April 3, 2023, 8:21am UTC](https://discourse.julialang.org/t/argument-type-of-higher-order-functions/96989/5 "2023-04-03T08:21:17Z")

</div>

Both arguments need to be of the same type, and due to only concrete types of the passed in objects (instead of their abstract super types) being used in dispatch, the constraint that the types must be the same results in dispatch saying “the types don’t match, ergo there’s a `MethodError`”. Runtime objects can never have an abstract type.

Julia doesn’t implicitly constrain `T` to be a concrete type - it’s the concreteness of the types of the objects that results in the `MethodError`.
