guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Help: equivalent syntax-case to defmacro


From: Taylan Kammer
Subject: Re: Help: equivalent syntax-case to defmacro
Date: Wed, 6 May 2020 17:49:08 +0200
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0

On 05.05.2020 19:34, Dale Mellor wrote:
Been struggling with this for a while, and nothing I try works.

In test-suite/tests/getopt-long there is

      (defmacro deferr (name-frag re)
         (let ((name (symbol-append 'exception: name-frag)))
            `(define ,name (cons 'quit ,re))))

      (deferr no-such-option "no such option")
      (display exception:no-such-option)

and I would like to know how the equivalent with define-syntax... syntax-case 
would look.
(define-syntax deferr
  (lambda (s)
    (syntax-case s ()
      ((_ name-frag re)
       (let* ((name-frag-sym (syntax->datum #'name-frag))
              (name-sym (symbol-append 'exception: name-frag-sym))
              (name (datum->syntax #'name-frag name-sym)))
         #`(define #,name (cons 'quit re)))))))

Some notes to help understand this:

- Syntax-case deals with syntax objects rather than raw symbols. We use syntax->datum to turn 'name-frag' into a symbol and datum->syntax to turn it back into a syntax object.
- For some reason, the pattern variables bound via syntax-case (i.e. 
'name-frag' and 're' in our case) are forbidden by syntax-case to be 
referenced outside of a #' or #` form.  They must always appear in one 
of those, period.  Hence we have to call (syntax->datum #'name-frag) 
instead of simply (syntax->datum name-frag).  Honestly I still don't 
know why they designed it this way.
- The datum->syntax form requires its first argument to be an existing 
syntax object, which will tell datum->syntax for which "syntax context" 
you're creating your new syntax object.  In this case I'm passing it 
#'name-frag because the context where that comes from is the context in 
which the resulting full name will be used.
- In the output form starting with #` the 're' pattern variable can 
appear naked, whereas the manually created 'name' syntax object must be 
inserted with the #, form.  (This is related to the same design 
weirdness I mentioned before so don't ask me why.)

Hope that helps! Happy to answer further questions. Syntax-case is very tricky but once you get it, it's amazing.
- Taylan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]