append - LISP List Not Appending And Printing Twice -
i'm quite new lisp , trying work on cond statement class. currently, attempting check if value passed list , if so, append letter d onto list.
here code:
(defun test(l) (listp l) (cond ((listp l) (append l (list 'd))) ) (write l) ) (test (list 'a 'b 'c))
the output is:
(a b c) (a b c)
if change test to: (test (car(list 'a 'b 'c)))
the new output is:
a
two things wondering is
1.) why isn't d appended onto list if first test passes list?
2.) why being printed twice? i'm using lisp works figure it's how outputs final value or something.
1.) same reason str + "d"
doesn't mutate str
in java or python. creates new list not use!
>>> str + "d" 'abcd' >>> str 'abc'
crazy similar isn't it?
2.) in cl return
last evaluated expression. repl prints every top level expression result terminal. python too:
>>> def test(): ... x = 2 + 3 ... print x ... return x ... >>> test() 5 5
update
how mutate argument list. simple answer need mutate last pair of argument instead:
(defun test (l) (assert (consp 1) (l) "l needs non nil list. got: ~a" l) (nconc l (list 'd) (write l))) (defparameter *test1* (list 1 2 3)) (defparameter *test1-copy* *test1*) (test *test1*) ; ==> (1 2 3 d) (and prints (1 2 3 d)) *test1* ; ==> (1 2 3 d) *test1-copy* ; ==> (1 2 3 d) (eq *test1* *test1-copy*) ; ==> t (test '()) ** error l needs non nil list. got: nil
(nconc l x)
(setf (cdr (last l)) x)
if need alter binding, need make macro:
(defmacro testm (var) (assert (symbolp var) (var) "list needs variable binding. got: ~a" var) `(progn (when (listp ,var) (setf ,var (append ,var (list 'd))) (write ,var)))) (macroexpand '(testm *test2*)) ; ==> (progn ; (when (consp *test2*) ; (setf *test2* (append *test2* (list 'd)))) ; (write *test2*)) (defparameter *test2* (list 1 2 3)) (defparameter *test2-copy* *test2*) (testm *test2*) ; ==> (1 2 3 d) (and prints (1 2 3 d)) *test2* ; ==> (1 2 3 d) *test2-copy* ; ==> (1 2 3) (eq *test2* *test2-copy*) ; ==> nil (defparameter *x* nil) (testm *x*) ; ==> (d) (and prints (d)) *x* ; ==> (d) (testm '(1)) ** error list needs variable binding. got: '(1)
idiomatic way it
(defun test (list) (if (consp list) (append list '(d)) list)) (write (test '(1 2 3))) ; ==> (1 2 3 d) (and prints (1 2 3 d)) (defparameter *test3* '(1 2 3)) (setf *test3* (test *test3*)) *test3* ; ==> (1 2 3 d)
Comments
Post a Comment