public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
From: Jamison Hope <jrh@theptrgroup.com>
To: "kawa@sourceware.org list" <kawa@sourceware.org>
Subject: enums and case
Date: Thu, 06 Mar 2014 06:13:00 -0000	[thread overview]
Message-ID: <21EE67EB-02CA-4E60-9A8A-01DD09C6C1B0@theptrgroup.com> (raw)

It occurs to me that it would be very handy if we could use Java enums
in Scheme case expressions the way that they can be used in Java switch
statements:

> public enum Day {
>     SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
>     THURSDAY, FRIDAY, SATURDAY 
> }
> 
> Day day = ...;
> 
> switch (day) {
>   case MONDAY: ...
>   case FRIDAY: ...
>   ...
> }

becomes something like

> (define-enum Day (SUNDAY MONDAY TUESDAY ...))
> 
> (define d ::Day ...)
> 
> (case d ((MONDAY) ...) ((TUESDAY) ...) ...)

There are several issues which must be addressed:

1. How to recognize in (case d ((MONDAY) ...) ...) that we intend
   to compare against the enum constant Day:MONDAY and not the
   symbol named "MONDAY".  Should this depend upon the type
   declaration for d?  In Java, this is a compile-time error:
>    Object day = Day.MONDAY; switch (day) { /* ... */ }

   Is it acceptable for the presence or absence of a type
   declaration to alter the semantics like this in Kawa?

   If so, can a macro defined in Scheme get to a variable's
   gnu.expr.Declaration, or would case need to be rewritten as
   a Java class extending Syntax?

2. Would it be preferable to require qualified constants, as in
   (case d ((Day:MONDAY) ...) ((Day:TUESDAY) ...) ...)?  In that
   case we wouldn't need to chase the declaration for d, but on
   the downside it's more verbose.

3. The current implementation of case checks for matches with each
   datum via (eqv? key (quote datum)).  That means that here we
   would get an expansion of (eqv? d (quote Day:MONDAY)), assuming
   that we require qualified constants.

   But (quote Day:MONDAY) evaluates to the symbol with the name
   "Day:MONDAY", not to the constant named "MONDAY" of the enum
   class Day.

   Should quote recognize that there's a colon in there and check
   for an enum constant before constructing a symbol?  After all,
   '3 evaluates to an integer, not the symbol named "3".

   But what if we actually do want to have the symbol?

4. Should this be a separate macro, "enum-case"?  But standard
   case already handles booleans and numbers and symbols, so why
   should enums require a separate facility?

We would want to do the checking at compile time to catch spelling
errors or other mistakes such as (case d ((JANUARY) ...) ...), so
while altering %case-match like this works (kind of), it isn't
the Right Thing:

> (define-syntax %case-match
>   (syntax-rules ()
>     ((%case-match key datum)
>      (if (*:isEnum key:class)
>          (eq? key (key:class:valueOf (quote datum)))
>          (eqv? key (quote datum))))
>     ((%case-match key datum more ...)
>      (or (if (*:isEnum key:class)
>              (eq? key (key:class:valueOf (quote datum)))
>              (eqv? key (quote datum)))
>          (%case-match key more ...)))))

(Besides, it's horribly inefficient, calling Class#isEnum over and
over again.)


Thoughts?  Once we decide upon the right semantics, this should be
a fairly small task to complete.  Any potential GSoC students want
to give it a try?

--
Jamison Hope
The PTR Group
www.theptrgroup.com



                 reply	other threads:[~2014-03-06  6:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=21EE67EB-02CA-4E60-9A8A-01DD09C6C1B0@theptrgroup.com \
    --to=jrh@theptrgroup.com \
    --cc=kawa@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).