[comp.lang.scheme] Scheme's case

guttman@mitre.org (Joshua D. Guttman) (05/04/90)

Why is it that Scheme has the case statement, which does not evaluate its keys?
Wouldn't it be a great deal more useful to have instead a select statement (as
does T) which is exactly the same except that it *does* evaluate its keys?

After all, you can simulate the case using the select by strewing around the
needed quotation marks, but obviously not conversely.  And as for smart
compilers, if a compiler does something clever for case, why not have it do
just the same clever thing for select if it observes that all of the keys are
constants?  


	Josh

dorai@titan.rice.edu (Dorai Sitaram) (05/05/90)

In article <GUTTMAN.90May4113544@darjeeling.mitre.org> guttman@mitre.org (Joshua D. Guttman) writes:
>Why is it that Scheme has the case statement, which does not evaluate its keys?
>Wouldn't it be a great deal more useful to have instead a select statement (as
>does T) which is exactly the same except that it *does* evaluate its keys?
>
>After all, you can simulate the case using the select by strewing around the
>needed quotation marks, but obviously not conversely.  And as for smart
>compilers, if a compiler does something clever for case, why not have it do
>just the same clever thing for select if it observes that all of the keys are
>constants?  

You're certainly right.  I first saw uses of what you call SELECT in
the original paper on engines [1].  They called it EVCASE.  It is so
much more useful than plain CASE, especially when you want to make
full use of both Scheme's lexical scoping (to ensure proper hiding)
_and_ CASE-like dispatching (sp? despatching?)  constructs.
Similarly, there is an analogous RECORD-EVCASE, which is to
RECORD-CASE, as EVCASE is to CASE.

E.g., let's say we have a slew of tagged messages humming around
inside a lexically cordoned-off portion of code.  Dispatching on the
tags of the messages could be done with EVCASE or RECORD-EVCASE.

(record-evcase this-here-tagged-message
  [tag1 (msg-par1 ...) larry]
  [tag2 (msg-par1 ...) curly]
  [tag3 (msg-par1 ...) mo]
  ...)

The tags can be introduced as

(let ([tag1 (unique)] [tag2 (unique)] ...) <the-whole-caboodle>)

where <the-whole-caboodle> contains all the relevant code using the
tags.  Since the tags are created as unique markers (using gensyms or
new conses or boxes or lambdas or whatever) and can only be referred
to by accessing the corresponding variables, we're assured that
nothing EQ? to them can be created by code outside
<the-whole-caboodle>.  Hence the latter is safe from spurious messages
(or Trojan horses).  Thus, we have a nice way to meaningfully
abbreviate a watertight piece of code.

In sum, both the EV-forms are such charming dears.  They can of course
be created by any modest "macro" facility, but it would be nice to
have them recognized by the Scheme standard.  Code using them would
then have one less portability issue to worry about, since any
syntactic extension facility used to create them is not portable --
RRRS not having a stance on s.e.'s as yet.

--dorai

[1] Engines build Process Abstractions, Haynes & Friedman, L&FP 1985