|
Prev: Lisp & physics
Next: trouble learning LISP
From: Dustin Withers on 6 Oct 2006 14:35 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 6 Oct 2006 14:40 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 6 Oct 2006 15:02 "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 6 Oct 2006 15:00 "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 6 Oct 2006 15:46
"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. |