I have a list of nils (NIL NIL NIL NIL) and i need to add two X in place of the two first NILs, so it becomes (X X NIL NIL).
I have the following code:
(cons x (cons x (cons (cdr '(NIL NIL NIL NIL))nil)))
But this way it returns
(X X (NIL NIL))
Those parenteses need to be removed, and i don't know how. Can someone help me? Thanks
If you pass a list to the first argument of cons
then you are making a nested list. First lets say we make your initial list and the symbol x
variables:
(defparameter *nils* '(nil nil nil nil))
*nils* ; ==> (nil nil nil nil)
(defparameter *x* 'x)
*x* ; ==> x
So how do we remove the two first. Well we can remove one with (cdr *nils*)
so that means we can do it twice:
(cdr (cdr *nils*))
; ==> (nil nil)
Actually more than one car
and cdr
accessor has a shorthand upto 5 combinations. The shorthand is just starting with c and do the a/d's and end with r like this:
(cddr *nils*)
; ==> (nil nil)
Goodie, how do we add *x*
in front of that? Well cons
is defines as making an element in front of the second argument, thus (cons *x* (cddr *nils*)) will make
(x nil nil). Again if you want to have another
x` in front of that you do the same with the firt result:
(cons *x* (cons *x* (cddr *nils*)))
; ==> (x x nil nil)
Using list*
is like nested cons with a tail in the end. Thus the above code can be replaced with:
(list* *x* *x* (cddr *nils*))
; ==> (x x nil nil)
Now replacing the variables the expression that was stored as their value (substitution method):
(list* 'x 'x (cddr '(nil nil nil nil)))
; ==> (x x nil nil)