Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The conditional in Conad Barski's lisp function is redundant?

This question is related to the Chapter 6 code of Conrad Barski's Book, Land of Lisp.

The code is the following

(defun tweak-text (lst caps lit)
  (when lst
    (let ((item (car lst))
          (rest (cdr lst)))
      (cond ((eq item #\space) (cons item (tweak-text rest caps lit)))
            ((member item '(#\! #\? #\.)) (cons item (tweak-text rest t lit)))
            ((eq item #\") (tweak-text rest caps (not lit)))
            (lit (cons item (tweak-text rest nil lit)))
            ((or caps lit) (cons (char-upcase item) (tweak-text rest nil lit)))
            (t (cons (char-downcase item) (tweak-text rest nil nil)))))))

Now look at the (lit ..) part and the stuff below it .. ((or caps nil) ..), so my question is the following

  • if lit is ever true, it will be will be evaluated in the former expression stated
  • if it is not true, the latter expression will always evaluate to (or caps false) => (or caps false) which is pretty much useless?

So shouldn't the latter expression simply be (caps (cons (char ...)) ?

This book has been read by thousands so I must be wrong about something and I'm not John Bell.

like image 874
metric-space Avatar asked May 12 '16 00:05

metric-space


2 Answers

Yes, the simpler expression is equivalent. It is mentioned in the page 97 errata http://landoflisp.com/errata.html

like image 52
sigjuice Avatar answered Oct 22 '22 01:10

sigjuice


One of the problems is the use of recursion, which limits the length of lists the function is able to process.

(defun tweak-text (list &aux (caps t) (lit nil))
  (mapcon (lambda (c)
            (case c
              (#\space (list c))
              ((#\! #\? #\.)
               (setf caps t)
               (list c))
              (#\"
               (setf lit (not lit))
               ())
              (otherwise
               (cond (lit (setf caps nil) (list c))
                     (caps (setf caps nil) (list (char-upcase c)))
                     (t (setf caps nil lit nil)
                        (list (char-downcase c)))))))
          list))
like image 29
Rainer Joswig Avatar answered Oct 22 '22 01:10

Rainer Joswig