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 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)
(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.
Related
Hello I am looking forward to convert my existing function:
(defun checkMember (L A)
(cond
((NULL L) nil)
( (and (atom (car L)) (equal (car L) A)) T )
(T (checkMember (cdr L) A))))
To use map functions, but i honestly cant understand exactly how map functions work, could you maybe advice me how this func's work?
this is my atempt:
(defun checkMem (L A)
(cond
((NULL L) nil)
( (and (atom (car L)) (equal (car L) (car A))) T )
(T (mapcar #'checkMem (cdr L) A))))
A mapping function is not appropriate here because the task involves searching the list to determine whether it contains a matching item. This is not mapping.
Mapping means passing each element through some function (and usually collecting the return values in some way). Sure, we can abuse mapping into solving the problem somehow.
But may I instead suggest that this is a reduce problem rather than a mapping problem? Reducing means processing all the elements of a list in order to produce a single value which summarizes that list.
Warm up: use reduce to add elements together:
(reduce #'+ '(1 2 3)) -> 6
In our case, we want to reduce the list differently: to a single value which is T or NIL based on whether the list contains some item.
Solution:
(defun is-member (list item)
(reduce (lambda (found next-one) (or found (eql next-one item)))
list :initial-value nil))
;; tests:
(is-member nil nil) -> NIL
(is-member nil 42) -> NIL
(is-member '(1) 1) -> T
(is-member '(1) 2) -> NIL
(is-member '(t t) 1) -> NIL ;; check for accumulator/item mixup
(is-member '(1 2) 2) -> T
(is-member '(1 2) 3) -> NIL
...
A common pattern in using a (left-associative) reduce function is to treat the left argument in each reduction as an accumulated value that is being "threaded" through the reduce. When we do a simple reduce with + to add numbers, we don't think about this, but the left argument of the function used for the reduction is always the partial sum. The partial sum is initialized to zero because reduce first calls the + function with no arguments, which is possible: (+) is zero in Lisp.
Concretely, what happens in (reduce #'+ '(1 2 3)) is this:
first, reduce calls (+) which returns 0.
then, reduce calls (+ 0 1), which produces the partial sum 1.
next, reduce calls (+ 1 2), using the previous partial sum as the left argument, and the next element as the right argument. This returns 3, of course.
finally, reduce calls (+ 3 3), resulting in 6.
In our case, the accumulated value we are "threading" through the reduction is not a partial sum, but a boolean value. This boolean becomes the left argument which is called found inside the reducing function. We explicitly specify the initial value using :initial-value nil, because our lambda function does not support being called with no arguments. On each call to our lambda, we short-circuit: if found is true, it means that a previous reduction has already decided that the list contains the item, and we just return true. Otherwise, we check the right argument: the next item from the list. If it is equal to item, then we return T, otherwise NIL. And this T or NIL then becomes the found value in the next call. Once we return T, this value will "domino" through the rest of the reduction, resulting in a T return out of reduce.
If you insist on using mapping, you can do something like: map each element to a list which is empty if the element doesn't match the item, otherwise nonempty. Do the mapping in such a way that the lists are catenated together. If the resulting list is nonempty, then the original list must have contained one or more matches for the item:
(defun is-member (list item)
(if (mapcan (lambda (elem)
(if (eq elem item) (list elem))) list)
t))
This approach performs lots of wasteful allocations if the list contains many occurrences of the item.
(The reduce approach is also wasteful because it keeps processing the list after it is obvious that the return value will be T.)
What about this:
(defun checkMember (L a)
(car (mapcan #'(lambda (e)
(and (equal a e) (list T)))
L)))
Note: it does not recurse into list elements, but the original function did not either.
(defun memb (item list)
(map nil
(lambda (element)
(when (eql item element)
(return-from memb t)))
list))
Try this,
Recursive version:
(defun checkmember (l a)
(let ((temp nil))
(cond ((null l) nil) ((find a l) (setf temp (or temp t)))
(t
(mapcar #'(lambda (x) (cond ((listp x)(setf temp (or temp (checkmember x a))))))
l)))
temp))
Usage: (checkmember '(1 (2 5) 3) 20) => NIL
(checkmember '(1 (2 5) 3) 2) => T
(checkmember '(1 2 3) 2) => T
(checkmember '((((((((1)))))))) 1) = T
In LISP, I have a function that is passed a list. I would like to change an element of this list without changing the original list. Normally, I would use copy-list to create the local copy of the list which I will change, but this doesn't seem to be working:
CL-USER> (defun test (item)
(let ((copy (copy-list item)))
(setf (nth 0 (nth 0 (nth 0 copy))) t)
(print item)
(print copy)))
CL-USER> (defparameter item `(((NIL NIL) (NIL NIL) (NIL NIL))
((NIL NIL NIL) (NIL NIL NIL))
((3 3) (NIL NIL))))
CL-USER> (test item)
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
CL-USER> item
(((T NIL) (NIL NIL) (NIL NIL)) ((NIL NIL NIL) (NIL NIL NIL)) ((3 3) (NIL NIL)))
As you can see, the value of item was changed by test even though I copied the list into a local variable and changed the local copy. This seems to be a symptom of using nth. If I use a single call of car rather than the repeated call to nth, the function works as expected and the item is unchanged after the call.
Why does nth behave like this and how can I continue to use nth without altering the value passed to test?
I am using Common Lisp.
Short answer: use cl:copy-tree
You probably want to copy the whole tree with copy-tree. The copy made by copy-list only generates new "backbone"; you get a new list, but with the same elements. Copy-tree will copy all the cons-tree structure that makes up the tree.
Long answer: list structure vs. tree structure
The background here is referenced in the documentation. From the HyperSpec:
Function COPY-LIST
Only the list structure of list is copied; the elements of the
resulting list are the same as the corresponding elements of the given
list.
That glossary entry for list structure is important:
list structure n. (of a list) the set of conses that make up the list.
Note that while the car component of each such cons is part of the
list structure, the objects that are elements of the list (i.e., the
objects that are the cars of each cons in the list) are not
themselves part of its list structure, even if they are conses, except
in the (circular) case where the list actually contains one of its
tails as an element. (The list structure of a list is sometimes
redundantly referred to as its "top-level list structure" in order
to emphasize that any conses that are elements of the list are not
involved.)
As a very simple example, we can exploit the fact that *print-circle* will show us common substructure:
CL-USER> (setf *print-circle* t)
T
CL-USER> (let ((l '((a b c) (d e f))))
(list l (copy-list l)))
;=> ((#1=(A B C) #2=(D E F)) (#1# #2#))
CL-USER> (let ((l '((a b c) (d e f))))
(list l (copy-tree l)))
;=> (((A B C) (D E F)) ((A B C) (D E F)))
The HyperSpec entry on copy-tree doesn't link to tree structure, but there is a glossary entry:
tree structure n. (of a tree) the set of conses that make up the
tree. Note that while the car component of each such cons is part
of the tree structure, the objects that are the cars of each cons
in the tree are not themselves part of its tree structure unless they
are also conses.
That second sentence is a bit strange, but it's probably just in there as a minimally adjusted copy and paste of the list structure entry. See my answer to Definition of tree structure in Lisp for a bit more about that.
I am new to lisp and I'm trying to a simple check to see if a list is empty. For test purposes i created this test function:
(defun test (list)
(if (null (caddr list))
(make-node 1)
(caddr list)))
if uses the make-node function defined as:
(defun make-node (atm)
(cons atm `(`() `())))
when running (make-node 6) I get:
(6 (QUOTE NIL) (QUOTE NIL))
which is what I want.
i then call (test (make-node 6)) which i then get:
(QUOTE NIL)
which is the (caddr list) from test. if you run (null (QUOTE NIL)) you get T which is what i want to get but when i run it from the given test function i receive NIL.
So my question is why when i check if this is null why do i get NIL instead of T?
When you evaluate (null (quote nil)), (quote nil) is evaluated, resulting in nil being used as the argument for the function null.
However when you evaluate something like (null (function-returning-quote-nil)), function-returning-quote-nil is evaluated, resulting in the list (quote nil) which is then used as the argument for the function null without further evaluation.
Compare to the difference between
(null (quote nil)) ; => t
and
(null '(quote nil)) ; => nil
(CADDR '(6 (QUOTE NIL) (QUOTE NIL))) ; ==> (QUOTE NIL) or just 'NIL
The list with the two symbols QUOTE and NIL are not equal to NIL. Only NIL is equal to NIL. eg.
(DEFPARAMETER TEST 'NIL)
TEST ; ==> NIL
(NULL TEST) ; ==> T
This works since 'NIL gets evaluated to NIL and assigned to TEST. TEST gets evaluated to NIL and it's CLs NULL value. However:
(DEFPARAMETER TEST2 ''NIL)
TEST2 ; ==> 'NIL or (QUOTE NIL)
(NULL TEST2) ; ==> NIL
A list with two elements QUOTE and NIL, famously displayed as 'NIL, is NOT NIL. Only NIL is NIL.
EDIT
After looking at your comments about unquoting I'm pretty sure you want this as make-node:
(defun make-node (atm)
(cons atm '(() ())))
(test (make-node 6)) ; ==> (1 NIL NIL)
There is no such thing as unquoting in a data structure and unless you actually want the symbol quote in your data there is no sense in having quotes inside something quoted. (Half truth since there is, but it involves macros)
This is the Common Lisp code:
(defun take (L)
(if (null L) nil
(cons (car L) (skip (cdr L)))))
(defun skip (L)
(if (null L) nil
(cons (car L) (take (cdr L)))))
The idea here is that, "take" will give all the odd sequence elements in the input list and "skip" will give all the even sequence elements in the input list. However, in both cases the entire list is returned.
What is the error in this code? Is this something to do with how CL handles lists, because the similar code in SML gives the desired output.
fun take(lst) =
if lst = nil then nil
else hd(lst)::skip(tl(lst))
and
skip(lst) =
if lst = nil then nil
else hd(lst)::take(tl(lst));
To expound on what Sylwester has said, your skip is wrong in both Lisp and SML. It should be
(defun take (L) ; even-indexed elements of a list L
(if (not (null L))
(cons (car L) (skip (cdr L)))))
(defun skip (L) ; odd-indexed elements of a list L
(if (not (null L))
(take (cdr L))))
and
fun take(lst) =
if lst = nil then nil
else hd(lst)::skip(tl(lst))
and
skip(lst) =
if lst = nil then nil
else take(tl(lst));
The take and skip are identical so that is no mystery. skip should just tail call instead of cons-ing. It's the consing that makes the return here.
It's worth pointing out that indexing in Common Lisp (like many other programming languages) starts with 0, so the even-indexed elements of a list are the first, the third, the fifth, and so on, since those have indices 0, 2, 4, etc. It's also worth noting that in Common Lisp, you can take the rest of the empty list and get back the empty list. (You can't do this in every Lisp, though. E.g., in Scheme it's an error to call cdr on something that's not a pair.) This means that you can implement even-elements and odd-elements rather easily. even-elementsjust returns a list of the first element, and the odd elements of the rest of the list. odd-elements returns the even-elements of the rest of the list:
(defun even-elements (list)
(if (endp list) list
(list* (first list) (odd-elements (rest list)))))
(defun odd-elements (list)
(even-elements (rest list)))
These behave in the expected fashion:
CL-USER> (even-elements '(0 1 2 3 4 5))
(0 2 4)
CL-USER> (odd-elements '(0 1 2 3 4 5))
(1 3 5)
Of course, if you note that the call to (odd-elements x) is just a call to (even-elements (rest x)), we could have implemented even-elements as follows, and had the same result:
(defun even-elements (list)
(if (endp list) list
(list* (first list) (even-elements (rest (rest list))))))
I'm a beginner in lisp and I need somebody to explain to me how the prog form works, step by step. What is the initial value of l1 ? Nil ?
The problem outputs T if the list has an even number of elements on the first level, nil if not.
(defun nr_par (l)
(prog ((l1 l))
ciclu
(cond
((null l1) (return T))
((null (cdr l1)) (return NIL))
((null (cddr l1)) (return T))
(T (setf l1 (cddr l1))
(go ciclu)))))
On console:
(nr_par '(1 2 3 4 5 6 7 8))
T
The program is straightforward, but not very idiomatic lisp (it is rather imperative instead of functional). Step by step goes as follows.
prog uses a series of variable bindings, in this case, l1 is assigned the value of l initially. Then, a series of statements in which a loop starts (again, not very lisp idiomatic).
This type of loops use a tag (ciclu) and a goto instruction (go), again, not recommended, but it is there. After that, the cond checks a series of cases. When the list is empty (null), you return true, in other cases, you check if the length is even or odd, and return the value in consequence.
In the case that the list is longer than one or two elements (neither of the cases is null), the l1 list is adjusted to point to the next of the next element of itself (the cddr function).
Finally, the go function turns the program back to the ciclu tag.
The program will finish when any of the cond clauses is met, returning either T or NIL.
See PROG in CLHS: L1 is var, L is init-form, so the initial value of L1 is the value of L.
As the CLHS page for prog says, it does three things: lets you have local vars and initialize them; lets you have tags as in tagbody and use go; and lets you use return as inside a block named NIL:
(defun nr_par (l)
(prog ((l1 l)) ; local binding(s)
ciclu
(if (null l1) (return T)) ; return
(if (null (cdr l1)) (return NIL))
(setf l1 (cddr l1))
(go ciclu))) ; go
(defun nr_par1 (l) ; directly equivalent
(labels ((ciclu (l1)
(if (null l1) (return-from ciclu T))
(if (null (cdr l1)) (return-from ciclu NIL))
(ciclu (cddr l1))))
(ciclu l)))
(defun nr_par2 (l) ; also equivalent
(do ((l1 l (cddr l1)))
(NIL) ; while T ...
(cond
((null l1) (return T))
((null (cdr l1)) (return NIL)))))
Function call is a glorified goto after all, isn't it?
See also Longest decreasing sequence in Lisp for an example representing several mutually-recursive functions hand-compiled into a prog with a bunch of GO statements.