Вопрос

Я прочитал много хороших вещей о Земля Липпа Поэтому я подумал, что могу пройти через это, чтобы увидеть, что нужно было увидеть.

(defun tweak-text (lst caps lit)
  (when lst
    (let ((item (car lst))
      (rest (cdr lst)))
      (cond 
       ; If item = space, then call recursively starting with ret
       ; Then, prepend the space on to the result.
       ((eq item #\space) (cons item (tweak-text rest caps lit)))
       ; if the item is an exclamation point.  Make sure that the
       ; next non-space is capitalized.
       ((member item '(#\! #\? #\.)) (cons item (tweak-text rest t lit)))
       ; if item = " then toggle whether we are in literal mode
       ((eq item #\") (tweak-text rest caps (not lit)))
       ; if literal mode, just add the item as is and continue
       (lit (cons item (tweak-text rest nil lit)))
       ; if either caps or literal mode = true capitalize it?
       ((or caps lit) (cons (char-upcase item) (tweak-text rest nil lit)))
       ; otherwise lower-case it.
       (t (cons (char-downcase item) (tweak-text rest nil nil)))))))

(Комментарии мои)
(К вашему сведению - подпись метода (list-of-symbols bool-whether-to-caps bool-whether-to-treat-literally) Но автор сократил их (lst caps lit).)

Но в любом случае, вот вопрос:
Это имеет (cond... (lit ...) ((or caps lit) ...)) в этом. Насколько я понимаю, это приведет к if(lit){ ... } else if(caps || lit){...} В синтаксисе стиля C. Разве утверждение не избыточно? Есть ли когда -нибудь состояние, где (or caps lit) условие будет вызвано, если Caps nil?

Это было полезно?

Решение

Действительно, вы правы. Увидеть ошибки для книги.

Страница 97: В Tweak-Text Function есть два сбоя, хотя она будет работать OK в большинстве реализаций LISP. Прежде всего, он использует функцию EQ для сравнения символов- символы всегда следует проверять с помощью других функций, таких как EQL или char-equal в соответствии с спецификацией ANSI. Кроме того, существует ненужная проверка (или зажженных), которые можно упростить до CAPS.

Другие советы

Я бы написал это как:

(defun tweak-text (list caps lit)
  (when list
    (destructuring-bind (item . rest) list
      (case item
        ((#\space)             (cons item (tweak-text rest caps lit)))
        ((#\! #\? #\.)         (cons item (tweak-text rest t    lit)))
        ((#\")                 (tweak-text rest caps (not lit)))
        (otherwise (cond (lit  (cons item (tweak-text rest nil  lit)))
                         (caps (cons (char-upcase item)
                                     (tweak-text rest nil lit)))
                         (t    (cons (char-downcase item)
                                     (tweak-text rest nil nil)))))))))

Заявление о случае отправляется на символ. Заявление Cond затем заботится о других условиях. Случай сравнивается с EQL. Это означает, что Case работает также для персонажей и даже может сравниться с несколькими элементами. Я также фанат стиля макета кода, который выстраивает соответствующие выражения - это полезно только с моносированными шрифтами. Это помогает мне обнаружить шаблоны визуально в коде и помогает обнаружить код, который можно упростить.

Destructuring-Bind разбирает список.

За весело, переписано с использованием цикла:

(defun tweak-text (list)
  (loop with caps and lit

        for item in list

        when (eql item #\space)
        collect item

        else when (member item '(#\! #\? #\.))
        collect item and do (setf caps t)

        else when (eql item #\")
        do (setf lit (not lit))

        else when lit
        collect item and do (setf caps nil)

        else when caps
        collect (char-upcase item) and do (setf caps nil)

        else
        collect (char-downcase item) and
        do (setf caps nil lit nil)))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top