[R6RS] Bawden quasiquote extension

dyb at cs.indiana.edu dyb at cs.indiana.edu
Fri Jun 23 10:17:06 EDT 2006


> Just to be clear, you're proposing that
> 
> (unquote <exp> ...)
> 
> gets a list of the values of <exp> ... plugged into the quasiquote
> from, right?
> 
> I guess that's fine, but it does look a bit strange in that the list
> construction with unquote suddenly gets introduced by moving from 1 to
> n>1 arguments.  I think I would prefer if the unquote were duplicated.
> 
> I'm not sure how that relates to "Bawden's quasiquote extensions," as
> Alan's expander assumes that there's only one operand to unquote:
> 
> (qq-expand '`(foo (unquote (union x y) (list 'sqrt 9))))
> =>
> (append '(append) (append (list (append '(quote) (append (list (append '(foo) '(
> ))) '()))) (append (list (append '(append) (append (list (append '(list) (append
>  (list (append '(union) (append '(x) (append '(y) '())))) '()))) (append (list (
> append '(quote) (append '(()) '()))) '())))) '())))
> 
> (The (sqrt 9) disappears.)

Ack.  You're right.

This has finally jogged my memory.  Alan and I had an exchange about this
after his paper appeared.  Alan had claimed that Chez Scheme and many
other Scheme implementations got quasiquote wrong, and I emailed him to
ask about it.  During the course of the exchange, we agreed that his PEPM
notion of quasiquote was not compatible with R5RS, prompting him to
propose a new mechanism.  I've included his proposal below.  It is this
proposal that I was thinking was in his PEPM paper, that the syntax-case
reference implementation implements, and that I'd like to incorporate into
R6RS.

I apologize for the confusion.

Kent

--------

> I think the code below has all these desireable properties.  It requires a
> conservative extension to the way `unquote' and `unquote-splicing' are
> currently described in R5RS -- i.e. no old programs should notice the
> extension.  The basic idea is that we allow `unquote' and
> `unquote-splicing' to contain a -sequence- of expressions.  When expanding
> a quasiquotation, if you're in a context where splicing is allowed, the
> expressions in
> 
>   (unquote <expr1> <expr2> <expr3>)
> 
> always appear in the expansion as successive arguments in a call to `list':
> 
>   (list <expr1> <expr2> <expr3>).
> 
> Similarly, the expressions in
> 
>   (unquote-splicing <expr1> <expr2> <expr3>)
> 
> always appear in the expansion as successive arguments in a call to `append':
> 
>   (append <expr1> <expr2> <expr3>).
> 
> If you're expanding in a context where splicing -isn't- allowed, then only
> `(unquote <expr>)' is legal.
> 
> I'm working on a version of this code that generates a reasonable exansion,
> but it won't be as clear as this version.
> 
> Let me know what you think.
> 
>                                 - Alan
> 
> ------- Begin Code -------
> 
> (define (ev x)
>   (eval (qq-expand-toplevel x)
>         (interaction-environment)))
> 
> (define (qq-expand-toplevel x)
>   (if (eq? 'quasiquote (car x))
>       (qq-expand (cadr x) 0)
>       x))
> 
> (define (qq-expand x depth)
>   (if (pair? x)
>       (case (car x)
>         ((quasiquote)
>          `(cons ',(car x) ,(qq-expand (cdr x) (+ depth 1))))
>         ((unquote unquote-splicing)
>          (cond ((> depth 0)
>                 `(cons ',(car x) ,(qq-expand (cdr x) (- depth 1))))
>                ((and (eq? 'unquote (car x))
>                      (not (null? (cdr x)))
>                      (null? (cddr x)))
>                 (cadr x))
>                (else 
>                 (error "Illegal"))))
>         (else
>          `(append ,(qq-expand-list (car x) depth)
>                   ,(qq-expand (cdr x) depth))))
>       `',x))
> 
> (define (qq-expand-list x depth)
>   (if (pair? x)
>       (case (car x)
>         ((quasiquote)
>          `(list (cons ',(car x) ,(qq-expand (cdr x) (+ depth 1)))))
>         ((unquote unquote-splicing)
>          (cond ((> depth 0)
>                 `(list (cons ',(car x) ,(qq-expand (cdr x) (- depth 1)))))
>                ((eq? 'unquote (car x))
>                 `(list . ,(cdr x)))
>                (else
>                 `(append . ,(cdr x)))))
>         (else
>          `(list (append ,(qq-expand-list (car x) depth)
>                         ,(qq-expand (cdr x) depth)))))
>       `'(,x)))



More information about the R6RS mailing list