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.

Reply via email to