[racket] How to make unit signature macros take prefix into account
False alarm - but thank you for making me spend time in the Macro Stepper -
it was very enlightening !
I am building a gui app that is wired-up/decoupled via messages dispatched
through the event-space queue and I am using units to encapsulate the
messaging end-points.
The problematic code was
#lang racket
;; Manager for a particular frame
(require "../util/message-channel.rkt")
(require "messages.rkt")
(require "diagram-manager.rkt")
(provide frame-manager-for)
;; Make a frame manager and return the message channel unit for it
(define (frame-manager-for frame)
; new local message channel
(use-message-channel event-space-channel@)
; manager for the diagram itself
(use-message-channel (diagram-manager-for (send frame
get-diagram-container))
as diag)
(==>
[(Show/Hide-Diagram) (diag<-- the-message)]) ; diag manager makes the
canvas
(diag==>
[(Diagram-Was-Shown) (send+ frame
(get-diagram-view-menu)
(set-label "Hide Diagram"))]
[(Diagram-Was-Hidden) (send+ frame
(get-diagram-view-menu)
(set-label "Show Diagram"))])
(unit-from-context message-channel^))
The problem turned out to be that the diagram manager was sending
Diagram-Was-Shown (a structure constructor) rather than
(Diagram-Was-Shown), which made me believe that the (diag==> ...) form was
not working. Anyway, I will make all the message structs extend a root
message struct and check for that in the ==> macro to catch this in future.
Thanks for the response !
On Wed, Aug 7, 2013 at 7:21 PM, Carl Eastlund <cce at ccs.neu.edu> wrote:
> Nick,
>
> You can't just go by the immediate expansion. Lots of temporary names are
> bound by forms like define-values/invoke-unit; it binds an internal alias
> called msg-chan-subscribe that should be defined as a rename transformer
> for diagrammsg-chan-subscribe. Can you give a full example the rest of us
> can look at, and perhaps illustrate what incorrect runtime behavior is
> caused by this problem? That will be more telling than just the textual
> name from expansion, because identifiers carry a lot of "invisible" data
> about their bindings.
>
> Carl Eastlund
>
>
> On Wed, Aug 7, 2013 at 10:00 PM, Nick Main <david.nick.main at gmail.com>wrote:
>
>> I have a signature that includes a macro to clean up the use of one of
>> the procs in the signature.
>>
>> Two different units with the same signature are used
>> via define-values/invoke-unit - the second one uses a prefix in the export
>> sig-spec to differentiate it from the first.
>> The macro introduced by the second use does not refer to the other proc
>> using the prefix.
>>
>> The concrete example:
>>
>> ;; Signature of a message channel
>> (define-signature message-channel^
>> (
>> ;; ...
>> msg-chan-subscribe ; ( (msg -> boolean) first? -> thunk)
>>
>> ;; Enqueue message(s) for a channel at normal priority
>> <-- ; ( msg .. -> void )
>>
>> ;; Enqueue message(s) for a channel at high priority
>> <++ ; ( msg .. -> void )
>>
>> ;; Macro to create a message handler.
>> ;; ...
>> (define-syntaxes (==>)
>> (syntax-rules (msg)
>> [(_ match-body ...) (msg-chan-subscribe
>> (λ(msg)
>> (syntax-parameterize
>> ([the-message (make-rename-transformer
>> #'msg)])
>> (match msg
>> match-body ...
>> [_ #t])))
>> #f)]))))
>>
>>
>> When (define-values/invoke-unit <some-unit> (import) (export (prefix
>> diagram message-channel^))) is used it introduces the bindings diagram<-- ,
>> diagram<++ , diagrammsg-chan-subscribe and diagram==> .
>>
>> The form
>>
>> (diagram==>
>> .. message handlers ..)
>>
>> expands to (msg-chan-subscribe ...) rather than (diagrammsg-chan-subscribe
>> ...) - and thus it listens to the first (wrong) message channel.
>>
>> Is there any way to make macros defined in signatures be aware of the
>> prefix used with the signature ?
>>
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130807/a2bcbf4a/attachment.html>