# Why does Julia have multiple ways to define functions?

**URL:** <https://discourse.julialang.org/t/why-does-julia-have-multiple-ways-to-define-functions/102424>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [August 2, 2023, 11:31pm UTC](https://discourse.julialang.org/t/why-does-julia-have-multiple-ways-to-define-functions/102424 "2023-08-02T23:31:02Z")\
**Posts on this page:** 1\
**Showing post:** 10

<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:** [August 3, 2023, 1:12am UTC](https://discourse.julialang.org/t/why-does-julia-have-multiple-ways-to-define-functions/102424/10 "2023-08-03T01:12:18Z")

</div>

> [@danielwe](#):
>
> it was never obvious to me

Me neither. The `(::typeof(h))` thing is actually very logical if you look up the couple sections on functors and realize that a function is just an instance of a singleton type, that’s not the part that I complain about.

I also prefer if there was only 1 way to do things, but if you try to stick to 1 form instead of the typical usages, you hit parser issues. Let’s take the 4 forms: named `function`, anonymous `function`, named `=`, and anonymous `->` (the latter two take single expressions, not single lines):

> **return type issue for anonymous \`function\` and \`-\>\` forms**
>
> ```julia
> julia> function f(x::Int)::Int 0 end
> f (generic function with 1 method)
> 
> julia> function (x::Int)::Int 0 end # comma or more arguments does not help
> ERROR: syntax: ambiguous signature in function definition. Try adding a comma if this is a 1-argument anonymous function...
> 
> julia> f(x::Int)::Int = 0
> f (generic function with 1 method)
> 
> julia> ((x::Int)::Int) -> 0 # even parentheses doesn't help
> ERROR: syntax: "x::Int" is not a valid function argument name around...
> 
> ```

> **return type and \`where\` clause issue for anonymous \`function\`, \`=\`, and \`-\>\` forms**
>
> ```julia
> julia> function f(x::T)::Int where T 0 end
> f (generic function with 1 method)
> 
> julia> function (x::T)::Int where T 0 end # comma or more arguments does not help
> ERROR: syntax: ambiguous signature in function definition. Try adding a comma if this is a 1-argument anonymous function...
> 
> julia> f(x::T)::Int where T = 0
> ERROR: UndefVarError: T not defined
> 
> julia> (f(x::T)::Int) where T = 0 # need parentheses to work
> f (generic function with 1 method)
> 
> julia> ((x::T)::Int) where T -> 0 # parentheses doesn't help
> ERROR: syntax: invalid variable expression in "where" around...
> 
> ```

> **single-line parentheses, brackets, or braces expression issue for named and anonymous \`function\` forms**
>
> ```julia
> julia> function f(x) (x,) end
> ERROR: syntax: space before "(" not allowed in "f(x) (" at...
> 
> julia> function f(x)(x,) end # ^it thought (x,) was the arguments expression
> ERROR: syntax: invalid function name "f(x)" around
> 
> julia> function f(x); (x,) end # need new line or ; to work
> f (generic function with 1 method)
> 
> julia> function (x); (x,) end # need new line or ; to work
> #1 (generic function with 1 method)
> 
> julia> f(x) = (x,)
> f (generic function with 1 method)
> 
> julia> (x) -> (x,)
> #3 (generic function with 1 method)
> 
> ```

I think it should be possible to patch these issues, since we can identify the proper rules: {optional name or (var::type) parentheses}{no space here!!}{arguments parentheses}::{optional return type} where {optional arguments’ type parameters brace}{function body} {end}. But patching the parser is probably really hard. I think if somebody (me) would like to use 1 form for everything, it’d be a patched `function` block.

---

_[View the full topic](https://discourse.julialang.org/t/why-does-julia-have-multiple-ways-to-define-functions/102424)._
