Say we have a function:
def func(a, b \\ 0) do
I believe this generates func/1 and func/2. Is it possible to make func/2 private without spinning out a helper/implementation/do_func/2 equivalent?
Say we have a function:
def func(a, b \\ 0) do
I believe this generates func/1 and func/2. Is it possible to make func/2 private without spinning out a helper/implementation/do_func/2 equivalent?
Does not seem to be possible, no.
You can mix def and defp with different arities:
defmodule Foo do
def bar(arg), do: bar(arg, 42)
defp bar(arg, arg2), do: {arg, arg2}
end
iex(6)> Foo.bar(1)
{1, 42}
iex(7)> Foo.bar(1, 2)
** (UndefinedFunctionError) function Foo.bar/2 is undefined or private. Did you mean:
* bar/1
Foo.bar(1, 2)
iex:7: (file)
That is where I landed, that the default parameter has to be expressed differently.
Would it be more idiomatic to change the name of the private function?
I’d say yes. It’s just accidental that the private one happens to have a different arity, which allows for it being named the same.
This is just because what defines a function is its module, name and arity. So foo/1 and foo/2 are 2 different functions that just happen to have the same name.
I guess my more general question was “is it possible to affect implied functions created by default parameters”. An example that doesn’t work:
defmodule Foo do
def bar(arg)
defp bar(arg, arg2 \\ 0), do: {arg, arg2}
end
error: defp bar/1 already defined as def in iex:5
I’ve always found it helpful to think of \\ as a simple convenience rather than “default arguments.” All it’s doing is turning this:
def bar(a, b \\ 0) do
a + b
end
into this:
def bar(a) do
bar(a, 0)
end
def bar(a, b) do
a + b
end
The easiest and clearest way to get what you want it to just write it out manually as suggested.
So the short answer is no, but technically yes if you consider redefining def and changing how \\ works ![]()