From: DaveNlp
Subject: [newbie] apply the function (remove) to a list.
Date: 
Message-ID: <t7CMb.246059$vO5.10177910@twister1.libero.it>
Dear Lispers,
could anybody help me to reduce this function using
apply/mapcar/funcall??
I tried but without success.

(defun multi-remove (remove-list whole-list)
  (dolist (sym remove-list whole-list)
    (setf whole-list (remove sym whole-list :test #'equal))))

>(multi-remove '(a (one) (two)) '(a b c (two) d e (one) f g h i (one)))
>(b c d e f g h i)
>

Thanks you.
DaveNlp.

From: Tayssir John Gabbour
Subject: Re: [newbie] apply the function (remove) to a list.
Date: 
Message-ID: <866764be.0401121817.41a44693@posting.google.com>
"DaveNlp" <(NOSPAM)·········@iol.it> wrote in message news:<·························@twister1.libero.it>...
> could anybody help me to reduce this function using
> apply/mapcar/funcall??
> I tried but without success.
> (defun multi-remove (remove-list whole-list)
>   (dolist (sym remove-list whole-list)
>     (setf whole-list (remove sym whole-list :test #'equal))))

Is this an artificial situation like a puzzle, or are you looking for
any functional kinda answer using map/filter/fold?

If it's a puzzle, two strategies strike me offhand:
- use mapcar like it was a mapcan
- using mapcar on whole-list, and for each element that's on the
shitlist, map it to a gensym, which I then remove from the answer.

For the second stratgy, I'd take a quick look at exactly how gensyms
work again, just to make sure I'll realistically never get a list with
the same damn gensym, but it should be fine.

I'm just talking about mapcar.  If you need funcall/apply, I'd use
them gratuitously.

- - - -

Incidentally, I love gensym.  I disagree with the overly hygenic
people who consider it a flaw in lisp.  Sometimes I want to draw from
the set of symbols which are not in my working universe.
From: DaveNlp
Subject: Re: [newbie] apply the function (remove) to a list.
Date: 
Message-ID: <lB0Nb.255627$e6.10062086@twister2.libero.it>
"Tayssir John Gabbour" <···········@yahoo.com> ha scritto nel messaggio
·································@posting.google.com...
> "DaveNlp" <(NOSPAM)·········@iol.it> wrote in message
news:<·························@twister1.libero.it>...
> > could anybody help me to reduce this function using
> > apply/mapcar/funcall??
> > I tried but without success.
> > (defun multi-remove (remove-list whole-list)
> >   (dolist (sym remove-list whole-list)
> >     (setf whole-list (remove sym whole-list :test #'equal))))
>
> Is this an artificial situation like a puzzle, or are you looking for
> any functional kinda answer using map/filter/fold?

No, it's an artificial situation for a planning system.
:-)

(Sussman anomally problem)

--=initial state=--
((on c a) (on a table) (on b table) (clear c) (clear b))

--=goal state=--
((on a b) (on b c) (on c table) (clear a))

+-----------------------------+
(put-on c table a)
(put-on b c table)
(put-on a b table)

PROBLEM SOLVED.
From: Henrik Motakef
Subject: Re: [newbie] apply the function (remove) to a list.
Date: 
Message-ID: <x7eku53puq.fsf@crocket.internal.henrik-motakef.de>
"DaveNlp" <(NOSPAM)·········@iol.it> writes:

> Dear Lispers,
> could anybody help me to reduce this function using
> apply/mapcar/funcall??
> I tried but without success.
> 
> (defun multi-remove (remove-list whole-list)
>   (dolist (sym remove-list whole-list)
>     (setf whole-list (remove sym whole-list :test #'equal))))
> 
> >(multi-remove '(a (one) (two)) '(a b c (two) d e (one) f g h i (one)))
> >(b c d e f g h i)

Do you /insist/ on using apply/mapcar/funcall? (I'd be more concerned
about the ugly setf)
Otherwise I'd probably do

(defun multi-remove (remove-list whole-list)
  (remove-if #'(lambda (x) 
                 (member x remove-list :test #'equal))
             whole-list))

or if the order of elements doesn't matter,

(defun multi-remove (remove-list whole-list)
   (set-difference whole-list remove-list :test #'equal))


For a mostly direct translation of your function to one that uses mapcar:

(defun multi-remove (remove-list whole-list)
   (mapcar #'(lambda (thing)
               (setf whole-list (remove thing whole-list :test #'equal)))
           remove-list)
   whole-list)

but that doesn't quite qualify as "reducing" the original.

Something like

(defun multi-remove (remove-list whole-list)
  (mapcar #'(lambda (thing) (delete thing whole-list :test #'equal))
         remove-list))

won't work because "delete" is only allowed, not required, to modify
the list from which it removes things.  As far as I know there is no
premade CL function that reliably can be used to destructively a list,
but it could certainly be built. Something along the lines of

(defun inplace-delete (item list &key (test #'eql))
  (loop for sublist on list
        when (funcall test item (cadr sublist))
        do (setf (cdr sublist) (cddr sublist))))

(this is buggy, for example it won't ever remove the first element of
the list; it's just for the general idea)
From: DaveNlp
Subject: Re: [newbie] apply the function (remove) to a list.
Date: 
Message-ID: <5wGMb.252676$e6.9970514@twister2.libero.it>
"Henrik Motakef" <············@henrik-motakef.de> ha scritto nel
messaggio

> or if the order of elements doesn't matter,
>
> (defun multi-remove (remove-list whole-list)
>    (set-difference whole-list remove-list :test #'equal))
>

Great!
This one is just the solution that I looked for.
It seem very smaller if compared to the usage of
"apply/mapcar/funcall"..
I must use this function to develop a small planner like "Strips"
and your other examples will serve me however for learning
the "apply/mapcar/funcall" functions.

Thank you very much for your answers. :-)
DaveNlp.

(You excuse me for brief answer but I don't speak English very well..)
From: Wolfhard Buß
Subject: Re: [newbie] apply the function (remove) to a list.
Date: 
Message-ID: <m3smijpy50.fsf@buss-14250.user.cis.dfn.de>
* DaveNlp writes:
> could anybody help me to reduce this function using
> apply/mapcar/funcall??
:
> (defun multi-remove (remove-list whole-list)
>   (dolist (sym remove-list whole-list)
>     (setf whole-list (remove sym whole-list :test #'equal))))

mapclan - yet another variation on the zip theme - is possible:

 (defun multi-remove (list1 list2 &optional (test #'eql))
   (mapclan (lambda (item)
              (unless (member item list1 :test test)
                item))
            list2))

but Henrik has already pointed out, that your multi-remove is a
set-difference.

mapclan was recently mentioned on this forum.

-- 
"Hurry if you still want to see something. Everything is vanishing."
                                       --  Paul C�zanne (1839-1906)