2009-09-13 28 views
7

Czytam "Na lisp" i napotkałem ten kod (trochę go uprościłem).Jaka jest różnica między "(a b c) a (listą" 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) 
  • Co dokładnie * oznacza? Czy to poprzednie wywołanie funkcji? Czy można go używać w prawdziwym kodzie?

  • Dlaczego (nconc * '(D E)) zmienia wartość zwracaną pierwszej funkcji foo?

  • Zawsze uważałem, że (list 'a 'b 'c) i '(a b c) są takie same? Jaka jest różnica?

Odpowiedz

14

Wywołanie LISTY tworzy nową listę za każdym razem, gdy jest oceniany. Literał listy może zostać umieszczony w segmencie pamięci tylko do odczytu po kompilacji. Destrukcyjna aktualizacja list przez NCONC jest wówczas problematyczna, prawdopodobnie z nieokreślonymi konsekwencjami (błąd segmentacji, zmiana literału dla przyszłych odniesień lub w ogóle nic).

+0

o tym nie myślałem;) –

8

Zmienne *, ** i *** są określone językiem standard i są bardzo przydatne podczas testowania różnych rzeczy. Są one cechą REPL, a więc nie są i nie powinny być użyteczne w "prawdziwym kodzie świata".

+0

+1 za referencję HyperSpec – sigjuice

Powiązane problemy