links: Functions in Elixir
Default Arguments
Named functions in Elixir supports default arguments
defmodule Concat do
def join(a, b, sep \\ " ") do
a <> sep <> b
end
end
IO.puts Concat.join("Hello", "world") #=> Hello world
IO.puts Concat.join("Hello", "world", "_") #=> Hello_worldAny expression is allowed to serve as a default value, but it won’t be evaluated during the function definition. Every time the function is invoked and any of it’s default values have to be used, the expression for that default value will be evaluated
defmodule Test do
def dowork(x \\ "hello") do
x
end
end
IO.puts Test.dowork #=> hello
IO.puts Test.dowork 123 #=> 123
IO.puts Test.dowork #=> helloIf a function with multiple clauses has default values, it is required to create a function head(a function definition without a body) for declaring defaults
defmodule Concat do
# A function head declaring defaults
def join(a, b \\ nil, sep \\ " ")
def join(a, b, _sep) when is_nil(b) do
a
end
def join(a, b, sep) do
a <> sep <> b
end
end
IO.puts Concat.join("Hello", "world") #=> Hello world
IO.puts Concat.join("Hello", "world", "_") #=> Hello_world
IO.puts Concat.join("Hello") #=> HelloWhen using default values, one must be careful to avoid overlapping function definitions. consider the following example:
defmodule Concat do
def join(a, b) do
IO.puts "***First join"
a <> b
end
def join(a, b, sep \\ " ") do
IO.puts "***Second join"
a <> sep <> b
end
endElixir will emit the following warning
concat.ex:7: warning: this clause cannot match because a previous clause at line 2 always matches
The compiler is telling us that invoking the join function with two arguments will always choose the first definition of join whereas the second one is only invoked when three arguments are passed.
Removing the default argument, in this case, will fix the warning.
- Any expression can serve as the default value
- Anonymous functions cannot have the default arguments