Subject: Re: position and test
From: (Rob Warnock)
Date: Sat, 16 Dec 2006 20:58:50 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
Matthew D Swank <> wrote:
| Pascal Bourguignon <> writes:
| > Matthew D Swank <> 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:
| >
| 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)))


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)))


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)))))


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))


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



Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607