From: Marco Antoniotti
Subject: Need CASE CCASE and ECASE clarification.
Date: 
Message-ID: <lwk8ob5snm.fsf@copernico.parades.rm.cnr.it>
Hi

I am looking at the Hyperspec on the [EC]?CASE spec.  I wonder what
the exact meaning of "a clause is selected by matching the test-key on
the basis of its identity."

May I assume that the test will always be run by using at least EQL?

Reading the scpe for IDENTITY may seem to ensure this.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa

From: Barry Margolin
Subject: Re: Need CASE CCASE and ECASE clarification.
Date: 
Message-ID: <HL0R3.65$J44.2804@burlma1-snr2>
In article <··············@copernico.parades.rm.cnr.it>,
Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
>
>Hi
>
>I am looking at the Hyperspec on the [EC]?CASE spec.  I wonder what
>the exact meaning of "a clause is selected by matching the test-key on
>the basis of its identity."
>
>May I assume that the test will always be run by using at least EQL?

yes.  Three sentences later, it says "If the <test-key> is the same as any
<key> for that clause...."  If you follow the link on "same" to the
glossary, it says "(of objects if no predicate is implied by context)
indistinguishable by EQL."  I don't think "on the basis of its identify"
implies a specific predicate, so I would take this to mean that "same"
defaults to EQL.

The closest word I can find in the glossary to "identity" is "identical".
It says "the same under EQ."  I suppose it's possible to interpret
"matching on the basis of its identity" to mean "testing if they're
identical", which would mean that EQ would be used.

One other piece of evidence: CLtL specifically said "If <key> is in the
<keylist> (that is, is EQL to any item in the <keylist>)...."  Although
CLtL is not part of the standard, this wording and the X3J13 records, which
I don't think show any intentional change to this aspect of CASE, is
evidence that this may just be poor choice of words in the standard.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
From: Christopher R. Barry
Subject: SELECTOR and TESTCASE. Re: Need CASE CCASE and ECASE clarification.
Date: 
Message-ID: <87r9iir7k2.fsf_-_@2xtreme.net>
Barry Margolin <······@bbnplanet.com> writes:

> In article <··············@copernico.parades.rm.cnr.it>,
> Marco Antoniotti  <·······@copernico.parades.rm.cnr.it> wrote:
> >
> >Hi
> >
> >I am looking at the Hyperspec on the [EC]?CASE spec.  I wonder what
> >the exact meaning of "a clause is selected by matching the test-key on
> >the basis of its identity."
> >
> >May I assume that the test will always be run by using at least EQL?
> 
> yes.  Three sentences later, it says "If the <test-key> is the same as any
> <key> for that clause...."  If you follow the link on "same" to the
> glossary, it says "(of objects if no predicate is implied by context)
> indistinguishable by EQL."  I don't think "on the basis of its identify"
> implies a specific predicate, so I would take this to mean that "same"
> defaults to EQL.

I like the SCL:SELECTOR macro on the Symbolics which is like case
except you can specify the predicate you want to use. I just wrote two
slightly different versions of it. The first is (if I remember
correctly) true to the original one which evaluates its keys and takes
the symbol of its predicate function and is thus a little ackward to
use:

(defmacro selector (key test &body clauses)
  (let ((key-val (gensym "KEY")))
    `(let ((,key-val ,key))
       (cond
	,@(loop for (keys . forms) in clauses
	        if (member keys '(t otherwise) :test #'eq)
	          collect `(t ,@forms)
	        else
		  when (atom keys)
		    collect `((,test ,key-val ,keys) ,@forms)
	        else
	          collect
		    `((or ,@(mapcar #'(lambda (key) `(,test ,key-val ,key))
				    keys))
		      ,@forms))))))

> (selector 'foo eq
    ('bar          1)
    (('foo 'blah)  2)
    (('frob 'bleh) 3)
    (t             4))
 => 2

> (selector '(foo (bar baz) quux) tree-equal
    (('(bar (foo baz) quux)) 1)
    (('(baz (quux bar) foo)) 2)
    (('(foo (bar baz) quux)) 3)
    (t                       4))
 => 3


The second one I did takes its test argument the more ANSI-CL-like way 
and doesn't evaluate its keys like [EC]?CASE does. I think TESTCASE is 
a natural name for it.

(defmacro testcase (key test &body clauses)
  (let ((key-val (gensym "KEY")))
    `(let ((,key-val ,key))
       (cond
	,@(loop for (keys . forms) in clauses
	        if (member keys '(t otherwise) :test #'eq)
	          collect `(t ,@forms)
	        else
		  when (atom keys)
		    collect `((funcall ,test ,key-val ',keys) ,@forms)
	        else
	          collect
		    `((or ,@(mapcar #'(lambda (key)
					`(funcall ,test ,key-val ',key))
				    keys))
		      ,@forms))))))

> (testcase 'foo #'eq
    (bar         1)
    ((foo blah)  2)
    ((frob bleh) 3)
    (t           4))
 => 2

> (testcase '(foo (bar baz) quux) #'tree-equal
    (((bar (foo baz) quux)) 1)
    (((baz (quux bar) foo)) 2)
    (((foo (bar baz) quux)) 3)
    (t                      4))
 => 3


Christopher