lisp的直積集合

appendを使わなくても書ける

(define (cp . seqs)
  (define (cp1 xs acc)
    (fold (lambda (e r) 
		  (fold (cut acons <> e <>) r xs))
		'() acc))
  (let loop ((seqs seqs))
    (match seqs
      [(xs) (map list xs)]
      [(xs . seqs*) (cp1 xs (loop seqs*))])))

reduceを使いまくればelispでも同様に

(defun cp1 (seq xs)
  (reduce (lambda (r e)
	    (reduce (lambda (r* x) (acons x e r*))
		    xs :initial-value r))
	  seq :initial-value '()))

(defun cp (&rest seq)
  (let ((rseq (reverse seq)))
    (reduce 'cp1 (cdr rseq)
	    :initial-value (mapcar 'list (car rseq)))))