2011-01-02 18 views
10

He leído un lote de cosas buenas sobre Land of Lisp, así que pensé que podría verlo para ver qué había para ver.Land of Lisp example redundency?

(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))))))) 

(los comentarios son míos)
(. FYI - la firma del método es (list-of-symbols bool-whether-to-caps bool-whether-to-treat-literally) pero el autor acortados éstos a (lst caps lit))

Pero de todos modos, aquí está la pregunta:
Esto tiene (cond... (lit ...) ((or caps lit) ...)) en eso. Según entiendo, esto se traduciría en if(lit){ ... } else if(caps || lit){...} en una sintaxis de estilo C. ¿No es la declaración o redundante entonces? ¿Hay alguna vez una condición en la que se llame a la condición (or caps lit) si caps es nil?

Respuesta

10

De hecho, estás en lo cierto. Vea el errata para el libro.

Página 97: La función tweak-text tiene dos fallos, aunque se ejecutará correctamente en la mayoría de las implementaciones de Lisp. En primer lugar, usa la función eq para comparar caracteres: los caracteres siempre deben verificarse con otras funciones como eql o char-equal según las especificaciones de ANSI. Además, hay una verificación innecesaria de (o mayúsculas) que se puede simplificar a mayúsculas.

+0

Gracias. Estaba empezando a pensar que me estaba volviendo loco (recordaré revisar la errata la próxima vez) – cwallenpoole

8

que iba a escribir que a medida:

(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))))))))) 

el caso despachos declaración sobre el carácter. La declaración COND se ocupa de las otras condiciones. CASE se compara con EQL. Eso significa que CASE funciona también para los personajes e incluso se puede comparar con varios elementos. También soy fanático de un estilo de diseño de código que alinea las expresiones correspondientes; esto solo es útil con fuentes monoespaciadas. Esto me ayuda a detectar patrones visualmente en el código y ayuda a detectar código que se puede simplificar.

DESTRUCTURING-BIND separa la lista.

Para divertido, reescrito usando BUCLE:

(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))) 
+1

'((Hay algunas cosas en el libro que he notado que habría hecho de manera diferente (tiene un poco de recurrencia aquí donde la iteración es mucho más clara y (en mi opinión) más fácil de entender)) (pero (estoy siguiendo los ejemplos (en el caso (tiene un plan mejor de lo que hubiera imaginado))))) (Lisp hace inglés) . – cwallenpoole