Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are there two ways to define named functions in elixir?

Tags:

elixir

In elixir, one could define the "sum" function in two different ways:

def sum, do: 0
def sum(a), do: a
def sum(a, b), do: a + b
def sum(a, b, c), do: a + b + c

or

def sum() do 0 end
def sum(a) do a end
def sum(a,b) do a + b end
def sum(a,b,c) do a + b+ c end

I can even mix the two approaches:

def sum() do 0 end
def sum(a) do a end
def sum(a,b) do a + b end
def sum(a,b,c), do: a + b + c

My questions are: Why are there two ways of achieving the same? Is the second one preferred in the case of inline functions? What are the advantages of either of them?

Thanks in advance!

like image 951
Santiago Ignacio Poli Avatar asked Oct 28 '15 15:10

Santiago Ignacio Poli


Video Answer


2 Answers

The do...end format is syntactic sugar for the do: format.

This applies not only to functions, also to if, case, cond, etc.

case 1, do: (1 -> "a")

vs

case 1 do
  1 -> "a"
end

In general, the do...end format is preferred unless the function definitions are short enough to fit on one line.

do in this case is actually a parameter in a keyword list. The implementation of the if macro looks something like:

do_clause = Keyword.get(clauses, :do, nil)
else_clause = Keyword.get(clauses, :else, nil)

This gets the expressions inside the do...else...end block:

if foo do
  #this gets stored in do_clause
else
  #this gets stored in else_clause
end

Note the implementation of if has change slightly, you can see the version I am referring to at https://github.com/elixir-lang/elixir/blob/1a7412502fd581da8ef1378fcd5a057ab96378f7/lib/elixir/lib/kernel.ex#L2294

like image 102
Gazler Avatar answered Sep 28 '22 17:09

Gazler


It's for programmer convenience. Defining the functions in any of the mentioned ways wont make any difference to the actual function.

do..end is syntactic sugar for do:. Which means it is a syntax that makes things easier to read or express. It makes the language "sweeter" for human use: things can be expressed more clearly, more concisely, or in an alternative style that some may prefer.[wikipiedia]

In general, do: syntax is preferred for single line, and do..end for multiple lines

def count(limit), do: count(1,limit)

defp count(current,limit) when current <= limit do
    IO.inspect(current)
    count(current+1,limit)
end

#The underscore means we dont care what the arguments are
defp count(_,_), do: IO.puts("finished")
like image 21
coderVishal Avatar answered Sep 28 '22 18:09

coderVishal