Push question
Can someone tell me why: CL-USER 5 > (let ((acc nil) (val 1)) (push val acc)) (1) CL-USER 6 > (push 1 nil) Error: Cannot change NIL -- it is a constant. Are the Lisp gods crazy? Laughing Water
Can someone tell me why: CL-USER 5 > (let ((acc nil) (val 1)) (push val acc)) (1) CL-USER 6 > (push 1 nil) Error: Cannot change NIL -- it is a constant. Are the Lisp gods crazy? Laughing Water
On September 9, 2005 05:16 pm, Laughing Water wrote: > Can someone tell me why: > > > CL-USER 5 > (let ((acc nil) > (val 1)) > (push val acc)) > (1) > > CL-USER 6 > (push 1 nil) > > Error: Cannot change NIL -- it is a constant. > > > Are the Lisp gods crazy? The 2nd arg of PUSH is a "place", not a value. From TFM: "push prepends item to the list that is stored in place, stores the resulting list in place, and returns the list". (push 1 nil) - nil isn't a "place", it's a constant, hence you simply cannot do this (actually, you could do this in my 1978 version of lisp, which didn't actually check what you were rplaca'ing and rplacd'ing, with the result that you physically altered the value of nil and destroyed the system :-). You might be confusing push with cons (cons 1 nil) returns a new list (1) (push val acc) is the same as : (setf acc (cons val acc))
On Fri, 9 Sep 2005 15:16:02 -0600, Laughing Water <lw@mt.net> wrote: > Can someone tell me why: > > CL-USER 5 > (let ((acc nil) > (val 1)) > (push val acc)) > (1) > > CL-USER 6 > (push 1 nil) > > Error: Cannot change NIL -- it is a constant. PUSH is a macro which modifies a /place/, its second argument. ACC is a perfectly valid place because it's a variable, NIL isn't. Think of it this way: (PUSH VAL ACC) is translated by the macro to something like (SETQ ACC (CONS VAL ACC)). Now, what happens if you replace ACC with NIL in that form? Cheers, Edi.
While this sort of issue is being mentioned, I noticed something odd the other day that sort of makes sense (insofar as I've seen similar behavior before), but I'm still not quite clear on why it happens: CL-USER 4 > (dotimes (x 4) (let ((foo '(a b c d))) (setf (nth x foo) 'e) (print foo))) (E B C D) (E E C D) (E E E D) (E E E E) Nil CL-USER 5 > (dotimes (x 4) (let ((foo (list 'a 'b 'c 'd))) (setf (nth x foo) 'e) (print foo))) (E B C D) (A E C D) (A B E D) (A B C E) Nil CL-USER 6 > Why is it that the space for foo isn't refreshed between iterations of the dotimes with '(a b c d) but is with (list 'a 'b 'c 'd) ? On 09/09/05, Edi Weitz <edi@agharta.de> wrote: > On Fri, 9 Sep 2005 15:16:02 -0600, Laughing Water <lw@mt.net> wrote: > > > Can someone tell me why: > > > > CL-USER 5 > (let ((acc nil) > > (val 1)) > > (push val acc)) > > (1) > > > > CL-USER 6 > (push 1 nil) > > > > Error: Cannot change NIL -- it is a constant. > > PUSH is a macro which modifies a /place/, its second argument. ACC is > a perfectly valid place because it's a variable, NIL isn't. > > Think of it this way: (PUSH VAL ACC) is translated by the macro to > something like (SETQ ACC (CONS VAL ACC)). Now, what happens if you > replace ACC with NIL in that form? > > Cheers, > Edi. > > -- ===================== Joshua Taylor tayloj@rpi.edu
On Fri, 9 Sep 2005 17:49:33 -0400, Joshua Taylor <joshuaaaron@gmail.com> wrote: > While this sort of issue is being mentioned, I noticed something odd > the other day that sort of makes sense (insofar as I've seen similar > behavior before), but I'm still not quite clear on why it happens: > > CL-USER 4 > > (dotimes (x 4) > (let ((foo '(a b c d))) > (setf (nth x foo) 'e) > (print foo))) > > (E B C D) > (E E C D) > (E E E D) > (E E E E) > Nil > > CL-USER 5 > > (dotimes (x 4) > (let ((foo (list 'a 'b 'c 'd))) > (setf (nth x foo) 'e) > (print foo))) > > (E B C D) > (A E C D) > (A B E D) > (A B C E) > Nil > > CL-USER 6 > > > Why is it that the space for foo isn't refreshed between iterations > of the dotimes with '(a b c d) but is with (list 'a 'b 'c 'd) ? <http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part3/faq-doc-14.html> Cheers, Edi.