From: Matthew D Swank
Subject: position and test
Date: 
Message-ID: <2m%gh.1561$s91.1408@newsfe05.lga>
Are there any guarantees w/regard to argument order when you pass a test 
to a function like position?
For example, I would like to do something like:

(position '(#\space #\tab #\newline) "This	is   a
very

silly string" :test #'member)
=> 4
Matt

From: Pascal Bourguignon
Subject: Re: position and test
Date: 
Message-ID: <874prvfkbt.fsf@thalassa.informatimago.com>
Matthew D Swank <··································@c.net> writes:
> Are there any guarantees w/regard to argument order when you pass a
> test to a function like position?
> For example, I would like to do something like:
>
> (position '(#\space #\tab #\newline) "This	is   a
> very
>
> silly string" :test #'member)
> => 4

Yes, there are. They are explicited in:
http://www.lispworks.com/documentation/HyperSpec/Body/17_b.htm

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

"Our users will know fear and cower before our software! Ship it!
Ship it and let them flee like the dogs they are!"
From: ··································@c.net
Subject: Re: position and test
Date: 
Message-ID: <uzm9ngwph.fsf@JASPER.i-did-not-set--mail-host-address--so-tickle-me>
Pascal Bourguignon <···@informatimago.com> writes:

> Matthew D Swank <··································@c.net> writes:
>> Are there any guarantees w/regard to argument order when you pass a
>> test to a function like position?
> Yes, there are. They are explicited in:
> http://www.lispworks.com/documentation/HyperSpec/Body/17_b.htm

Ah... So it's always going to be-- :test #'(lambda (o zi) ...)

Thanks

Matt
From: Rob Warnock
Subject: Re: position and test
Date: 
Message-ID: <y46dnR7mf9j3LxnYnZ2dnUVZ_rmdnZ2d@speakeasy.net>
Matthew D Swank <··································@c.net> wrote:
+---------------
| Pascal Bourguignon <···@informatimago.com> writes:
| > Matthew D Swank <··································@c.net> writes:
| >> Are there any guarantees w/regard to argument order when you pass a
| >> test to a function like position?
| >
| > Yes, there are. They are explicited in:
| > http://www.lispworks.com/documentation/HyperSpec/Body/17_b.htm
| 
| Ah... So it's always going to be-- :test #'(lambda (o zi) ...)
+---------------

Yes, so to do what you were trying to do in your original question
you would have to do this:

    > (position '(#\space #\tab #\newline)
		"This is	a very
		silly string"
	        :test (lambda (o zi) (member zi o)))

    4
    >

But note that now you can also supply a :TEST to MEMBER as well,
which lets you do things like this:

    > (position '("FIRST" "SECOND" "THIRD")
		'("This" "is" "the" "second" "silly" "arglist")
		:test (lambda (o zi) (member zi o :test #'equalp)))

    3
    >

And you can continue to stack tests to a quite amazing degree, e.g.:

    > (position '("FIRST" "SECOND" "THIRD")
		'("This" "is" "the" "*Second*" "silly" "arglist")
		:test (lambda (o zi)
			(member zi o :test (lambda (o zi)
					     (search zi o :test #'equalp)))))

    3
    >

Though when things get this complex, for readability I tend to
pre-define the tests with FLET or LABELS [since there's no FLET*]:

    > (labels ((ci-search (o zi) (search zi o :test #'equalp))
	       (cis-member (o zi) (member zi o :test #'ci-search)))
	(position '("FIRST" "SECOND" "THIRD")
		  '("This" "is" "the" "*Second*" "silly" "arglist")
		  :test #'cis-member))

    3
    >

Finally, note that all of the above have N^2 (well, M*N) performance
when the target-value set and the argument lists are long, so in
those cases you might be better off using a hash table for the
target-value set [though in that case you can't use the SEARCH hack].

    > (let ((keys (make-hash-table :test #'equalp)))
	(dolist (i '("FIRST" "SECOND" "THIRD"))
	  (setf (gethash i keys) t))
	(position keys '("This" "is" "the" "second" "silly" "arglist")
		  :test (lambda (o zi) (gethash zi o))))  ; Note reversal

    3
    >


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607