I really enjoyed reading the blog post The Evolution of a Haskell Programmer by Fritz Ruehr on Willamette.edu.
I thought I’d try to do something similar for Lisp, based on uLisp, although I haven’t quite managed to take it to the same extremes as the original!
These programs will work using uLisp on any 32-bit board, or using Common Lisp.
Newcomer to Lisp - writes in C style
(defun fac (n)
(let ((f 1))
(dotimes (i n)
(setq f (* (1+ i) f)))
f))
> (fac 11)
39916800
Computer science student - has discovered the joy of recursion
(defun fac (n)
(if (zerop n) 1 (* n (fac (1- n)))))
> (fac 11)
39916800
Second year computer science student; more efficient recursive version using an accumulator
(defun facacc (a n)
(if (zerop n) a (facacc (* n a) (1- n))))
(defun fac (n) (facacc 1 n))
> (fac 11)
39916800
Generalist - can’t resist turning it into a more general problem
(defun product (a b)
(if (= a b) a (* a (product (1+ a) b))))
(defun fac (n) (product 1 n))
> (fac 11)
39916800
Haskell programmer - first creates a recursive Lisp equivalent for the ‘..’ operator
(defun dotdot (from to)
(if (> from to) nil (cons from (dotdot (1+ from) to))))
(defun fac (n) (apply #'* (dotdot 1 n)))
> (dotdot 1 11)
(1 2 3 4 5 6 7 8 9 10 11)
> (fac 11)
39916800
Purist Lisp programmer - uses lists, because numbers aren’t really pure Lisp!
(defun mul (a b)
(cond
((null a) nil)
((null (cdr a)) b)
(t (append b (mul (cdr a) b)))))
(defun fac (n)
(cond
((null n) '(x))
(t (mul n (fac (cdr n))))))
> (fac '(x x x x))
(x x x x x x x x x x x x x x x x x x x x x x x x)
Any other suggestions or contributions welcomed!