From: Dustin Withers on
Hello All,

My first attempt at this hasn't worked and I was hoping for some
insight. I'm trying to remove all string from a list and return them
as a list.

This is my first attempt:
(let ((elements ()))
(dolist item *LIST*
(if (stringp item)
(push (pop *LIST*) elements)
()))
elements)

What is wrong with this? It causes the error:

Execution of a form compiled with errors.
Form:
(DOLIST ITEM
*LIST*
(IF (STRINGP ITEM) (PUSH (POP *LIST*) ELEMENTS)))
Compile-time error:
(in macroexpansion of (DOLIST ITEM *LIST* ...))
(hint: For more precise location, try *BREAK-ON-SIGNALS*.)
error while parsing arguments to DEFMACRO DOLIST:
bogus sublist
ITEM
to satisfy lambda-list
(SB-DEBUG:VAR LIST &OPTIONAL (SB-IMPL::RESULT NIL))
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]

Thanks for any help,
-dustin

From: bradb on
Dustin Withers wrote:
> Hello All,
>
> My first attempt at this hasn't worked and I was hoping for some
> insight. I'm trying to remove all string from a list and return them
> as a list.
>
> This is my first attempt:
> (let ((elements ()))
> (dolist item *LIST*
DOLIST syntax is (dolist (x list) ...)
http://www.lisp.org/HyperSpec/Body/mac_dolist.html

Also, you can use REMOVE to do what you want.

Cheers
Brad

From: Zach Beane on
"Dustin Withers" <fadeddata(a)gmail.com> writes:

> I'm trying to remove all string from a list and return them as a
> list.
>
> This is my first attempt:
> (let ((elements ()))
> (dolist item *LIST*
> (if (stringp item)
> (push (pop *LIST*) elements)
> ()))
> elements)
>
> What is wrong with this?


"bradb" <brad.beveridge(a)gmail.com> writes:

> DOLIST syntax is (dolist (x list) ...)
> http://www.lisp.org/HyperSpec/Body/mac_dolist.html

Actually, DOLIST syntax is:

(dolist (var list-form [result-form]) ...)

I use RESULT-FORM a lot. I wouldn't solve the original problem with
dolist, but if I did, it might look something like this:

(let ((elements '()))
(dolist (item *list* elements)
(when (stringp item)
(push item elements))))

Zach
From: Rahul Jain on
"Dustin Withers" <fadeddata(a)gmail.com> writes:

> Hello All,
>
> My first attempt at this hasn't worked and I was hoping for some
> insight. I'm trying to remove all string from a list and return them
> as a list.

Looks like you're trying to use the PARTITION function that some of us
have contributed to.

Um... but it seems to be superseded by SPLIT-SEQUENCE... didn't
PARTITION do something different? Separate the seq into multiple seqs
based on some criterion?

--
Rahul Jain
rjain(a)nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Pascal Bourguignon on
"Dustin Withers" <fadeddata(a)gmail.com> writes:
> My first attempt at this hasn't worked and I was hoping for some
> insight. I'm trying to remove all string from a list and return them
> as a list.

This is problematic.

There is not list data type in lisp.

We build lists as a pun on cons cells or nil.

(deftype proper-list () (or null (cons t list)))
(deftype list () (or null cons))

The consequence, is that when a variable refers the first cons of a
list, and given that parameter passing is always done by value, not by
reference, we cannot meaningfully remove the first cons of the list
from this list.

Another way to see it is that these chaining of cons cells allow for
sharing of the tail of the lists, and the whole lists can be seen as
their own tail:

(let ((a (list 1 2 3)))
(let ((b a))
;; here, we cannot remove 1 from the list a and have it removed
;; too from the list b!
))


The second case where problems would occur is with empty lists, since
they are all NIL, and you cannot modify NIL. Well for your problem
this wouldn't matter since you can't remove anything from NIL, but
with this conception you couldn't add elements to your list.



So if you really persist in wanting to do what you say you are wanting
to do, then you should create a list data type.

(defstruct mylist elements)

Then you can write:

(defun delete-strings-from-mylist-and-return-them (mylist)
(loop
:for item :in (mylist-elements mylist)
:if (stringp item) :collect item :into strings
:else :collect item :into others
:finally (setf (mylist-elements mylist) others)
(return strings)))



[53]> (defparameter *ml* (make-mylist :elements (list 1 2 "one" "two" 'one 'two)))
*ML*
[54]> (delete-strings-from-mylist-and-return-them *ml*)
("one" "two")
[55]> *ml*
#S(MYLIST :ELEMENTS (1 2 ONE TWO))
[56]>

Note that my implementation doesn't modify the list inside the mylist,
it creates a two lists. This to avoid suprizing results, and to allow
to put a literal list inside a mylist:


[56]> (defparameter *ml* (make-mylist :elements '(1 2 "one" "two" 'one 'two)))
*ML*
[57]> (delete-strings-from-mylist-and-return-them *ml*)
("one" "two")
[58]> *ml*
#S(MYLIST :ELEMENTS (1 2 'ONE 'TWO))
[59]> (defparameter *l* (list 1 2 "one" "two" 'one 'two))
*L*
[60]> (defparameter *ml* (make-mylist :elements *l*))
*ML*
[61]> (delete-strings-from-mylist-and-return-them *ml*)
("one" "two")
[62]> *ml*
#S(MYLIST :ELEMENTS (1 2 ONE TWO))
[63]> *l*
(1 2 "one" "two" ONE TWO)
[64]>

If you use destructive functions (such as POP, DELETE or DELETE-IF)
on the elements of the mylist, then you have to be very careful never
pass literal list (or tails), and to make sure that any other
structure sharing is not done unconciously.

--
__Pascal Bourguignon__ http://www.informatimago.com/
Kitty like plastic.
Confuses for litter box.
Don't leave tarp around.
 |  Next  |  Last
Pages: 1 2 3
Prev: Lisp & physics
Next: trouble learning LISP