;; Simple list comprehensions. Example: ;; ;; (collect x ;; when ;; (in x '(1 2 3 4 5 6 7)) ;; (> x 3)) ;; (defmacro collect (exp when &body body) (assert (eq 'when when)) (let ((list (gensym "LIST"))) (labels ((transform (body list exp) (cond ((null body) `(push ,exp ,list)) ((eq (car (car body)) 'in) (let ((var (cadr (car body))) (list-exp (caddr (car body)))) `(dolist (,var ,list-exp) ,(transform (cdr body) list exp)))) (t `(when ,(car body) ,(transform (cdr body) list exp)))))) `(let ((,list)) ,(transform body list exp) (reverse ,list))))) (defun test1 (l) (collect x when (in x l) (> x 3))) ;; perms([]) -> [[]]; ;; perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])]. (defun perms(l) (cond ((null l) (list nil)) (t (collect (cons h tt) when (in h l) (in tt (perms (remove h l))))))) (defun seq (a b) (cond ((> a b) nil) (t (cons a (seq (1+ a) b))))) ;; pyth(N) -> ;; [ {A,B,C} || ;; A <- lists:seq(1,N), ;; B <- lists:seq(1,N), ;; C <- lists:seq(1,N), ;; A+B+C =< N, ;; A*A+B*B == C*C ;; ]. (defun pyth (n) (collect (list a b c) when (in a (seq 1 n)) (in b (seq 1 n)) (in c (seq 1 n)) ; (<= a b c) (<= (+ a b c) n) (= (+ (* a a) (* b b)) (* c c))))