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!
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
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")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With