Flexibility in Lisp
21st May 2016
It recently occurred to me that one of the great things about programming in Lisp is the wide choice of ways to approach a problem, giving you the flexibility to choose the one that fits best with your requirements.
As an example, I tried to see how many different ways I could think of to sum a list of integers in Common Lisp. Here's what I came up with:
Quick and dirty
Cons a '+ onto the front of the list, and eval it:
(eval (cons '+ '(1 2 3 4 5 6 7 8 9)))
Using apply
A more respectable way of the above [1]:
(apply '+ '(1 2 3 4 5 6 7 8 9))
Using dolist
More cumbersome, but more flexible:
(let ((n 0)) (dolist (x '(1 2 3 4 5 6 7 8 9) n) (incf n x)))
and of course using dotimes and nth to achieve a similar result.
Using mapc
Similar to the above:
(let ((n 0)) (mapc #'(lambda (x) (incf n x)) '(1 2 3 4 5 6 7 8 9)) n)
Using reduce
Most elegant:
(reduce '+ '(1 2 3 4 5 6 7 8 9))
Using recursion
Back to first principles:
(defun sum (list) (if (null list) 0 (+ (car list) (sum (cdr list)))))
(sum '(1 2 3 4 5 6 7 8 9))
Using loop
There are probably umpteen more ways using the loop macro - I'll leave that as an exercise for the reader.
Have I missed any?
- ^ This approach limits the length of the list to the constant CALL-ARGUMENTS-LIMIT, which is 2047 in LispWorks.
blog comments powered by Disqus