# Why Julia doesn't have function types?

**URL:** <https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934>\
**Category:** Internals & Design\
**Tags:** question\
**Created:** [February 7, 2022, 5:58am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934 "2022-02-07T05:58:56Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 5:58am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/1 "2022-02-07T05:58:56Z")

</div>

I was wondering what’s the reason that in Julia we don’t have `function types` based on input variables, and output variables respective types. I mean, `f(x::Int) = x` would be of type `Function{input<: Int}` while `f(x::Int)::Int = x` would be `Function{input<: Int, output<:Int}`. Is there some “compiler related” reason or something like it?

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [February 7, 2022, 6:26am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/2 "2022-02-07T06:26:18Z")

</div>

most functions in Julia wouldn’t have useful types… also, lots of functions would have undecidable types or types that can change at runtime.

---

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 6:31am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/3 "2022-02-07T06:31:40Z")

</div>

So it’s more a matter of utility? I think that at leas the `Function{input<:Type}` would be quite common. Indeed, without the output type specified, I don’t think it’s that useful.

---

<div class="post-metadata">

**Author:** ![goretkin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goretkin/32/167_2.png) [@goretkin](https://discourse.julialang.org/u/goretkin)\
**Post date:** [February 7, 2022, 7:57am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/4 "2022-02-07T07:57:14Z")

</div>

What should the type of the function below be?

```julia
function foo(x)
  return 2*x
end

function foo(x::String)
  return 2*length(x)
end

```

Because the _function_ is `foo`. There may be methods, e.g. `foo(x::String)`. Even if that were the only method for the function [at the moment], later in execution, new methods may be defined.

---

<div class="post-metadata">

**Author:** ![tomaklutfu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomaklutfu/32/2411_2.png) [@tomaklutfu](https://discourse.julialang.org/u/tomaklutfu)\
**Post date:** [February 7, 2022, 8:05am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/5 "2022-02-07T08:05:27Z")

</div>

You can always make a callable type-parametric sub-type of `Function`(an abstract type). However, there are infinite number of input and output combinations so that you will end up with many parameters to deal with in type annotations.

---

<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:** [February 7, 2022, 8:27am UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/6 "2022-02-07T08:27:34Z")

</div>

FunctionWrappers.jl kind of provides this, see e.g. the tests [https://github.com/yuyichao/FunctionWrappers.jl/blob/2b76f6fb71ec67e8bb3a23a2158f2571955a59be/test/runtests.jl#L35](https://github.com/yuyichao/FunctionWrappers.jl/blob/2b76f6fb71ec67e8bb3a23a2158f2571955a59be/test/runtests.jl#L35)

---

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 1:11pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/7 "2022-02-07T13:11:43Z")

</div>

I mean, the first one would be type `Function{Any, Any}` the second would be `Function{String, Any}`. And you could do `foo(x::String)::String = x*x` which would be `Function{String, String}`, no?

---

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 1:14pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/8 "2022-02-07T13:14:03Z")

</div>

Thanks, @kristoffer.carlsson . Do you know if this package is still maintained? There is no documentation 😕

BTW, I ended up using Catlab.jl. Here is my solution:

```julia
struct JFunction
    f::Function
    dom::Type
    codom::Type
end
(::JFunction)(x) = f(x)
@instance Category{Type, JFunction} begin
  dom(ȷf::JFunction) = getfield(ȷf,:dom)
  codom(ȷf::JFunction) = getfield(ȷf,:codom)

  id(d::Type) = JFunction(x->x, d, d)
  compose(ȷg::JFunction, ȷf::JFunction) = JFunction(ȷg ∘ ȷf, ȷf.dom, ȷg.codom)
end

```

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [February 7, 2022, 1:37pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/9 "2022-02-07T13:37:19Z")

</div>

There is no “first one” and “second one”, the two are the same function, if you are describing _function_ types, then the description should be valid for all _method bodies_ of the _function_. And note that new code can extend the function adding new method bodies to it. If you are describing _methods_, then you will have situations in which you do not know which method is being called in a block of code before runtime.

---

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 2:13pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/10 "2022-02-07T14:13:21Z")

</div>

Hmmm, I think I get your point. I was wondering about language’s such as Haskell that do have this function type definition. I mean, what makes it unfeasible in Julia? Is the fact that is dynamic or the multiple dispatch?  
I’ll try understanding the code in `FunctionWrappers.jl` to see what they are doing, since it seems that the package implements this.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 7, 2022, 2:22pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/12 "2022-02-07T14:22:07Z")

</div>

I guess they are doing something like this, which would allow you to dispatch on function types (fun exercise):

```julia
julia> struct MyFunc{Input,Output} end

julia> (f::MyFunc{Input,Output})(x::Input) where {Input,Output} = Output(x)

julia> const myfunc = MyFunc{Int,Float64}()
MyFunc{Int64, Float64}()

julia> myfunc(1)
1.0

julia> const myfunc2 = MyFunc{Int,Int}()
MyFunc{Int64, Int64}()

julia> myfunc2(1)
1

julia> g(f::MyFunc{Int,Float64}) = "This is Int -> Float64"
g (generic function with 1 method)

julia> g(f::MyFunc{Int,Int}) = "This is Int -> Int"
g (generic function with 2 methods)

julia> g(myfunc)
"This is Int -> Float64"

julia> g(myfunc2)
"This is Int -> Int"

```

But maybe this is a XY problem? I don’t see people trying to dispatch on function types very often here.

---

<div class="post-metadata">

**Author:** ![tbeason](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tbeason/32/15898_2.png) [@tbeason](https://discourse.julialang.org/u/tbeason)\
**Post date:** [February 7, 2022, 2:26pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/13 "2022-02-07T14:26:30Z")

</div>

Is your question more of an academic one or do you see something major that you can’t do right now because functions are untyped?

I’ve found one of the best parts of Julia to be that once you really understand the type system you can actually stop worrying about types for many things. Duck typing is great.

---

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 2:27pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/14 "2022-02-07T14:27:56Z")

</div>

More of academic interest I guess. The question came as I was studying Category Theory, and the lecturer used Haskell as an example. I then wondered if it could be done in Julia.

---

<div class="post-metadata">

**Author:** ![sashmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sashmit/32/18791_2.png) [@sashmit](https://discourse.julialang.org/u/sashmit)\
**Post date:** [February 7, 2022, 2:31pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/15 "2022-02-07T14:31:42Z")

</div>

> [@davibarreira](#):
>
> Hmmm, I think I get your point. I was wondering about language’s such as Haskell that do have this function type definition. I mean, what makes it unfeasible in Julia? Is the fact that is dynamic or the multiple dispatch?  
> I’ll try understanding the code in `FunctionWrappers.jl` to see what they are doing, since it seems that the package implements this.

Are you talking about the full type signature?

Eg, for example, the haskell equivalent (I think, typing this on my phone) of goretkin’s code above is:

```julia
foo :: Num a => a -> a
foo x = 2 * x

foo :: [Char] -> Int
foo x = length x

```

of course what’s annoying is that the terms “functions” and 'methods" mean completely different things in different languages

---

<div class="post-metadata">

**Author:** ![Oscar\_Smith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oscar_smith/32/25343_2.png) [@Oscar\_Smith](https://discourse.julialang.org/u/Oscar_Smith)\
**Post date:** [February 7, 2022, 2:54pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/16 "2022-02-07T14:54:40Z")

</div>

I think a lot of the answer is that there isn’t a strong technical reason, but there is a very good social reason. Haskell is a really cool language, but it has an incredibly complicated type system that pretty much requires a basic understanding of category theory (or some group theory) to use effectively.  
Julia’s design is based on a lot of the same category theory as Haskell, but exposing that complexity to the user directly makes it a lot harder to use for people who don’t have experience with abstract math.

---

<div class="post-metadata">

**Author:** ![davibarreira](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/davibarreira/32/20270_2.png) [@davibarreira](https://discourse.julialang.org/u/davibarreira)\
**Post date:** [February 7, 2022, 3:02pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/17 "2022-02-07T15:02:03Z")

</div>

I see. Indeed, perhaps it’s not that useful.  
On a side note, it seems that FunctionWrappers.jl does not enforce type consistency of the domain/codomain. But the solution with Catlab.jl does 🙂 , which is quite nice. I mean, I can do:

```julia
f = FunctionWrapper{Int,Int}((x) -> x)
g = FunctionWrapper{Float64, Float64}((x) -> x)
f∘g

```

But in Catlab, I’d get an error right away.

---

<div class="post-metadata">

**Author:** ![sashmit](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sashmit/32/18791_2.png) [@sashmit](https://discourse.julialang.org/u/sashmit)\
**Post date:** [February 7, 2022, 3:49pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/18 "2022-02-07T15:49:37Z")

</div>

> [@Oscar\_Smith](#):
>
> I think a lot of the answer is that there isn’t a strong technical reason, but there is a very good social reason. Haskell is a really cool language, but it has an incredibly complicated type system that pretty much requires a basic understanding of category theory (or some group theory) to use effectively.  
> Julia’s design is based on a lot of the same category theory as Haskell, but exposing that complexity to the user directly makes it a lot harder to use for people who don’t have experience with abstract math.

I think more important (at least in “everyday” haskell) is the link between haskell (or any typed functional language) and the simply typed lambda calculus: [Simply typed lambda calculus - Wikipedia](https://en.wikipedia.org/wiki/Simply_typed_lambda_calculus)

This does have a link to (cartesian closed) categories.

Julia is not based on the lambda calculus (afaik), nor do I think it makes sense for a high performance lang of it’s type.

Catlab is very impressive, but as far as I can tell, it’s a different interpretation of categories in the context of computing (perhaps even more suited for numerical work, haskell w/ the standard prelude is pretty bad for that).

---

<div class="post-metadata">

**Author:** ![greatpet](https://avatars.discourse-cdn.com/v4/letter/g/e495f1/32.png) [@greatpet](https://discourse.julialang.org/u/greatpet)\
**Post date:** [February 7, 2022, 4:35pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/19 "2022-02-07T16:35:34Z")

</div>

FunctionWrappers.jl is needed if you want to store a function as a data field in a struct without causing type instability. This is the equivalent of function pointers in C, not necessarily some exotic Haskell-like stuff. It would be useful, e.g., if you want to set up a virtual function table manually to emulate single dispatch of classic OOP.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 7, 2022, 5:28pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/20 "2022-02-07T17:28:50Z")

</div>

> [@davibarreira](#):
>
> I was wondering about language’s such as Haskell that do have this function type definition.

Because in Haskell you can’t define multiple methods for the same function except [with parametric polymorphism or type classes](https://wiki.haskell.org/Polymorphism#Ad-hoc_polymorphism). The former is equivalent to a _single_ method definition in Julia with a `where` clause, and the latter _explicitly_ constrains all of the methods (“instances”) to have the same form of type signature.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [February 7, 2022, 5:36pm UTC](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934/21 "2022-02-07T17:36:54Z")

</div>

> [@greatpet](#):
>
> function pointers in C

exactly (or C++), the conclusion being that having typed function pointers doesn’t make a language more haskell, the typing system doesn’t work with these informations (i.e. you can’t specify a function to take only “functions that takes A and spits out B”

[Next page](https://discourse.julialang.org/t/why-julia-doesnt-have-function-types/75934.md?page=2)
