2009-09-13 20 views
7

Estoy leyendo "En lisp" y encontré este código (lo simplifiqué un poco).¿Cuál es la diferencia entre '(a b c) y (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) 
  • ¿Qué significa exactamente *? ¿Es la llamada a la función anterior? ¿Es adecuado usarlo en el código del mundo real?

  • ¿Por qué (nconc * '(D E)) cambia el valor de retorno de la primera función foo?

  • Siempre pensé que (list 'a 'b 'c) y '(a b c) son lo mismo? ¿Cuál es la diferencia?

Respuesta

14

La llamada a LIST crea una nueva lista cada vez que se evalúa. El literal de la lista puede colocarse en un segmento de memoria de solo lectura después de la compilación. Una actualización destructiva en las listas con NCONC es entonces problemática, posiblemente con consecuencias indefinidas (error de segmentación, cambio del literal para futuras referencias, o nada en absoluto).

+0

no habíamos pensado en eso;) –

8

Las variables *, ** y *** se especifican por el idioma standard y son bastante útiles cuando se prueban cosas. Son una característica de REPL, por lo que no son, y no deben ser, útiles en un "código de mundo real".

+0

+1 para la referencia de HyperSpec – sigjuice

Cuestiones relacionadas