Date: Wed, 08 Jan 1997 21:29:43 GMT Server: NCSA/1.4.2 Content-type: text/html
(defun main-function (args) (let ((local-variable (process-args args))) (defun helper-function (x) -- some function of local-variable --) -- do some more processing --))This creates a global binding for helper-function and therefore is a case of a global side effect that is not well documented. Never put a DEFUN inside a DEFUN. The LAMBDA macro allows you to create local, unnamed functions "on the fly."
;;; UGLY UGLY UGLY UGLY UGLY (defun count-symbols (nested-list) (let ((the-car NIL) ;; "Declarations" only (the-cdr NIL) ;; (symbols-in-car NIL) ;; (symbols-in-cdr NIL)) ;; (cond ((null nested-list) 0) (T (setf symbols-in-car 0) (setf the-car (car nested-list)) (if (symbolp the-car) (setf symbols-in-car 1)) (if (listp the-car) (setf symbols-in-car (count-symbols the-car))) (setf symbols-in-cdr (count-symbols (cdr nested-list))) (+ symbols-in-car symbols-in-cdr)))))This is really bad Lisp style because there is no need to "pre-declare" then set these variables.
Here's a better way to write it: we let the different clauses of the COND separate the cases for us. In many cases doing that carefully allows fewer conditionals and local variables.
(defun count-symbols (nested-list) (cond ((null nested-list) 0) (T (let ((the-car (car nested-list)) (symbols-in-rest (count-symbols (cdr nested-list)))) (cond ((symbolp the-car) (+ 1 symbols-in-rest)) ((listp the-car) (+ (count-symbols the-car) symbols-in-rest)) (T symbols-in-rest))))))Here's another version that uses a conditional assignment to a variable. It's open to debate whether this is good style or not. It's the most purely "Lisp-like" of the three, but I personally find it a little hard to read.
(defun count-symbols (nested-list) (cond ((null nested-list) 0) (T (let* ((the-car (car nested-list)) (symbols-in-car (cond ((symbolp the-car) 1) ((listp the-car) (count-symbols the-car)) (T 0)))) (+ symbols-in-car (count-symbols (cdr nested-list)))))))