
context::new := λ . (
   (Context(
      ()
      0
   ))
);

context::lookup := λ ctx key key-type . (tail(
   (local bindings)
   (set bindings (context::get-bindings ctx))
   (local return)
   (while bindings (tail(
      (if (eq( key (head(tail bindings)) )) (tail(
         (if key-type (tail(
            (local body)
            (set body (tail(tail bindings)))
            (local body-type)
            (set body-type (typecheck-lookup body))
            (if (not body-type) (
               (fail (UntypedBinding body))
            ) ())
            (if (not(eq( '-> (head(typecheck-slot( body-type '-> ))) ))) (tail(
               (set return body)
               (set bindings ())
            )) (
               (if (typecheck-apply-plural( body-type key-type )) (tail(
                  (set return body)
                  (set bindings ())
               )) ())
            ))
         )) (tail(
            (set return (tail(tail bindings)))
            (set bindings ())
         )))
      )) ())
      (set bindings (head bindings))
   )))
   return
));

context::bind := λ ctx key term . (match ctx (
   ()
   ( (Context( old-ctx offset )) (tail(
      ()
      (Context( (old-ctx (key term)) offset ))
   )))
));

context::get-bindings := λ ctx . (match ctx (
   ()
   ( (Context( bindings _ )) bindings )
));

context::get-offset := λ ctx . (match ctx (
   ()
   ( (Context( _ offset )) offset )
));

context::set-offset := λ ctx offset . (match ctx (
   ()
   ( (Context( bindings _ )) (Context( bindings offset )) )
));
