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