softshipper
softshipper

Reputation: 34071

Anonymous function cannot mix clauses

I have created a module that looks as follow:

defmodule Sum do

    def sum(x,y) do
        x + y
    end

    def sum(x) do
        x
    end

end

and it works as I expected with pattern matching of course:

iex(2)> Sum.sum(3)
3
iex(3)> Sum.sum(3,5)
8

When I define an anonymous function like:

iex(1)> sum = fn
...(1)>  x, y -> x + y
...(1)>  x -> x
...(1)> end
** (CompileError) iex:1: cannot mix clauses with different arities in function definition

then the compiler complain. Why I can not mix with different arities, the example above with module it works like a charm.

Upvotes: 5

Views: 1046

Answers (2)

CoderDennis
CoderDennis

Reputation: 13837

sum/2 and sum/1 are actually 2 different functions. The one that gets executed isn't chosen by pattern matching. The compiler knows which one to call based on how many arguments you specified.

As others have noted, an anonymous function may have different clauses, but they must have the same arity because you are just creating a single function.

Consider the following code:

defmodule Sum do

    def sum(x,y) where is_integer(y) do
        x + y
    end

    def sum(x,_) do
        x
    end

end

This creates 2 clauses of the single sum/2 function and which one is called will be determined by pattern matching and the guard clause like this:

iex> Sum.sum(3,nil)
3
iex> Sum.sum(3,5)
8
iex> Sum.sum(5,:foo)
5

You would be able to do the same thing with an anonymous function.

Upvotes: 11

Onorio Catenacci
Onorio Catenacci

Reputation: 15293

Take a look at this prior answer:

https://stackoverflow.com/a/18023790/2820

It discusses exactly your question. You can have multiple clauses in a lambda but the clauses all have to match in arity.

Upvotes: 1

Related Questions