         languages: [%{name: "ELIXIR", type: :functional},
                     %{name: "C", type: :procedural}]}
 
-  See the functions `key/1`, `key!/1`, `elem/1` and `all/0` for the current
-  accessors.
-
-  ## Adding the Access behaviour to your own data structures
-  
-  If you want to be able to use the Access protocol 
-  with your own data structures, you can do so by adding:
-
-    @behaviour Access
-
-  inside the module that contains the struct representing your data structure.
-  You will then need to define implementations of 
-  `fetch/2`, `get/3`, `get_and_update/3` and `pop/2`,
-  which will be invoked whenever one of the Access functions is used. 
+  See the functions `key/1`, `key!/1`, `elem/1`, and `all/0` for some of the
+  available accessors.
+
+  ## Implementing the Access behaviour for custom data structures
+
+  In order to be able to use the `Access` protocol with custom data structures
+  (which have to be structs), such structures have to implement the `Access`
+  behaviour. For example, for a `User` struct, this would have to be done:
+
+      defmodule User do
+        defstruct [:name, :email]
+
+        @behaviour Access
+        # Implementation of the Access callbacks...
+      end
 
   """
 


  ## Dynamic lookups

  Out of the box, Access works with `Keyword` and `Map`:

      iex> keywords = [a: 1, b: 2]
      iex> keywords[:a]

  @type value :: any

  @doc """
  Invoked in order to access the value stored under `key` in the given term `term`.

  This function should return `{:ok, value}` where `value` is the value under
  `key` if it succeeded, or `:error` if the key does not exist in the structure.

  Many of the functions defined in the `Access` module internally call this
  function. This function is also used when the square-brackets access syntax
  (`structure[key]`) is used: the `fetch/2` callback implemented by the module
  that defines the `structure` struct is invoked and if it returns `{:ok,
  value}` then `value` is returned, or if it returns `:error` then `nil` is
  returned.


  See the `Map.fetch/2` and `Keyword.fetch/2` implementations for examples of
  how to implement this callback.
  """
  @callback fetch(term :: t, key) :: {:ok, value} | :error

  @doc """
  Invoked in order to access the value stored under `key` in the given term `term`,
  defaulting to `default` if not present.

  This function should return the value under the key `key` in `term` if there's
  such key, otherwise `default`.

  For most data structures, this can be implemented using `fetch/2` internally;
  for example:

      def get(structure, key, default) do
        case fetch(structure, key) do
          {:ok, value} -> value
          :error       -> default
        end
      end

  See the `Map.get/3` and `Keyword.get/3` implementations for more examples.
  """
  @callback get(term :: t, key, default :: value) :: value

  @doc """
  Invoked in order to access the value under `key` and updated it at the same time.

  The implementation of this callback should invoke the passed function on the
  value under key `key` in the passed structure; this function should return
  either `{value_to_return, new_value}` or `:pop`.

  If it returns `{value_to_return, new_value}`, the return value of this
  callback should be `{value_to_return, new_term}` where `new_term` is `term`
  after updating the value of `key` with `new_value`.

  If it returns `:pop`, the return value of this callback should be `{value,
  new_term}` where `value` is the value under `key` and `new_term` is `term`
  after removing the key `key`.

  See the implementations of `Map.get_and_update/3` or `Keyword.get_and_update/3`
  for more examples.
  """
  @callback get_and_update(term :: t, key, (value -> {value, value} | :pop)) :: {value, t}

  @doc """
  Invoked to "pop" the value under `key` out of the given term.

  The implementation should remove `key` from the given `term` and return a
  `{value, new_term}` tuple where `value` is the value that was under `key` and
  `new_term` is `term` without `key`.

  See the implementations for `Map.pop/2` or `Keyword.pop/2` for more examples.
  """
  @callback pop(term :: t, key) :: {value, t}

  defmacrop raise_undefined_behaviour(e, struct, top) do
    quote do
