You can "pass" information from one macro to another by binding information
to an identifier defined to be a syntax parameter that both macros have in
scope. You would need to functionally update its value for each rebinding. Its
value would be retrievable with syntax-local-value.
(define-syntax-parameter my-let-info #f)
;; in definition of my-let:
#'(syntax-parameterize ([my-let-info (cons more-info (syntax-local-value
I would recommend that way over a big free-identifier-table that's mutated
by my-let and read by access, since those tables don't persist their values
across builds, and you can get into scoping problems with what an
identifier could possibly mean.
On Mon, Apr 16, 2018 at 4:03 PM Dmitry Pavlov <dpav...@iaaras.ru> wrote:
> Thank you, this is impressive and helpful. I did not know about
> syntax-local-value (I also am not certain that I know it now good enough).
> However, I did not mean to use the (my-let)'s "definition" of x to pass
> information to (access). (Also, can (access y) fail in a customizable way?)
> I was wondering if there is a way to just pass any information (list of
> variables, which can be empty, or whatever else) from (my-let) to (access).
> Best regards,
> On 17.04.2018 1:18, Dionna Amalie Glaze wrote:
> syntax-local-value is likely what you'll want to use here. You can bind
> your x to a compile-time value that you can access with syntax-local-value.
> You can even make that value a struct with #:procedure prop:procedure and
> have its procedure be a syntax transformer (so it can expand into something
> meaningful outside its use by access).
> #lang racket
> (require (for-syntax syntax/parse racket/list syntax/transformer))
> (struct communicate (syntax value) #:prefab))
> (define-syntax (access stx)
> (syntax-parse stx
> [(_ x:id)
> #:fail-unless (communicate? (syntax-local-value #'x))
> (format "Expected ~a to be bound by my-let" (syntax-e #'x))
> (define slv (syntax-local-value #'x))
> #`(list #,(communicate-syntax slv) 'has-tree-nodes
> '#,(communicate-value slv))]))
> (define-syntax (my-let stx)
> (syntax-parse stx
> [(_ ([x:id e:expr] ...) body:expr)
> #'(let-syntax ([x (communicate #'e
> (length (flatten (syntax->datum #'e))))] ...)
> (my-let ([x '(a b ((c d) 4) (5 9))])
> (access x))
> '((a b ((c d) 4) (5 9)) has-tree-nodes 8)
> (the answer is 8 and not 7 because it's counting the 'quote in the syntax)
> On Mon, Apr 16, 2018 at 2:16 PM Dmitry Pavlov <dpav...@iaaras.ru> wrote:
>> I would like to write two seemingly simple macros and I found
>> no way to do it.
>> (my-let ((x 2))
>> (access x)
>> (access y)))))
>> I would like the (access) macro to know at compile (expansion)
>> time that x is up there in (my-let) macro and y is not.
>> I tried the following:
>> - save information about 'x during (my-let) expansion
>> in a parameter (present in expander but not in
>> expanded code) and check that parameter in (access).
>> This does not seem to work, probably because of
>> the way expansion works.
>> - attach information as a property to syntax object
>> generated by (my-let), then bring it all the way down
>> (that requires redefining begin) and get it back
>> from syntax object in (access). That works, but is
>> a pain.
>> - explicitly call (expand-syntax) for (my-let)'s body
>> in (my-let)'s expansion. Does not work because (access)
>> is not yet available at that point.
>> - find and read "Macros that work together" my Flatt et al.
>> Well, I did try to find what I need, until the code
>> has switched from Racket to some other fancy language
>> and then I am stuck.
>> Any advice please?
>> Best regards,
>> You received this message because you are subscribed to the Google Groups
>> "Racket Users" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to racket-users+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
> -Dionna Glaze, PhD (she/her)
-Dionna Glaze, PhD (she/her)
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
For more options, visit https://groups.google.com/d/optout.