Here's my solution. It is pure (if you ignore the set! nature of letrec), has linear expansion, avoids multiple values, and uses a single "case" for conditional tests. The only thing it lacks that I know of is support for "else".
-------------------------------------------------------------------------------- #lang racket (require (for-syntax syntax/parse) racket/stxparam) (define-syntax-parameter break (lambda (stx) (raise-syntax-error #f "used outside of cas-cad-e" stx))) (define-syntax cas-cad-e (syntax-parser [(_ e:expr [(v ...) body:expr ...+] ...) (with-syntax ([(id ...) (generate-temporaries #'((v ...) ...))]) (with-syntax ([(f ...) #'(start id ... finish)] [(action ...) #'((begin) (begin body ...) ... (begin))] [(next ...) #'(id ... finish void)]) #'(let/ec escape (syntax-parameterize ([break (make-rename-transformer #'escape)]) (letrec ([f (lambda () action (next))] ...) (case e [(v ...) (id)] ...))))))])) (define (nursery-rhyme n) (cas-cad-e n [(1 2) (displayln "buckle my shoe")] [(3 4) (displayln "shut the door") (break)] [(5 6) (displayln "pick up sticks")] [(7 8) (displayln "lay them straight") (break)] [(9 10) (displayln "a big fat hen")])) (for ([i '(1 2 3 4 5 6 7 8 9 10)]) (nursery-rhyme i)) -------------------------------------------------------------------------------- Carl Eastlund _________________________________________________ For list-related administrative tasks: http://lists.racket-lang.org/listinfo/users