1

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

2
  • This works for me: (setf (first *NILS*) :hello) => (:HELLO NIL NIL NIL) . Commented Nov 30, 2017 at 10:19
  • 1
    Lisp objects don't have parentheses; cons-cell-based objects just print that way. Commented Nov 30, 2017 at 15:45

2 Answers 2

3

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 anotherx` 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)
Sign up to request clarification or add additional context in comments.

Comments

3
(list* X X (nthcdr 2 your-list))

The function NTHCDR returns the list with two first elements dropped & the function LIST* returns a new list appending specified items at the front. Observe that thus you obtain a new list rather then modify the original one. If you really want to modify the original list (this may very well be a bad idea, proceed with caution), you can just make the assignment:

(setf (first your-list) 'X)
(setf (second your-list) 'X)

Modifying a list like this may result in modifications of seemingly unrelated data. It is not compatible with the quoted literal list, anyway.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.