[racket-dev] except-out oddity
At Sat, 12 Feb 2011 23:28:47 -0500, Eli Barzilay wrote:
> 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
> this?
Ok, I'll try to clarify in the docs.
> But at a higher level, is there a reason to not look at the name?
I think it interacts badly with `require'- and `provide'-generating
macros.
> 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.
I'm not sure I understand what you mean. Do you mean that `x' is
different from `(rename-out [y x])' when wrapped with `(except-out ...
y)'?
> It's also weird that the two names
> are the same for `except-out' but in an `except-in' they're still
> separate.
If I'm following, then I think it derives from the difference between
bindings and uses and how those interact with macros.
A variant of `except-out' that refers to external names instead of
internal bindings may be useful, too.
> 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?
I think I've probably used `struct-out' in the second part of
`except-out', but that's the only example that comes to mind.