Basic Types

Integers are arbitrary precision: 2 ** 200 works.

42, -7, 1_000_000, 0xFF, 0o17, 0b1010, ?a (code point = 97)

3.14, 1.0e-10 (64-bit double; must have digit before & after .) true, false (atoms!)

:ok, :error, :"with spaces", Elixir.String nil (also an atom) "hello" — UTF-8 encoded binary

~c"hello" (list of code points, formerly 'hello') %{a: 1, "b" => 2} fn x -> x * 2 end PID / Port / Reference self(), make_ref()

4.1 Integers & floats

Integers are arbitrary precision: 2 ** 200 works.

10 / 2          # 5.0   — `/` always returns a float
div(10, 3)      # 3     — integer division
rem(10, 3)      # 1     — remainder
Integer.mod(-5, 3)   # 1 (modulo, sign of divisor)
2 ** 10         # 1024  (Elixir 1.13+)
round(3.6)      # 4
trunc(3.6)      # 3
Float.round(3.14159, 2)  # 3.14
Integer.parse("42abc")   # {42, "abc"}
String.to_integer("42")  # 42
Integer.to_string(255, 16)  # "FF"
Integer.digits(123)      # [1, 2, 3]

4.2 Atoms

Atoms are constants whose value is their name. Used for tags (:ok, :error), options, module names.

⚠️ Atoms are not garbage collected (default limit ~1,048,576). Never call String.to_atom/1 on untrusted input — use String.to_existing_atom/1.

:apple == :apple    # true
is_atom(:ok)        # true
is_atom(true)       # true — booleans are atoms
is_atom(String)     # true — module names are atoms (:"Elixir.String")

4.3 Strings (quick intro)

"hello" <> " " <> "world"      # concatenation
name = "Ann"
"Hello, #{name}!"               # interpolation
String.length("héllo")          # 5 (graphemes)
byte_size("héllo")              # 6 (bytes)
String.upcase("abc")
"""
Multi-line
heredoc string
"""

4.4 Type checks

is_integer/1, is_float/1, is_number/1, is_atom/1, is_boolean/1, is_binary/1, is_bitstring/1, is_list/1, is_tuple/1, is_map/1, is_map_key/2, is_function/1, is_function/2, is_pid/1, is_reference/1, is_port/1, is_nil/1, is_struct/1, is_exception/1.