Boongle, Inc. ships literature electronically from its web server (in HTML form), though you can also order it in hard-copy form from them, in which case they print a copy for you (via PDF). A book is stored as follows:
(define-struct book (author title chapters))
(define-struct chapter (title content))
;; A Book is (make-book String String [Listof Chapter])
;; A Chapter is (make-chapter String [Listof String])

The representation is well-suited for rendering the book in many different formats and for processing it in other ways (searching, sorting, text analysis).

In addition to a charge for the (intellectual value of the) book itself, the company also charges for delivery cost, which depends on the number of chars in a book. The task of designing an appropriate function has fallen to you. Fortunately, Eden Schultheiss, the owner of Boongle, mentioned string-length before she steamed off to the next meeting.

  1. Which of the following two definitions is not a legitimate book? Why?

    (define one
      (make-book "J.D. Salinger" "The Catcher in the Rye" 
                 (list (make-chapter "Catcher" empty)
                       (make-chapter "Rye" (list "aha")))))
    
    (define two
      (make-book "TC" "Breakfast at Tiffany's" 
                 (list (make-chapter "Breakfast" "")
                       (make-chapter "Tiffany's"
                         "She was looking gorgeous that night."))))
    



    Solution: Grader: Felix

    [PTS 1] Book two is not a legal piece of data because it contains strings in the chapter content fields rather than list of strings.

  2. Make up a Book that contains no characters.



    Solution:

     ;; [PTS 1: for both answers]
     (make-book "" "" empty) ;; etc
    

  3. Design the function book-size, which consumes a Book and counts how many chars the book contains. For examples/tests, you may make up samples of your own and/or employ the above.



    Solution:

    ;; [PTS 3: 1: contract & purpose; 1:
    ;;         3 selectors; 1: correct]
    ;; book-size : Book -> Number 
    ;; determine the size of the book 
    (define (book-size b)
      (+ (string-length (book-author b))
         (string-length (book-title b))
         (chapters-size (book-chapters b))))
    
    ;; [PTS 3: 1 for cond, 1 for rec, 1 correct
    ;;  XOR 3: 1 for map, 1 for foldl, 1 for correct
    ;;  XOR 3 if in-lined correctly]
    ;; chapters-size : [Listof Chapter] -> Number 
    ;; determine the size of the list of chapters 
    (define (chapters-size.v0 loc)
      (cond
        [(empty? loc) 0]
        [else (+ (chapter-size (first loc))
                 (chapters-size (rest loc)))]))
    
    (define (chapters-size loc)
      (foldl + 0 (map chapter-size loc)))
    
    ;; [PTS 2: for correctness
    ;;  XOR 2: for correct in-lining]
    ;; chapter-size : Chapter -> Number 
    ;; determine the size of a chapter 
    (define (chapter-size c)
      (+ (string-length (chapter-title c))
         (los-size (chapter-content c))))
    
    ;; [PTS 3, as for chapters-size]
    ;; los-size : [Listof String] -> Number 
    ;; determine the size of a list of strings
    (define (los-size.v0 los)
      (cond
        [(empty? los) 0]
        [else (+ (string-length (first los))
                 (los-size (rest los)))]))
    
    (define (los-size los)
      (foldl + 0 (map string-length los)))
    
    ;; Tests: [PTS 1]
    (equal? (book-size one) 48)