emacs - Why does an elisp local variable keep its value in this case? -


could explain me what's going on in simple code snippet?

(defun test-a ()   (let ((x '(nil)))     (setcar x (cons 1 (car x)))     x)) 

upon calling (test-a) first time, expected result: ((1)). surprise, calling once more, ((1 1)), ((1 1 1)) , on. why happening? wrong expect (test-a) return ((1))? note after re-evaluating definition of test-a, return result resets.

also consider function works expect:

(defun test-b ()   (let ((x '(nil)))     (setq x (cons (cons 1 (car x))                    (cdr x))))) 

(test-b) returns ((1)). why aren't test-a , test-b equivalent?

the bad

test-a self-modifying code. extremely dangerous. while variable x disappears @ end of let form, initial value persists in function object, , value modifying. remember in lisp a function first class object, can passed around (just number or list), and, sometimes, modified. doing here: initial value x part of function object , modifying it.

let see happening:

(symbol-function 'test-a) => (lambda nil (let ((x (quote (nil)))) (setcar x (cons 1 (car x))) x)) (test-a) => ((1)) (symbol-function 'test-a) => (lambda nil (let ((x (quote ((1))))) (setcar x (cons 1 (car x))) x)) (test-a) => ((1 1)) (symbol-function 'test-a) => (lambda nil (let ((x (quote ((1 1))))) (setcar x (cons 1 (car x))) x)) (test-a) => ((1 1 1)) (symbol-function 'test-a) => (lambda nil (let ((x (quote ((1 1 1))))) (setcar x (cons 1 (car x))) x)) 

the good

test-b returns fresh cons cell , safe. initial value of x never modified. difference between (setcar x ...) , (setq x ...) former modifies object stored in variable x while latter stores new object in x. difference similar x.setfield(42) vs. x = new myobject(42) in c++.

the bottom line

in general, best treat quoted data '(1) constants - not modify them:

quote returns argument, without evaluating it. (quote x) yields x. warning: quote not construct return value, returns value pre-constructed lisp reader (see info node printed representation). means (a . b) not identical (cons 'a 'b): former not cons. quoting should reserved constants never modified side-effects, unless self-modifying code. see common pitfall in info node rearrangement example of unexpected results when quoted object modified.

if need modify list, create list or cons or copy-list instead of quote.

see more examples.

ps. has been duplicated on emacs.

pps. see why function return different value every time? identical common lisp issue.


Comments

Popular posts from this blog

blackberry 10 - how to add multiple markers on the google map just by url? -

php - guestbook returning database data to flash -

delphi - Dynamic file type icon -