anchor.diff:                  end,
     lists:foldl(PutLocalFun, Env, Locals).
   
  +%% @equiv get(Name, undefined, Env)
   -spec get(atom(), env()) -> any().
   get(Name, Env) ->
     get(Name, ?NIL, Env).
   
  +%% @doc Get a value stored in the environment or `Default' if not
  +%% found.
   -spec get(atom(), any(), env()) -> any().
   get(Name, Default, #{mapping := Mapping}) ->
     clj_scope:get(Name, Default, Mapping).
   
  +%% @doc Push a custom `Mapping' into the custom scope {@link clj_scope}.
   -spec push(map(), env()) -> env().
   push(Mapping, Env = #{mapping := Parent}) ->
     Child = clj_scope:new(Parent),
     Env#{mapping := clj_scope:put(Mapping, Child)}.
   
  +%% @doc Update a value in the custom scope {@link clj_scope:update/3}.
   -spec update(any(), any(), env()) -> env().
   update(Name, Value, Env = #{mapping := Mapping}) ->
     Env#{mapping := clj_scope:update(Name, Value, Mapping)}.
   
  +%% @doc Put a value in the custom scope {@link clj_scope:put/3}.
   -spec put(any(), any(), env()) -> env().
   put(Name, Value, Env = #{mapping := Mapping}) ->
     Env#{mapping := clj_scope:put(Name, Value, Mapping)}.
   
  +%% @doc Pop the custom scope.
   -spec pop(env()) -> env().
   pop(Env = #{mapping := Parent}) ->
     Env#{mapping := clj_scope:parent(Parent)}.
  
positive.code:   Times1 = Times0#{Key => T + Delta},
    put(times, Times1, Env).
  
  -spec push_expr(expr(), env()) -> env().
  push_expr(Expr, Env = #{exprs := Exprs}) ->
    Env#{exprs => [Expr | Exprs]}.
  
  -spec pop_expr(env()) -> {expr(), env()}.
  pop_expr(Env = #{exprs := [H | Exprs]}) ->
    {H, Env#{exprs => Exprs}}.
  
  -spec last_exprs(integer(), env()) -> {[any()], env()}.
  last_exprs(N, Env = #{exprs := AllExprs}) when N >= 0 ->
    Exprs = lists:sublist(AllExprs, N),
    RestExprs = lists:sublist(AllExprs, N + 1, length(AllExprs)),
    {lists:reverse(Exprs),
     Env#{exprs => RestExprs}}.
  
  -spec exprs(env()) -> [any()].
  exprs(#{exprs := AllExprs}) -> lists:reverse(AllExprs).
  
  -spec add_locals_scope(env()) -> env().
  add_locals_scope(Env = #{locals := ParentLocals}) ->
    Env#{locals => clj_scope:new(ParentLocals)}.
  
  -spec remove_locals_scope(env()) -> env().
  remove_locals_scope(Env = #{locals := Locals}) ->
    Env#{locals => clj_scope:parent(Locals)}.
  
  -spec save_locals_scope(env()) -> clj_scope:scope().
  save_locals_scope(#{locals := Locals} = Env) ->
    Env#{locals := clj_scope:new(), saved_locals := Locals}.
  
  -spec restore_locals_scope(env()) -> env().
  restore_locals_scope(#{saved_locals := LocalsCache} = Env) ->
    Env#{locals := LocalsCache, saved_locals := ?NIL}.
  
  -spec get_local('clojerl.Symbol':type(), env()) -> any().
  get_local(Sym, _Env = #{locals := Locals}) ->
    clj_scope:get(clj_rt:str(Sym), Locals).
  
  -spec get_locals(env()) -> [any()].
  get_locals(#{locals := Locals}) ->
    clj_scope:values(Locals).
  
  -spec put_local('clojerl.Symbol':type(), any(), env()) -> env().
  put_local(Sym, Local, Env = #{locals := Locals}) ->
    Env#{locals => clj_scope:put(clj_rt:str(Sym), Local, Locals)}.
  
  -spec put_locals([map()], env()) -> env().
  put_locals(Locals, Env) ->
    PutLocalFun = fun(Local, EnvAcc) ->
                      Name = maps:get(name, Local),
  
negative.code: %% @doc Clojerl compilation environment.
  %%
  %% `clj_env:env()' holds the information for the current compilation
  %% environment. It is used by all the compilation stages: the
  %% `clj_reader', the `clj_analyzer' and the `clj_emitter'.
  %%
  %% Some examples of the information it keeps are:
  %% <ul>
  %%   <li>Local variables available in the current scope.</li>
  %%   <li>Current location in the file or string being processed.</li>
  %%   <li>Stack of expressions added by the `clj_analyzer'.</li>
  %%   <li>... and more.</li>
  %% </ul>
  -module(clj_env).
  
  -include("clojerl.hrl").
  