Making your suggested change corrects the issue with prefixes happening in what seems to be reverse order, but the interaction between prefix and rename together still has some problems. For example:
(define-signature a^ (a))
(define u-bad
(unit (import (prefix x: (rename (prefix y: a^) (q y:a))))
(export)
x:q))
Complains that x:q is an unbound identifier, but changing x:q to simply q works. It seems to me that prefixes pass through renames in such a way that the above seems to be the same as:
(rename (prefix x: (prefix y: a^)) (q x:y:a))
According to the docs though it seems as though the correct behavior should be to also prefix q, so that x:q is bound rather than simply q.
I think this stems from the following lines in "collects/racket/private/unit-compiletime.rkt".
(do-rename (process-import/export #'sub-spec res bind? add-prefix)
#'(internal ...)
(datum->syntax #f (add-prefixes add-prefix #'(external ...)))))
Changing #'(internal ...) to
(datum->syntax #f (add-prefixes add-prefix #'(internal ...)))
So that any outer prefixing applies to both sets of identifiers in a rename form seems to fix the problems I've been experiencing.
I think the current implementation/documentation disagreement is probably a bug, but I'm not sure if the bug is with the implementation or with the documentation. The current implementation is difficult to reason about when looking at prefix/rename clauses like the above and doesn't match what the documentation specifies.
I have a branch with the above fixes and can submit a pull request if it would be better to have the implementation match the current documentation. but if it would be better to keep the current implementation I can try to add to the documentation to correctly specify the current behavior.
Thanks for all the help
Dan
----- Forwarded Message -----
From: "Matthew Flatt" <mflatt at cs.utah.edu>
To: dfeltey at ccs.neu.edu
Cc: users at racket-lang.org
Sent: Friday, May 9, 2014 8:39:02 PM GMT -05:00 US/Canada Eastern
Subject: Re: [racket] prefix/rename for signatures in unit and define-signature forms
I think the problem is with `process-import/export` in
"collects/racket/private/unit-compiletime.rkt".
If you change
(do-prefix (add-prefix id) #'pid)
to
(add-prefix (do-prefix id #'pid))
then it looks like the tests still pass, and your examples work more as
expected. I'm not sure it's as simple as that; can you take a closer
look there?
At Fri, 9 May 2014 16:39:34 -0400 (EDT), dfeltey at ccs.neu.edu wrote:
> I've been digging in to this some more, and it seems that the prefix form works
> backwards on a sig-spec, for example:
>> (define-signature a^ (a))
> (define-signature dcc^ ((open (prefix d: (prefix c: (prefix c: a^))))))
> (define [email protected] (unit (import dcc^) (export) c:c:d:a))
>> (unit (import)
> (export (prefix d: (prefix c: (prefix c: a^))))
> (define c:c:d:a 5))
>> This makes some sort of sense, I suppose, but it doesn't really match what the
> docs seem to say.
>> On the other hand rename does seem to work in expected way when used by itself:
>> (define-signature da^
> ((open (rename (rename (rename a^ (b a)) (c b)) (d c)))))
> (unit (import da^) (export) d)
> (unit (import (rename (rename (rename a^ (b a)) (c b)) (d c))) (export) d)
>> When I try to nest different combinations of rename and prefix together,
> however, I get the strange behavior I was experiencing yesterday, and I cannot
> figure out how to correctly reason about what the resulting bindings should be.
>> Thanks
> Dan
>>> ----- Original Message -----
> From: dfeltey at ccs.neu.edu> To: users at racket-lang.org> Sent: Thursday, May 8, 2014 4:56:52 PM GMT -05:00 US/Canada Eastern
> Subject: [racket] prefix/rename for signatures in unit and define-signature
> forms
>> I'm trying to make sense of how prefix/rename work for signatures, but in
> trying to run some examples the actual implementation doesn't seem to match
> either my intuition or the documentation.
>> For example I have the following simple signature:
>> (define-signature a^ (a))
>> I then try to build a new signature from a^ with a combination of open and
> prefix/rename.
>> (define-signature b-bad^
> ((open (prefix x: (rename (prefix y: a^) (q y:a))))))
>> This example, however, gives the error:
> "open: listed identifier not present in signature specification in: x:y:a"
>> I'm not sure I understand this since it appears as though prefixing x: comes
> before the renaming, but I would have though that first y: is prefixed to a, so
> that y:a is in the signature which can then be renamed q. So in the end the
> only variable in the signature should be x:q.
>> Attempting the same in a unit form gives a similar error:
>> (define u-bad
> (unit (import (prefix x: (rename (prefix y: a^) (q y:a))))
> (export)
> x:q))
> "unit: listed identifier not present in signature specification in: x:y:a"
>>> If I change the prefix x: to y: things seem to work for some reason.
>> (define-signature b-good^
> ((open (prefix y: (rename (prefix y: a^) (q y:a))))))
>> In this case, I still expect the variable in the signature to be something like
> y:q, but trying a similar renaming in a unit form fails:
>> (define u-bad2
> (unit (import (prefix y: (rename (prefix y: a^) (q y:a))))
> (export)
> y:q))
>> With the error:
> "y:q: unbound identifier in module in: y:q"
>> while the following does work
>> (define u-good
> (unit (import (prefix y: (rename (prefix y: a^) (q y:a))))
> (export)
> q))
>>> Am I misunderstanding something obvious about the way that the
> renaming/prefixing should be taking place on the level of a signature or unit
> import/export clause? The results I'm seeing are completely unintuitive to me
> and the documentation doesn't seem to clarify this for me.
>> Thanks
> Dan
> ____________________
> Racket Users list:
>http://lists.racket-lang.org/users> ____________________
> Racket Users list:
>http://lists.racket-lang.org/users