Elixir basics · Lesson 13 (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 1325 minutes

Let function clauses choose

Define named functions with defaults, patterns, and guards.

01 · Start with the whole example

Run this first

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

Elixir
# Define one public function with two clauses
defmodule Fare do
  def price(age, discount \\ 0)
  def price(age, _discount) when age < 12, do: 5
  def price(_age, discount), do: 10 - discount
end

{Fare.price(10), Fare.price(20, 2)}
Check the result first
  • The calls return {5, 8}.
02 · Take the code apart

Read from the first line down

  1. Read def price(age, discount \\ 0): Declare a default second argument.
  2. Read when age < 12: Choose this clause only when its guard passes.
  3. Read _discount: Accept an argument that this clause does not use.
03 · Meet the new symbols

Symbols are not secret signs

def price(age, discount \\ 0)

Declare a default second argument.

when age < 12

Choose this clause only when its guard passes.

_discount

Accept an argument that this clause does not use.

04 · Ideas inside the code

Match each name to its meaning

01

function clause

Several definitions with the same name and arity can accept different patterns or guards.

02

guard

A guard adds a permitted check after when.

03

default argument

\\ supplies an argument when the caller leaves it out.

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.

Several definitions with the same name and arity can accept different patterns or guards.

A guard adds a permitted check after when.

06 · Change it yourself

Close the answer and try

Add Label.name/1 clauses for zero and positive numbers.

Practice starting point
defmodule Label do
  def name(0), do: ____
  def name(number) when number > 0, do: ____
end

{Label.name(0), Label.name(3)}

Target result: Return {:zero, :positive}.

Stuck? Read one hint

Return the atoms :zero and :positive.

After you run it, see one answer
One answer
defmodule Label do
  def name(0), do: :zero
  def name(number) when number > 0, do: :positive
end

{Label.name(0), Label.name(3)}
Think about it: Which matching clause runs?

Elixir tries clauses from top to bottom and runs the first match whose guard passes.

Take with you

Remember these three lines

  1. 1

    Name and arity identify a function.

  2. 2

    Patterns and guards select clauses.

  3. 3

    Defaults belong in a function head when clauses follow.

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