* how to remove shadowed bindings?

* how to remove shadowed bindings?
  option 1: add new bindings to front of list; remove shadowed bindings
    from middle, but preserve ordering.
  option 2: add only non-shadowing bindings to front of list; all shadowing
    bindings will (functionally) replace existing bindings.

  option 1 is O((n + m)^2); option 2 is O(nm), where n is # bindings in
  existing environment and m is # bindings being added.  When n << m or
  vice versa, option 2 is more efficient; when n and m are approximately
  equal, neither implementation is asymptotically faster than the other.

  For displaying to users, though, option 1 is probably more intuitive,
  since the bindings appear in the order in which they were added to the
  environment.  In option 2, the order is less predictable.

* decent contracts on the library.  Could actually write some decent
  contracts if make-empty-env took 2 additional arguments, predicates that
  recognized valid keys and values, respectively.  Then the contracts could
  extract these predicates and use them in the appropriate positions.

  But do people want to have to supply these predicates to make-empty-env?

* Enforcing predicate condition on weaken-env:
  1) specify a contract for the argument that imposes this condition.  What
     would the error message look like for a violation?  (Suggested by Dave

  2) Dave's other suggestion, coerce the new predicate to ensure that it's
     less precise.  That is, use
        (lambda (x y) (or (old-eq? x y) (new-eq? x y)))

  3) Similar to #1, wrap the function in a new lambda that raises an
     exception if the condition is violated.  Somewhat simpler, and I've
     got more control over the error message.

  I think #3 is best: I don't like implicit coersions, and it's easier to
  implement than #1.  I'm willing to revisit this issue later, if there is

* env-domain: We don't want the user to be able to mutate the list of keys
  actually in the environment itself; that could violate invariants.  Two
  1) Make the list in the env struct immutable and simply return it.
     env-domain is O(1), but extend-env is now slower, as it requires an
     additional O(n) pass across the list.  (Asymptotic complexity
  2) Copy the list on demand.  env-domain now O(1).

  I've gone with option 2, on the grounds that you shouldn't have to pay
  for this feature unless you use it.

* Should I use env/c instead of env? in contracts?  Slower, and can't
  really use anything except any/c for keys and values, but better error