Hi,
I am trying to pick up Common Lisp, and whilst playing around with
list functions I have come across a rather strange situation that I am
failing to understand.
Here are two functions that I have defined:
(defun not-ok (x)
(nconc x (list 'c)))
(defun test ()
(let ((x '(1)))
(not-ok x)
x))
These are the results that I get when calling test
CL-USER> (test)
(1 C)
CL-USER> (test)
(1 C C)
CL-USER> (test)
(1 C C C)
CL-USER> (test)
(1 C C C C)
CL-USER> (test)
(1 C C C C C)
I really do not understand why let is not initializing x to a new list
but rather x is turned into accumulator. I suppose this is a side-
effect of using nconc but how is nconc affecting let?
I am using latest version of SLIME and SBCL on OSX.
Thank you very much for your help I really do appreciate it.
Cheers,
Srdjan
On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
> (defun test ()
> (let ((x '(1)))
> (not-ok x)
> x))
> CL-USER> (test)
> (1 C)
> CL-USER> (test)
> (1 C C)
> I really do not understand why let is not initializing x
quote (the single quotation mark) doesn't create a new list, and of
course nconc alters x in place. So you're repeatedly binding x to the
same list and appending 'c to that list.
Incidentally, this is the universal beginner's question. It's been
asked at least three or four times in the last few months. So you
have plenty of company :)
--Dan
-------------------------------
Dan Bensen
http://www.prairienet.org/~dsb/
danb wrote:
> On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
>
>>(defun test ()
>> (let ((x '(1)))
>> (not-ok x)
>> x))
>>CL-USER> (test)
>>(1 C)
>>CL-USER> (test)
>>(1 C C)
>
>
>>I really do not understand why let is not initializing x
>
>
> quote (the single quotation mark) doesn't create a new list, and of
> course nconc alters x in place. So you're repeatedly binding x to the
> same list and appending 'c to that list.
>
> Incidentally, this is the universal beginner's question. It's been
> asked at least three or four times in the last few months. So you
> have plenty of company :)
IIANM somewhere in here is either a list or a pointer to a list of these
common nooby coding gotchas:
http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html
kenny
--
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
"In the morning, hear the Way;
in the evening, die content!"
-- Confucius
On Mar 9, 12:01 am, Ken Tilton <···········@optonline.net> wrote:
> danb wrote:
> > On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
>
> >>(defun test ()
> >> (let ((x '(1)))
> >> (not-ok x)
> >> x))
> >>CL-USER> (test)
> >>(1 C)
> >>CL-USER> (test)
> >>(1 C C)
>
> >>I really do not understand why let is not initializing x
>
> > quote (the single quotation mark) doesn't create a new list, and of
> > course nconc alters x in place. So you're repeatedly binding x to the
> > same list and appending 'c to that list.
>
> > Incidentally, this is the universal beginner's question. It's been
> > asked at least three or four times in the last few months. So you
> > have plenty of company :)
>
> IIANM somewhere in here is either a list or a pointer to a list of these
> common nooby coding gotchas:
>
> http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html
>
> kenny
>
> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>
> "In the morning, hear the Way;
> in the evening, die content!"
> -- Confucius
Hello,
Indeed there it is http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html.
Thank you very much for your time and a link to the faq
regards
srdjan
srdjan.m wrote:
> On Mar 9, 12:01 am, Ken Tilton <···········@optonline.net> wrote:
>
>>danb wrote:
>>
>>>On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
>>
>>>>(defun test ()
>>>> (let ((x '(1)))
>>>> (not-ok x)
>>>> x))
>>>>CL-USER> (test)
>>>>(1 C)
>>>>CL-USER> (test)
>>>>(1 C C)
>>
>>>>I really do not understand why let is not initializing x
>>
>>>quote (the single quotation mark) doesn't create a new list, and of
>>>course nconc alters x in place. So you're repeatedly binding x to the
>>>same list and appending 'c to that list.
>>
>>>Incidentally, this is the universal beginner's question. It's been
>>>asked at least three or four times in the last few months. So you
>>>have plenty of company :)
>>
>>IIANM somewhere in here is either a list or a pointer to a list of these
>>common nooby coding gotchas:
>>
>> http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html
>>
>>kenny
>>
>>--http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>>
>>"In the morning, hear the Way;
>> in the evening, die content!"
>> -- Confucius
>
>
> Hello,
>
> Indeed there it is http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html.
Good! Now ignore it. :(
http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-fear-no-evil.html
kenny
--
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
"In the morning, hear the Way;
in the evening, die content!"
-- Confucius
Ken Tilton wrote:
>
>
> srdjan.m wrote:
>
>> On Mar 9, 12:01 am, Ken Tilton <···········@optonline.net> wrote:
>>
>>> danb wrote:
>>>
>>>> On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
>>>
>>>
>>>>> (defun test ()
>>>>> (let ((x '(1)))
>>>>> (not-ok x)
>>>>> x))
>>>>> CL-USER> (test)
>>>>> (1 C)
>>>>> CL-USER> (test)
>>>>> (1 C C)
>>>
>>>
>>>>> I really do not understand why let is not initializing x
>>>
>>>
>>>> quote (the single quotation mark) doesn't create a new list, and of
>>>> course nconc alters x in place. So you're repeatedly binding x to the
>>>> same list and appending 'c to that list.
>>>
>>>
>>>> Incidentally, this is the universal beginner's question. It's been
>>>> asked at least three or four times in the last few months. So you
>>>> have plenty of company :)
>>>
>>>
>>> IIANM somewhere in here is either a list or a pointer to a list of these
>>> common nooby coding gotchas:
>>>
>>> http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html
>>>
>>> kenny
>>>
>>> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>>>
>>> "In the morning, hear the Way;
>>> in the evening, die content!"
>>> -- Confucius
>>
>>
>>
>> Hello,
>>
>> Indeed there it is
>> http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html.
>
>
> Good! Now ignore it. :(
>
Blogware got weird on me, had to redo post:
http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-fear-no-evil_09.html
Hopefully more useful than the FAQ on destructive list operations.
Corrections/questions/confusions welcome.
kenny
--
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
"In the morning, hear the Way;
in the evening, die content!"
-- Confucius
On Mar 9, 5:45 am, Ken Tilton <···········@optonline.net> wrote:
> Ken Tilton wrote:
>
> > srdjan.m wrote:
>
> >> On Mar 9, 12:01 am, Ken Tilton <···········@optonline.net> wrote:
>
> >>> danb wrote:
>
> >>>> On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
>
> >>>>> (defun test ()
> >>>>> (let ((x '(1)))
> >>>>> (not-ok x)
> >>>>> x))
> >>>>> CL-USER> (test)
> >>>>> (1 C)
> >>>>> CL-USER> (test)
> >>>>> (1 C C)
>
> >>>>> I really do not understand why let is not initializing x
>
> >>>> quote (the single quotation mark) doesn't create a new list, and of
> >>>> course nconc alters x in place. So you're repeatedly binding x to the
> >>>> same list and appending 'c to that list.
>
> >>>> Incidentally, this is the universal beginner's question. It's been
> >>>> asked at least three or four times in the last few months. So you
> >>>> have plenty of company :)
>
> >>> IIANM somewhere in here is either a list or a pointer to a list of these
> >>> common nooby coding gotchas:
>
> >>> http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html
>
> >>> kenny
>
> >>> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>
> >>> "In the morning, hear the Way;
> >>> in the evening, die content!"
> >>> -- Confucius
>
> >> Hello,
>
> >> Indeed there it is
> >>http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html.
>
> > Good! Now ignore it. :(
>
> Blogware got weird on me, had to redo post:
>
> http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-...
>
> Hopefully more useful than the FAQ on destructive list operations.
> Corrections/questions/confusions welcome.
>
> kenny
>
> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>
> "In the morning, hear the Way;
> in the evening, die content!"
> -- Confucius
Kenny is modest (HA! yeah, right), but I love this little tale that he
also put up on blogspot.
http://smuglispweeny.blogspot.com/2008/03/my-biggest-lisp-project.html
thus spoke Ken Tilton <···········@optonline.net>:
> http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-fear-no-evil_09.html
> Hopefully more useful than the FAQ on destructive list operations.
> Corrections/questions/confusions welcome.
| We could do something herculean such as using mapl and rplaca together
| to mutate the list in place, or we can just use loop:
MAP-INTO seems to be a better example than the former.
--
Nawet świnka wejdzie na drzewo kiedy ją chwalą.
Stanisław Halik wrote:
> thus spoke Ken Tilton <···········@optonline.net>:
>
>
>>http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-fear-no-evil_09.html
>
>
>>Hopefully more useful than the FAQ on destructive list operations.
>>Corrections/questions/confusions welcome.
>
>
> | We could do something herculean such as using mapl and rplaca together
> | to mutate the list in place, or we can just use loop:
>
> MAP-INTO seems to be a better example than the former.
>
PWUAHAHAHAHHAHAHHAHA!
(Big frickin language, isn't it?)
Thx, I'll amend the entry.
kenny
--
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
"In the morning, hear the Way;
in the evening, die content!"
-- Confucius
thus spoke Ken Tilton <···········@optonline.net>:
>> MAP-INTO seems to be a better example than the former.
> PWUAHAHAHAHHAHAHHAHA!
> (Big frickin language, isn't it?)
:)
> Thx, I'll amend the entry.
You got map-into arguments wrong. It should be:
(defun filter-do-and-flatten (lists do filter)
(apply #'nconc
(let ((tmp (remove-if-not filter lists)))
(map-into tmp do tmp))))
--
Nawet świnka wejdzie na drzewo kiedy ją chwalą.
Stanisław Halik wrote:
> thus spoke Ken Tilton <···········@optonline.net>:
>
>
>>>MAP-INTO seems to be a better example than the former.
>>
>>PWUAHAHAHAHHAHAHHAHA!
>
>
>>(Big frickin language, isn't it?)
>
>
> :)
>
>
>>Thx, I'll amend the entry.
>
>
> You got map-into arguments wrong. It should be:
>
> (defun filter-do-and-flatten (lists do filter)
> (apply #'nconc
> (let ((tmp (remove-if-not filter lists)))
> (map-into tmp do tmp))))
>
Thx for the handholding. One more iteration and I'll just give you my
password.
:)
kenny
--
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
"In the morning, hear the Way;
in the evening, die content!"
-- Confucius
thus spoke Ken Tilton <···········@optonline.net>:
>> MAP-INTO seems to be a better example than the former.
> PWUAHAHAHAHHAHAHHAHA!
> (Big frickin language, isn't it?)
:)
> Thx, I'll amend the entry.
You got map-into arguments wrong. It should be:
(defun filter-do-and-flatten (lists do filter)
(apply #'append
(let ((tmp (remove-if-not filter lists)))
(map-into tmp do tmp))))
--
Nawet świnka wejdzie na drzewo kiedy ją chwalą.
På Mon, 10 Mar 2008 22:05:04 +0100, skrev Stanisław Halik
<··············@tehran.lain.pl>:
> thus spoke Ken Tilton <···········@optonline.net>:
>
>> http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-fear-no-evil_09.html
>
>> Hopefully more useful than the FAQ on destructive list operations.
>> Corrections/questions/confusions welcome.
>
> | We could do something herculean such as using mapl and rplaca together
> | to mutate the list in place, or we can just use loop:
>
> MAP-INTO seems to be a better example than the former.
>
Edi: map-into doesn't appear when I press F5. Searching for it does work
though.
--------------
John Thingstad
On Mar 9, 3:12 am, Ken Tilton <···········@optonline.net> wrote:
> srdjan.m wrote:
> > On Mar 9, 12:01 am, Ken Tilton <···········@optonline.net> wrote:
>
> >>danb wrote:
>
> >>>On Mar 8, 10:59 am, "srdjan.m" <················@gmail.com> wrote:
>
> >>>>(defun test ()
> >>>> (let ((x '(1)))
> >>>> (not-ok x)
> >>>> x))
> >>>>CL-USER> (test)
> >>>>(1 C)
> >>>>CL-USER> (test)
> >>>>(1 C C)
>
> >>>>I really do not understand why let is not initializing x
>
> >>>quote (the single quotation mark) doesn't create a new list, and of
> >>>course nconc alters x in place. So you're repeatedly binding x to the
> >>>same list and appending 'c to that list.
>
> >>>Incidentally, this is the universal beginner's question. It's been
> >>>asked at least three or four times in the last few months. So you
> >>>have plenty of company :)
>
> >>IIANM somewhere in here is either a list or a pointer to a list of these
> >>common nooby coding gotchas:
>
> >> http://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/top.html
>
> >>kenny
>
> >>--http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>
> >>"In the morning, hear the Way;
> >> in the evening, die content!"
> >> -- Confucius
>
> > Hello,
>
> > Indeed there it ishttp://www.cs.cmu.edu/Groups/AI/html/faqs/lang/lisp/part1/faq-doc-4.html.
>
> Good! Now ignore it. :(
>
> http://smuglispweeny.blogspot.com/2008/03/tiltons-law-of-programming-...
>
> kenny
>
> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
>
> "In the morning, hear the Way;
> in the evening, die content!"
> -- Confucius
I love it. We need more no fear programming, and less weenie pundits
throwing shit fits when people don't follow their weenie programming
paradigms, and less weenie proteges that tremble in fear because they
can't fit something into some paradigm. Program with no fear, and
refactor when you know it's wrong.
Dynamic people, you have the REPL. Java people, you have your
refactoring tools - use them.
srdjan.m wrote:
> Hi,
>
> I am trying to pick up Common Lisp, and whilst playing around with
> list functions I have come across a rather strange situation that I am
> failing to understand.
> Here are two functions that I have defined:
>
> (defun not-ok (x)
> (nconc x (list 'c)))
>
> (defun test ()
> (let ((x '(1)))
> (not-ok x)
> x))
>
> These are the results that I get when calling test
>
> CL-USER> (test)
> (1 C)
> CL-USER> (test)
> (1 C C)
> CL-USER> (test)
> (1 C C C)
> CL-USER> (test)
> (1 C C C C)
> CL-USER> (test)
> (1 C C C C C)
>
> I really do not understand why let is not initializing x to a new list
> but rather x is turned into accumulator. I suppose this is a side-
> effect of using nconc but how is nconc affecting let?
NCONC performs a side effect on the list structure itself. In your
example, you actually change the literal value '(1)! This is not
supported by ANSI Common Lisp, but this is what apparently happens in
your test runs. (It's not a very good idea to perform side effects on
literal values!)
Try this:
(defvar *x* (list 1)) ;; note: not a literal value,
;; but a list constructed at runtime
(defun test ()
(let ((x *x*))
(not-ok x)
x)))
And see what happens to *x* while you execute your tests.
Since in this version, *x* is not bound to a literal value, using side
effects here is not a problem.
Pascal
--
1st European Lisp Symposium (ELS'08)
http://prog.vub.ac.be/~pcostanza/els08/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
srdjan.m wrote:
> I really do not understand why let is not initializing x to a new list
> but rather x is turned into accumulator. I suppose this is a side-
> effect of using nconc but how is nconc affecting let?
You should not destructively modify a literal constant (such as '(...)
). The consequences are undefined (as you showed above).
You have two options:
(1) Use append
(defun ok-1 (x)
(append (list x) (list 'c)))
(2) Use list to initialize a mutable list:
(defun test-2 ()
(let ((x (list 1)))
(not-ok x)
x))
If you initialize variables with constants such as '(1 2 3), DO NOT use
destructive operations such as nconc on them.
You can think of it like this: '(1 2 3) is a constant that is stored as
part of your compiled code. If you modify this, in effect you modify
your program, not data.
As a rule of thumb, I use (list 1 2 3) by default, and if I use '(1 2 3)
I ask myself twice whether I might under some circumstance destructively
modify this list later.
Peter
srdjan.m wrote:
> I really do not understand why let is not initializing x to a new list
> but rather x is turned into accumulator. I suppose this is a side-
> effect of using nconc but how is nconc affecting let?
'(1) is a literal and nconc modifies this literal. You can use copy-seq to
make new lists every time test is called.
I'm sure there is a more formal definition for this behaviour in the CLHS,
but sometimes it is difficult to find the right chapter, even if you know
what you are searching for :-)
--
Frank Buss, ··@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de