Elixir basics · Lesson 14 (open contents)
01 · Let the code speak02 · Meet six kinds of values03 · Put values together04 · Build a new list05 · Make the shapes match06 · Choose with case07 · Parse a number safely08 · Unpack &1 and the pipe09 · Put code in a project10 · Ask precise true-or-false questions11 · Read and update nested data12 · Count visible text and bytes13 · Let function clauses choose14 · Solve a list twice15 · Choose the smallest clear control form16 · Give domain data a shape17 · Put one tested module in Mix18 · Make success and failure predictable19 · Read and write one real file20 · Take only the data you need21 · Give different data one shared action22 · Write a callback contract23 · Write down the data contract24 · Test behavior and boundaries25 · Turn a project into a command26 · Write the project promise27 · Parse one real line28 · Keep the public API small29 · Make the promise executable30 · Package the edge and leave clues31 · Prove the project is done
ELIXIR · FOUNDATION · LESSON 1425 minutes

Solve a list twice

Compare explicit recursion with `Enum.reduce/3`.

01 · Start with the whole example

Run this first

Run it once, change one input, and compare the new result.

Elixir
# Compare recursion with a library fold
defmodule Totals do
  def sum([]), do: 0
  def sum([head | tail]), do: head + sum(tail)
end

numbers = [1, 2, 3, 4]
{Totals.sum(numbers), Enum.reduce(numbers, 0, fn n, acc -> n + acc end)}
Check the result first
  • Both paths return 10, so the result is {10, 10}.
02 · Take the code apart

Read from the first line down

  1. Read sum([]): Stop at an empty list.
  2. Read sum([head | tail]): Handle one item and the remaining list.
  3. Read Enum.reduce/3: Fold values into one accumulator.
03 · Meet the new symbols

Symbols are not secret signs

sum([])

Stop at an empty list.

sum([head | tail])

Handle one item and the remaining list.

Enum.reduce/3

Fold values into one accumulator.

04 · Ideas inside the code

Match each name to its meaning

01

base clause

A recursive function needs a clause that returns without calling itself.

02

recursive clause

The recursive clause handles one piece and calls itself with a smaller input.

03

fold

Enum.reduce/3 carries an accumulator through a collection.

05 · Make the idea clear

Why these forms are useful

Run the example first. Predict one result, then change one input and run it again.

A recursive function needs a clause that returns without calling itself.

The recursive clause handles one piece and calls itself with a smaller input.

06 · Change it yourself

Close the answer and try

Multiply [2, 3, 4] with Enum.reduce/3.

Practice starting point
Enum.reduce([2, 3, 4], ____, fn number, acc -> ____ end)

Target result: Return 24.

Stuck? Read one hint

Start the accumulator at 1 and multiply it by each number.

After you run it, see one answer
One answer
Enum.reduce([2, 3, 4], 1, fn number, acc -> number * acc end)
Think about it: What stops `Totals.sum/1`?

The sum([]) clause returns 0 without another call.

Take with you

Remember these three lines

  1. 1

    Every recursion needs a stopping clause.

  2. 2

    Make recursive input smaller.

  3. 3

    Prefer clear Enum functions for common collection work.

Lesson completeRun the code once, then mark this lesson as done.