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

Re: Opaque syntax objects

This page is part of the web mail archives of SRFI 72 from before July 7th, 2015. The new archives for SRFI 72 contain all messages, not just those from before July 7th, 2015.



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