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

Re: Opaque syntax objects



Keith Wright wrote:

As an example of a macro written using normal Scheme operators and
these syntactical abbreviations, I have taken the macro do-primes
from "Practical Common Lisp" p. 94.

I do not see the point of this example. I just ran the following through the SRFI reference implementation,
it works fine.

That's (part of) the point. Felix asked:

  But wouldn't this completely break the (IMHO) rather practical ability
  to destructure arguments passed to macros via normal Scheme operators?
  What I like about srfi-72 is that I can write hygienic macros with
  (nearly) the same ease as in conventional Lisp-/quasiquote-style. In
  fact this is what I consider the most innovative feature for SRFI-72.

So the do-primes example shows that the abstract approach too allows
for i) destructuring with normal Scheme operations and ii) that
macros can be written in the traditional quasiquote-style.

The template
happens to be a loop, but so what?
A more interesting example would do the loop in the macro expander.
I don't have time right now to work up a prime example, but here
is one I have laying about:

(define-syntax define-count
  (lambda (form)
      #`,(let loop ((names (cdr form))
                    (k 0)
                    (result '()))
           (if (null? names)
               (quasisyntax (begin ,@result))
                  (loop (cdr names)
                        (+ k 1)
                        (cons #`(define ,(car names) ,k))
                              result)))))

Adding one syntax->list and replacing , and ,@ with
#, and #,@ one gets:

(define-syntax define-count
  (lambda (form)
      #`#,(let loop ((names (cdr (syntax->list form)))
                     (k 0)
                     (result '()))
            (if (null? names)
                (quasisyntax (begin #,@result))
                (loop (cdr names)
                      (+ k 1)
                      (cons #`(define #,(car names) #,k)
                            result))))))

which runs in DrScheme.

For fun, here is a syntax-case version:

(require-for-syntax (lib "list.ss" "srfi" "1"))
(define-syntax (define-count stx)
  (syntax-case stx ()
    [(define-count name ...)
     (with-syntax ([(count ...)
                    (iota (length (syntax->list #'(name ...))))])
       #'(begin
           (define name count)
           ...))]))

A macro whose expansion uses quasiquote to construct a list can
be hard to read (and write), if ordinary lists are used to represent
syntax. It is not immediately obvious whether a given quasiquote
is used to construct the expansion or is a part of the expansion
of a call to the macro.

Indeed, nested quasiquote is notoriously mind-bending.
What part of the SRFI should be changed to fix that?
How does a lot of syntax->list help?

It isn't syntax->list that help.

Spotting #' or #` signals that here a piece of code is constructed.
Spotting  ' or  ` signals that a list will be constructed, when
the expanded code is run.

--
Jens Axel Søgaard