views:

284

answers:

2

I am reading "On lisp" and encounter this code (I simplified a bit).

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)
  • What does "*" exactly mean, the previous function call? Is it suitable to use in real world code?

  • Why does (nconc * '(D E)) change the return value of the first foo function? I always thought (list 'a 'b 'c) and '(a b c) are the same? What is the difference?

+13  A: 

The call to LIST creates a new list each time it is evaluated. The list literal might be placed in a read-only memory segment after compilation. A destructive update on the lists with NCONC is then problematic, possibly with undefined consequences (segmentation error, changing the literal for future references, or nothing at all).

Christian
hadn't thought of that ;)
Robert Karl
+7  A: 

Variables *, ** and *** are specified by the language standard and they are quite useful when testing things. They are a feature of the REPL, and so are not, and not supposed to, be useful in a "real world code".

Ramarren
+1 for HyperSpec reference
sigjuice