[r6rs-discuss] Use backquote in "case"

MichaelL at frogware.com MichaelL at frogware.com
Sun Nov 12 16:11:03 EST 2006


>  | (I was interested in feedback on the following before submitting a 
formal 
>  | comment.)

Thanks to everyone for the feedback. I've decided not to submit the 
comment. From my perspective, it's still true that case is broken in the 
sense that you can't use it with constants (or, more specifically, named 
values); having said that, the problem with case is the hidden quote. 
Changing that to backquote addresses the symptom rather than the cause. At 
this point I think it would make more sense to suggest a different kind of 
control structure, one that selects from a number of clauses but leaves it 
to the user to decide whether those clauses contain quoted values, 
backquoted values, function calls, etc. At this point, though, I don't 
think that that should be an R6RS issue. If anything, it sounds more like 
an SRFI.

> In SCM (http://swiss.csail.mit.edu/~jaffer/SCM), the QASE syntax
> provides this and unquote-splicing as well.

Thanks Aubrey, it was interesting to see that. Now I know that at least 
two of us think that there's a problem with case. :-) I think your qase is 
a very reasonable construct. After thinking about it a bit more, though, I 
decided that my version (which acts like yours) didn't rise to the level 
of deserving to be in the core. As I said, I think that the construct in 
the core should probably be more general rather than more specialized. 
That still leaves room for many specialized versions, though, as useful 
conveniences.

> I suspect that QASE can't be defined using just R5RS-macros (SCM does
> DEFMACRO).  Is it possible using R6RS macros?

Before I wrote the note I tested the idea by taking the definition of case 
from R6RS and changing the quotes to backquotes. I've included the code 
below. I presume that something similar would work in R5RS, but I haven't 
tried.

(define-syntax new-case
  (lambda (x)
    (syntax-case x ()
      ((_ e c1 c2 ...)
       (with-syntax ((body
           (let f ((c1 (syntax c1)) (cmore (syntax (c2 ...))))
             (if (null? cmore)
                 (syntax-case c1 (else)
                   ((else e1 e2 ...) (syntax (begin e1 e2 ...)))
                   (((k ...) e1 e2 ...)
                    (syntax (if (memv t `(k ...)) (begin e1 e2 ...)))))
                 (with-syntax ((rest (f (car cmore) (cdr cmore))))
                   (syntax-case c1 ()
                     (((k ...) e1 e2 ...)
                      (syntax (if (memv t `(k ...))
                                  (begin e1 e2 ...)
                                  rest)))))))))
         (syntax (let ((t e)) body)))))))

(define some-const 'x)
(define some-other-const 'y)
(define some-other-consts '(z))

(new-case 'x 
          [(,some-const) 'one] 
          [(,some-other-const) 'two] 
          [(, at some-other-consts) 'three] 
          [else 'none])
=> 'one

(new-case 'y
          [(,some-const) 'one] 
          [(,some-other-const) 'two] 
          [(, at some-other-consts) 'three] 
          [else 'none])
=> 'two

(new-case 'z 
          [(,some-const) 'one] 
          [(,some-other-const) 'two] 
          [(, at some-other-consts) 'three] 
          [else 'none])
=> 'three

(new-case 'xxx 
          [(,some-const) 'one] 
          [(,some-other-const) 'two] 
          [(, at some-other-consts) 'three] 
          [else 'none])
=> 'none





More information about the r6rs-discuss mailing list