[racket-dev] except-out oddity

From: Eli Barzilay (eli at barzilay.org)
Date: Sat Feb 12 23:28:47 EST 2011

Using (except-out whatever x) will omit not only `x', but also any
other names that `x' is provided as.  For example:

  (module A racket
    (define x 1)
    (provide x (rename-out [x y])))
  (module B racket
    (require 'A)
    (provide (except-out (all-from-out 'A) x)))
  (module C racket
    (require 'B)
    y) ; error

and it goes the other way too (excluding `y' and trying to use `x').
When I saw this, it seemed familiar so I looked at the docs.  My guess
is that this:

  The symbolic export name information in the latter provide-specs is
  ignored; only the bindings are used.

is saying that the above is expected.  If so, then it looks like it
should definitely be clarified, maybe move this sentence after the
example, explain the specific (common) case of excluding a name that
was provided with a different name, and also adding an example for

But at a higher level, is there a reason to not look at the name?  It
seems bad in that the two options of
  1. (define x y) (provide x)
  2. (provide (rename-out [y x]))
can lead to a different result, where the second one ties the two
names for this kind of filtering.  It's also weird that the two names
are the same for `except-out' but in an `except-in' they're still

And BTW, it's also surprising that the exceptions are provide-specs,
which makes these:

  (provide (except-out (all-from-out 'A) (rename-out [y foo])))
  (provide (except-out (all-from-out 'A) (prefix-out foo y)))

be the same as the above.  Is this ever useful?

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.