; (q X) -> q(X) ; (q :x) -> q(x) ; [(q X) (p X)] -> q(X) :- p(X) (fn clause [c] (match c (where [:unquote expr] (list? c)) `[:const ,expr] (where [name & params] (list? c)) `[:literal ,(tostring name) ,(icollect [_ param (ipairs params)] (clause param))] (where [head & tail] (sequence? c)) `[:clause ,(clause head) ,(icollect [_ elem (ipairs tail)] (clause elem))] (where v (sym? c)) `[:var ,(tostring v)] _ `[:const ,c])) (fn clauses [...] (icollect [_ c (ipairs [...]) :into `(values)] (clause c))) {: clause : clauses :$ clauses}