Amalie,
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,
Dmitry
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))
(begin-for-syntax
(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))))] ...)
body)]))
(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
<mailto:dpav...@iaaras.ru>> wrote:
Hello,
I would like to write two seemingly simple macros and I found
no way to do it.
(my-let ((x 2))
(begin
(begin
(begin
(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,
Dmitry
--
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
<mailto:racket-users%2bunsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.
--
-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
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.