This question already has an answer here:
Test if array is inside a list in lisp
(1 answer)
Closed 2 years ago.
(remove '(1 2) '((1 2) (1 3)))
doesn't remove '(1 2) from list in common lisp. (I think it uses eq and not equal).
Do we have any other alternative to delete element from list of lists in common lisp?
(remove '(1 2) '((1 2) (1 3)) :test #'equal)
Related
This question already has answers here:
How do I splice into a list outside of a macro in Common Lisp?
(2 answers)
Closed 7 years ago.
I have a function that returns something like this:
'(1 4 2 8)
and I want to apply the following type of functions to it:
(name &rest)
for example:
(max '(1 4 2 8))
produces an error, but:
(max 1 4 2 8)
does not.
so I have to "unlist" that list. How may I go about doing that?
The form apply is the traditional way:
(apply 'max '(1 2 3 4))
; => 4
I am experiencing a behavior of the push function that I don't get. Maybe someone could explain to me why Lisp behaves this way.
Supposed I define a list as a global variable, and then try to push a new value to it using the following code:
(defparameter *primes* '(3 5 7 11))
(push 2 *primes*)
Then *primes* is now (2 3 5 7 11). So far, so good.
Now I try to do the same thing, but without the *primes* variable, i.e.:
(push 2 '(3 5 7 11))
The result is an error message:
EVAL: 3 is not a function name; try using a symbol instead
Now I have two questions:
Why does this not work? I would expect that push returns the list (2 3 5 7 11), why does this not happen? Where am I wrong?
Apart from that, I don't get the error message. What is Lisp trying to tell me with 3 is not a function name? Of course, 3 is not a function name, but I don't try to call a function named 3 anywhere, do I?
Any help is appreciated :-)
If you read the CL Hyperspec for PUSH, you will read that push expects a place.
A place is something like a variable, a structure slot, a class slot, an array access, or similar. Since Lisp uses linked cons cells for lists, it does not make sense to push something in front of a cons cell, without a reference for that.
So above is simple: we can't push to a direct list.
Why this error message?
This gets a bit complicated...
(push 2 '(3 5 7 11))
Is actually:
(push 2 (quote (3 5 7 11))
A function can be a place, it then needs a corresponding setter function. Here the setter is thought to be (setf quote) - that's right, Common Lisp can sometimes have lists as function names, not only symbols.
If we look at the macroexpansion of above:
? (pprint (macroexpand '(push 2 (quote (3 5 7 11)))))
(LET* ((#:G328 2) (#:G327 (3 5 7 11)) (#:G326 (CONS #:G328 '#:G327)))
#:G327
#:G326
(FUNCALL #'(SETF QUOTE) #:G326 #:G327))
You can see that it tries to call the setter. But it also thinks that (3 5 7 11) is a Lisp form.
I give you an example, where it actually works, but we don't use quote, but a real accessor function:
CL-USER 40 > (let ((v (vector (list (list 'a 'b 'c) (list 'd 'e 'f))
(list (list 1 2 3) (list 4 5 6)))))
(print v)
(push 42 (first (aref v 1)))
(print v)
(values))
#(((A B C) (D E F)) ((1 2 3) (4 5 6)))
#(((A B C) (D E F)) ((42 1 2 3) (4 5 6)))
In above first is the getter and CL knows the corresponding setter. The form (aref v 1) is the call and returns the index 1 element of the vector. We are then pushing to the first list of the element.
Your call has a similar structure and (3 5 7 11) is at a similar position as (aref v 1). The Lisp system says that in (3 4 7 11) then number 3 is not a valid function. Which is correct. But the real error was about the push operation. Since the macro could not detect the error, the error gets later detected in the macro expanded code.
I have found only the emacs lisp manual push, but I guess it behaves similar for Common Lisp
— Macro: push element listname
This macro creates a new list whose car is element and whose cdr is the list specified by listname, and saves that list in listname.
So it seems push is modifying its argument listname, which isn't possible with a literal list. To do what you have in mind, one would use cons instead.
To the second part 3 is not a function name, I would say push, or some function inside it, tries to evaluate the literal list. Evaluating (3 5 7 11) means, call the function 3 with arguments 5 7 11. Hence the error message.
Again from emacs, Ctrl-h f push
push is a Lisp macro in `cl.el'.
(push X PLACE)
Insert X at the head of the list stored in PLACE.
Analogous to (setf PLACE (cons X PLACE)), though more careful about
evaluating each argument only once and in the right order. PLACE may
be a symbol, or any generalized variable allowed by `setf'.
setf in turn allows place to be a
symbolic references such as (car x) or (aref x i)
which explains, why push evaluates the second argument.
I think you need CONS in second case:
(cons 2 '(3 5 7 11)) => (2 3 5 7 11)
This question already has answers here:
Test if array is inside a list in lisp
(1 answer)
Remove duplicate strings from a list
(1 answer)
Closed 8 years ago.
How do i remove duplicated lists inside a list in common-lisp?
I tried this:
(remove-duplicates '( (1 2 3) (1 2 3)))
But it evaluates to ((1 2 3) (1 2 3)), not ((1 2 3)).
Thanks.
Use the keyword argument :test to specify the function that defines whether or not two items are duplicates of each other. Most lisp functions, including remove-duplicates, use eql to test for equality by default. eql is much stricter than equal, which is what you probably want to be using.
(remove-duplicates '((1 2 3) (1 2 3)) :test #'equal)
This evaluates to '((1 2 3)).
See this post for more detail about the difference between eql and equal.
Try:
(remove-duplicates '((1 2 3) (1 2 3)) :test #'equal)
I do not see why we need nil [1] when to cons a sequence (so-called proper list) of items. It seems to me we can achieve the same goal by using the so-called improper list (cons-ed pairs without an ending nil) alone. Since Lisps [2] have already provided a primitive procedure to distinguish between a pair? and an atom (some implementations even provide atom?), when defining a procedure on a list, e.g., length, I can do the same with just dotted-pairs, as shown below:
(define len
(lambda (l)
(cond ((pair? l) (+ 1 (len (cdr l))))
(else 1) ) ) )
It is obvious that we can apply this procedure to an improper list like '(1 . (2 . 3)) to get the expected answer 3, in contrast to the traditional (length '(1 2 3)).
I'd like to hear any opinions in defense of the necessity of nil. Thanks in advance.
[1] Let's ignore the debate among nil/NIL, '() and ().
[2] Here it means the Lisp family of languages.
Working with lists without nil (or '()) would be like doing arithmetic without zero. Using only pairs without nil, how would we represent an empty list, or a singleton list '(1)?
It gets worse: since lists don't have to be lists of atoms, but can contain other lists, how would we represent the nested list '(1 2 (3 4))? If we do the following conversions:
'(3 4) => '(3 . 4)
'(1 2 x) => '(1 . (2 . x)) == '(1 2 . x)
we get:
'(1 2 (3 4)) => '(1 . (2 . (3 . 4))) == '(1 2 3 . 4)
But also:
'(1 2 3 4) => '(1 . (2 . (3 . 4))) == '(1 2 3 . 4)
So constructing lists only using pairs and no nil prevents us from distinguishing between a nested list structure and a flat list, at least at the end of the list. You can still include nested lists as any element except the last, so now there's a strange and arbitrary limitation on what the elements of a list can be.
More theoretically, proper lists are an inductively defined data type: a list is either the empty list, or it has a first element, which can be anything, and a rest, which is always another list defined in the same way. Take away the empty list, and now you have a data type where the rest might be another list, or it might be the last element of the list. We can't tell except by passing it to pair?, which leads to the problem with nested listing above. Keeping nil around lets us have whatever we like as list elements, and allows us to distinguish between 1, '(1), '((1)) and so on.
You need it to represent "Nothing".
I'm learning Lisp. I'm implementing solution to some relatively simple problem. I'm thinking of list that represents initial state of problem like this
((0 1) (2 3) (5 4))
I want to create variable and assign that list to it. I've tried
(let ((initial-state ((0 1) (2 3) (5 4)))))
but this won't compile. After that I've tried
(let ((initial-state list (list 0 1) (list 2 3) (list 5 4))))
this works, but it's too long. Is there better way to do this?
(let ((initial-state '((0 1) (2 3) (4 5))))
...)
The ' expands to (quote ...) which basically means "don't evaluate this, just return it to me as a list". It's used to separate data from code (which in lisp are related concepts).
Do you mean this?
(let ((initial-state '((0 1) (2 3) (5 4)))) ...)
That single quote is a quote. :)
More about quoting here:
When to use 'quote in Lisp
Wikipedia article on Lisp