All ways to define functions in Julia?

I tried to list all the ways one can define functions in Julia. Some are practical, some are silly but collecting them all is fun.

Planning to make a video for fun exploring this.

``````
function name(a, b)
a + b
end

name(a,b) = a + b

if false
name = (a,b) -> a+b
end

name2 = (a,b) -> a+b

name3 = function(a, b)
a+b
end

macro defining_function(fnname)
:(
function \$fnname(a, b)
a+b
end
)
end

@defining_function name4

function fn_generator()
function (a, b)
a*b
end
end

name5 = fn_generator()

function fn_generator2()
function name(a, b)
a*b
end
end

# what would happen here?
fn_generator2()

``````

edit

Thanks to @thofma for `a+b=a*b`

I just thought of `LambdaFn.jl` https://github.com/haberdashPI/LambdaFn.jl which allows

`@lf _+_`

9 Likes

`a * b = a + b`

16 Likes

I am shocked and horrified.

6 Likes

Mind blown!

1 Like
``````name3 = function(a, b)
a+b
end
``````

This one is also surprising to me. Is that described somewhere in the manual? Itâ€™s rather reminiscent of the way you define functions in Râ€¦

Yeah. Itâ€™s got interesting properties though.

the RHS is just another syntax to define an anonymous function so itâ€™s the same as

``````name3 = (a,b) -> a+b
``````

But `typeof(name3)` is NOT `name`! Itâ€™s the â€śnameâ€ť given to the anonymous function.

Interestingly, `@edit name3(1,2)` can stil find it

1 Like

This is very interesting as well

``````function (x::Int)(y)

x+y

end

x = 2

x(2)
``````

what is this called? `function (x::Int)(y)`

Functors, typically.

https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects

4 Likes

Can we change that? afaik itâ€™s only C++ that calls those â€śfunctorsâ€ť and everywhere else â€śfunctorsâ€ť are a different thing. â€śCallablesâ€ť is a good and widely used name.

6 Likes
``````struct Name <: Function end

(::Name)(a,b) = a+b

const name = Name()
``````
4 Likes

yeah, i got a pure math degree so functor is a totally different thing to me I think.

3 Likes

What do you mean by that example? If you enter it at the Julia prompt, then `name` is not defined afterwards.

Just the content within false

``````function fn_generator()
if true
f() = 0
else
f(x, y) = x+y
end
end

name = fn_generator()

name(1,2)   # 3
``````

cool

This is the same as

``````function fn_generator()
f(x, y) = x+y
end
``````

since `true` branch is ignored. And original version should produce warning in 1.6 or 1.7

This is surprising. What is happening here?

The last definition of `f` is used. Some may see this as a bug. To avoid this â€śbehaviourâ€ť use anonymous functions instead.

``````julia> function fn_generator()
if true
f = () -> 0
else
f = (x, y) -> x+y
end
end
fn_generator (generic function with 1 method)

julia> name = fn_generator()
#10 (generic function with 1 method)

julia> name()
0
``````
5 Likes

I donâ€™t see a warning for either version. Can you demonstrate this?

UPDATE:

Ah, I see, the function signature must be the same (it isnâ€™t in the example above):

``````julia> function fn_generator()
if true
f() = 0
else
f() = 2
end
end
WARNING: Method definition f() in module Main at REPL[1]:3 overwritten at REPL[1]:5.
fn_generator (generic function with 1 method)
``````
3 Likes