2009-09-13 8 views
7

Sto leggendo "On lisp" e ho incontrato questo codice (l'ho semplificato un po ').Qual è la differenza tra '(a b c) e (lista' a 'b' c)?

CL-USER> (defun foo()               
      '(a b c)) 
FOO                    
CL-USER> (foo) 
(A B C)                   
CL-USER> (nconc * '(D E)) 
(A B C D E)                  
CL-USER> (foo) 
(A B C D E) 
CL-USER> (defun foo()               
      (list 'a 'b 'c)) 
STYLE-WARNING: redefining FOO in DEFUN           
FOO                    
CL-USER> (foo) 
(A B C)                   
CL-USER> (nconc * '(D E)) 
(A B C D E)                  
CL-USER> (foo) 
(A B C) 
  • cosa fa esattamente * significa? È la chiamata alla funzione precedente? È adatto per l'uso nel codice del mondo reale?

  • Perché il (nconc * '(D E)) modifica il valore di ritorno della prima funzione foo?

  • Ho sempre pensato che (list 'a 'b 'c) e '(a b c) sono gli stessi? Qual è la differenza?

risposta

14

La chiamata a LIST crea una nuova lista ogni volta che viene valutata. La lista letterale può essere inserita in un segmento di memoria di sola lettura dopo la compilazione. Un aggiornamento distruttivo sugli elenchi con NCONC è quindi problematico, possibilmente con conseguenze non definite (errore di segmentazione, modifica letterale per riferimenti futuri o niente).

+0

non ci avevo pensato;) –

8

Le variabili *, ** e *** sono specificate dalla lingua standard e sono molto utili quando si verificano le cose. Sono una caratteristica del REPL, e quindi non lo sono, e non dovrebbero, essere utili in un "codice del mondo reale".

+0

+1 per riferimento HyperSpec – sigjuice