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

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -