[ Home  |  FAQ-Related Q&As  |  General Q&As  |  Answered Questions ]


    Search the Q&A Archives


Afternoon All, I created two functions that use let. ...

<< Back to: FAQ: Lisp Frequently Asked Questions 1/7 [Monthly posting]

Question by juanfie
Submitted on 3/25/2004
Related FAQ: FAQ: Lisp Frequently Asked Questions 1/7 [Monthly posting]
Rating: Not yet rated Rate this question: Vote
Afternoon All,

I created two functions that use let.  Both are pretty much the same, except that in one, I initialize a list using quote and later on modify it using setf; in the second one I modify the variable using setq.

(defun test (x)
  (let ((lista '(a)))
    (print lista)
    (setf (cdr lista) x)
    (print lista)
    lista))

(defun test2 (x)
  (let ((lista '(a)))
    (print lista)
    (setq lista (cons (car lista) x))
    (print lista)
    lista))

When I run test repeatedly, it seems to keep the variable's value as if it was global.  The second one does not maintain the value from the previous one.  Here's the run under Franz CL (Solaris) - same results using other implementations.

; Loading /users/juan/Homeworks/Lisp/let.lisp
CL-USER(12): (test 3)

(A)
(A . 3)
(A . 3)
CL-USER(13): (test 5)

(A . 3)
(A . 5)
(A . 5)
CL-USER(14): (test2 3)

(A)
(A . 3)
(A . 3)
CL-USER(15): (test2 5)

(A)
(A . 5)
(A . 5)
CL-USER(16): :Ex
; Exiting Lisp

Can anyone explain this behavior?

ThX a million.

Juan Flores


Answer by Tagore Smith
Submitted on 6/24/2004
Rating: Not yet rated Rate this answer: Vote
This is not an issue of scope- it is not the binding of your variable that is being "kept", it is the actual memory used to store the literal '(a) that is being modified. Basically, you should never destructively modify a literal, as your implementation may choose to keep only one copy of a literal and reuse that every time that literal is seen.

So the real answer is- don't do that :). If you are going to destructively modify a list in this fashion you should cons up a fresh one, using the list function (or some other function, like cons, that allocates a new list). So your let should look like: (let ((lista (list 'a)))...)

This is a pretty big gotcha, but it becomes second nature after a while- the basic rule is, if you are going to destructively modify a list, make sure that you created that list at runtime.
  

 

Your answer will be published for anyone to see and rate.  Your answer will not be displayed immediately.  If you'd like to get expert points and benefit from positive ratings, please create a new account or login into an existing account below.


Your name or nickname:
If you'd like to create a new account or access your existing account, put in your password here:
Your answer:

FAQS.ORG reserves the right to edit your answer as to improve its clarity.  By submitting your answer you authorize FAQS.ORG to publish your answer on the WWW without any restrictions. You agree to hold harmless and indemnify FAQS.ORG against any claims, costs, or damages resulting from publishing your answer.

 

FAQS.ORG makes no guarantees as to the accuracy of the posts. Each post is the personal opinion of the poster. These posts are not intended to substitute for medical, tax, legal, investment, accounting, or other professional advice. FAQS.ORG does not endorse any opinion or any product or service mentioned mentioned in these posts.

 

<< Back to: FAQ: Lisp Frequently Asked Questions 1/7 [Monthly posting]


[ Home  |  FAQ-Related Q&As  |  General Q&As  |  Answered Questions ]

© 2008 FAQS.ORG. All rights reserved.