; [ʞ] select.scm
; ~ lexi hale <lexi@hale.su>
; © CC0 / public domain
; > (include "lisp-macro.scm")
; (include "select.scm")
; ? a reimplementation of (case) that lets you
; specify your own evaluator function. same syntax,
; except the expression to evaluate is preceeded by
; a predicate function
; = (select equal? "weed"
; ("weed" 420)
; ("sex" 69)
; (else 42069)
(define-macro (select . body)
(let* ([eqfn (list-ref body 0)]
[expr (list-ref body 1)]
[cases (cddr body)]
[result (gensym)])
(define (make-cond-entry case)
(let ([case-expr (car case)]
[func (cdr case)])
(if (eqv? case-expr 'else) (cons #t func)
(cons (list eqfn result case-expr) func))))
(define cond-entries (map make-cond-entry cases))
`(let ([,result ,expr]) (cond ,@cond-entries))))
(define-macro (maybe . body)
(let (( result (gensym) ))
`(let (( ,result ,(cadr body) ))
(if ,result (let (( ,(car body) ,result ))
,(cddr body))
#f))))