2011-01-02 7 views
10

Ho letto un lotto di cose buone su Land of Lisp così ho pensato che potevo passare attraverso di esso per vedere cosa c'era da vedere.Land of Lisp esempio di ridondanza?

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

(i commenti sono miei)
(. A proposito - la firma del metodo è (list-of-symbols bool-whether-to-caps bool-whether-to-treat-literally) ma l'autore accorciato questi per (lst caps lit))

Ma in ogni caso, ecco la domanda:
Questo ha (cond... (lit ...) ((or caps lit) ...)) in esso. La mia comprensione è che ciò si tradurrebbe in if(lit){ ... } else if(caps || lit){...} in una sintassi in stile C. Allora non è la dichiarazione o ridondante? C'è mai una condizione in cui verrà chiamata la condizione (or caps lit) se le maiuscole sono nil?

risposta

10

In effetti, hai ragione. Vedere lo errata per il libro.

Pagina 97: La funzione tweak-text ha due glitch in esso, anche se verrà eseguita correttamente sulla maggior parte delle implementazioni Lisp. Prima di tutto, usa la funzione eq per confrontare i caratteri: i caratteri dovrebbero sempre essere controllati con altre funzioni come eql o char-equal come per le specifiche ANSI. Inoltre, c'è un controllo superfluo (o maiuscolo acceso) che può essere semplificato per i tappi.

+0

Grazie. Stavo cominciando a pensare che stavo impazzendo (ricorderò di controllare l'errata la prossima volta) – cwallenpoole

8

avrei scritto che come:

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

caso dispacci dichiarazione sul carattere. L'affermazione COND si occupa quindi delle altre condizioni. CASE confronta con EQL. Ciò significa che CASE funziona anche per i personaggi e può persino essere confrontato con più elementi. Sono anche un fan di uno stile di layout del codice che allinea le espressioni corrispondenti - questo è utile solo con i font a spaziatura fissa. Questo mi aiuta a rilevare visivamente i pattern nel codice e aiuta a rilevare il codice che può essere semplificato.

DESTRUCTURING-BIND separa la lista.

Per divertimento, riscritto utilizzando LOOP:

(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

((Ci sono alcune cose nel libro che ho notato che avrei fatto diversamente (ha un po 'di ricorsione qui dove l'iterazione è molto più pulita e (secondo me) più facile da comprendere)) (ma (sto seguendo gli esempi (in-case (ha un piano migliore di quello che avrei inventato))))) (Lisp fa l'inglese) . – cwallenpoole