On Sun, 24 Apr 2011, Alex Shinn wrote: > On Sun, Apr 24, 2011 at 9:04 AM, Andre van Tonder <andre@het.brown.edu> wrote: >> and (unquote-splicing <expression> ...)? >> >> In other words, more than one argument to UNQUOTE(-SPLICING). >> >> These were added in R6RS to fix some well-known shortcomings of quasiquote. >> The issue and the R6RS solution had been known for a long time and were >> discussed by many authors for many years before being adopted. >> I for one liked the change and probably have code that depends on it. > > It looks reasonable to me, but could you point us > to the discussions or rationales? > > Specifically, how is (unquote-splicing a b c) different from > ,@a ,@b ,@c ? I think the issue is a little more complex that this, it has to do with the fact that nested unquote-splicing was accidentally broken in Scheme, but since I don't remember the details offhand, let me quote Al* Petrofsky on this issue. By the way, the solution he suggests was not the one adopted for R6RS - instead I think R6RS adopted the Chez fix he mentions, probably becasue it is more backwards compatible and there was more experience with it. Anyway, here is Petrofsky's discussion: From: Alf Petrofsky <alf@petrofsky.org> Newsgroups: comp.lang.scheme Subject: Re: getting a list into a macro Date: 27 Nov 2001 16:39:42 -0800 Message-ID: <87k7wbbuep.fsf@radish.petrofsky.org> ds26@goldshoe.gte.com (Dorai Sitaram) writes: >(define-macro create-class > (lambda (superclass slots . methods) > `(create-class-proc > ,superclass > (list ,@(map (lambda (slot) `',slot) slots)) > (list ,@(map (lambda (method) `',(car method)) methods)) > (vector ,@(map (lambda (method) `,(cadr method)) methods))))) This quasiquotation seems overly complicated to me. Is there any reason you don't write it more simply, like this: (define-macro create-class (lambda (superclass slots . methods) `(create-class-proc ,superclass ',slots ',(map car methods) (vector ,@(map cadr methods))))) -al P.S. The vector should be further abbreviable to `#(,,@(map cadr methods)), but unfortunately the r5rs specification of quasiquote is broken with respect to nested unquote-splicing. Chez scheme supports such quasiquotations as a compatible extension to the r5rs semantics. P.P.S. Common Lisp specifies nested quasiquotation in a way that makes ,,@expr useful. When nested quasiquote was added to scheme in r3rs, it was intended to be compatible with lisp. Because the method of specification was turned inside out from the lisp method, it was not noticed that nested quasiquotation had been broken. One way to make scheme compatible with common lisp would be to add the following to r5rs: When a comma at-sign and the expression that follows it are being replaced by the elements of the list that resulted from the expression's evaluation, any sequence of commas and comma at-signs that immediately preceeded the comma at-sign is also removed and is added to the front of each of the replacements. (let ((x '(a b c))) ``(,,x ,@,x ,,@x ,@,@x)) => `(,(a b c) ,@(a b c) ,a ,b ,c ,@a ,@b ,@c) ``(,,@'() ,@,@(list)) => `() `````(a ,(b c ,@,,@,@(list a b c))) => ````(a ,(b c ,@,,@a ,@,,@b ,@,,@c)) When I discovered this problem, I couldn't find anything that had been written about it, so I started to prepare a long-winded missive and a srfi. The work withered after I discovered the chez scheme fix and couldn't decide whether I preferred their approach (uglier, but more backwards-compatible) or mine. This postscript, and the excuse for an article that preceeded it, are an attempt to at least get something about the subject into google. Here's a simple implementation of the above specification: ;; As an undocumented "feature" this takes optional extra arguments, ;; which must all be #f. One level of unquotation is ignored per ;; extra argument supplied. (define-syntax quasiquote (syntax-rules (unquote unquote-splicing quasiquote) ((_ ,x ) x) ((_ (,@x . y) ) (append x `y)) ((_ `x . d) (list 'quasiquote (quasiquote x #f . d))) ((_ ,x #f . d) (list 'unquote (quasiquote x . d))) ((_ (,x . y) #f . d) (append (map (lambda (z) (list 'unquote z)) (quasiquote (x) . d)) (quasiquote y #f . d))) ((_ (,@x . y) #f . d) (append (map (lambda (z) (list 'unquote-splicing z)) (quasiquote (x) . d)) (quasiquote y #f . d))) ((_ (x . y) . d) (cons (quasiquote x . d) (quasiquote y . d))) ((_ #(x ...) . d) (list->vector (quasiquote (x ...) . d))) ((_ x . d) 'x))) _______________________________________________ Scheme-reports mailing list Scheme-reports@scheme-reports.org http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports