2

Have a simple summation of values in a list:

defmodule ListMath do
  def sum_list([head | tail], accumulator) do
    sum_list(tail, head + accumulator)
  end

  def sum_list([], accumulator) do
    accumulator
  end
end

But calling this requires passing in a value for accumulator, like:

IO.puts ListMath.sum_list([4,5,6],0)
15

I'd like to call it like this:

IO.puts ListMath.sum_list([4,5,6])
** (UndefinedFunctionError) function ListMath.sum_list/1 is undefined...

If I change it to take a default value for the accumulator param, it no longer compiles:

defmodule ListMath do
  def sum_list([head | tail], accumulator // 0) do
    sum_list(tail, head + accumulator)
  end

  def sum_list([], accumulator) do
    accumulator
  end
end
  • I'm using Elixir 1.3.4.
  • I've seen this question back in Elixir 0.12 which seems quite related but still don't understand.
Community
  • 1
  • 1
joseph.hainline
  • 24,829
  • 18
  • 53
  • 70

1 Answers1

4

You are on the right path there with the last example.

Default values in elixir are dictated by \\ not //. So you in your case:

defmodule ListMath do
  def sum_list([head | tail], accumulator \\ 0) do
    sum_list(tail, head + accumulator)
  end

  def sum_list([], accumulator) do
    accumulator
  end
end

You can even have whats called a function head definition which dictates the expected variables for the method e.g.

defmodule ListMath do
  def sum_list(list, acc \\ 0)
  def sum_list([head | tail], accumulator) do
    sum_list(tail, head + accumulator)
  end

  def sum_list([], accumulator) do
    accumulator
  end
end

That way from a glance you can tell what the method function head looks like without having to find where the default value is created.

Harrison Lucas
  • 2,829
  • 19
  • 25