(use-for-syntax matchable) (define-syntax lcond (ir-macro-transformer (lambda (e _inj cmp) (apply (lambda [#!rest forms] (letrec [(let? (lambda [f] (cmp f 'let:))) (let*? (lambda [f] (cmp f 'let*:))) (and-let*? (lambda [f] (cmp f 'and-let*:))) (receive? (lambda [f] (cmp f 'receive:))) (R (lambda [fs] (if (pair? fs) (match fs [((and l (or (? let?) (? let*?) (? and-let*?))) bindings rest ...) `((else (,(cond [(let? l) 'let] [(let*? l)'let*] [(and-let*? l) 'and-let*]) ,bindings (cond ,@(R rest)))))] [((? receive?) ((and vars ((? symbol?) ...)) form) . rest) `((else (receive ,vars ,form (cond ,@(R rest)))))] [(form rest ...) (cons form (R rest))]) '())))] `(cond ,@(R forms)))) (cdr e))))) (define (foo a) (lcond [(null? a) 'null] [(not (pair? a)) 'not-a-pair] let: [(ca (car a))] [(fixnum? ca) (+ ca (cdr a))] receive: [(x y) (bar ca)] [else (string-append x y)])) (define (bar p) (values (car p) (cdr p))) (print (foo '())) ; -> null (print (foo 1)) ; -> not-a-pair (print (foo '(1 . 2))) ; -> 3 (print (foo '(("a" . "b")))) -> "ab"