Kernel.def

You're seeing just the macro def, go back to Kernel module for more information.
Link to this macro

def(call, expr \\ nil)

View Source (macro)

Defines a public 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.

Default arguments

\\ is used to specify a default value for a parameter of a function. For example:

defmodule MyMath do
  def multiply_by(number, factor \\ 2) do
    number * factor
  end
end

MyMath.multiply_by(4, 3)
#=> 12

MyMath.multiply_by(4)
#=> 8

The compiler translates this into multiple functions with different arities, here MyMath.multiply_by/1 and MyMath.multiply_by/2, that represent cases when arguments for parameters with default values are passed or not passed.

When defining a function with default arguments as well as multiple explicitly declared clauses, you must write a function head that declares the defaults. For example:

defmodule MyString do
  def join(string1, string2 \\ nil, separator \\ " ")

  def join(string1, nil, _separator) do
    string1
  end

  def join(string1, string2, separator) do
    string1 <> separator <> string2
  end
end

Note that \\ can't be used with anonymous functions because they can only have a sole arity.

Keyword lists with default arguments

Functions containing many arguments can benefit from using Keyword lists to group and pass attributes as a single value.

defmodule MyConfiguration do

 @default_opts [storage: "local"]

 def configure(resource, opts \\ []) do
   opts = Keyword.merge(@default_opts, opts)
   storage = opts[:storage]
   # ...
 end

end

The difference between using Map and Keyword to store many arguments is Keyword's keys:

  • must be atoms
  • can be given more than once
  • ordered, as specified by the developer

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

rescue/catch/after/else

Function bodies support rescue, catch, after, and else as Kernel.SpecialForms.try/1 does (known as "implicit try"). For example, the following two functions are equivalent:

def convert(number) do
  try do
    String.to_integer(number)
  rescue
    e in ArgumentError -> {:error, e.message}
  end
end

def convert(number) do
  String.to_integer(number)
rescue
  e in ArgumentError -> {:error, e.message}
end