So, here it suggest writing functions without heads
for default arguments.
But, understandably, Dialyzer complains.
Is it or should it be preferable to default by say
def a(b), do: a b, 2
def a(b,c), do: ...
So, here it suggest writing functions without heads
for default arguments.
But, understandably, Dialyzer complains.
Is it or should it be preferable to default by say
def a(b), do: a b, 2
def a(b,c), do: ...
I don’t believe the getting started guide suggests that it’s preferable to not use default arguments, if I understand your question correctly.
Dialyzer seemed okay with this (silly) function, which has an optional argument that may be one of multiple types:
@type int_string :: integer() | binary()
@spec increment(integer(), int_string()) :: integer()
def increment(number, by \\ 1)
def increment(number, by) when is_integer(by) do
number + 1
end
def increment(number, by) when is_binary(by) do
number + 1
end
def runit() do
increment(1)
increment(1, 4)
increment(1, "4")
end
As to whether it’s clearer or more idiomatic to expose two functions with different arities instead, I don’t know. I’m curious what others think.
In fact the first example is only a sugared version of the second:
# 1. version
def foo(a, b \\ 0)
def foo(a, b), do: a + b
# 2. version
def foo(a), do: foo(a, 0)
def foo(a, b), do: a + b
So I do prefer to use the first version in most of the cases, but only iff I really want to expose both aritys. Lets consider another function, which operates on a list and builds up another list. It is common to write one function taking one list and a function taking two lists, where the second function does all the work and the first does just call the second. In this case I want to have */2-version of the function private and only the first version exposed.