From: Tzury Bar Yochay
Subject: newbie question
Date: 
Message-ID: <19e88ccd-97f7-468c-b2dc-7366c6c01cd4@i12g2000prf.googlegroups.com>
I am starting now learning common lisp.
here is a function which meant to return all elements found in list1
which dose not exists on list 2.

The first version which aims to return a value returns nil while using
the same approach but printing it dose shows the new values.


>>(defun not-members (lst1 lst2)
    (let ((newlist nil))
        (dolist (elm lst1)
            (if (null (member elm lst2))
                (append newlist elm)))
        newlist))

NOT-MEMBERS
>>(not-members '(d f g r t) '(a b c d e f g h i))

NIL
>>(defun print-not-members (lst1 lst2)
    (let ((newlist nil))
        (dolist (elm lst1)
            (if (null (member elm lst2))
                (format t "~A" elm)))
        newlist))

PRINT-NOT-MEMBERS
>>(print-not-members '(d f g r t) '(a b c d e f g h i))
RT
NIL

From: Slobodan Blazeski
Subject: Re: newbie question
Date: 
Message-ID: <708c98ea-1707-42da-9a2c-33383393c20d@p68g2000hsd.googlegroups.com>
On Jan 3, 5:51 pm, Tzury Bar Yochay <············@gmail.com> wrote:
> I am starting now learning common lisp.
> here is a function which meant to return all elements found in list1
> which dose not exists on list 2.
Try loop :
(defun not-present (x1 x2)
   (loop for e in x1
      when  (not (member e x2)) collect e))

(not-present '(1 2 3 4 7 8 ) '( 3 4 5))
(1 2 7 8)
>
> The first version which aims to return a value returns nil while using
> the same approach but printing it dose shows the new values.
>
> >>(defun not-members (lst1 lst2)
>
>     (let ((newlist nil))
>         (dolist (elm lst1)
>             (if (null (member elm lst2))
>                 (append newlist elm)))
>         newlist))
>
> NOT-MEMBERS
>
> >>(not-members '(d f g r t) '(a b c d e f g h i))
>
> NIL>>(defun print-not-members (lst1 lst2)
>
>     (let ((newlist nil))
>         (dolist (elm lst1)
>             (if (null (member elm lst2))
>                 (format t "~A" elm)))
>         newlist))
>
> PRINT-NOT-MEMBERS>>(print-not-members '(d f g r t) '(a b c d e f g h i))
>
> RT
> NIL
From: Pillsy
Subject: Re: newbie question
Date: 
Message-ID: <dc0d1ccd-59d2-4b4c-a26e-9f1b371737bd@i12g2000prf.googlegroups.com>
On Jan 3, 11:51 am, Tzury Bar Yochay <············@gmail.com> wrote:

> The first version which aims to return a value returns nil while using
> the same approach but printing it dose shows the new values.

> >>(defun not-members (lst1 lst2)

>     (let ((newlist nil))
>         (dolist (elm lst1)
>             (if (null (member elm lst2))
>                 (append newlist elm)))
>         newlist))

There's a potential efficiency issue here, in that MEMBER may traverse
the entirety of LST2 looking for ELM, and will do that for each
element of LST1.  If LST1 and LST2 are long, this could take a while.
There are a few ways around this; the one that looks best suited to
your needs, especially since you make no provision for using anything
but MEMBER's default test of EQL, is to use a hash table to keep track
of all the elements in one list and check the other list against it.
This is a common strategy for doing "settish" things, but in portable
Common Lisp it's only really easy if you want to use one of the four
basic hash table equality tests (EQ, EQL, EQUAL and EQUALP).

(defun not-members/ht (list1 list2)
  "Returns a list of all elements of LIST1 which are not present in
LIST2."
  (let ((set2 (make-hash-table)))
    (loop
       :for elt :in list2
       :do (setf (gethash elt set2) t))
    (loop
       :for elt :in list1
       :unless (gethash elt set2)
         :collect elt)))

Also, you said elsewhere in the thread you were ultimately interested
in doing a version of UNION that will preserve the order of elements.
Also, LOOP with the COLLECT clause is very useful for this sort of
thing.

Cheers,
Pillsy
From: Ken Tilton
Subject: Re: newbie question
Date: 
Message-ID: <477d1592$0$13810$607ed4bc@cv.net>
Tzury Bar Yochay wrote:
> I am starting now learning common lisp.
> here is a function which meant to return all elements found in list1
> which dose not exists on list 2.

You mean set-difference?

> 
> The first version which aims to return a value returns nil while using
> the same approach but printing it dose shows the new values.
> 
> 
> 
>>>(defun not-members (lst1 lst2)
> 
>     (let ((newlist nil))
>         (dolist (elm lst1)
>             (if (null (member elm lst2))
>                 (append newlist elm)))
>         newlist))

Aside: append wants lists. Is elm always a list? (Meaning lst1 is always 
a list of lists.) Anyway...

You have to (setf newlist (append newlist elm)), append is not 
destructive, it copies all but the last list so the result is fresh up 
front.

nconc would be destructive, but you are starting with a nil value for 
newlist so you would still have to capture the first nconc.

kt


> 
> NOT-MEMBERS
> 
>>>(not-members '(d f g r t) '(a b c d e f g h i))
> 
> 
> NIL
> 
>>>(defun print-not-members (lst1 lst2)
> 
>     (let ((newlist nil))
>         (dolist (elm lst1)
>             (if (null (member elm lst2))
>                 (format t "~A" elm)))
>         newlist))
> 
> PRINT-NOT-MEMBERS
> 
>>>(print-not-members '(d f g r t) '(a b c d e f g h i))
> 
> RT
> NIL

-- 
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Tzury Bar Yochay
Subject: Re: newbie question
Date: 
Message-ID: <bb3dd423-438c-4c6c-bbde-23ec3235792a@e23g2000prf.googlegroups.com>
Thanks for quick response.

> You mean set-difference?
The idea is to write my own version of union which preserves the order
of the elements in the original lists. e.g:

> (new-union '(a b c) '(b a d))
(A B C D)

> You have to (setf newlist (append newlist elm)), append is not
> destructive, it copies all but the last list so the result is fresh up
> front.

;; Got the point here is my working version ;-)

(defun not-members (lst1 lst2)
    (let ((newlist ()))
        (dolist (elm lst1)
            (if (null (member elm lst2))
                (setf newlist (append newlist (list elm)))))
        newlist))
From: Slobodan Blazeski
Subject: Re: newbie question
Date: 
Message-ID: <0244ad41-cf16-41ae-9d2c-96de6bb97161@e6g2000prf.googlegroups.com>
On Jan 3, 6:15 pm, Tzury Bar Yochay <············@gmail.com> wrote:
> Thanks for quick response.
>
> > You mean set-difference?
>
> The idea is to write my own version of union which preserves the order
> of the elements in the original lists. e.g:
>
> > (new-union '(a b c) '(b a d))
>
> (A B C D)
Something like this?
;; Unoptimized code fallowing
(defun new-union (&rest args)
   (remove-duplicates (reduce #'append args)
        :from-end t))

(new-union '(a b c) '(b a d))
>(A B C D)

(new-union '(a b c) '(b a d) '(d a))
>(A B C D)

>
> > You have to (setf newlist (append newlist elm)), append is not
> > destructive, it copies all but the last list so the result is fresh up
> > front.
>
> ;; Got the point here is my working version ;-)
>
> (defun not-members (lst1 lst2)
>     (let ((newlist ()))
>         (dolist (elm lst1)
>             (if (null (member elm lst2))
>                 (setf newlist (append newlist (list elm)))))
>         newlist))
From: danb
Subject: Re: newbie question
Date: 
Message-ID: <13340d5a-9562-49b7-a303-6cd4492986dd@s8g2000prg.googlegroups.com>
On Jan 3, 11:15 am, Tzury Bar Yochay wrote:
> The idea is to write my own version of union which preserves
> the order of the elements in the original lists.

>       (setf newlist (append newlist (list elm)))))

TBY, APPEND is very slow.  To return the elements in order,
all you have to do is (push elm newlist) and then when your
function is finished adding elements to newlist, newlist will
be exactly backwards, so you can just return (nreverse newlist).

--Dan
www.prairienet.org/~dsb/
From: viper-2
Subject: Re: newbie question
Date: 
Message-ID: <39348faa-f479-4fa9-984b-4e40a530dd59@s8g2000prg.googlegroups.com>
On Jan 3, 11:51 am, Tzury Bar Yochay <············@gmail.com> wrote:
> I am starting now learning common lisp.
> here is a function which meant to return all elements found in list1
> which dose not exists on list 2.


If you're really just beginning Lisp I believe you should be working
on becoming comfortable with recursion, before considering iteration.
IMO, LOOP is really for black belts who have already mastered the art
of recursion. Here is some advice from Mark Tarver, author of Qi:

http://groups.google.com/group/comp.lang.lisp/msg/5d01f946fdc2ecfe

This is a recursive solution for NOT-MEMBER.

>
(defun not-member (l1 l2)
  (cond ((endp l1) nil)
	((member (first l1) l2) (not-member (rest l1) l2))
	(t (cons (first l1) (not-member (rest l1) l2)))))
NOT-MEMBER

>
(setf lst1 '(1 2 3 4 5 6 7 8) lst2 '(2 4 6 8))
(2 4 6 8)

>
(not-member lst1 lst2)
(1 3 5 7)

agt
From: Ken Tilton
Subject: Re: newbie question
Date: 
Message-ID: <477d9bbd$0$13883$607ed4bc@cv.net>
viper-2 wrote:
> On Jan 3, 11:51 am, Tzury Bar Yochay <············@gmail.com> wrote:
> 
>>I am starting now learning common lisp.
>>here is a function which meant to return all elements found in list1
>>which dose not exists on list 2.
> 
> 
> 
> If you're really just beginning Lisp I believe you should be working
> on becoming comfortable with recursion, before considering iteration.

Scheme is the dreamy idealistic language for crap like that, CL is for 
practical people trying to get work done and the first thing a Lisper 
needs to learn after how conses work is to use the right tool for the 
job and loop is the right tool for iteration which this example requires.

Recursion is great fun and should be used only when a task cannot be 
completed on one element without the result of that task performed on 
subsequent elements.

kt


-- 
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
  in the evening, die content!"
                     -- Confucius
From: Tzury Bar Yochay
Subject: Re: newbie question
Date: 
Message-ID: <892d40ed-c2de-4a76-a591-63aa811ee883@f3g2000hsg.googlegroups.com>
Thank you all. Lisp Rocks!
From: viper-2
Subject: Re: newbie question
Date: 
Message-ID: <30aa7ed5-5dc1-4793-994a-9cf2f5169734@e23g2000prf.googlegroups.com>
On Jan 3, 9:37 pm, Ken Tilton <···········@optonline.net> wrote:
> viper-2 wrote:
> > On Jan 3, 11:51 am, Tzury Bar Yochay <············@gmail.com> wrote:
>
> >>I am starting now learning common lisp.
> >>here is a function which meant to return all elements found in list1
> >>which dose not exists on list 2.
>
> > If you're really just beginning Lisp I believe you should be working
> > on becoming comfortable with recursion, before considering iteration.
>
> Scheme is the dreamy idealistic language for crap like that, CL is for
> practical people trying to get work done and the first thing a Lisper
> needs to learn after how conses work is to use the right tool for the
> job and loop is the right tool for iteration which this example requires.
>
> Recursion is great fun and should be used only when a task cannot be
> completed on one element without the result of that task performed on
> subsequent elements.


Now, that definitely sounds loopy ;-)

agt
From: viper-2
Subject: Re: newbie question
Date: 
Message-ID: <6f8d5bd4-d4ba-4768-ab50-fac02df79e4e@h11g2000prf.googlegroups.com>
On Jan 4, 8:50 am, viper-2 <········@mail.infochan.com> wrote:
> On Jan 3, 9:37 pm, Ken Tilton <···········@optonline.net> wrote:
>
>
>
> > viper-2 wrote:
> > > On Jan 3, 11:51 am, Tzury Bar Yochay <············@gmail.com> wrote:
>
> > >>I am starting now learning common lisp.
> > >>here is a function which meant to return all elements found in list1
> > >>which dose not exists on list 2.
>
> > > If you're really just beginning Lisp I believe you should be working
> > > on becoming comfortable with recursion, before considering iteration.
>
> > Scheme is the dreamy idealistic language for crap like that, CL is for
> > practical people trying to get work done and the first thing a Lisper
> > needs to learn after how conses work is to use the right tool for the
> > job and loop is the right tool for iteration which this example requires.
>
> > Recursion is great fun and should be used only when a task cannot be
> > completed on one element without the result of that task performed on
> > subsequent elements.
>
> Now, that definitely sounds loopy ;-)
>
> agt

This thread is missing from my profile. Is there sometimes a problem
with indexing?

agt