Kernel
Provides the default macros and functions Elixir imports into your environment.
These macros and functions can be skipped or cherry-picked via the import/2
macro. For instance, if you want to tell Elixir not to import the if/2
macro, you can do:
import Kernel, except: [if: 2]
Elixir also has special forms that are always imported and cannot be skipped. These are described in Kernel.SpecialForms
.
Some of the functions described in this module are inlined by the Elixir compiler into their Erlang counterparts in the :erlang
module. Those functions are called BIFs (builtin internal functions) in Erlang-land and they exhibit interesting properties, as some of them are allowed in guards and others are used for compiler optimizations.
Most of the inlined functions can be seen in effect when capturing the function:
iex> &Kernel.is_atom/1 &:erlang.is_atom/1
Those functions will be explicitly marked in their docs as “inlined by the compiler”.
Summary
Functions
- !arg
-
Boolean not
- left != right
-
Returns
true
if the two items are not equal - left !== right
-
Returns
true
if the two items do not match - left && right
-
Provides a short-circuit operator that evaluates and returns the second expression only if the first one evaluates to
true
(i.e., it is neithernil
norfalse
). Returns the first expression otherwise - left * right
-
Arithmetic multiplication
- +value
-
Arithmetic unary plus
- left + right
-
Arithmetic addition
- left ++ right
-
Concatenates two lists
- -value
-
Arithmetic unary minus
- left - right
-
Arithmetic subtraction
- left -- right
-
Removes the first occurrence of an item on the left list for each item on the right
- first..last
-
Returns a range with the specified start and end
- left / right
-
Arithmetic division
- left < right
-
Returns
true
if left is less than right - left <= right
-
Returns
true
if left is less than or equal to right - left <> right
-
Concatenates two binaries
- left == right
-
Returns
true
if the two items are equal - left === right
-
Returns
true
if the two items are match - left =~ right
-
Matches the term on the left against the regular expression or string on the right. Returns
true
ifleft
matchesright
(if it’s a regular expression) or containsright
(if it’s a string) - left > right
-
Returns
true
if left is more than right - left >= right
-
Returns
true
if left is more than or equal to right - @expr
-
Reads and writes attributes of the current module
- abs(number)
-
Returns an integer or float which is the arithmetical absolute value of
number
- alias!(alias)
-
When used inside quoting, marks that the given alias should not be hygienized. This means the alias will be expanded when the macro is expanded
- left and right
-
Boolean and
- apply(fun, args)
-
Invokes the given
fun
with the list of argumentsargs
- apply(module, fun, args)
-
Invokes the given
fun
frommodule
with the list of argumentsargs
- binary_part(binary, start, length)
-
Extracts the part of the binary starting at
start
with lengthlength
. Binaries are zero-indexed - binding(context \\ nil)
-
Returns the binding for the given context as a keyword list
- bit_size(bitstring)
-
Returns an integer which is the size in bits of
bitstring
- byte_size(bitstring)
-
Returns the number of bytes needed to contain
bitstring
- def(call, expr \\ nil)
-
Defines a function with the given name and body
- defdelegate(funs, opts)
-
Defines a function that delegates to another module
- defexception(fields)
-
Defines an exception
- defimpl(name, opts, do_block \\ [])
-
Defines an implementation for the given protocol
- defmacro(call, expr \\ nil)
-
Defines a macro with the given name and body
- defmacrop(call, expr \\ nil)
-
Defines a private macro with the given name and body
- defmodule(alias, list)
-
Defines a module given by name with the given contents
- defoverridable(keywords)
-
Makes the given functions in the current module overridable
- defp(call, expr \\ nil)
-
Defines a private function with the given name and body
- defprotocol(name, list)
-
Defines a protocol
- defstruct(fields)
-
Defines a struct
- destructure(left, right)
-
Destructures two lists, assigning each term in the right one to the matching term in the left one
- div(left, right)
-
Performs an integer division
- elem(tuple, index)
-
Gets the element at the zero-based
index
intuple
- exit(reason)
-
Stops the execution of the calling process with the given reason
- function_exported?(module, function, arity)
-
Returns
true
ifmodule
is loaded and contains a publicfunction
with the givenarity
, otherwisefalse
- get_and_update_in(path, fun)
-
Gets a value and updates a nested data structure via the given
path
- get_and_update_in(data, keys, fun)
-
Gets a value and updates a nested structure
- get_in(data, keys)
-
Gets a value from a nested structure
- hd(list)
-
Returns the head of a list; raises
ArgumentError
if the list is empty - if(condition, clauses)
-
Provides an
if/2
macro - left in right
-
Checks if the element on the left-hand side is a member of the collection on the right-hand side
- inspect(arg, opts \\ [])
-
Inspects the given argument according to the
Inspect
protocol. The second argument is a keyword list with options to control inspection - is_atom(term)
-
Returns
true
ifterm
is an atom; otherwise returnsfalse
- is_binary(term)
-
Returns
true
ifterm
is a binary; otherwise returnsfalse
- is_bitstring(term)
-
Returns
true
ifterm
is a bitstring (including a binary); otherwise returnsfalse
- is_boolean(term)
-
Returns
true
ifterm
is either the atomtrue
or the atomfalse
(i.e., a boolean); otherwise returnsfalse
- is_float(term)
-
Returns
true
ifterm
is a floating point number; otherwise returnsfalse
- is_function(term)
-
Returns
true
ifterm
is a function; otherwise returnsfalse
- is_function(term, arity)
-
Returns
true
ifterm
is a function that can be applied witharity
number of arguments; otherwise returnsfalse
- is_integer(term)
-
Returns
true
ifterm
is an integer; otherwise returnsfalse
- is_list(term)
-
Returns
true
ifterm
is a list with zero or more elements; otherwise returnsfalse
- is_map(term)
-
Returns
true
ifterm
is a map; otherwise returnsfalse
- is_nil(term)
-
Returns
true
ifterm
isnil
,false
otherwise - is_number(term)
-
Returns
true
ifterm
is either an integer or a floating point number; otherwise returnsfalse
- is_pid(term)
-
Returns
true
ifterm
is a pid (process identifier); otherwise returnsfalse
- is_port(term)
-
Returns
true
ifterm
is a port identifier; otherwise returnsfalse
- is_reference(term)
-
Returns
true
ifterm
is a reference; otherwise returnsfalse
- is_tuple(term)
-
Returns
true
ifterm
is a tuple; otherwise returnsfalse
- length(list)
-
Returns the length of
list
- macro_exported?(module, macro, arity)
-
Returns
true
ifmodule
is loaded and contains a publicmacro
with the givenarity
, otherwisefalse
- make_ref()
-
Returns an almost unique reference
- map_size(map)
-
Returns the size of a map
- match?(pattern, expr)
-
A convenience macro that checks if the right side (an expression) matches the left side (a pattern)
- max(first, second)
-
Returns the biggest of the two given terms according to Erlang’s term ordering. If the terms compare equal, the first one is returned
- min(first, second)
-
Returns the smallest of the two given terms according to Erlang’s term ordering. If the terms compare equal, the first one is returned
- node()
-
Returns an atom representing the name of the local node. If the node is not alive,
:nonode@nohost
is returned instead - node(arg)
-
Returns the node where the given argument is located. The argument can be a pid, a reference, or a port. If the local node is not alive,
:nonode@nohost
is returned - not arg
-
Boolean not
- left or right
-
Boolean or
- pop_in(path)
-
Pops a key from the nested structure via the given
path
- pop_in(data, keys)
-
Pops a key from the given nested structure
- put_elem(tuple, index, value)
-
Inserts
value
at the given zero-basedindex
intuple
- put_in(path, value)
-
Puts a value in a nested structure via the given
path
- put_in(data, keys, value)
-
Puts a value in a nested structure
- raise(msg)
-
Raises an exception
- raise(exception, attrs)
-
Raises an exception
- rem(left, right)
-
Computes the remainder of an integer division
- reraise(msg, stacktrace)
-
Raises an exception preserving a previous stacktrace
- reraise(exception, attrs, stacktrace)
-
Raises an exception preserving a previous stacktrace
- round(number)
-
Rounds a number to the nearest integer
- self()
-
Returns the pid (process identifier) of the calling process
- send(dest, msg)
-
Sends a message to the given
dest
and returns the message - sigil_C(term, modifiers)
-
Handles the sigil
~C
- sigil_D(date, modifiers)
-
Handles the sigil
~D
for dates - sigil_N(date, modifiers)
-
Handles the sigil
~N
for naive date times - sigil_R(term, modifiers)
-
Handles the sigil
~R
- sigil_S(term, modifiers)
-
Handles the sigil
~S
- sigil_T(date, modifiers)
-
Handles the sigil
~T
for times - sigil_W(term, modifiers)
-
Handles the sigil
~W
- sigil_c(term, modifiers)
-
Handles the sigil
~c
- sigil_r(term, modifiers)
-
Handles the sigil
~r
- sigil_s(term, modifiers)
-
Handles the sigil
~s
- sigil_w(term, modifiers)
-
Handles the sigil
~w
- spawn(fun)
-
Spawns the given function and returns its pid
- spawn(module, fun, args)
-
Spawns the given module and function passing the given args and returns its pid
- spawn_link(fun)
-
Spawns the given function, links it to the current process and returns its pid
- spawn_link(module, fun, args)
-
Spawns the given module and function passing the given args, links it to the current process and returns its pid
- spawn_monitor(fun)
-
Spawns the given function, monitors it and returns its pid and monitoring reference
- spawn_monitor(module, fun, args)
-
Spawns the given module and function passing the given args, monitors it and returns its pid and monitoring reference
- struct(struct, kv \\ [])
-
Creates and updates structs
- struct!(struct, kv \\ [])
-
Similar to
struct/2
but checks for key validity - throw(term)
-
A non-local return from a function. Check
Kernel.SpecialForms.try/1
for more information - tl(list)
-
Returns the tail of a list. Raises
ArgumentError
if the list is empty - to_charlist(arg)
-
Converts the argument to a charlist according to the
List.Chars
protocol - to_string(arg)
-
Converts the argument to a string according to the
String.Chars
protocol - trunc(number)
-
Returns the integer part of
number
- tuple_size(tuple)
-
Returns the size of a tuple
- unless(condition, clauses)
-
Provides an
unless
macro - update_in(path, fun)
-
Updates a nested structure via the given
path
- update_in(data, keys, fun)
-
Updates a key in a nested structure
- use(module, opts \\ [])
-
Uses the given module in the current context
- var!(var, context \\ nil)
-
When used inside quoting, marks that the given variable should not be hygienized
- left |> right
-
Pipe operator
- left || right
-
Provides a short-circuit operator that evaluates and returns the second expression only if the first one does not evaluate to
true
(i.e., it is eithernil
orfalse
). Returns the first expression otherwise
Functions
!arg (macro)
Boolean not.
Receives any argument (not just booleans) and returns true
if the argument is false
or nil
; returns false
otherwise.
Not allowed in guard clauses.
Examples
iex> !Enum.empty?([]) false iex> !List.first([]) true
left != right
term != term :: boolean
Returns true
if the two items are not equal.
This operator considers 1 and 1.0 to be equal. For match comparison, use !==
instead.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 != 2 true iex> 1 != 1.0 false
left !== right
term !== term :: boolean
Returns true
if the two items do not match.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 !== 2 true iex> 1 !== 1.0 true
left && right (macro)
Provides a short-circuit operator that evaluates and returns the second expression only if the first one evaluates to true
(i.e., it is neither nil
nor false
). Returns the first expression otherwise.
Not allowed in guard clauses.
Examples
iex> Enum.empty?([]) && Enum.empty?([]) true iex> List.first([]) && true nil iex> Enum.empty?([]) && List.first([1]) 1 iex> false && throw(:bad) false
Note that, unlike and/2
, this operator accepts any expression as the first argument, not only booleans.
left * right
number * number :: number
Arithmetic multiplication.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 * 2 2
+value
+number :: number
Arithmetic unary plus.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> +1 1
left + right
number + number :: number
Arithmetic addition.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 + 2 3
left ++ right
list ++ term :: maybe_improper_list
Concatenates two lists.
The complexity of a ++ b
is proportional to length(a)
, so avoid repeatedly appending to lists of arbitrary length, e.g. list ++ [item]
.
Instead, consider prepending via [item | rest]
and then reversing.
Inlined by the compiler.
Examples
iex> [1] ++ [2, 3] [1, 2, 3] iex> 'foo' ++ 'bar' 'foobar'
-value
-number :: number
Arithmetic unary minus.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> -2 -2
left - right
number - number :: number
Arithmetic subtraction.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 - 2 -1
left -- right
list -- list :: list
Removes the first occurrence of an item on the left list for each item on the right.
The complexity of a -- b
is proportional to length(a) * length(b)
, meaning that it will be very slow if both a
and b
are long lists. In such cases, consider converting each list to a MapSet
and using MapSet.difference/2
.
Inlined by the compiler.
Examples
iex> [1, 2, 3] -- [1, 2] [3] iex> [1, 2, 3, 2, 1] -- [1, 2, 2] [3, 1]
first..last (macro)
Returns a range with the specified start and end.
Both ends are included.
Examples
iex> 0 in 1..3 false iex> 1 in 1..3 true iex> 2 in 1..3 true iex> 3 in 1..3 true
left / right
number / number :: float
Arithmetic division.
The result is always a float. Use div/2
and rem/2
if you want an integer division or the remainder.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 / 2 0.5 iex> 2 / 1 2.0
left < right
term < term :: boolean
Returns true
if left is less than right.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 < 2 true
left <= right
term <= term :: boolean
Returns true
if left is less than or equal to right.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 <= 2 true
left <> right (macro)
Concatenates two binaries.
Examples
iex> "foo" <> "bar" "foobar"
The <>
operator can also be used in pattern matching (and guard clauses) as long as the first part is a literal binary:
iex> "foo" <> x = "foobar" iex> x "bar"
x <> "bar" = "foobar"
would have resulted in a CompileError
exception.
left == right
term == term :: boolean
Returns true
if the two items are equal.
This operator considers 1 and 1.0 to be equal. For match semantics, use ===
instead.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 == 2 false iex> 1 == 1.0 true
left === right
term === term :: boolean
Returns true
if the two items are match.
This operator gives the same semantics as the one existing in pattern matching, i.e., 1
and 1.0
are equal, but they do not match.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 === 2 false iex> 1 === 1.0 false
left =~ right
String.t =~ String.t | Regex.t :: boolean
Matches the term on the left against the regular expression or string on the right. Returns true
if left
matches right
(if it’s a regular expression) or contains right
(if it’s a string).
Examples
iex> "abcd" =~ ~r/c(d)/ true iex> "abcd" =~ ~r/e/ false iex> "abcd" =~ "bc" true iex> "abcd" =~ "ad" false iex> "abcd" =~ "" true
left > right
term > term :: boolean
Returns true
if left is more than right.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 > 2 false
left >= right
term >= term :: boolean
Returns true
if left is more than or equal to right.
All terms in Elixir can be compared with each other.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> 1 >= 2 false
@expr (macro)
Reads and writes attributes of the current module.
The canonical example for attributes is annotating that a module implements the OTP behaviour called gen_server
:
defmodule MyServer do @behaviour :gen_server # ... callbacks ... end
By default Elixir supports all the module attributes supported by Erlang, but custom attributes can be used as well:
defmodule MyServer do @my_data 13 IO.inspect @my_data #=> 13 end
Unlike Erlang, such attributes are not stored in the module by default since it is common in Elixir to use custom attributes to store temporary data that will be available at compile-time. Custom attributes may be configured to behave closer to Erlang by using Module.register_attribute/3
.
Finally, notice that attributes can also be read inside functions:
defmodule MyServer do @my_data 11 def first_data, do: @my_data @my_data 13 def second_data, do: @my_data end MyServer.first_data #=> 11 MyServer.second_data #=> 13
It is important to note that reading an attribute takes a snapshot of its current value. In other words, the value is read at compilation time and not at runtime. Check the Module
module for other functions to manipulate module attributes.
abs(number)
abs(number) :: number
Returns an integer or float which is the arithmetical absolute value of number
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> abs(-3.33) 3.33 iex> abs(-3) 3
alias!(alias) (macro)
When used inside quoting, marks that the given alias should not be hygienized. This means the alias will be expanded when the macro is expanded.
Check Kernel.SpecialForms.quote/2
for more information.
left and right (macro)
Boolean and.
If the first argument is false
, false
is returned; otherwise, the second argument is returned.
Requires only the first argument to be a boolean since it short-circuits. If the first argument is not a boolean, an ArgumentError
exception is raised.
Allowed in guard tests.
Examples
iex> true and false false iex> true and "yay!" "yay!"
apply(fun, args)
apply((... -> any), [any]) :: any
Invokes the given fun
with the list of arguments args
.
Inlined by the compiler.
Examples
iex> apply(fn x -> x * 2 end, [2]) 4
apply(module, fun, args)
apply(module, atom, [any]) :: any
Invokes the given fun
from module
with the list of arguments args
.
Inlined by the compiler.
Examples
iex> apply(Enum, :reverse, [[1, 2, 3]]) [3, 2, 1]
binary_part(binary, start, length)
binary_part(binary, pos_integer, integer) :: binary
Extracts the part of the binary starting at start
with length length
. Binaries are zero-indexed.
If start
or length
reference in any way outside the binary, an ArgumentError
exception is raised.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> binary_part("foo", 1, 2) "oo"
A negative length
can be used to extract bytes that come before the byte at start
:
iex> binary_part("Hello", 5, -3) "llo"
binding(context \\ nil) (macro)
Returns the binding for the given context as a keyword list.
In the returned result, keys are variable names and values are the corresponding variable values.
If the given context
is nil
(by default it is), the binding for the current context is returned.
Examples
iex> x = 1 iex> binding() [x: 1] iex> x = 2 iex> binding() [x: 2] iex> binding(:foo) [] iex> var!(x, :foo) = 1 1 iex> binding(:foo) [x: 1]
bit_size(bitstring)
bit_size(bitstring) :: non_neg_integer
Returns an integer which is the size in bits of bitstring
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> bit_size(<<433::16, 3::3>>) 19 iex> bit_size(<<1, 2, 3>>) 24
byte_size(bitstring)
byte_size(bitstring) :: non_neg_integer
Returns the number of bytes needed to contain bitstring
.
That is, if the number of bits in bitstring
is not divisible by 8, the resulting number of bytes will be rounded up (by excess). This operation happens in constant time.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> byte_size(<<433::16, 3::3>>) 3 iex> byte_size(<<1, 2, 3>>) 3
def(call, expr \\ nil) (macro)
Defines a function with the given name and body.
Examples
defmodule Foo do def bar, do: :baz end Foo.bar #=> :baz
A function that expects arguments can be defined as follows:
defmodule Foo do def sum(a, b) do a + b end end
In the example above, a sum/2
function is defined; this function receives two arguments and returns their sum.
Function and variable names
Function and variable names have the following syntax: A lowercase ASCII letter or an underscore, followed by any number of lowercase or uppercase ASCII letters, numbers, or underscores. Optionally they can end in either an exclamation mark or a question mark.
For variables, any identifier starting with an underscore should indicate an unused variable. For example:
def foo(bar) do [] end #=> warning: variable bar is unused def foo(_bar) do [] end #=> no warning def foo(_bar) do _bar end #=> warning: the underscored variable "_bar" is used after being set
defdelegate(funs, opts) (macro)
Defines a function that delegates to another module.
Functions defined with defdelegate/2
are public and can be invoked from outside the module they’re defined in (like if they were defined using def/2
). When the desire is to delegate as private functions, import/2
should be used.
Delegation only works with functions; delegating macros is not supported.
Options
-
:to
- the expression to delegate to. Any expression is allowed and its results will be evaluated at runtime. Usually evaluates to the name of a module. -
:as
- the function to call on the target given in:to
. This parameter is optional and defaults to the name being delegated (funs
). -
:append_first
- iftrue
, when delegated, the first argument passed to the delegated function will be relocated to the end of the arguments when dispatched to the target.The motivation behind this is because Elixir normalizes the “handle” as the first argument while some Erlang modules expect it as the last argument.
Examples
defmodule MyList do defdelegate reverse(list), to: :lists defdelegate other_reverse(list), to: :lists, as: :reverse defdelegate [reverse(list), map(list, callback)], to: :lists, append_first: true end MyList.reverse([1, 2, 3]) #=> [3, 2, 1] MyList.other_reverse([1, 2, 3]) #=> [3, 2, 1] MyList.map([1, 2, 3], &(&1 * 2)) #=> [2, 4, 6]
defexception(fields) (macro)
Defines an exception.
Exceptions are structs backed by a module that implements the Exception
behaviour. The Exception
behaviour requires two functions to be implemented:
-
exception/1
- receives the arguments given toraise/2
and returns the exception struct. The default implementation accepts either a set of keyword arguments that is merged into the struct or a string to be used as the exception’s message. -
message/1
- receives the exception struct and must return its message. Most commonly exceptions have a message field which by default is accessed by this function. However, if an exception does not have a message field, this function must be explicitly implemented.
Since exceptions are structs, the API supported by defstruct/1
is also available in defexception/1
.
Raising exceptions
The most common way to raise an exception is via raise/2
:
defmodule MyAppError do defexception [:message] end value = [:hello] raise MyAppError, message: "did not get what was expected, got: #{inspect value}"
In many cases it is more convenient to pass the expected value to raise/2
and generate the message in the exception/1
callback:
defmodule MyAppError do defexception [:message] def exception(value) do msg = "did not get what was expected, got: #{inspect value}" %MyAppError{message: msg} end end raise MyAppError, value
The example above shows the preferred strategy for customizing exception messages.
defimpl(name, opts, do_block \\ []) (macro)
Defines an implementation for the given protocol.
See defprotocol/2
for more information and examples on protocols.
Inside an implementation, the name of the protocol can be accessed via @protocol
and the current target as @for
.
defmacro(call, expr \\ nil) (macro)
Defines a macro with the given name and body.
Examples
defmodule MyLogic do defmacro unless(expr, opts) do quote do if !unquote(expr), unquote(opts) end end end require MyLogic MyLogic.unless false do IO.puts "It works" end
defmacrop(call, expr \\ nil) (macro)
Defines a private macro with the given name and body.
Private macros are only accessible from the same module in which they are defined.
Check defmacro/2
for more information.
defmodule(alias, list) (macro)
Defines a module given by name with the given contents.
This macro defines a module with the given alias
as its name and with the given contents. It returns a tuple with four elements:
-
:module
- the module name
- the binary contents of the module
- the result of evaluating the contents block
Examples
iex> defmodule Foo do ...> def bar, do: :baz ...> end iex> Foo.bar :baz
Nesting
Nesting a module inside another module affects the name of the nested module:
defmodule Foo do defmodule Bar do end end
In the example above, two modules - Foo
and Foo.Bar
- are created. When nesting, Elixir automatically creates an alias to the inner module, allowing the second module Foo.Bar
to be accessed as Bar
in the same lexical scope where it’s defined (the Foo
module).
If the Foo.Bar
module is moved somewhere else, the references to Bar
in the Foo
module need to be updated to the fully-qualified name (Foo.Bar
) or an alias has to be explicitly set in the Foo
module with the help of Kernel.SpecialForms.alias/2
.
defmodule Foo.Bar do # code end defmodule Foo do alias Foo.Bar # code here can refer to "Foo.Bar" as just "Bar" end
Module names
A module name can be any atom, but Elixir provides a special syntax which is usually used for module names. What is called a module name is an uppercase ASCII letter followed by any number of lowercase or uppercase ASCII letters, numbers, or underscores. This identifier is equivalent to an atom prefixed by Elixir.
. So in the defmodule Foo
example Foo
is equivalent to :"Elixir.Foo"
Dynamic names
Elixir module names can be dynamically generated. This is very useful when working with macros. For instance, one could write:
defmodule String.to_atom("Foo#{1}") do # contents ... end
Elixir will accept any module name as long as the expression passed as the first argument to defmodule/2
evaluates to an atom. Note that, when a dynamic name is used, Elixir won’t nest the name under the current module nor automatically set up an alias.
defoverridable(keywords) (macro)
Makes the given functions in the current module overridable.
An overridable function is lazily defined, allowing a developer to override it.
Example
defmodule DefaultMod do defmacro __using__(_opts) do quote do def test(x, y) do x + y end defoverridable [test: 2] end end end defmodule InheritMod do use DefaultMod def test(x, y) do x * y + super(x, y) end end
As seen as in the example above, super
can be used to call the default implementation.
defp(call, expr \\ nil) (macro)
Defines a private function with the given name and body.
Private functions are only accessible from within the module in which they are defined. Trying to access a private function from outside the module it’s defined in results in an UndefinedFunctionError
exception.
Check def/2
for more information.
Examples
defmodule Foo do def bar do sum(1, 2) end defp sum(a, b), do: a + b end Foo.bar #=> 3 Foo.sum(1, 2) #=> ** (UndefinedFunctionError) undefined function Foo.sum/2
defprotocol(name, list) (macro)
Defines a protocol.
A protocol specifies an API that should be defined by its implementations.
Examples
In Elixir, only false
and nil
are considered falsy values. Everything else evaluates to true
in if/2
clauses. Depending on the application, it may be important to specify a blank?
protocol that returns a boolean for other data types that should be considered “blank”. For instance, an empty list or an empty binary could be considered blank.
Such protocol could be implemented as follows:
defprotocol Blank do @doc "Returns `true` if `data` is considered blank/empty" def blank?(data) end
Now that the protocol is defined it can be implemented. It needs to be implemented for each Elixir type; for example:
# Integers are never blank defimpl Blank, for: Integer do def blank?(number), do: false end # The only blank list is the empty one defimpl Blank, for: List do def blank?([]), do: true def blank?(_), do: false end # The only blank atoms are "false" and "nil" defimpl Blank, for: Atom do def blank?(false), do: true def blank?(nil), do: true def blank?(_), do: false end
The implementation of the Blank
protocol would need to be defined for all Elixir types. The available types are:
- Structs (see below)
-
Tuple
-
Atom
-
List
-
BitString
-
Integer
-
Float
-
Function
-
PID
-
Map
-
Port
-
Reference
-
Any
(see below)
Protocols and Structs
The real benefit of protocols comes when mixed with structs. For instance, Elixir ships with many data types implemented as structs, like MapSet
. We can implement the Blank
protocol for those types as well:
defimpl Blank, for: MapSet do def blank?(enum_like), do: Enum.empty?(enum_like) end
When implementing a protocol for a struct, the :for
option can be omitted if the defimpl
call is inside the module that defines the struct:
defmodule User do defstruct [:email, :name] defimpl Blank do def blank?(%User{}), do: false end end
If a protocol is not found for a given type, it will fallback to Any
. Protocols that are implemented for maps don’t work by default on structs; look at defstruct/1
for more information about deriving protocols.
Fallback to any
In some cases, it may be convenient to provide a default implementation for all types. This can be achieved by setting the @fallback_to_any
attribute to true
in the protocol definition:
defprotocol Blank do @fallback_to_any true def blank?(data) end
The Blank
protocol can now be implemented for Any
:
defimpl Blank, for: Any do def blank?(_), do: true end
One may wonder why such behaviour (fallback to any) is not the default one.
It is two-fold: first, the majority of protocols cannot implement an action in a generic way for all types; in fact, providing a default implementation may be harmful, because users may rely on the default implementation instead of providing a specialized one.
Second, falling back to Any
adds an extra lookup to all types, which is unnecessary overhead unless an implementation for Any
is required.
Types
Defining a protocol automatically defines a type named t
, which can be used as follows:
@spec present?(Blank.t) :: boolean def present?(blank) do not Blank.blank?(blank) end
The @spec
above expresses that all types allowed to implement the given protocol are valid argument types for the given function.
Reflection
Any protocol module contains three extra functions:
-
__protocol__/1
- returns the protocol name when:name
is given, and a keyword list with the protocol functions and their arities when:functions
is given -
impl_for/1
- receives a structure and returns the module that implements the protocol for the structure,nil
otherwise -
impl_for!/1
- same as above but raises an error if an implementation is not foundEnumerable.__protocol__(:functions) #=> [count: 1, member?: 2, reduce: 3] Enumerable.impl_for([]) #=> Enumerable.List Enumerable.impl_for(42) #=> nil
Consolidation
In order to cope with code loading in development, protocols in Elixir provide a slow implementation of protocol dispatching specific to development.
In order to speed up dispatching in production environments, where all implementations are known up-front, Elixir provides a feature called protocol consolidation. For this reason, all protocols are compiled with debug_info
set to true
, regardless of the option set by elixirc
compiler. The debug info though may be removed after consolidation.
For more information on how to apply protocol consolidation to a given project, please check the functions in the Protocol
module or the mix compile.protocols
task.
defstruct(fields) (macro)
Defines a struct.
A struct is a tagged map that allows developers to provide default values for keys, tags to be used in polymorphic dispatches and compile time assertions.
To define a struct, a developer must define both __struct__/0
and __struct__/1
functions. defstruct/1
is a convenience macro which defines such functions with some conveniences.
For more information about structs, please check Kernel.SpecialForms.%/2
.
Examples
defmodule User do defstruct name: nil, age: nil end
Struct fields are evaluated at compile-time, which allows them to be dynamic. In the example below, 10 + 11
is evaluated at compile-time and the age field is stored with value 21
:
defmodule User do defstruct name: nil, age: 10 + 11 end
The fields
argument is usually a keyword list with field names as atom keys and default values as corresponding values. defstruct/1
also supports a list of atoms as its argument: in that case, the atoms in the list will be used as the struct’s field names and they will all default to nil
.
defmodule Post do defstruct [:title, :content, :author] end
Deriving
Although structs are maps, by default structs do not implement any of the protocols implemented for maps. For example, attempting to use a protocol with the User
struct leads to an error:
john = %User{name: "John"} MyProtocol.call(john) ** (Protocol.UndefinedError) protocol MyProtocol not implemented for %User{...}
defstruct/1
, however, allows protocol implementations to be derived. This can be done by defining a @derive
attribute as a list before invoking defstruct/1
:
defmodule User do @derive [MyProtocol] defstruct name: nil, age: 10 + 11 end MyProtocol.call(john) #=> works
For each protocol in the @derive
list, Elixir will assert there is an implementation of that protocol for any (regardless if fallback to any is true
) and check if the any implementation defines a __deriving__/3
callback. If so, the callback is invoked, otherwise an implementation that simply points to the any implementation is automatically derived.
Enforcing keys
When building a struct, Elixir will automatically guarantee all keys belongs to the struct:
%User{name: "john", unknown: :key} ** (KeyError) key :unknown not found in: %User{age: 21, name: nil}
Elixir also allows developers to enforce certain keys must always be given when building the struct:
defmodule User do @enforce_keys [:name] defstruct name: nil, age: 10 + 11 end
Now trying to build a struct without the name key will fail:
%User{age: 21} ** (ArgumentError) the following keys must also be given when building struct User: [:name]
Keep in mind @enforce_keys
is a simply a compile-time guarantee to aid developers when building structs. It is not enforced on updates and it does not provide any sort of value-validation.
Types
It is recommended to define types for structs. By convention such type is called t
. To define a struct inside a type, the struct literal syntax is used:
defmodule User do defstruct name: "John", age: 25 @type t :: %User{name: String.t, age: non_neg_integer} end
It is recommended to only use the struct syntax when defining the struct’s type. When referring to another struct it’s better to use User.t
instead of %User{}
.
The types of the struct fields that are not included in %User{}
default to term
.
Structs whose internal structure is private to the local module (pattern matching them or directly accessing their fields should not be allowed) should use the @opaque
attribute. Structs whose internal structure is public should use @type
.
destructure(left, right) (macro)
Destructures two lists, assigning each term in the right one to the matching term in the left one.
Unlike pattern matching via =
, if the sizes of the left and right lists don’t match, destructuring simply stops instead of raising an error.
Examples
iex> destructure([x, y, z], [1, 2, 3, 4, 5]) iex> {x, y, z} {1, 2, 3}
In the example above, even though the right list has more entries than the left one, destructuring works fine. If the right list is smaller, the remaining items are simply set to nil
:
iex> destructure([x, y, z], [1]) iex> {x, y, z} {1, nil, nil}
The left-hand side supports any expression you would use on the left-hand side of a match:
x = 1 destructure([^x, y, z], [1, 2, 3])
The example above will only work if x
matches the first value in the right list. Otherwise, it will raise a MatchError
(like the =
operator would do).
div(left, right)
div(integer, integer) :: integer
Performs an integer division.
Raises an ArithmeticError
exception if one of the arguments is not an integer.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> div(5, 2) 2
elem(tuple, index)
elem(tuple, non_neg_integer) :: term
Gets the element at the zero-based index
in tuple
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> tuple = {:foo, :bar, 3} iex> elem(tuple, 1) :bar
exit(reason)
exit(term) :: no_return
Stops the execution of the calling process with the given reason.
Since evaluating this function causes the process to terminate, it has no return value.
Inlined by the compiler.
Examples
When a process reaches its end, by default it exits with reason :normal
. You can also call exit/1
explicitly if you want to terminate a process but not signal any failure:
exit(:normal)
In case something goes wrong, you can also use exit/1
with a different reason:
exit(:seems_bad)
If the exit reason is not :normal
, all the processes linked to the process that exited will crash (unless they are trapping exits).
OTP exits
Exits are used by the OTP to determine if a process exited abnormally or not. The following exits are considered “normal”:
-
exit(:normal)
-
exit(:shutdown)
-
exit({:shutdown, term})
Exiting with any other reason is considered abnormal and treated as a crash. This means the default supervisor behaviour kicks in, error reports are emitted, etc.
This behaviour is relied on in many different places. For example, ExUnit
uses exit(:shutdown)
when exiting the test process to signal linked processes, supervision trees and so on to politely shutdown too.
CLI exits
Building on top of the exit signals mentioned above, if the process started by the command line exits with any of the three reasons above, its exit is considered normal and the Operating System process will exit with status 0.
It is, however, possible to customize the Operating System exit signal by invoking:
exit({:shutdown, integer})
This will cause the OS process to exit with the status given by integer
while signaling all linked OTP processes to politely shutdown.
Any other exit reason will cause the OS process to exit with status 1
and linked OTP processes to crash.
function_exported?(module, function, arity)
function_exported?(atom | tuple, atom, arity) :: boolean
Returns true
if module
is loaded and contains a public function
with the given arity
, otherwise false
.
Note that this function does not load the module in case it is not loaded. Check Code.ensure_loaded/1
for more information.
Examples
iex> function_exported?(Enum, :member?, 2) true
get_and_update_in(path, fun) (macro)
Gets a value and updates a nested data structure via the given path
.
This is similar to get_and_update_in/3
, except the path is extracted via a macro rather than passing a list. For example:
get_and_update_in(opts[:foo][:bar], &{&1, &1 + 1})
Is equivalent to:
get_and_update_in(opts, [:foo, :bar], &{&1, &1 + 1})
Note that in order for this macro to work, the complete path must always be visible by this macro. See the Paths section below.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_and_update_in(users["john"].age, &{&1, &1 + 1}) {27, %{"john" => %{age: 28}, "meg" => %{age: 23}}}
Paths
A path may start with a variable, local or remote call, and must be followed by one or more:
-
foo[bar]
- access the keybar
infoo
; in casefoo
is nil,nil
is returned -
foo.bar
- access a map/struct field; in case the field is not present, an error is raised
Here are some valid paths:
users["john"][:age] users["john"].age User.all["john"].age all_users()["john"].age
Here are some invalid ones:
# Does a remote call after the initial value users["john"].do_something(arg1, arg2) # Does not access any key or field users
get_and_update_in(data, keys, fun)
get_and_update_in(Access.t, [term, ...], (term -> {get, term})) :: {get, Access.t} when get: var
Gets a value and updates a nested structure.
It expects a tuple to be returned, containing the value retrieved and the update one.
It uses the Access
module to traverse the structures according to the given keys
, unless the key
is a function.
If a key is a function, the function will be invoked passing three arguments, the operation (:get_and_update
), the data to be accessed, and a function to be invoked next.
This means get_and_update_in/3
can be extended to provide custom lookups. The downside is that functions cannot be stored as keys in the accessed data structures.
Examples
This function is useful when there is a need to retrieve the current value (or something calculated in function of the current value) and update it at the same time. For example, it could be used to increase the age of a user by one and return the previous age in one pass:
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_and_update_in(users, ["john", :age], &{&1, &1 + 1}) {27, %{"john" => %{age: 28}, "meg" => %{age: 23}}}
When one of the keys is a function, the function is invoked. In the example below, we use a function to get and increment all ages inside a list:
iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}] iex> all = fn :get_and_update, data, next -> ...> Enum.map(data, next) |> :lists.unzip ...> end iex> get_and_update_in(users, [all, :age], &{&1, &1 + 1}) {[27, 23], [%{name: "john", age: 28}, %{name: "meg", age: 24}]}
If the previous value before invoking the function is nil
, the function will receive nil
as a value and must handle it accordingly (be it by failing or providing a sane default).
The Access
module ships with many convenience accessor functions, like the all
function defined above. See Access.all/0
, Access.key/1
and others as examples.
get_in(data, keys)
get_in(Access.t, [term, ...]) :: term
Gets a value from a nested structure.
Uses the Access
module to traverse the structures according to the given keys
, unless the key
is a function.
If a key is a function, the function will be invoked passing three arguments, the operation (:get
), the data to be accessed, and a function to be invoked next.
This means get_in/2
can be extended to provide custom lookups. The downside is that functions cannot be stored as keys in the accessed data structures.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_in(users, ["john", :age]) 27
In case any of entries in the middle returns nil
, nil
will be returned as per the Access module:
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> get_in(users, ["unknown", :age]) nil
When one of the keys is a function, the function is invoked. In the example below, we use a function to get all the maps inside a list:
iex> users = [%{name: "john", age: 27}, %{name: "meg", age: 23}] iex> all = fn :get, data, next -> Enum.map(data, next) end iex> get_in(users, [all, :age]) [27, 23]
If the previous value before invoking the function is nil
, the function will receive nil as a value and must handle it accordingly.
hd(list)
hd(maybe_improper_list) :: term
Returns the head of a list; raises ArgumentError
if the list is empty.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> hd([1, 2, 3, 4]) 1
if(condition, clauses) (macro)
Provides an if/2
macro.
This macro expects the first argument to be a condition and the second argument to be a keyword list.
One-liner examples
if(foo, do: bar)
In the example above, bar
will be returned if foo
evaluates to true
(i.e., it is neither false
nor nil
). Otherwise, nil
will be returned.
An else
option can be given to specify the opposite:
if(foo, do: bar, else: baz)
Blocks examples
It’s also possible to pass a block to the if/2
macro. The first example above would be translated to:
if foo do bar end
Note that do/end
become delimiters. The second example would translate to:
if foo do bar else baz end
In order to compare more than two clauses, the cond/1
macro has to be used.
left in right (macro)
Checks if the element on the left-hand side is a member of the collection on the right-hand side.
Examples
iex> x = 1 iex> x in [1, 2, 3] true
This operator (which is a macro) simply translates to a call to Enum.member?/2
. The example above would translate to:
Enum.member?([1, 2, 3], x)
Guards
The in/2
operator can be used in guard clauses as long as the right-hand side is a range or a list. In such cases, Elixir will expand the operator to a valid guard expression. For example:
when x in [1, 2, 3]
translates to:
when x === 1 or x === 2 or x === 3
When using ranges:
when x in 1..3
translates to:
when x >= 1 and x <= 3
inspect(arg, opts \\ [])
inspect(Inspect.t, Keyword.t) :: String.t
Inspects the given argument according to the Inspect
protocol. The second argument is a keyword list with options to control inspection.
Options
inspect/2
accepts a list of options that are internally translated to an Inspect.Opts
struct. Check the docs for Inspect.Opts
to see the supported options.
Examples
iex> inspect(:foo) ":foo" iex> inspect [1, 2, 3, 4, 5], limit: 3 "[1, 2, 3, ...]" iex> inspect [1, 2, 3], pretty: true, width: 0 "[1,\n 2,\n 3]" iex> inspect("olá" <> <<0>>) "<<111, 108, 195, 161, 0>>" iex> inspect("olá" <> <<0>>, binaries: :as_strings) "\"olá\\0\"" iex> inspect("olá", binaries: :as_binaries) "<<111, 108, 195, 161>>" iex> inspect('bar') "'bar'" iex> inspect([0 | 'bar']) "[0, 98, 97, 114]" iex> inspect(100, base: :octal) "0o144" iex> inspect(100, base: :hex) "0x64"
Note that the Inspect
protocol does not necessarily return a valid representation of an Elixir term. In such cases, the inspected result must start with #
. For example, inspecting a function will return:
inspect fn a, b -> a + b end #=> #Function<...>
is_atom(term)
is_atom(term) :: boolean
Returns true
if term
is an atom; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_binary(term)
is_binary(term) :: boolean
Returns true
if term
is a binary; otherwise returns false
.
A binary always contains a complete number of bytes.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> is_binary "foo" true iex> is_binary <<1::3>> false
is_bitstring(term)
is_bitstring(term) :: boolean
Returns true
if term
is a bitstring (including a binary); otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> is_bitstring "foo" true iex> is_bitstring <<1::3>> true
is_boolean(term)
is_boolean(term) :: boolean
Returns true
if term
is either the atom true
or the atom false
(i.e., a boolean); otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_float(term)
is_float(term) :: boolean
Returns true
if term
is a floating point number; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_function(term)
is_function(term) :: boolean
Returns true
if term
is a function; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_function(term, arity)
is_function(term, non_neg_integer) :: boolean
Returns true
if term
is a function that can be applied with arity
number of arguments; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> is_function(fn(x) -> x * 2 end, 1) true iex> is_function(fn(x) -> x * 2 end, 2) false
is_integer(term)
is_integer(term) :: boolean
Returns true
if term
is an integer; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_list(term)
is_list(term) :: boolean
Returns true
if term
is a list with zero or more elements; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_map(term)
is_map(term) :: boolean
Returns true
if term
is a map; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_nil(term) (macro)
Returns true
if term
is nil
, false
otherwise.
Allowed in guard clauses.
Examples
iex> is_nil(1) false iex> is_nil(nil) true
is_number(term)
is_number(term) :: boolean
Returns true
if term
is either an integer or a floating point number; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_pid(term)
is_pid(term) :: boolean
Returns true
if term
is a pid (process identifier); otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_port(term)
is_port(term) :: boolean
Returns true
if term
is a port identifier; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_reference(term)
is_reference(term) :: boolean
Returns true
if term
is a reference; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
is_tuple(term)
is_tuple(term) :: boolean
Returns true
if term
is a tuple; otherwise returns false
.
Allowed in guard tests. Inlined by the compiler.
length(list)
length(list) :: non_neg_integer
Returns the length of list
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> length([1, 2, 3, 4, 5, 6, 7, 8, 9]) 9
macro_exported?(module, macro, arity)
macro_exported?(atom, atom, integer) :: boolean
Returns true
if module
is loaded and contains a public macro
with the given arity
, otherwise false
.
Note that this function does not load the module in case it is not loaded. Check Code.ensure_loaded/1
for more information.
Examples
iex> macro_exported?(Kernel, :use, 2) true
make_ref()
make_ref() :: reference
Returns an almost unique reference.
The returned reference will re-occur after approximately 2^82 calls; therefore it is unique enough for practical purposes.
Inlined by the compiler.
Examples
make_ref() #=> #Reference<0.0.0.135>
map_size(map)
map_size(map) :: non_neg_integer
Returns the size of a map.
The size of a map is the number of key-value pairs that the map contains.
This operation happens in constant time.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> map_size(%{a: "foo", b: "bar"}) 2
match?(pattern, expr) (macro)
A convenience macro that checks if the right side (an expression) matches the left side (a pattern).
Examples
iex> match?(1, 1) true iex> match?(1, 2) false iex> match?({1, _}, {1, 2}) true iex> map = %{a: 1, b: 2} iex> match?(%{a: _}, map) true iex> a = 1 iex> match?(^a, 1) true
match?/2
is very useful when filtering of finding a value in an enumerable:
list = [{:a, 1}, {:b, 2}, {:a, 3}] Enum.filter list, &match?({:a, _}, &1) #=> [{:a, 1}, {:a, 3}]
Guard clauses can also be given to the match:
list = [{:a, 1}, {:b, 2}, {:a, 3}] Enum.filter list, &match?({:a, x} when x < 2, &1) #=> [{:a, 1}]
However, variables assigned in the match will not be available outside of the function call (unlike regular pattern matching with the =
operator):
iex> match?(_x, 1) true iex> binding() []
max(first, second)
max(term, term) :: term
Returns the biggest of the two given terms according to Erlang’s term ordering. If the terms compare equal, the first one is returned.
Inlined by the compiler.
Examples
iex> max(1, 2) 2 iex> max(:a, :b) :b
min(first, second)
min(term, term) :: term
Returns the smallest of the two given terms according to Erlang’s term ordering. If the terms compare equal, the first one is returned.
Inlined by the compiler.
Examples
iex> min(1, 2) 1 iex> min("foo", "bar") "bar"
node()
node() :: node
Returns an atom representing the name of the local node. If the node is not alive, :nonode@nohost
is returned instead.
Allowed in guard tests. Inlined by the compiler.
node(arg)
node(pid | reference | port) :: node
Returns the node where the given argument is located. The argument can be a pid, a reference, or a port. If the local node is not alive, :nonode@nohost
is returned.
Allowed in guard tests. Inlined by the compiler.
not arg
not boolean :: boolean
Boolean not.
arg
must be a boolean; if it’s not, an ArgumentError
exception is raised.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> not false true
left or right (macro)
Boolean or.
If the first argument is true
, true
is returned; otherwise, the second argument is returned.
Requires only the first argument to be a boolean since it short-circuits. If the first argument is not a boolean, an ArgumentError
exception is raised.
Allowed in guard tests.
Examples
iex> true or false true iex> false or 42 42
pop_in(path) (macro)
Pops a key from the nested structure via the given path
.
This is similar to pop_in/2
, except the path is extracted via a macro rather than passing a list. For example:
pop_in(opts[:foo][:bar])
Is equivalent to:
pop_in(opts, [:foo, :bar])
Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check get_and_update_in/2
docs.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> pop_in(users["john"][:age]) {27, %{"john" => %{}, "meg" => %{age: 23}}} iex> users = %{john: %{age: 27}, meg: %{age: 23}} iex> pop_in(users.john[:age]) {27, %{john: %{}, meg: %{age: 23}}}
In case any entry returns nil
, its key will be removed and the deletion will be considered a success.
pop_in(data, keys)
pop_in(Access.t, [term, ...]) :: {term, Access.t}
Pops a key from the given nested structure.
Uses the Access
protocol to traverse the structures according to the given keys
, unless the key
is a function. If the key is a function, it will be invoked as specified in get_and_update_in/3
.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> pop_in(users, ["john", :age]) {27, %{"john" => %{}, "meg" => %{age: 23}}}
In case any entry returns nil
, its key will be removed and the deletion will be considered a success.
put_elem(tuple, index, value)
put_elem(tuple, non_neg_integer, term) :: tuple
Inserts value
at the given zero-based index
in tuple
.
Inlined by the compiler.
Examples
iex> tuple = {:foo, :bar, 3} iex> put_elem(tuple, 0, :baz) {:baz, :bar, 3}
put_in(path, value) (macro)
Puts a value in a nested structure via the given path
.
This is similar to put_in/3
, except the path is extracted via a macro rather than passing a list. For example:
put_in(opts[:foo][:bar], :baz)
Is equivalent to:
put_in(opts, [:foo, :bar], :baz)
Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check get_and_update_in/2
docs.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users["john"][:age], 28) %{"john" => %{age: 28}, "meg" => %{age: 23}} iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users["john"].age, 28) %{"john" => %{age: 28}, "meg" => %{age: 23}}
put_in(data, keys, value)
put_in(Access.t, [term, ...], term) :: Access.t
Puts a value in a nested structure.
Uses the Access
module to traverse the structures according to the given keys
, unless the key
is a function. If the key is a function, it will be invoked as specified in get_and_update_in/3
.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> put_in(users, ["john", :age], 28) %{"john" => %{age: 28}, "meg" => %{age: 23}}
In case any of entries in the middle returns nil
, an error will be raised when trying to access it next.
raise(msg) (macro)
Raises an exception.
If the argument msg
is a binary, it raises a RuntimeError
exception using the given argument as message.
If msg
is an atom, it just calls raise/2
with the atom as the first argument and []
as the second argument.
If msg
is anything else, raises an ArgumentError
exception.
Examples
iex> raise "oops" ** (RuntimeError) oops try do 1 + :foo rescue x in [ArithmeticError] -> IO.puts "that was expected" raise x end
raise(exception, attrs) (macro)
Raises an exception.
Calls the exception/1
function on the given argument (which has to be a module name like ArgumentError
or RuntimeError
) passing attrs
as the attributes in order to retrieve the exception struct.
Any module that contains a call to the defexception/1
macro automatically implements the exception/1
callback expected by raise/2
. See the docs for defexception/1
for more information.
Examples
iex> raise(ArgumentError, message: "Sample") ** (ArgumentError) Sample
rem(left, right)
rem(integer, integer) :: integer
Computes the remainder of an integer division.
Raises an ArithmeticError
exception if one of the arguments is not an integer.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> rem(5, 2) 1
reraise(msg, stacktrace) (macro)
Raises an exception preserving a previous stacktrace.
Works like raise/1
but does not generate a new stacktrace.
Notice that System.stacktrace/0
returns the stacktrace of the last exception. That said, it is common to assign the stacktrace as the first expression inside a rescue
clause as any other exception potentially raised (and rescued) between the rescue clause and the raise call may change the System.stacktrace/0
value.
Examples
try do raise "oops" rescue exception -> stacktrace = System.stacktrace if Exception.message(exception) == "oops" do reraise exception, stacktrace end end
reraise(exception, attrs, stacktrace) (macro)
Raises an exception preserving a previous stacktrace.
reraise/3
works like reraise/2
, except it passes arguments to the exception/1
function like explained in raise/2
.
Examples
try do raise "oops" rescue exception -> stacktrace = System.stacktrace reraise WrapperError, [exception: exception], stacktrace end
round(number)
round(number) :: integer
Rounds a number to the nearest integer.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> round(5.6) 6 iex> round(5.2) 5 iex> round(-9.9) -10
self()
self() :: pid
Returns the pid (process identifier) of the calling process.
Allowed in guard clauses. Inlined by the compiler.
send(dest, msg)
send(dest :: pid | port | atom | {atom, node}, msg) :: msg when msg: any
Sends a message to the given dest
and returns the message.
dest
may be a remote or local pid, a (local) port, a locally registered name, or a tuple {registered_name, node}
for a registered name at another node.
Inlined by the compiler.
Examples
iex> send self(), :hello :hello
sigil_C(term, modifiers) (macro)
Handles the sigil ~C
.
It simply returns a charlist without escaping characters and without interpolations.
Examples
iex> ~C(foo) 'foo' iex> ~C(f#{o}o) 'f\#{o}o'
sigil_D(date, modifiers) (macro)
Handles the sigil ~D
for dates.
The lower case ~d
variant does not exist as interpolation and escape characters are not useful for date sigils.
Examples
iex> ~D[2015-01-13] ~D[2015-01-13]
sigil_N(date, modifiers) (macro)
Handles the sigil ~N
for naive date times.
The lower case ~n
variant does not exist as interpolation and escape characters are not useful for datetime sigils.
Examples
iex> ~N[2015-01-13 13:00:07] ~N[2015-01-13 13:00:07] iex> ~N[2015-01-13T13:00:07.001] ~N[2015-01-13 13:00:07.001]
sigil_R(term, modifiers) (macro)
Handles the sigil ~R
.
It returns a regular expression pattern without escaping nor interpreting interpolations.
More information on regexes can be found in the Regex
module.
Examples
iex> Regex.match?(~R(f#{1,3}o), "f#o") true
sigil_S(term, modifiers) (macro)
Handles the sigil ~S
.
It simply returns a string without escaping characters and without interpolations.
Examples
iex> ~S(foo) "foo" iex> ~S(f#{o}o) "f\#{o}o"
sigil_T(date, modifiers) (macro)
Handles the sigil ~T
for times.
The lower case ~t
variant does not exist as interpolation and escape characters are not useful for time sigils.
Examples
iex> ~T[13:00:07] ~T[13:00:07] iex> ~T[13:00:07.001] ~T[13:00:07.001]
sigil_W(term, modifiers) (macro)
Handles the sigil ~W
.
It returns a list of “words” split by whitespace without escaping nor interpreting interpolations.
Modifiers
-
s
: words in the list are strings (default) -
a
: words in the list are atoms -
c
: words in the list are charlists
Examples
iex> ~W(foo #{bar} baz) ["foo", "\#{bar}", "baz"]
sigil_c(term, modifiers) (macro)
Handles the sigil ~c
.
It returns a charlist as if it were a single quoted string, unescaping characters and replacing interpolations.
Examples
iex> ~c(foo) 'foo' iex> ~c(f#{:o}o) 'foo' iex> ~c(f\#{:o}o) 'f\#{:o}o'
sigil_r(term, modifiers) (macro)
Handles the sigil ~r
.
It returns a regular expression pattern, unescaping characters and replacing interpolations.
More information on regexes can be found in the Regex
module.
Examples
iex> Regex.match?(~r(foo), "foo") true iex> Regex.match?(~r/abc/, "abc") true
sigil_s(term, modifiers) (macro)
Handles the sigil ~s
.
It returns a string as if it was a double quoted string, unescaping characters and replacing interpolations.
Examples
iex> ~s(foo) "foo" iex> ~s(f#{:o}o) "foo" iex> ~s(f\#{:o}o) "f\#{:o}o"
sigil_w(term, modifiers) (macro)
Handles the sigil ~w
.
It returns a list of “words” split by whitespace. Character unescaping and interpolation happens for each word.
Modifiers
-
s
: words in the list are strings (default) -
a
: words in the list are atoms -
c
: words in the list are charlists
Examples
iex> ~w(foo #{:bar} baz) ["foo", "bar", "baz"] iex> ~w(foo #{" bar baz "}) ["foo", "bar", "baz"] iex> ~w(--source test/enum_test.exs) ["--source", "test/enum_test.exs"] iex> ~w(foo bar baz)a [:foo, :bar, :baz]
spawn(fun)
spawn((() -> any)) :: pid
Spawns the given function and returns its pid.
Check the Process
and Node
modules for other functions to handle processes, including spawning functions in nodes.
Inlined by the compiler.
Examples
current = self() child = spawn(fn -> send current, {self(), 1 + 2} end) receive do {^child, 3} -> IO.puts "Received 3 back" end
spawn(module, fun, args)
spawn(module, atom, list) :: pid
Spawns the given module and function passing the given args and returns its pid.
Check the Process
and Node
modules for other functions to handle processes, including spawning functions in nodes.
Inlined by the compiler.
Examples
spawn(SomeModule, :function, [1, 2, 3])
spawn_link(fun)
spawn_link((() -> any)) :: pid
Spawns the given function, links it to the current process and returns its pid.
Check the Process
and Node
modules for other functions to handle processes, including spawning functions in nodes.
Inlined by the compiler.
Examples
current = self() child = spawn_link(fn -> send current, {self(), 1 + 2} end) receive do {^child, 3} -> IO.puts "Received 3 back" end
spawn_link(module, fun, args)
spawn_link(module, atom, list) :: pid
Spawns the given module and function passing the given args, links it to the current process and returns its pid.
Check the Process
and Node
modules for other functions to handle processes, including spawning functions in nodes.
Inlined by the compiler.
Examples
spawn_link(SomeModule, :function, [1, 2, 3])
spawn_monitor(fun)
spawn_monitor((() -> any)) :: {pid, reference}
Spawns the given function, monitors it and returns its pid and monitoring reference.
Check the Process
and Node
modules for other functions to handle processes, including spawning functions in nodes.
Inlined by the compiler.
Examples
current = self() spawn_monitor(fn -> send current, {self(), 1 + 2} end)
spawn_monitor(module, fun, args)
spawn_monitor(module, atom, list) :: {pid, reference}
Spawns the given module and function passing the given args, monitors it and returns its pid and monitoring reference.
Check the Process
and Node
modules for other functions to handle processes, including spawning functions in nodes.
Inlined by the compiler.
Examples
spawn_monitor(SomeModule, :function, [1, 2, 3])
struct(struct, kv \\ [])
struct(module | map, Enum.t) :: map
Creates and updates structs.
The struct
argument may be an atom (which defines defstruct
) or a struct
itself. The second argument is any Enumerable
that emits two-element tuples (key-value pairs) during enumeration.
Keys in the Enumerable
that don’t exist in the struct are automatically discarded. Note that keys must be atoms, as only atoms are allowed when defining a struct.
This function is useful for dynamically creating and updating structs, as well as for converting maps to structs; in the latter case, just inserting the appropriate :__struct__
field into the map may not be enough and struct/2
should be used instead.
Examples
defmodule User do defstruct name: "john" end struct(User) #=> %User{name: "john"} opts = [name: "meg"] user = struct(User, opts) #=> %User{name: "meg"} struct(user, unknown: "value") #=> %User{name: "meg"} struct(User, %{name: "meg"}) #=> %User{name: "meg"} # String keys are ignored struct(User, %{"name" => "meg"}) #=> %User{name: "john"}
struct!(struct, kv \\ [])
struct!(module | map, Enum.t) :: map | no_return
Similar to struct/2
but checks for key validity.
The function struct!/2
emulates the compile time behaviour of structs. This means that:
-
when building a struct, as in
struct!(SomeStruct, key: :value)
, it is equivalent to%SomeStruct{key: :value}
and therefore this function will check if every given key-value belongs to the struct. If the struct is enforcing any key via@enforce_keys
, those will be enforced as well; -
when updating a struct, as in
struct!(%SomeStruct{}, key: :value)
, it is equivalent to%SomeStruct{struct | key: :value}
and therefore this function will check if every given key-value belongs to the struct. However, updating structs does not enforce keys, as keys are enforced only when building;
throw(term)
throw(term) :: no_return
A non-local return from a function. Check Kernel.SpecialForms.try/1
for more information.
Inlined by the compiler.
tl(list)
tl(maybe_improper_list) :: maybe_improper_list
Returns the tail of a list. Raises ArgumentError
if the list is empty.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> tl([1, 2, 3, :go]) [2, 3, :go]
to_charlist(arg) (macro)
Converts the argument to a charlist according to the List.Chars
protocol.
Examples
iex> to_charlist(:foo) 'foo'
to_string(arg) (macro)
Converts the argument to a string according to the String.Chars
protocol.
This is the function invoked when there is string interpolation.
Examples
iex> to_string(:foo) "foo"
trunc(number)
trunc(number) :: integer
Returns the integer part of number
.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> trunc(5.4) 5 iex> trunc(5.99) 5
tuple_size(tuple)
tuple_size(tuple) :: non_neg_integer
Returns the size of a tuple.
This operation happens in constant time.
Allowed in guard tests. Inlined by the compiler.
Examples
iex> tuple_size {:a, :b, :c} 3
unless(condition, clauses) (macro)
Provides an unless
macro.
This macro evaluates and returns the do
block passed in as the second argument unless clause
evaluates to true
. Otherwise, it returns the value of the else
block if present or nil
if not.
See also if/2
.
Examples
iex> unless(Enum.empty?([]), do: "Hello") nil iex> unless(Enum.empty?([1, 2, 3]), do: "Hello") "Hello" iex> unless Enum.sum([2, 2]) == 5 do ...> "Math still works" ...> else ...> "Math is broken" ...> end "Math still works"
update_in(path, fun) (macro)
Updates a nested structure via the given path
.
This is similar to update_in/3
, except the path is extracted via a macro rather than passing a list. For example:
update_in(opts[:foo][:bar], &(&1 + 1))
Is equivalent to:
update_in(opts, [:foo, :bar], &(&1 + 1))
Note that in order for this macro to work, the complete path must always be visible by this macro. For more information about the supported path expressions, please check get_and_update_in/2
docs.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users["john"][:age], &(&1 + 1)) %{"john" => %{age: 28}, "meg" => %{age: 23}} iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users["john"].age, &(&1 + 1)) %{"john" => %{age: 28}, "meg" => %{age: 23}}
update_in(data, keys, fun)
update_in(Access.t, [term, ...], (term -> term)) :: Access.t
Updates a key in a nested structure.
Uses the Access
module to traverse the structures according to the given keys
, unless the key
is a function. If the key is a function, it will be invoked as specified in get_and_update_in/3
.
Examples
iex> users = %{"john" => %{age: 27}, "meg" => %{age: 23}} iex> update_in(users, ["john", :age], &(&1 + 1)) %{"john" => %{age: 28}, "meg" => %{age: 23}}
In case any of entries in the middle returns nil
, an error will be raised when trying to access it next.
use(module, opts \\ []) (macro)
Uses the given module in the current context.
Examples
For example, in order to write tests using the ExUnit framework, a developer should use the ExUnit.Case
module:
defmodule AssertionTest do use ExUnit.Case, async: true test "always pass" do assert true end end
By calling use/2
, a hook called __using__/1
will be invoked in ExUnit.Case
which will then do the proper setup.
Simply put, use/2
translates to:
defmodule AssertionTest do require ExUnit.Case ExUnit.Case.__using__([async: true]) test "always pass" do assert true end end
Where __using__/1
is just a regular macro that can be defined in any module:
defmodule MyModule do defmacro __using__(opts) do quote do # code that will run in the module that uses MyModule end end end
Best practices
__using__/1
is typically used when there is a need to set some state (via module attributes) or callbacks (like @before_compile
) into the caller.
__using__/1
may also be used to alias, require or import functionality from different modules:
defmodule MyModule do defmacro __using__(opts) do quote do import MyModule.Foo import MyModule.Bar import MyModule.Baz alias MyModule.Repo end end end
However, do not provide __using__/1
if all it does is to import, alias or require the module itself. For example, do not:
defmodule MyModule do defmacro __using__(opts) do quote do import MyModule end end end
In such cases, developers must just import or alias the module directly, allowing developers to customize those as they wish, without the indirection behind use/2
.
Finally, developers should also avoid defining functions inside the __using__/1
callback, unless those functions are the default implementation of a previously defined @callback
. In case you want to provide some existing functionality to the user module, please define it in a module which will be imported accordingly.
var!(var, context \\ nil) (macro)
When used inside quoting, marks that the given variable should not be hygienized.
The argument can be either a variable unquoted or in standard tuple form {name, meta, context}
.
Check Kernel.SpecialForms.quote/2
for more information.
left |> right (macro)
Pipe operator.
This operator introduces the expression on the left-hand side as the first argument to the function call on the right-hand side.
Examples
iex> [1, [2], 3] |> List.flatten() [1, 2, 3]
The example above is the same as calling List.flatten([1, [2], 3])
.
The |>
operator is mostly useful when there is a desire to execute a series of operations resembling a pipeline:
iex> [1, [2], 3] |> List.flatten |> Enum.map(fn x -> x * 2 end) [2, 4, 6]
In the example above, the list [1, [2], 3]
is passed as the first argument to the List.flatten/1
function, then the flattened list is passed as the first argument to the Enum.map/2
function which doubles each element of the list.
In other words, the expression above simply translates to:
Enum.map(List.flatten([1, [2], 3]), fn x -> x * 2 end)
Pitfalls
There are two common pitfalls when using the pipe operator.
The first one is related to operator precedence. For example, the following expression:
String.graphemes "Hello" |> Enum.reverse
Translates to:
String.graphemes("Hello" |> Enum.reverse)
which results in an error as the Enumerable
protocol is not defined for binaries. Adding explicit parentheses resolves the ambiguity:
String.graphemes("Hello") |> Enum.reverse
Or, even better:
"Hello" |> String.graphemes |> Enum.reverse
The second pitfall is that the |>
operator works on calls. For example, when you write:
"Hello" |> some_function()
Elixir sees the right-hand side is a function call and pipes to it. This means that, if you want to pipe to an anonymous or captured function, it must also be explicitly called.
Given the anonymous function:
fun = fn x -> IO.puts(x) end fun.("Hello")
This won’t work as it will rather try to invoke the local function fun
:
"Hello" |> fun()
This works:
"Hello" |> fun.()
As you can see, the |>
operator retains the same semantics as when the pipe is not used since both require the fun.(...)
notation.
left || right (macro)
Provides a short-circuit operator that evaluates and returns the second expression only if the first one does not evaluate to true
(i.e., it is either nil
or false
). Returns the first expression otherwise.
Not allowed in guard clauses.
Examples
iex> Enum.empty?([1]) || Enum.empty?([1]) false iex> List.first([]) || true true iex> Enum.empty?([1]) || 1 1 iex> Enum.empty?([]) || throw(:bad) true
Note that, unlike or/2
, this operator accepts any expression as the first argument, not only booleans.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.3.4/Kernel.html