eintr: recursive-graph-body-print

 
 15.2 The ‘recursive-graph-body-print’ Function
 ==============================================
 
 The ‘graph-body-print’ function may also be written recursively.  The
 recursive solution is divided into two parts: an outside wrapper that
 uses a ‘let’ expression to determine the values of several variables
 that need only be found once, such as the maximum height of the graph,
 and an inside function that is called recursively to print the graph.
 
    The wrapper is uncomplicated:
 
      (defun recursive-graph-body-print (numbers-list)
        "Print a bar graph of the NUMBERS-LIST.
      The numbers-list consists of the Y-axis values."
        (let ((height (apply 'max numbers-list))
              (symbol-width (length graph-blank))
              from-position)
          (recursive-graph-body-print-internal
           numbers-list
           height
           symbol-width)))
 
    The recursive function is a little more difficult.  It has four
 parts: the do-again-test, the printing code, the recursive call, and the
 next-step-expression.  The do-again-test is a ‘when’ expression that
 determines whether the ‘numbers-list’ contains any remaining elements;
 if it does, the function prints one column of the graph using the
 printing code and calls itself again.  The function calls itself again
 according to the value produced by the next-step-expression which causes
 the call to act on a shorter version of the ‘numbers-list’.
 
      (defun recursive-graph-body-print-internal
        (numbers-list height symbol-width)
        "Print a bar graph.
      Used within recursive-graph-body-print function."
 
        (when numbers-list
              (setq from-position (point))
              (insert-rectangle
               (column-of-graph height (car numbers-list)))
              (goto-char from-position)
              (forward-char symbol-width)
              (sit-for 0)     ; Draw graph column by column.
              (recursive-graph-body-print-internal
               (cdr numbers-list) height symbol-width)))
 
    After installation, this expression can be tested; here is a sample:
 
      (recursive-graph-body-print '(3 2 5 6 7 5 3 4 6 4 3 2 1))
 
    Here is what ‘recursive-graph-body-print’ produces:
 
                      *
                     **   *
                    ****  *
                    **** ***
                  * *********
                  ************
                  *************
 
    Either of these two functions, ‘graph-body-print’ or
 ‘recursive-graph-body-print’, create the body of a graph.