anchor.diff:                    , mappings => map()
                     }.
   
  +%% @doc Creates a new empty scope.
   -spec new() -> scope().
   new() -> new(?NIL).
   
  +%% @doc Creates a scope with an assigned parent.
   -spec new(scope() | ?NIL) -> scope().
   new(Parent) ->
    #{ parent   => Parent
     , mappings => #{}
     }.
   
  +%% @doc Returns the parent of the current scope.
   -spec parent(scope()) -> scope() | ?NIL.
   parent(?NIL)  -> ?NIL;
   parent(Scope) -> maps:get(parent, Scope).
   
  +%% @equiv get(Key, undefined, Scope)
   -spec get(any(), scope()) -> any().
   get(Key, Scope) ->
     get(Key, ?NIL, Scope).
   
  +%% @doc Gets a value from the current scope or `Default' if not
  +%% found.
   -spec get(any(), any(), scope()) -> any().
   get(Key, Default, Scope) ->
     do_get(Key, Default, Scope).
   
  +%% @doc Checks whether `Key' is in the current scope.
   -spec contains(any(), scope()) -> boolean().
   contains(Key, Scope) ->
     do_contains(Key, Scope).
   
  +%% @doc Adds a value to the current scope.
   -spec put(any(), any(), scope()) -> scope().
   put(Key, Value, Scope = #{mappings := Mappings}) ->
     Scope#{mappings => Mappings#{Key => Value}}.
   
  +%% @doc Adds all values in `Map' to the current scope.
   -spec put(map(), scope()) -> scope().
   put(Map, Scope) ->
     PutFun = fun(Key, Acc) ->
  
positive.code:       end
    end.
  
  -spec do_values([any()], scope()) -> [any()].
  do_values(Values, ?NIL) ->
    Values;
  do_values(Values, #{mappings := Mappings, parent := Parent}) ->
    do_values(maps:values(Mappings) ++ Values, Parent).
  
negative.code: %% @doc Nested scopes.
  %%
  %% Implements nested scopes through nested maps. This is heavily used
  %% in all throughout the compilation process, from the reader to the
  %% emitter.
  -module(clj_scope).
  
  -include("clojerl.hrl").
  