anchor.diff:  
   -export_type([env/0]).
   
  +%% @doc Returns a default new environment.
   -spec default() -> env().
   default() ->
     #{ context      => expr
  
positive.code: -module(clj_env).
  
  -include("clojerl.hrl").
  
negative.code:   Times1 = Times0#{Key => T + Delta},
    put(times, Times1, Env).
  
  %% @doc Push a Clojerl expression to the stack.
  -spec push_expr(expr(), env()) -> env().
  push_expr(Expr, Env = #{exprs := Exprs}) ->
    Env#{exprs => [Expr | Exprs]}.
  
  %% @doc Pop a Clojerl expression from the stack.
  -spec pop_expr(env()) -> {expr(), env()}.
  pop_expr(Env = #{exprs := [H | Exprs]}) ->
    {H, Env#{exprs => Exprs}}.
  
  %% @doc Returns the last `N' expressions that where pushed to the
  %% stack.
  %%
  %% The order of the returned expression is reversed to obtain a FIFO
  %% result. The environment returned does not contain the returned
  %% expressions.
  -spec last_exprs(integer(), env()) -> {Exprs :: [any()], Env :: 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}}.
  
  %% @doc Returns all the expressions on the stack, but in FIFO order.
  -spec exprs(env()) -> [any()].
  exprs(#{exprs := AllExprs}) -> lists:reverse(AllExprs).
  
  %% @doc Push a new local variables scope.
  %%
  %% A single local variable can be registered in the current scope by
  %% using {@link put_local/2}. It's possible to register multiple at the
  %% same time through {@link put_locals/2}.
  %%
  %% The scope can be popped using {@link remove_locals_scope/1}.
  -spec add_locals_scope(env()) -> env().
  add_locals_scope(Env = #{locals := ParentLocals}) ->
    Env#{locals => clj_scope:new(ParentLocals)}.
  
  %% @doc Pop a local variables scope.
  %%
  %% The scope can be popped using {@link remove_locals_scope/1}.
  -spec remove_locals_scope(env()) -> env().
  remove_locals_scope(Env = #{locals := Locals}) ->
    Env#{locals => clj_scope:parent(Locals)}.
  
  %% @doc Saves the local variables in the current scope and empties the
  %% scope.
  %%
  %% The saved local variables can be restored using {@link
  %% restore_locals_scope/1}.
  -spec save_locals_scope(env()) -> clj_scope:scope().
  save_locals_scope(#{locals := Locals} = Env) ->
    Env#{locals := clj_scope:new(), saved_locals := Locals}.
  
  %% @doc Restore the saved local variables to the current scope.
  %%
  %% See {@link save_locals_scope/1}.
  -spec restore_locals_scope(env()) -> env().
  restore_locals_scope(#{saved_locals := LocalsCache} = Env) ->
    Env#{locals := LocalsCache, saved_locals := ?NIL}.
  
  %% @doc Returns the information for the local variable with the name
  %% `Sym' or `undefined' if not found.
  -spec get_local('clojerl.Symbol':type(), env()) -> expr().
  get_local(Sym, _Env = #{locals := Locals}) ->
    clj_scope:get(clj_rt:str(Sym), Locals).
  
  %% @doc Returns all available local variables in the current scope.
  -spec get_locals(env()) -> [expr()].
  get_locals(#{locals := Locals}) ->
    clj_scope:values(Locals).
  
  %% @doc Adds the expression for the local variable named `Sym'.
  -spec put_local('clojerl.Symbol':type(), expr(), env()) -> env().
  put_local(Sym, Local, Env = #{locals := Locals}) ->
    Env#{locals => clj_scope:put(clj_rt:str(Sym), Local, Locals)}.
  
  %% @doc Adds the expression for multiple local variables.
  -spec put_locals([expr()], env()) -> env().
  put_locals(Locals, Env) ->
    PutLocalFun = fun(Local, EnvAcc) ->
                      Name = maps:get(name, Local),
  