home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 2001 May / SGI Freeware 2001 May - Disc 3.iso / dist / fw_elisp-intro.idb / usr / freeware / info / emacs-lisp-intro.info-9.z / emacs-lisp-intro.info-9
Encoding:
GNU Info File  |  1998-10-28  |  48.7 KB  |  1,180 lines

  1. This is Info file emacs-lisp-intro.info, produced by Makeinfo version
  2. 1.67 from the input file emacs-lisp-intro.texi.
  3.  
  4.    This is an introduction to `Programming in Emacs Lisp', for people
  5. who are not programmers.
  6.  
  7.    Edition 1.05, 21 October 1997
  8.  
  9.    Copyright (C) 1990, '91, '92, '93, '94, '95, '97 Free Software
  10. Foundation, Inc.
  11.  
  12.    Permission is granted to make and distribute verbatim copies of this
  13. manual provided the copyright notice and this permission notice are
  14. preserved on all copies.
  15.  
  16.    Permission is granted to copy and distribute modified versions of
  17. this manual under the conditions for verbatim copying, provided also
  18. that the sections entitled "Copying" and "GNU General Public License"
  19. are included exactly as in the original, and provided that the entire
  20. resulting derived work is distributed under the terms of a permission
  21. notice identical to this one.
  22.  
  23.    Permission is granted to copy and distribute translations of this
  24. manual into another language, under the above conditions for modified
  25. versions, except that this permission notice may be stated in a
  26. translation approved by the Free Software Foundation.
  27.  
  28. 
  29. File: emacs-lisp-intro.info,  Node: Whitespace Bug,  Prev: count-words-region,  Up: count-words-region
  30.  
  31. The Whitespace Bug in `count-words-region'
  32. ------------------------------------------
  33.  
  34.    The `count-words-region' command described in the preceding section
  35. has two bugs, or rather, one bug with two manifestations.  First, if
  36. you mark a region containing only whitespace in the middle of some
  37. text, the `count-words-region' command tells you that the region
  38. contains one word!  Second, if you mark a region containing only
  39. whitespace at the end of the buffer or the accessible portion of a
  40. narrowed buffer, the command displays an error message that looks like
  41. this:
  42.  
  43.      Search failed: "\\w+\\W*"
  44.  
  45.    If you are reading this in Info in GNU Emacs, you can test for these
  46. bugs yourself.
  47.  
  48.    First, evaluate the function in the usual manner to install it.
  49. Here is a copy of the definition.  Place your cursor after the closing
  50. parenthesis and type `C-x C-e' to install it.
  51.  
  52.      ;; First version; has bugs!
  53.      (defun count-words-region (beginning end)
  54.        "Print number of words in the region.
  55.      Words are defined as at least one word-constituent character followed
  56.      by at least one character that is not a word-constituent.  The buffer's
  57.      syntax table determines which characters these are."
  58.        (interactive "r")
  59.        (message "Counting words in region ... ")
  60.      
  61.      ;;; 1. Set up appropriate conditions.
  62.        (save-excursion
  63.          (goto-char beginning)
  64.          (let ((count 0))
  65.      
  66.      ;;; 2. Run the while loop.
  67.            (while (< (point) end)
  68.              (re-search-forward "\\w+\\W*")
  69.              (setq count (1+ count)))
  70.      
  71.      ;;; 3. Send a message to the user.
  72.            (cond ((zerop count)
  73.                   (message "The region does NOT have any words."))
  74.                  ((= 1 count) (message "The region has 1 word."))
  75.                  (t (message "The region has %d words." count))))))
  76.  
  77.    If you wish, you can also install this keybinding by evaluating it,
  78. too:
  79.  
  80.      (global-set-key "\C-c=" 'count-words-region)
  81.  
  82.    To conduct the first test, set mark and point to the beginning and
  83. end of the following line and then type `C-c =' (or `M-x
  84. count-words-region' if you have not bound `C-c ='):
  85.  
  86.          one   two  three
  87.  
  88. Emacs will tell you, correctly, that the region has three words.
  89.  
  90.    Repeat the test, but place mark at the beginning of the line and
  91. place point just *before* the word `one'.  Again type the command `C-c
  92. =' (or `M-x count-words-region').  Emacs should tell you that the
  93. region has no words, since it is composed only of the whitespace at the
  94. beginning of the line.  But instead Emacs tells you that the region has
  95. one word!
  96.  
  97.    For the third test, copy the sample line to the end of the
  98. `*scratch*' buffer and then type several spaces at the end of the line.
  99. Place mark right after the word `three' and point at the end of line.
  100. (The end of the line will be the end of the buffer.) Type `C-c =' (or
  101. `M-x count-words-region') as you did before.  Again, Emacs should tell
  102. you that the region has no words, since it is composed only of the
  103. whitespace at the end of the line.  Instead, Emacs displays an error
  104. message saying `Search failed'.
  105.  
  106.    The two bugs stem from the same problem.
  107.  
  108.    Consider the first manifestation of the bug, in which the command
  109. tells you that the whitespace at the beginning of the line contains one
  110. word.  What happens is this: The `M-x count-words-region' command moves
  111. point to the beginning of the region.  The `while' tests whether the
  112. value of point is smaller than the value of `end', which it is.
  113. Consequently, the regular expression search looks for and finds the
  114. first word.  It leaves point after the word.  `count' is set to one.
  115. The `while' loop repeats; but this time the value of point is larger
  116. than the value of `end', the loop is exited; and the function displays
  117. a message saying the number of words in the region is one.  In brief,
  118. the regular expression search looks for and finds the word even though
  119. it is outside the marked region.
  120.  
  121.    In the second manifestation of the bug, the region is whitespace at
  122. the end of the buffer.  Emacs says `Search failed'.  What happens is
  123. that the true-or-false-test in the `while' loop tests true, so the
  124. search expression is executed.  But since there are no more words in
  125. the buffer, the search fails.
  126.  
  127.    In both manifestations of the bug, the search extends or attempts to
  128. extend outside of the region.
  129.  
  130.    The solution is to limit the search to the region--this is a fairly
  131. simple action, but as you may have come to expect, it is not quite as
  132. simple as you might think.
  133.  
  134.    As we have seen, the `re-search-forward' function takes a search
  135. pattern as its first argument.  But in addition to this first,
  136. mandatory argument, it accepts three optional arguments.  The optional
  137. second argument bounds the search.  The optional third argument, if
  138. `t', causes the function to return `nil' rather than signal an error if
  139. the search fails.  The optional fourth argument is a repeat count.  (In
  140. Emacs, you can get a function's documentation by typing `C-h f', the
  141. name of the function, and then <RET>.)
  142.  
  143.    In the `count-words-region' definition, the value of the end of the
  144. region is held by the variable `end' which is passed as an argument to
  145. the function.  Thus, we can add `end' as an argument to the regular
  146. expression search expression:
  147.  
  148.      (re-search-forward "\\w+\\W*" end)
  149.  
  150.    However, if you make only this change to the `count-words-region'
  151. definition and then test the new version of the definition on a stretch
  152. of whitespace, you will receive an error message saying `Search failed'.
  153.  
  154.    What happens is this: the search is limited to the region, and fails
  155. as you expect because there are no word-constituent characters in the
  156. region.  Since it fails, we receive an error message.  But we do not
  157. want to receive an error message in this case; we want to receive the
  158. message that "The region does NOT have any words."
  159.  
  160.    The solution to this problem is to provide `re-search-forward' with
  161. a third argument of `t', which causes the function to return `nil'
  162. rather than signal an error if the search fails.
  163.  
  164.    However, if you make this change and try it, you will see the message
  165. "Counting words in region ... " and ... you will keep on seeing that
  166. message ..., until you type `C-g' (`keyboard-quit').
  167.  
  168.    Here is what happens: the search is limited to the region, as before,
  169. and it fails because there are no word-constituent characters in the
  170. region, as expected.  Consequently, the `re-search-forward' expression
  171. returns `nil'.  It does nothing else.  In particular, it does not move
  172. point, which it does as a side effect if it finds the search target.
  173. After the `re-search-forward' expression returns `nil', the next
  174. expression in the `while' loop is evaluated.  This expression
  175. increments the count.  Then the loop repeats.  The true-or-false-test
  176. tests true because the value of point is still less than the value of
  177. end, since the `re-search-forward' expression did not move point. ...
  178. and the cycle repeats ...
  179.  
  180.    The `count-words-region' definition requires yet another
  181. modification, to cause the true-or-false-test of the `while' loop to
  182. test false if the search fails.  Put another way, there are two
  183. conditions that must be satisfied in the true-or-false-test before the
  184. word count variable is incremented: point must still be within the
  185. region and the search expression must have found a word to count.
  186.  
  187.    Since both the first condition and the second condition must be true
  188. together, the two expressions, the region test and the search
  189. expression, can be joined with an `and' function and embedded in the
  190. `while' loop as the true-or-false-test, like this:
  191.  
  192.      (and (< (point) end) (re-search-forward "\\w+\\W*" end t))
  193.  
  194. (*Note forward-paragraph::, for information about `and'.)
  195.  
  196.    The `re-search-forward' expression returns `t' if the search
  197. succeeds and as a side effect moves point.  Consequently, as words are
  198. found, point is moved through the region.  When the search expression
  199. fails to find another word, or when point reaches the end of the
  200. region, the true-or-false-test tests false, the `while' loop exists,
  201. and the `count-words-region' function displays one or other of its
  202. messages.
  203.  
  204.    After incorporating these final changes, the `count-words-region'
  205. works without bugs (or at least, without bugs that I have found!).
  206. Here is what it looks like:
  207.  
  208.      ;;; Final version: `while'
  209.      (defun count-words-region (beginning end)
  210.        "Print number of words in the region."
  211.        (interactive "r")
  212.        (message "Counting words in region ... ")
  213.      
  214.      ;;; 1. Set up appropriate conditions.
  215.        (save-excursion
  216.          (let ((count 0))
  217.            (goto-char beginning)
  218.      
  219.      ;;; 2. Run the while loop.
  220.            (while (and (< (point) end)
  221.                        (re-search-forward "\\w+\\W*" end t))
  222.              (setq count (1+ count)))
  223.      
  224.      ;;; 3. Send a message to the user.
  225.            (cond ((zerop count)
  226.                   (message
  227.                    "The region does NOT have any words."))
  228.                  ((= 1 count)
  229.                   (message
  230.                    "The region has 1 word."))
  231.                  (t
  232.                   (message
  233.                    "The region has %d words." count))))))
  234.  
  235. 
  236. File: emacs-lisp-intro.info,  Node: recursive-count-words,  Next: Counting Exercise,  Prev: count-words-region,  Up: Counting Words
  237.  
  238. Count Words Recursively
  239. =======================
  240.  
  241.    You can write the function for counting words recursively as well as
  242. with a `while' loop.  Let's see how this is done.
  243.  
  244.    First, we need to recognize that the `count-words-region' function
  245. has three jobs: it sets up the appropriate conditions for counting to
  246. occur; it counts the words in the region; and it sends a message to the
  247. user telling how many words there are.
  248.  
  249.    If we write a single recursive function to do everything, we will
  250. receive a message for every recursive call.  If the region contains 13
  251. words, we will receive thirteen messages, one right after the other.
  252. We don't want this!  Instead, we must write two functions to do the
  253. job, one of which (the recursive function) will be used inside of the
  254. other.  One function will set up the conditions and display the
  255. message; the other will return the word count.
  256.  
  257.    Let us start with the function that causes the message to be
  258. displayed.  We can continue to call this `count-words-region'.
  259.  
  260.    This is the function that the user will call.  It will be
  261. interactive.  Indeed, it will be similar to our previous versions of
  262. this function, except that it will call `recursive-count-words' to
  263. determine how many words are in the region.
  264.  
  265.    We can readily construct a template for this function, based on our
  266. previous versions:
  267.  
  268.      ;; Recursive version; uses regular expression search
  269.      (defun count-words-region (beginning end)
  270.        "DOCUMENTATION..."
  271.        (INTERACTIVE-EXPRESSION...)
  272.      
  273.      ;;; 1. Set up appropriate conditions.
  274.        (EXPLANATORY MESSAGE)
  275.        (SET-UP FUNCTIONS...
  276.      
  277.      ;;; 2. Count the words.
  278.          RECURSIVE CALL
  279.      
  280.      ;;; 3. Send a message to the user.
  281.          MESSAGE PROVIDING WORD COUNT))
  282.  
  283.    The definition looks straightforward, except that somehow, the count
  284. returned by the recursive call must be passed to the message displaying
  285. the word count.  A little thought suggests that this can be done by
  286. making use of a `let' expression: we can bind a variable in the varlist
  287. of a `let' expression to the number of words in the region, as returned
  288. by the recursive call; and then the `cond' expression, using binding,
  289. can display the value to the user.
  290.  
  291.    Often, one thinks of the binding within a `let' expression as
  292. somehow secondary to the `primary' work of a function.  But in this
  293. case, what you might consider the `primary' job of the function,
  294. counting words, is done within the `let' expression.
  295.  
  296.    Using `let', the function definition looks like this:
  297.  
  298.      (defun count-words-region (beginning end)
  299.        "Print number of words in the region."
  300.        (interactive "r")
  301.      
  302.      ;;; 1. Set up appropriate conditions.
  303.        (message "Counting words in region ... ")
  304.        (save-excursion
  305.          (goto-char beginning)
  306.      
  307.      ;;; 2. Count the words.
  308.          (let ((count (recursive-count-words end)))
  309.      
  310.      ;;; 3. Send a message to the user.
  311.            (cond ((zerop count)
  312.                   (message
  313.                    "The region does NOT have any words."))
  314.                  ((= 1 count)
  315.                   (message
  316.                    "The region has 1 word."))
  317.                  (t
  318.                   (message
  319.                    "The region has %d words." count))))))
  320.  
  321.    Next, we need to write the recursive counting function.
  322.  
  323.    A recursive function has at least three parts: the `do-again-test',
  324. the `next-step-expression', and the recursive call.
  325.  
  326.    The do-again-test determines whether the function will or will not be
  327. called again.  Since we are counting words in a region and can use a
  328. function that moves point forward for every word, the do-again-test can
  329. check whether point is still within the region.  The do-again-test
  330. should find the value of point and determine whether point is before,
  331. at, or after the value of the end of the region.  We can use the
  332. `point' function to locate point.  Clearly, we must pass the value of
  333. the end of the region to the recursive counting function as an argument.
  334.  
  335.    In addition, the do-again-test should also test whether the search
  336. finds a word.  If it does not, the function should not call itself
  337. again.
  338.  
  339.    The next-step-expression changes a value so that when the recursive
  340. function is supposed to stop calling itself, it stops.  More precisely,
  341. the next-step-expression changes a value so that at the right time, the
  342. do-again-test stops the recursive function from calling itself again.
  343. In this case, the next-step-expression can be the expression that moves
  344. point forward word by word.
  345.  
  346.    The third part of a recursive function is the recursive call.
  347.  
  348.    Somewhere, also, we also need a part that does the `work' of the
  349. function, a part that does the counting.  A vital part!
  350.  
  351.    But already, we have an outline of the recursive counting function:
  352.  
  353.      (defun recursive-count-words (region-end)
  354.        "DOCUMENTATION..."
  355.         DO-AGAIN-TEST
  356.         NEXT-STEP-EXPRESSION
  357.         RECURSIVE CALL)
  358.  
  359.    Now we need to fill in the slots.  Let's start with the simplest
  360. cases first:  if point is at or beyond the end of the region, there
  361. cannot be any words in the region, so the function should return zero.
  362. Likewise, if the search fails, there are no words to count, so the
  363. function should return zero.
  364.  
  365.    On the other hand, if point is within the region and the search
  366. succeeds, the function should call itself again.
  367.  
  368.    Thus, the do-again-test should look like this:
  369.  
  370.      (and (< (point) region-end)
  371.           (re-search-forward "\\w+\\W*" region-end t))
  372.  
  373.    Note that the search expression is part of the do-again-test--the
  374. function returns `t' if its search succeeds and `nil' if it fails.
  375. (*Note The Whitespace Bug in `count-words-region': Whitespace Bug, for
  376. an explanation of how `re-search-forward' works.)
  377.  
  378.    The do-again-test is the true-or-false test of an `if' clause.
  379. Clearly, if the do-again-test succeeds, the then-part of the `if'
  380. clause should call the function again; but if it fails, the else-part
  381. should return zero since either point is outside the region or the
  382. search failed because there were no words to find.
  383.  
  384.    But before considering the recursive call, we need to consider the
  385. next-step-expression.  What is it?  Interestingly, it is the search
  386. part of the do-again-test.
  387.  
  388.    In addition to returning `t' or `nil' for the do-again-test,
  389. `re-search-forward' moves point forward as a side effect of a
  390. successful search.  This is the action that changes the value of point
  391. so that the recursive function stops calling itself when point
  392. completes its movement through the region.  Consequently, the
  393. `re-search-forward' expression is the next-step-expression.
  394.  
  395.    In outline, then, the body of the `recursive-count-words' function
  396. looks like this:
  397.  
  398.      (if DO-AGAIN-TEST-AND-NEXT-STEP-COMBINED
  399.          ;; then
  400.          RECURSIVE-CALL-RETURNING-COUNT
  401.        ;; else
  402.        RETURN-ZERO)
  403.  
  404.    How to incorporate the mechanism that counts?
  405.  
  406.    If you are not used to writing recursive functions, a question like
  407. this can be troublesome.  But it can and should be approached
  408. systematically.
  409.  
  410.    We know that the counting mechanism should be associated in some way
  411. with the recursive call.  Indeed, since the next-step-expression moves
  412. point forward by one word, and since a recursive call is made for each
  413. word, the counting mechanism must be an expression that adds one to the
  414. value returned by a call to `recursive-count-words'.
  415.  
  416.    Consider several cases:
  417.  
  418.    * If there are two words in the region, the function should return a
  419.      value resulting from adding one to the value returned when it
  420.      counts the first word, plus the number returned when it counts the
  421.      remaining words in the region, which in this case is one.
  422.  
  423.    * If there is one word in the region, the function should return a
  424.      value resulting from adding one to the value returned when it
  425.      counts that word, plus the number returned when it counts the
  426.      remaining words in the region, which in this case is zero.
  427.  
  428.    * If there are no words in the region, the function should return
  429.      zero.
  430.  
  431.    From the sketch we can see that the else-part of the `if' returns
  432. zero for the case of no words.  This means that the then-part of the
  433. `if' must return a value resulting from adding one to the value
  434. returned from a count of the remaining words.
  435.  
  436.    The expression will look like this, where `1+' is a function that
  437. adds one to its argument.
  438.  
  439.      (1+ (recursive-count-words region-end))
  440.  
  441.    The whole `recursive-count-words' function will then look like this:
  442.  
  443.      (defun recursive-count-words (region-end)
  444.        "DOCUMENTATION..."
  445.      
  446.      ;;; 1. do-again-test
  447.        (if (and (< (point) region-end)
  448.                 (re-search-forward "\\w+\\W*" region-end t))
  449.      
  450.      ;;; 2. then-part: the recursive call
  451.            (1+ (recursive-count-words region-end))
  452.      
  453.      ;;; 3. else-part
  454.          0))
  455.  
  456.    Let's examine how this works:
  457.  
  458.    If there are no words in the region, the else part of the `if'
  459. expression is evaluated and consequently the function returns zero.
  460.  
  461.    If there is one word in the region, the value of point is less than
  462. the value of `region-end' and the search succeeds.  In this case, the
  463. true-or-false-test of the `if' expression tests true, and the then-part
  464. of the `if' expression is evaluated.  The counting expression is
  465. evaluated.  This expression returns a value (which will be the value
  466. returned by the whole function) that is the sum of one added to the
  467. value returned by a recursive call.
  468.  
  469.    Meanwhile, the next-step-expression has caused point to jump over the
  470. first (and in this case only) word in the region.  This means that when
  471. `(recursive-count-words region-end)' is evaluated a second time, as a
  472. result of the recursive call, the value of point will be equal to or
  473. greater than the value of region end.  So this time,
  474. `recursive-count-words' will return zero.  The zero will be added to
  475. one, and the original evaluation of `recursive-count-words' will return
  476. one plus zero, which is one, which is the correct amount.
  477.  
  478.    Clearly, if there are two words in the region, the first call to
  479. `recursive-count-words' returns one added to the value returned by
  480. calling `recursive-count-words' on a region containing the remaining
  481. word--that is, it adds one to one, producing two, which is the correct
  482. amount.
  483.  
  484.    Similarly, if there are three words in the region, the first call to
  485. `recursive-count-words' returns one added to the value returned by
  486. calling `recursive-count-words' on a region containing the remaining
  487. two words--and so on and so on.
  488.  
  489.    With full documentation the two functions look like this:
  490.  
  491. The recursive function:
  492.  
  493.      (defun recursive-count-words (region-end)
  494.        "Number of words between point and REGION-END."
  495.      
  496.      ;;; 1. do-again-test
  497.        (if (and (< (point) region-end)
  498.                 (re-search-forward "\\w+\\W*" region-end t))
  499.      
  500.      ;;; 2. then-part: the recursive call
  501.            (1+ (recursive-count-words region-end))
  502.      
  503.      ;;; 3. else-part
  504.          0))
  505.  
  506. The wrapper:
  507.  
  508.      ;;; Recursive version
  509.      (defun count-words-region (beginning end)
  510.        "Print number of words in the region.
  511.      
  512.      Words are defined as at least one word-constituent
  513.      character followed by at least one character that is
  514.      not a word-constituent.  The buffer's syntax table
  515.      determines which characters these are."
  516.        (interactive "r")
  517.        (message "Counting words in region ... ")
  518.        (save-excursion
  519.          (goto-char beginning)
  520.          (let ((count (recursive-count-words end)))
  521.            (cond ((zerop count)
  522.                   (message
  523.                    "The region does NOT have any words."))
  524.                  ((= 1 count)
  525.                   (message "The region has 1 word."))
  526.                  (t
  527.                   (message
  528.                    "The region has %d words." count))))))
  529.  
  530. 
  531. File: emacs-lisp-intro.info,  Node: Counting Exercise,  Prev: recursive-count-words,  Up: Counting Words
  532.  
  533. Exercise: Counting Punctuation
  534. ==============================
  535.  
  536.    Using a `while' loop, write a function to count the number of
  537. punctuation marks in a region--period, comma, semicolon, colon,
  538. exclamation mark, question mark.  Do the same using recursion.
  539.  
  540. 
  541. File: emacs-lisp-intro.info,  Node: Words in a defun,  Next: Readying a Graph,  Prev: Counting Words,  Up: Top
  542.  
  543. Counting Words in a `defun'
  544. ***************************
  545.  
  546.    Our next project is to count the number of words in a function
  547. definition.  Clearly, this can be done using some variant of
  548. `count-word-region'.  *Note Counting Words: Repetition and Regexps:
  549. Counting Words.  If we are just going to count the words in one
  550. definition, it is easy enough to mark the definition with the `C-M-h'
  551. (`mark-defun') command, and then call `count-word-region'.
  552.  
  553.    However, I am more ambitious: I want to count the words and symbols
  554. in every definition in the Emacs sources and then print a graph that
  555. shows how many functions there are of each length: how many contain 40
  556. to 49 words or symbols, how many contain 50 to 59 words or symbols, and
  557. so on.  I have often been curious how long a typical function is, and
  558. this will tell.
  559.  
  560. * Menu:
  561.  
  562. * Divide and Conquer::          Split a daunting project into parts.
  563. * Words and Symbols::           What to count?
  564. * Syntax::                      What constitutes a word or symbol?
  565. * count-words-in-defun::        Very like `count-words'.
  566. * Several defuns::              Counting several defuns in a file.
  567. * Find a File::                 Do you want to look at a file?
  568. * lengths-list-file::           A list of the lengths of many definitions.
  569. * Several files::               Counting in definitions in different files.
  570. * Several files recursively::   Recursively counting in different files.
  571. * Prepare the data::            Prepare the data for display in a graph.
  572.  
  573. 
  574. File: emacs-lisp-intro.info,  Node: Divide and Conquer,  Next: Words and Symbols,  Prev: Words in a defun,  Up: Words in a defun
  575.  
  576. Divide and Conquer
  577. ==================
  578.  
  579.    Described in one phrase, the histogram project is daunting; but
  580. divided into numerous small steps, each of which we can take one at a
  581. time, the project becomes less fearsome.  Let us consider what the
  582. steps must be:
  583.  
  584.    * First, write a function to count the words in one definition.  This
  585.      includes the problem of handling symbols as well as words.
  586.  
  587.    * Second, write a function to list the numbers of words in each
  588.      function in a file.  This function can use the
  589.      `count-words-in-defun' function.
  590.  
  591.    * Third, write a function to list the numbers of words in each
  592.      function in each of several files.  This entails automatically
  593.      finding the various files, switching to them, and counting the
  594.      words in the definitions within them.
  595.  
  596.    * Fourth, write a function to convert the list of numbers that we
  597.      created in step three to a form that will be suitable for printing
  598.      as a graph.
  599.  
  600.    * Fifth, write a function to print the results as a graph.
  601.  
  602.    This is quite a project!  But if we take each step slowly, it will
  603. not be difficult.
  604.  
  605. 
  606. File: emacs-lisp-intro.info,  Node: Words and Symbols,  Next: Syntax,  Prev: Divide and Conquer,  Up: Words in a defun
  607.  
  608. What to Count?
  609. ==============
  610.  
  611.    When we first start thinking about how to count the words in a
  612. function definition, the first question is (or ought to be) what are we
  613. going to count?  When we speak of `words' with respect to a Lisp
  614. function definition, we are actually speaking, in large part, of
  615. `symbols'.  For example, the following `multiply-by-seven' function
  616. contains the five symbols `defun', `multiply-by-seven', `number', `*',
  617. and `7'.  In addition, in the documentation string, it contains the
  618. four words `Multiply', `NUMBER', `by', and `seven'.  The symbol
  619. `number' is repeated, so the definition contains a total of ten words
  620. and symbols.
  621.  
  622.      (defun multiply-by-seven (number)
  623.        "Multiply NUMBER by seven."
  624.        (* 7 number))
  625.  
  626. However, if we mark the `multiply-by-seven' definition with `C-M-h'
  627. (`mark-defun'), and then call `count-words-region' on it, we will find
  628. that `count-words-region' claims the definition has eleven words, not
  629. ten!  Something is wrong!
  630.  
  631.    The problem is twofold: `count-words-region' does not count the `*'
  632. as a word, and it counts the single symbol, `multiply-by-seven', as
  633. containing three words.  The hyphens are treated as if they were
  634. interword spaces rather than intraword connectors: `multiply-by-seven'
  635. is counted as if it were written `multiply by seven'.
  636.  
  637.    The cause of this confusion is the regular expression search within
  638. the `count-words-region' definition that moves point forward word by
  639. word.  In the canonical version of `count-words-region', the regexp is:
  640.  
  641.      "\\w+\\W*"
  642.  
  643. This regular expression is a pattern defining one or more word
  644. constituent characters possibly followed by one or more characters that
  645. are not word constituents.  What is meant by `word constituent
  646. characters' brings us to the issue of syntax, which is worth a section
  647. of its own.
  648.  
  649. 
  650. File: emacs-lisp-intro.info,  Node: Syntax,  Next: count-words-in-defun,  Prev: Words and Symbols,  Up: Words in a defun
  651.  
  652. What Constitutes a Word or Symbol?
  653. ==================================
  654.  
  655.    Emacs treats different characters as belonging to different "syntax
  656. categories".  For example, the regular expression, `\\w+', is a pattern
  657. specifying one or more *word constituent* characters.  Word constituent
  658. characters are members of one syntax category.  Other syntax categories
  659. include the class of punctuation characters, such as the period and the
  660. comma, and the class of whitespace characters, such as the blank space
  661. and the tab character.  (For more information, see *Note Syntax:
  662. (emacs)Syntax, and, *Note Syntax Tables: (elisp)Syntax Tables.)
  663.  
  664.    Syntax tables specify which characters belong to which categories.
  665. Usually, a hyphen is not specified as a `word constituent character'.
  666. Instead, it is specified as being in the `class of characters that are
  667. part of symbol names but not words.'  This means that the
  668. `count-words-region' function treats it in the same way it treats an
  669. interword white space, which is why `count-words-region' counts
  670. `multiply-by-seven' as three words.
  671.  
  672.    There are two ways to cause Emacs to count `multiply-by-seven' as
  673. one symbol: modify the syntax table or modify the regular expression.
  674.  
  675.    We could redefine a hyphen as a word constituent character by
  676. modifying the syntax table that Emacs keeps for each mode.  This action
  677. would serve our purpose, except that a hyphen is merely the most common
  678. character within symbols that is not typically a word constituent
  679. character; there are others, too.
  680.  
  681.    Alternatively, we can redefine the regular expression used in the
  682. `count-words' definition so as to include symbols.  This procedure has
  683. the merit of clarity, but the task is a little tricky.
  684.  
  685.    The first part is simple enough: the pattern must match "at least one
  686. character that is a word or symbol constituent".  Thus:
  687.  
  688.      \\(\\w\\|\\s_\\)+
  689.  
  690. The `\\(' is the first part of the grouping construct that includes the
  691. `\\w' and the `\\s_' as alternatives, separated by the `\\|'.  The
  692. `\\w' matches any word-constituent character and the `\\s_' matches any
  693. character that is part of a symbol name but not a word-constituent
  694. character.  The `+' following the group indicates that the word or
  695. symbol constituent characters must be matched at least once.
  696.  
  697.    However, the second part of the regexp is more difficult to design.
  698. What we want is to follow the first part with "optionally one or more
  699. characters that are not constituents of a word or symbol".  At first, I
  700. thought I could define this with the following:
  701.  
  702.      \\(\\W\\|\\S_\\)*"
  703.  
  704. The upper case `W' and `S' match characters that are *not* word or
  705. symbol constituents.  Unfortunately, this expression matches any
  706. character that is either not a word constituent or not a symbol
  707. constituent.  This matches any character!
  708.  
  709.    I then noticed that every word or symbol in my test region was
  710. followed by white space (blank space, tab, or newline).  So I tried
  711. placing a pattern to match one or more blank spaces after the pattern
  712. for one or more word or symbol constituents.  This failed, too.  Words
  713. and symbols are often separated by whitespace, but in actual code
  714. parentheses may follow symbols and punctuation may follow words.  So
  715. finally, I designed a pattern in which the word or symbol constituents
  716. are followed optionally by characters that are not white space and then
  717. followed optionally by white space.
  718.  
  719.    Here is the full regular expression:
  720.  
  721.      "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
  722.  
  723. 
  724. File: emacs-lisp-intro.info,  Node: count-words-in-defun,  Next: Several defuns,  Prev: Syntax,  Up: Words in a defun
  725.  
  726. The `count-words-in-defun' Function
  727. ===================================
  728.  
  729.    We have seen that there are several ways to write a
  730. `count-word-region' function.  To write a `count-words-in-defun', we
  731. need merely adapt one of these versions.
  732.  
  733.    The version that uses a `while' loop is easy to understand, so I am
  734. going to adapt that.  Because `count-words-in-defun' will be part of a
  735. more complex program, it need not be interactive and it need not
  736. display a message but just return the count.  These considerations
  737. simplify the definition a little.
  738.  
  739.    On the other hand, `count-words-in-defun' will be used within a
  740. buffer that contains function definitions.  Consequently, it is
  741. reasonable to ask that the function determine whether it is called when
  742. point is within a function definition, and if it is, to return the
  743. count for that definition.  This adds complexity to the definition, but
  744. saves us from needing to pass arguments to the function.
  745.  
  746.    These considerations lead us to prepare the following template:
  747.  
  748.      (defun count-words-in-defun ()
  749.        "DOCUMENTATION..."
  750.        (SET UP...
  751.           (WHILE LOOP...)
  752.         RETURN COUNT)
  753.  
  754. As usual, our job is to fill in the slots.
  755.  
  756.    First, the set up.
  757.  
  758.    We are presuming that this function will be called within a buffer
  759. containing function definitions.  Point will either be within a
  760. function definition or not.  For `count-words-in-defun' to work, point
  761. must move to the beginning of the definition, a counter must start at
  762. zero, and the counting loop must stop when point reaches the end of the
  763. definition.
  764.  
  765.    The `beginning-of-defun' function searches backwards for an opening
  766. delimiter such as a `(' at the beginning of a line, and moves point to
  767. that position, or else to the limit of the search.  In practice, this
  768. means that `beginning-of-defun' moves point to the beginning of an
  769. enclosing or preceding function definition, or else to the beginning of
  770. the buffer.  We can use `beginning-of-defun' to place point where we
  771. wish to start.
  772.  
  773.    The `while' loop requires a counter to keep track of the words or
  774. symbols being counted.  A `let' expression can be used to create a
  775. local variable for this purpose, and bind it to an initial value of
  776. zero.
  777.  
  778.    The `end-of-defun' function works like `beginning-of-defun' except
  779. that it moves point to the end of the definition.  `end-of-defun' can
  780. be used as part of an expression that determines the position of the
  781. end of the definition.
  782.  
  783.    The set up for `count-words-in-defun' takes shape rapidly: first we
  784. move point to the beginning of the definition, then we create a local
  785. variable to hold the count, and, finally, we record the position of the
  786. end of the definition so the `while' loop will know when to stop
  787. looping.
  788.  
  789.    The code looks like this:
  790.  
  791.      (beginning-of-defun)
  792.      (let ((count 0)
  793.            (end (save-excursion (end-of-defun) (point))))
  794.  
  795. The code is simple.  The only slight complication is likely to concern
  796. `end': it is bound to the position of the end of the definition by a
  797. `save-excursion' expression that returns the value of point after
  798. `end-of-defun' temporarily moves it to the end of the definition.
  799.  
  800.    The second part of the `count-words-in-defun', after the set up, is
  801. the `while' loop.
  802.  
  803.    The loop must contain an expression that jumps point forward word by
  804. word and symbol by symbol, and another expression that counts the
  805. jumps.  The true-or-false-test for the `while' loop should test true so
  806. long as point should jump forward, and false when point is at the end
  807. of the definition.  We have already redefined the regular expression
  808. for this (*note Syntax::.), so the loop is straightforward:
  809.  
  810.      (while (and (< (point) end)
  811.                  (re-search-forward
  812.                   "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*" end t)
  813.        (setq count (1+ count)))
  814.  
  815.    The third part of the function definition returns the count of words
  816. and symbols.  This part is the last expression within the body of the
  817. `let' expression, and can be, very simply, the local variable `count',
  818. which when evaluated returns the count.
  819.  
  820.    Put together, the `count-words-in-defun' definition looks like this:
  821.  
  822.      (defun count-words-in-defun ()
  823.        "Return the number of words and symbols in a defun."
  824.        (beginning-of-defun)
  825.        (let ((count 0)
  826.              (end (save-excursion (end-of-defun) (point))))
  827.          (while
  828.              (and (< (point) end)
  829.                   (re-search-forward
  830.                    "\\(\\w\\|\\s_\\)+[^ \t\n]*[ \t\n]*"
  831.                    end t))
  832.            (setq count (1+ count)))
  833.          count))
  834.  
  835.    How to test this?  The function is not interactive, but it is easy to
  836. put a wrapper around the function to make it interactive; we can use
  837. almost the same code as for the recursive version of
  838. `count-words-region':
  839.  
  840.      ;;; Interactive version.
  841.      (defun count-words-defun ()
  842.        "Number of words and symbols in a function definition."
  843.        (interactive)
  844.        (message
  845.         "Counting words and symbols in function definition ... ")
  846.        (let ((count (count-words-in-defun)))
  847.          (cond
  848.           ((zerop count)
  849.            (message
  850.             "The definition does NOT have any words or symbols."))
  851.           ((= 1 count)
  852.            (message
  853.             "The definition has 1 word or symbol."))
  854.           (t
  855.            (message
  856.             "The definition has %d words or symbols." count)))))
  857.  
  858. Let's re-use `C-c =' as a convenient keybinding:
  859.  
  860.      (global-set-key "\C-c=" 'count-words-defun)
  861.  
  862.    Now we can try out `count-words-defun': install both
  863. `count-words-in-defun' and `count-words-defun', and set the keybinding,
  864. and then place the cursor within the following definition:
  865.  
  866.      (defun multiply-by-seven (number)
  867.        "Multiply NUMBER by seven."
  868.        (* 7 number))
  869.           => 10
  870.  
  871. Success!  The definition has 10 words and symbols.
  872.  
  873.    The next problem is to count the numbers of words and symbols in
  874. several definitions within a single file.
  875.  
  876. 
  877. File: emacs-lisp-intro.info,  Node: Several defuns,  Next: Find a File,  Prev: count-words-in-defun,  Up: Words in a defun
  878.  
  879. Count Several `defuns' Within a File
  880. ====================================
  881.  
  882.    A file such as `simple.el' may have 80 or more function definitions
  883. within it.  Our long term goal is to collect statistics on many files,
  884. but as a first step, our immediate goal is to collect statistics on one
  885. file.
  886.  
  887.    The information will be a series of numbers, each number being the
  888. length of a function definition.  We can store the numbers in a list.
  889.  
  890.    We know that we will want to incorporate the information regarding
  891. one file with information about many other files; this means that the
  892. function for counting definition lengths within one file need only
  893. return the lengths' list.  It need not and should not display any
  894. messages.
  895.  
  896.    The word count commands contain one expression to jump point forward
  897. word by word and another expression to count the jumps.  The
  898. definitions' lengths' function can be designed to work the same way,
  899. with one expression to jump point forward definition by definition and
  900. another expression to construct the lengths' list.
  901.  
  902.    This statement of the problem makes it elementary to write the
  903. function definition.  Clearly, we will start the count at the beginning
  904. of the file, so the first command will be `(goto-char (point-min))'.
  905. Next, we start the `while' loop; and the true-or-false test of the loop
  906. can be a regular expression search for the next function definition--so
  907. long as the search succeeds, point is moved forward and then the body
  908. of the loop is evaluated.  The body needs an expression that constructs
  909. the lengths' list.  `cons', the list construction command, can be used
  910. to create the list.  That is almost all there is to it.
  911.  
  912.    Here is what this fragment of code looks like:
  913.  
  914.      (goto-char (point-min))
  915.      (while (re-search-forward "^(defun" nil t)
  916.        (setq lengths-list
  917.              (cons (count-words-in-defun) lengths-list)))
  918.  
  919.    What we have left out is the mechanism for finding the file that
  920. contains the function definitions.
  921.  
  922.    In previous examples, we either used this, the Info file, or we
  923. switched back and forth to some other buffer, such as the `*scratch*'
  924. buffer.
  925.  
  926.    Finding a file is a new process that we have not yet discussed.
  927.  
  928. 
  929. File: emacs-lisp-intro.info,  Node: Find a File,  Next: lengths-list-file,  Prev: Several defuns,  Up: Words in a defun
  930.  
  931. Find a File
  932. ===========
  933.  
  934.    To find a file in Emacs, you use the `C-x C-f' (`find-file')
  935. command.  This command is almost, but not quite right for the lengths
  936. problem.
  937.  
  938.    Let's look at the source for `find-file' (you can use the `find-tag'
  939. command to find the source of a function):
  940.  
  941.      (defun find-file (filename)
  942.        "Edit file FILENAME.
  943.      Switch to a buffer visiting file FILENAME,
  944.      creating one if none already exists."
  945.        (interactive "FFind file: ")
  946.        (switch-to-buffer (find-file-noselect filename)))
  947.  
  948.    The definition possesses short but complete documentation and an
  949. interactive specification that prompts you for a file name when you use
  950. the command interactively.  The body of the definition contains two
  951. functions, `find-file-noselect' and `switch-to-buffer'.
  952.  
  953.    According to its documentation as shown by `C-h f' (the
  954. `describe-function' command), the `find-file-noselect' function reads
  955. the named file into a buffer and returns the buffer.  However, the
  956. buffer is not selected.  Emacs does not switch its attention (or yours
  957. if you are using `find-file-noselect') to the named buffer.  That is
  958. what `switch-to-buffer' does: it switches the buffer to which Emacs
  959. attention is directed; and it switches the buffer displayed in the
  960. window to the new buffer.  We have discussed buffer switching
  961. elsewhere.  (*Note Switching Buffers::.)
  962.  
  963.    In this histogram project, we do not need to display each file on the
  964. screen as the program determines the length of each definition within
  965. it.  Instead of employing `switch-to-buffer', we can work with
  966. `set-buffer', which redirects the attention of the computer program to
  967. a different buffer but does not redisplay it on the screen.  So instead
  968. of calling on `find-file' to do the job, we must write our own
  969. expression.
  970.  
  971.    The task is easy: use  `find-file-noselect' and `set-buffer'.
  972.  
  973. 
  974. File: emacs-lisp-intro.info,  Node: lengths-list-file,  Next: Several files,  Prev: Find a File,  Up: Words in a defun
  975.  
  976. `lengths-list-file' in Detail
  977. =============================
  978.  
  979.    The core of the `lengths-list-file' function is a `while' loop
  980. containing a function to move point forward `defun by defun' and a
  981. function to count the number of words and symbols in each defun.  This
  982. core must be surrounded by functions that do various other tasks,
  983. including finding the file, and ensuring that point starts out at the
  984. beginning of the file.  The function definition looks like this:
  985.  
  986.      (defun lengths-list-file (filename)
  987.        "Return list of definitions' lengths within FILE.
  988.      The returned list is a list of numbers.
  989.      Each number is the number of words or
  990.      symbols in one function definition."
  991.        (message "Working on `%s' ... " filename)
  992.        (save-excursion
  993.          (let ((buffer (find-file-noselect filename))
  994.                (lengths-list))
  995.            (set-buffer buffer)
  996.            (setq buffer-read-only t)
  997.            (widen)
  998.            (goto-char (point-min))
  999.            (while (re-search-forward "^(defun" nil t)
  1000.              (setq lengths-list
  1001.                    (cons (count-words-in-defun) lengths-list)))
  1002.            (kill-buffer buffer)
  1003.            lengths-list)))
  1004.  
  1005. The function is passed one argument, the name of the file on which it
  1006. will work.  It has four lines of documentation, but no interactive
  1007. specification.  Since people worry that a computer is broken if they
  1008. don't see anything going on, the first line of the body is a message.
  1009.  
  1010.    The next line contains a `save-excursion' that returns Emacs
  1011. attention to the current buffer when the function completes.  This is
  1012. useful in case you embed this function in another function that
  1013. presumes point is restored to the original buffer.
  1014.  
  1015.    In the varlist of the `let' expression, Emacs finds the file and
  1016. binds the local variable `buffer' to the buffer containing the file.
  1017. At the same time, Emacs creates `lengths-list' as a local variable.
  1018.  
  1019.    Next, Emacs switches its attention to the buffer.
  1020.  
  1021.    In the following line, Emacs makes the buffer read-only.  Ideally,
  1022. this line is not necessary.  None of the functions for counting words
  1023. and symbols in a function definition should change the buffer.
  1024. Besides, the buffer is not going to be saved, even if it were changed.
  1025. This line is entirely the consequence of great, perhaps excessive,
  1026. caution.  The reason for the caution is that this function and those it
  1027. calls work on the sources for Emacs and it is very inconvenient if they
  1028. are inadvertently modified.  It goes without saying that I did not
  1029. realize a need for this line until an experiment went awry and started
  1030. to modify my Emacs source files ...
  1031.  
  1032.    Next comes a call to widen the buffer if it is narrowed.  This
  1033. function is usually not needed--Emacs creates a fresh buffer if none
  1034. already exists; but if a buffer visiting the file already exists Emacs
  1035. returns that one.  In this case, the buffer may be narrowed and must be
  1036. widened.  If we wanted to be fully `user-friendly', we would arrange to
  1037. save the restriction and the location of point, but we won't.
  1038.  
  1039.    The `(goto-char (point-min))' expression moves point to the
  1040. beginning of the buffer.
  1041.  
  1042.    Then comes a `while' loop in which the `work' of the function is
  1043. carried out.  In the loop, Emacs determines the length of each
  1044. definition and constructs a lengths' list containing the information.
  1045.  
  1046.    Emacs kills the buffer after working through it.  This is to save
  1047. space inside of Emacs.  My version of Emacs 19 contains over 300 source
  1048. files of interest.  Another function will apply `lengths-list-file' to
  1049. each of them.  If Emacs visits all of them and deletes none, my
  1050. computer may run out of virtual memory.
  1051.  
  1052.    Finally, the last expression within the `let' expression is the
  1053. `lengths-list' variable; its value is returned as the value of the
  1054. whole function.
  1055.  
  1056.    You can try this function by installing it in the usual fashion.
  1057. Then place your cursor after the following expression and type `C-x
  1058. C-e' (`eval-last-sexp').
  1059.  
  1060.      (lengths-list-file "../lisp/debug.el")
  1061.  
  1062. (You may need to change the pathname of the file; the one here works if
  1063. this Info file and the Emacs sources are in neighboring places, such as
  1064. `/usr/local/emacs/info' and `/usr/local/emacs/lisp'.  To change the
  1065. expression, copy it to the `*scratch*' buffer and edit it.  Then
  1066. evaluate it.)
  1067.  
  1068.    On my version of Emacs, the lengths' list for `debug.el' takes seven
  1069. seconds to produce and looks like this:
  1070.  
  1071.      (75 41 80 62 20 45 44 68 45 12 34 235)
  1072.  
  1073.    Note that the length of the last definition in the file is first in
  1074. the list.
  1075.  
  1076. 
  1077. File: emacs-lisp-intro.info,  Node: Several files,  Next: Several files recursively,  Prev: lengths-list-file,  Up: Words in a defun
  1078.  
  1079. Count Words in `defuns' in Different Files
  1080. ==========================================
  1081.  
  1082.    In the previous section, we created a function that returns a list of
  1083. the lengths of each definition in a file.  Now, we want to define a
  1084. function to return a master list of the lengths of the definitions in a
  1085. list of files.
  1086.  
  1087.    Working on each of a list of files is a repetitious act, so we can
  1088. use either a `while' loop or recursion.
  1089.  
  1090.    The design using a `while' loop is routine.  The argument passed the
  1091. function is a list of files.  As we saw earlier (*note Loop
  1092. Example::.), you can write a `while' loop so that the body of the loop
  1093. is evaluated if such a list contains elements, but to exit the loop if
  1094. the list is empty.  For this design to work, the body of the loop must
  1095. contain an expression that shortens the list each time the body is
  1096. evaluated, so that eventually the list is empty.  The usual technique
  1097. is to set the value of the list to the value of the CDR of the list
  1098. each time the body is evaluated.
  1099.  
  1100.    The template looks like this:
  1101.  
  1102.      (while TEST-WHETHER-LIST-IS-EMPTY
  1103.        BODY...
  1104.        SET-LIST-TO-CDR-OF-LIST)
  1105.  
  1106.    Also, we remember that a `while' loop returns `nil' (the result of
  1107. evaluating the true-or-false-test), not the result of any evaluation
  1108. within its body.  (The evaluations within the body of the loop are done
  1109. for their side effects.)  However, the expression that sets the
  1110. lengths' list is part of the body--and that is the value that we want
  1111. returned by the function as a whole.  To do this, we enclose the
  1112. `while' loop within a `let' expression, and arrange that the last
  1113. element of the `let' expression contains the value of the lengths'
  1114. list.  (*Note Loop Example with an Incrementing Counter: Incrementing
  1115. Example.)
  1116.  
  1117.    These considerations lead us directly to the function itself:
  1118.  
  1119.      ;;; Use `while' loop.
  1120.      (defun lengths-list-many-files (list-of-files)
  1121.        "Return list of lengths of defuns in LIST-OF-FILES."
  1122.        (let (lengths-list)
  1123.      
  1124.      ;;; true-or-false-test
  1125.          (while list-of-files
  1126.            (setq lengths-list
  1127.                  (append
  1128.                   lengths-list
  1129.      
  1130.      ;;; Generate a lengths' list.
  1131.                   (lengths-list-file
  1132.                    (expand-file-name (car list-of-files)))))
  1133.      
  1134.      ;;; Make files' list shorter.
  1135.            (setq list-of-files (cdr list-of-files)))
  1136.      
  1137.      ;;; Return final value of lengths' list.
  1138.          lengths-list))
  1139.  
  1140.    `expand-file-name' is a built-in function that converts a file name
  1141. to its absolute, long, path name form.  Thus,
  1142.  
  1143.      debug.el
  1144.  
  1145. becomes
  1146.  
  1147.      /usr/local/emacs/lisp/debug.el
  1148.  
  1149.    The only other new element of this function definition is the as yet
  1150. unstudied function `append', which merits a short section for itself.
  1151.  
  1152. * Menu:
  1153.  
  1154. * append::                      Attaching one list to another.
  1155.  
  1156. 
  1157. File: emacs-lisp-intro.info,  Node: append,  Prev: Several files,  Up: Several files
  1158.  
  1159. The `append' Function
  1160. ---------------------
  1161.  
  1162.    The `append' function attaches one list to another.  Thus,
  1163.  
  1164.      (append '(1 2 3 4) '(5 6 7 8))
  1165.  
  1166. produces the list
  1167.  
  1168.      (1 2 3 4 5 6 7 8)
  1169.  
  1170.    This is exactly how we want to attach two lengths' lists produced by
  1171. `lengths-list-file' to each other.  The results contrast with `cons',
  1172.  
  1173.      (cons '(1 2 3 4) '(5 6 7 8))
  1174.  
  1175. which constructs a new list in which the first argument to `cons'
  1176. becomes the first element of the new list:
  1177.  
  1178.      ((1 2 3 4) 5 6 7 8)
  1179.  
  1180.