Using different programming styles in Lisp
17th July 2021
One of the things I especially like about Lisp is that it gives you a choice of being able to program in a variety of different programming styles.
As an example, suppose we want to find the mean of the even numbers in a list of numbers. For example:
> (mean-even '(2 3 4 5 6 7 8 9 11)) 5
Here are solutions using Common Lisp in six different styles:
C iterative style
(defun mean-even (lst)
(let ((l (length lst))
(sum 0) (n 0) d)
(dotimes (i l)
(setq d (nth i lst))
(when (evenp d)
(setq sum (+ sum d))
(setq n (1+ n))))
(/ sum n)))
Lisp list iteration
(defun mean-even (lst)
(let ((sum 0) (n 0))
(dolist (d lst (/ sum n))
(when (evenp d)
(incf sum d)
(incf n)))))
Recursive
(defun count-even (lst)
(cond
((null lst) 0)
(t (+ (if (evenp (car lst)) 1 0) (count-even (cdr lst))))))
(defun mean-even (lst)
(cond
((null lst) 0)
((evenp (car lst))
(let ((n (count-even lst)))
(/ (+ (car lst)
(* (mean-even (cdr lst)) (1- n)))
n)))
(t (mean-even (cdr lst)))))
Recursive 2
(defun count-even (lst) (cond ((null lst) 0) (t (+ (if (evenp (car lst)) 1 0) (count-even (cdr lst)))))) (defun sum-even (lst) (cond ((null lst) 0) (t (+ (if (evenp (car lst)) (car lst) 0) (sum-even (cdr lst)))))) (defun mean-even (lst) (/ (sum-even lst) (count-even lst)))
Mapping with variables
(defun mean-even (lst)
(let ((sum 0) (neven 0))
(mapc #'(lambda (x) (when (evenp x) (incf sum x) (incf neven))) lst)
(/ sum neven)))
Functional style (like Haskell)
(defun mean-even (lst) (/ (reduce #'+ (remove-if-not #'evenp lst)) (count-if #'evenp lst)))
Can anyone suggest any others?
(I originally posted this on the uLisp forum: Using different programming styles in Lisp.)
blog comments powered by Disqus
