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