defuns
in Different FilesIn the previous section, we created a function that returns a list of the lengths of each definition in a file. Now, we want to define a function to return a master list of the lengths of the definitions in a list of files.
Working on each of a list of files is a repetitious act, so we can use
either a while
loop or recursion.
The design using a while
loop is routine. The argument passed
the function is a list of files. As we saw earlier (see section A while
Loop and a List), you can write a while
loop so that the body of the
loop is evaluated if such a list contains elements, but to exit the
loop if the list is empty. For this design to work, the body of the
loop must contain an expression that shortens the list each time the
body is evaluated, so that eventually the list is empty. The usual
technique is to set the value of the list to the value of the CDR
of the list each time the body is evaluated.
The template looks like this:
(while test-whether-list-is-empty body... set-list-to-cdr-of-list)
Also, we remember that a while
loop returns nil
(the
result of evaluating the true-or-false-test), not the result of any
evaluation within its body. (The evaluations within the body of the
loop are done for their side effects.) However, the expression that
sets the lengths' list is part of the body--and that is the value
that we want returned by the function as a whole. To do this, we
enclose the while
loop within a let
expression, and
arrange that the last element of the let
expression contains
the value of the lengths' list. (See section Example with incrementing counter.)
These considerations lead us directly to the function itself:
;;; Use while
loop.
(defun lengths-list-many-files (list-of-files)
"Return list of lengths of defuns in LIST-OF-FILES."
(let (lengths-list)
;;; true-or-false-test
(while list-of-files
(setq lengths-list
(append
lengths-list
;;; Generate a lengths' list.
(lengths-list-file
(expand-file-name (car list-of-files)))))
;;; Make files' list shorter.
(setq list-of-files (cdr list-of-files)))
;;; Return final value of lengths' list.
lengths-list))
expand-file-name
is a built-in function that converts a file
name to its absolute, long, path name form. Thus,
debug.el
becomes
/usr/local/emacs/lisp/debug.el
The only other new element of this function definition is the as yet
unstudied function append
, which merits a short section for
itself.
Go to the first, previous, next, last section, table of contents.