The Marker
SQL, Lisp, and Haskell are the only programming languages that I've seen where one spends more time thinking than typing. Philip Greenspun
Richard Gabriel once half-jokingly described C as a language for writing Unix. We could likewise describe Lisp as a language for writing Lisp. Paul Graham
Exercises
A friend is trying to write a function that returns the sum of all the non-nil elements in a list. He has written two versions of this function, and neither of them work. Explain what's wrong with each, and give a correct version:
;; error
;a
(defun summit (lst)
(remove nil lst)
(apply #'+ lst))
;b
(defun summit (lst)
(let ((x (car lst)))
(if (null x)
(summit (cdr lst))
(+ x (summit (cdr lst))))))
;; correct
;a
(defun summit (lst)
(apply #'+ (remove nil lst)))
;b
(defun summit (lst)
(let ((lst (remove nil lst)))
(let ((x (car lst)))
(if (null x)
0
(+ x (summit (cdr lst))))))))
While playing a little with the top level I came up with these sketches.
A recursive implementation of Python's built-in any function
(defun our-any(x)
(and x (or (listp x) x) (or (car x) (our-any (cdr x)))))
Writing a function that calculates the average of all numeric elements of a given list.
(defun all-numbers(x)
(and x (cons (and (numberp (car x)) (car x)) (all-numbers (cdr x)))))
(defun our-avg (lst)
(setf new-list (remove nil (all-numbers lst)))
(/ (apply #'+ new-list) (length new-list)))
>(our-avg '(1 2 3 4 5 NIL 22))
37/6
changed January 1