Elixir basics · Lesson 07 (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 · SCRATCH · LESSON 0730 minutes

Parse a number safely

Trim text, turn it into an integer, and return a clear error for invalid input.

01 · Start with the whole example

Parse valid text and catch invalid text

String.trim/1 names a function in documentation. String.trim(text) calls it with one argument.

Elixir
# Bind a complete parser to parse_integer
parse_integer = fn text ->
  try do
    clean = String.trim(text)
    {:ok, String.to_integer(clean)}
  rescue
    ArgumentError -> {:error, :not_an_integer}
  end
end

# Run both paths
{parse_integer.(" 42 "), parse_integer.("not-a-number")}
Check the result first
  • The valid input is trimmed to "42", parsed, and returned as {:ok, 42}.
  • The invalid input raises ArgumentError inside the try block.
  • The rescue clause turns that exception into {:error, :not_an_integer}.
02 · Take the code apart

Read from the first line down

  1. String.trim/1 and String.to_integer/1 are documentation names. Calls use parentheses and do not include /1.
  2. String.to_integer(clean) returns an integer for valid text and raises ArgumentError for invalid text.
  3. The rescue clause handles that expected exception and leaves unrelated exceptions visible.
  4. Both paths return tagged tuples: {:ok, integer} or {:error, :not_an_integer}.
03 · Meet the new symbols

Symbols are not secret signs

String.trim/1

The name-and-arity form used in documentation: module String, function trim, one argument.

String.to_integer/1

A one-argument function that parses integer text or raises ArgumentError.

fn text -> ... end

Create a full anonymous function whose argument is called text.

rescue ArgumentError ->

Handle only an ArgumentError raised inside the try block.

04 · Ideas inside the code

Match each name to its meaning

01

arity

The number of arguments a function takes. /1 says that both String.trim/1 and String.to_integer/1 take one argument.

02

anonymous function

A function written with fn ... end and bound to a name such as parse_integer.

03

try/rescue

Run code that may raise, then turn a named exception into a normal result.

05 · Make the idea clear

Why these forms are useful

String.trim/1 removes whitespace from both ends of a string. String.to_integer/1 turns clean integer text into an integer, but raises ArgumentError when the text is invalid.

An anonymous function lets us keep those steps together. Bind it to parse_integer, then call it with a dot: parse_integer.(text).

try/rescue handles the expected conversion error. The parser returns a tagged tuple for both paths, so the caller gets data instead of a crash.

DESIGN DECISION

Why this shape?

Why put /1 after a function name?

Choice

BEAM identifies an entry point by module, function name, and argument count. trim/1 means the trim function that takes one argument.

Cost and boundary

The same name with another argument count is another function. Default arguments generate arities at compile time; they do not make calls loosely sized.

A FAMILIAR POINT OF VIEW

Coming from Java, Python, or JavaScript

Java

Familiar starting point
Methods can overload by parameter types and count.
What BEAM changes
BEAM first finds a name and arity, then clauses can match data shapes.
False friend
run/1 and run/2 are distinct entry points.

Python

Familiar starting point
One function often uses defaults or *args.
What BEAM changes
Arity is part of a function's identity and appears in exports and docs.
False friend
Leaving out an argument does not discover another arity automatically.

JavaScript

Familiar starting point
Functions often tolerate missing or extra arguments.
What BEAM changes
A BEAM call must find the exact arity.
False friend
&1 is a capture placeholder; it is not another spelling of /1.
06 · Change it yourself

Close the answer and try

Complete safe_number so " 7 " returns {:ok, 7} and "seven" returns {:error, :not_an_integer}.

Practice starting point
safe_number = fn text ->
  try do
    clean = String.____(text)
    {:ok, String.____(clean)}
  rescue
    ____ -> {:error, :not_an_integer}
  end
end

{safe_number.(" 7 "), safe_number.("seven")}

Target result: The result should be {{:ok, 7}, {:error, :not_an_integer}}.

Stuck? Read one hint

Use trim, to_integer, and the exception name ArgumentError.

After you run it, see one answer
One answer
# Handle only the conversion error we expect
safe_number = fn text ->
  try do
    clean = String.trim(text)
    {:ok, String.to_integer(clean)}
  rescue
    ArgumentError -> {:error, :not_an_integer}
  end
end

{safe_number.(" 7 "), safe_number.("seven")}
Think about it: Why does the rescue clause name `ArgumentError` instead of catching every exception?

The parser expects one conversion error. Handling only ArgumentError keeps unrelated mistakes visible so they can be fixed.

Take with you

Remember these three lines

  1. 1

    Module.function/arity is a documentation name; Module.function(argument) is a call.

  2. 2

    Bind a full anonymous function with fn ... end and call it with .().

  3. 3

    Rescue the expected conversion error and return a tagged result.

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