From: Jim Newton
Subject: implementing SKILL exists with CL find
Date: 
Message-ID: <2sa5ehF1j64jtU1@uni-berlin.de>
The SKILL language has an exists function which is similar
to the CL FIND function but not exactly compatible.

(exists x '(1 2 3 4 5) (evenp x)) ==> (2 3 4 5)
(exists x '(t 1 nil 2) (listp x)) ==> (nil 2)
(exists x '(3 5 7) (evenp x)) ==> nil

The nice thing is that it does not return the element
which is identified, but rather a list whose first
element is the one identified.  Thus making it very
clear that if nil is returned, then nothing
matched.  Also it gives the remainder of the
list so you can search again on the rest of the
list for the second element that matches the condition.

How should this be accomlished with the CL FIND function?
Or is there an even better solution than with find?

-jim

From: Paul F. Dietz
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <415FE30B.3000900@dls.net>
Jim Newton wrote:

> How should this be accomlished with the CL FIND function?
> Or is there an even better solution than with find?

MEMBER-IF

	Paul
	(with a really bad OCR)
From: Jim Newton
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <2sa693F1i9q4pU2@uni-berlin.de>
member-if?  that is indeed similar to what i want but
not quite.  How can i do the following?

(exists x list1
    (exists y list2
       (somefun x y)))

????

Paul F. Dietz wrote:
> Jim Newton wrote:
> 
>> How should this be accomlished with the CL FIND function?
>> Or is there an even better solution than with find?
> 
> 
> MEMBER-IF
> 
>     Paul
>     (with a really bad OCR)
From: Paul F. Dietz
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <65ydnTJNNKk3ecLcRVn-qA@dls.net>
Jim Newton wrote:
> member-if?  that is indeed similar to what i want but
> not quite.  How can i do the following?
> 
> (exists x list1
>    (exists y list2
>       (somefun x y)))
> 
> ????

(member-if (lambda (x) (member x list2 :test 'somefun)) list1)

	Paul
From: Jim Newton
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <2sa6tiF1i32itU1@uni-berlin.de>
how about this?
(defmacro exists ( var some-list predicate)
   `(member-if (lambda ( ,var) (,predicate ,var)) ,some-list))



Paul F. Dietz wrote:
> Jim Newton wrote:
> 
>> member-if?  that is indeed similar to what i want but
>> not quite.  How can i do the following?
>>
>> (exists x list1
>>    (exists y list2
>>       (somefun x y)))
>>
>> ????
> 
> 
> (member-if (lambda (x) (member x list2 :test 'somefun)) list1)
> 
>     Paul
From: Jim Newton
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <2sa78eF1husmeU1@uni-berlin.de>
actually, here is a better solution.
sexpr given can be expressed in terms of the local variable.


(defmacro exists ( var some-list sexpr)
   `(member-if (lambda ( ,var) ,sexpr) ,some-list))

(exists x list1
    (exists y list2
       (somefun x y)))

Jim Newton wrote:
> how about this?
> (defmacro exists ( var some-list predicate)
>   `(member-if (lambda ( ,var) (,predicate ,var)) ,some-list))
> 
> 
> 
> Paul F. Dietz wrote:
> 
>> Jim Newton wrote:
>>
>>> member-if?  that is indeed similar to what i want but
>>> not quite.  How can i do the following?
>>>
>>> (exists x list1
>>>    (exists y list2
>>>       (somefun x y)))
>>>
>>> ????
>>
>>
>>
>> (member-if (lambda (x) (member x list2 :test 'somefun)) list1)
>>
>>     Paul
> 
> 
From: Thomas F. Burdick
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <xcv7jq77i0k.fsf@conquest.OCF.Berkeley.EDU>
Jim Newton <·····@rdrop.com> writes:

> The SKILL language has an exists function which is similar
> to the CL FIND function but not exactly compatible.
> 
> (exists x '(1 2 3 4 5) (evenp x)) ==> (2 3 4 5)
> (exists x '(t 1 nil 2) (listp x)) ==> (nil 2)
> (exists x '(3 5 7) (evenp x)) ==> nil
> 
> The nice thing is that it does not return the element
> which is identified, but rather a list whose first
> element is the one identified.  Thus making it very
> clear that if nil is returned, then nothing
> matched.  Also it gives the remainder of the
> list so you can search again on the rest of the
> list for the second element that matches the condition.
> 
> How should this be accomlished with the CL FIND function?
> Or is there an even better solution than with find?

This sounds like the kind of utility that usually goes by a name
containing "filter" or "some".  Eg:

  (declare (inline mapsome))
  (defun mapsome (predicate list &rest more-lists)
    (apply #'mapcan
           (lambda (&rest args)
             (when (apply predicate args)
               (copy-list args)))
           list more-lists))
From: Jim Newton
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <2sa5v9F1i9q4pU1@uni-berlin.de>
Perhaps this is better to solve with LOOP?
I often imbed the exists calls together.
E.g.,

(defun find-factor ( product domain )
   (exists x domain
     (exists y domain
       (equal product (times x y)))))

;; look in a domain and find the first factor x of 100
;; such that 100/x is also in the domain
(find-factor 100 '(3 4 5 20 25 30 40)) ==> ( 4 5 20 25 30 40)
(find-factor 100 '(3 4 5 20 30 40)) ==> ( 5 20 30 40)


can i do this with FIND, or do i need to imlement exists
with a LOOP construct?

-jim


Jim Newton wrote:
> The SKILL language has an exists function which is similar
> to the CL FIND function but not exactly compatible.
> 
> (exists x '(1 2 3 4 5) (evenp x)) ==> (2 3 4 5)
> (exists x '(t 1 nil 2) (listp x)) ==> (nil 2)
> (exists x '(3 5 7) (evenp x)) ==> nil
> 
> The nice thing is that it does not return the element
> which is identified, but rather a list whose first
> element is the one identified.  Thus making it very
> clear that if nil is returned, then nothing
> matched.  Also it gives the remainder of the
> list so you can search again on the rest of the
> list for the second element that matches the condition.
> 
> How should this be accomlished with the CL FIND function?
> Or is there an even better solution than with find?
> 
> -jim
> 
From: Raistlin Magere
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <cjoof8$bs1$1@news.ox.ac.uk>
"Jim Newton" <·····@rdrop.com> wrote in message
····················@uni-berlin.de...
> The SKILL language has an exists function which is similar
> to the CL FIND function but not exactly compatible.
>
> (exists x '(1 2 3 4 5) (evenp x)) ==> (2 3 4 5)
> (exists x '(t 1 nil 2) (listp x)) ==> (nil 2)
> (exists x '(3 5 7) (evenp x)) ==> nil
>
> The nice thing is that it does not return the element
> which is identified, but rather a list whose first
> element is the one identified.  Thus making it very
> clear that if nil is returned, then nothing
> matched.  Also it gives the remainder of the
> list so you can search again on the rest of the
> list for the second element that matches the condition.
>
> How should this be accomlished with the CL FIND function?
> Or is there an even better solution than with find?

A solution (not by me but from `On Lisp' pg 50) is the split-if function
(defun split-if (fn lst)
   (let ((acc nil))
       (do ((src lst (cdr src)))
              ((or (null src) (funcall fn (car src)))
               (values (nreverse acc) src))
           (push (car src) acc))))

which is not quite what you want, in order to get the same syntax the exist
function you would have replace
(defun split-if (fn lst)  with (defun split-if (lst fn)
and
(values (nreverse acc) src)) wiith (values src (nreverse acc)))

then you can write:
(split-if '(1 2 3 4 5) #'evenp) ==> (2 3 4 5) , (1)
(split-if '(t 1 nil 2) #'listp) ==> (nil 2) , (t 1)
(split-if '(3 5 7) #'evenp) ==> nil , (3 5 7)

In case you do not know in order to actually use the value returned after
the comma you need to use a special syntax (look up values and
multiple-value-bind).
Also notice that the Graham syntax is a bit schemish (i.e. lst insead of
list)
Finally given that "On Lisp" is freely downloadble it would be worthwhile
for you to get it and read through it.
From: Sergey Kataev
Subject: Re: implementing SKILL exists with CL find
Date: 
Message-ID: <qserjc.vo4.ln@195.171.216.1>
Jim Newton wrote:
> The SKILL language has an exists function which is similar
> to the CL FIND function but not exactly compatible.
> 
> (exists x '(1 2 3 4 5) (evenp x)) ==> (2 3 4 5)
> (exists x '(t 1 nil 2) (listp x)) ==> (nil 2)
> (exists x '(3 5 7) (evenp x)) ==> nil
> 
> The nice thing is that it does not return the element
> which is identified, but rather a list whose first
> element is the one identified.  Thus making it very
> clear that if nil is returned, then nothing
> matched.  Also it gives the remainder of the
> list so you can search again on the rest of the
> list for the second element that matches the condition.
 >
> How should this be accomlished with the CL FIND function?
> Or is there an even better solution than with find?

MEMBER-IF does the job I suppose, and given that you rely on local 
binding 'x in test expression, it can be a simple macro:

(defmacro exists (var list test)
   `(member-if (lambda (,var) ,test)
               ,list))

Surely someone had posted it already, but it worked for me:

[27]> (defmacro exists (var list test) `(member-if (lambda (,var) ,test) 
,list))
EXISTS
[28]> (exists x '(1 2 3 4 a b c 4 5) (symbolp x))
(A B C 4 5)
[29]> (exists x '(1 2 3 4 a b c 4 5) (evenp x))
(2 3 4 A B C 4 5)
[30]> (exists x '(1 2 3 4 5) (evenp x))
(2 3 4 5)
[31]> (exists x '(t 1 nil 2) (listp x))
(NIL 2)
[32]> (exists x '(3 5 7) (evenp x))
NIL
[33]> (exists x '(1 2 3 4 5 6) (exists y '(10 20 30 40 50) (eq 33 (+ x y))))
(3 4 5 6)

Sergey