Newsgroups: rec.arts.int-fiction
Path: nntp.gmd.de!Dortmund.Germany.EU.net!main.Germany.EU.net!EU.net!newsfeed.internetmci.com!news.webspan.net!ix.netcom.com!netcom.com!erkyrath
From: erkyrath@netcom.com (Andrew Plotkin)
Subject: Re: [Inform]  Adding exceptions to Inform (long)
Message-ID: <erkyrathDzE47w.489@netcom.com>
Organization: NETCOM On-line Communication Services (408 261-4700 guest)
X-Newsreader: TIN [version 1.2 PL1]
References: <53sk77$neh@mars.worldonline.nl> <540nam$4d2@mars.worldonline.nl>
Date: Wed, 16 Oct 1996 22:38:20 GMT
Lines: 108
Sender: erkyrath@netcom.netcom.com

Marnix Klooster (marnix@worldonline.nl) wrote:
> Two syntax issues have been brought up: having other keywords, and the
> syntax of the handler.

> For the handler, I proposed

>   try <statement>
>   finally <statement>
>   except {
>      <exception name>: <statement list>
>      <etc...>
>      default: <statement list>
>   }

> but Andrew argued that we do things the C++ way, because Inform is so
> C-like.  I agree that we should try to, but I'd say we either support
> exactly the same syntax, or a markedly different one; we shouldn't
> choose an almost-the-same syntax.  That would bring even more
> confusion.

> So what is the C++ (and Java) way?  If I remember correctly, it is

>   try <statement>
>   catch (<exception name>) <statement>
>   catch (<exception name>) <statement>
>   <etc...>
>   catch (...) <statement>

> Leaving aside the problem that C++ does not have a finally clause, I
> find this syntax has a number of disadvantages.  (1) It gives a longer
> program text, containing more brackets and braces, making it more
> difficult to read and write.  (2) It introduces new syntax "..." for
> the default case.  (We could use "default" instead of "...", but that
> leads to the almost-but-not-exactly-the-same-as-C++ pitfall.)  (3) The
> handler is in fact a kind of 'switch,' so I feel we should use a
> switch-like syntax here.

The reason for C++'s catch-catch-catch syntax is that exceptions are 
class objects, which can inherit from each other. So you have to catch 
them with (effectively) "instanceof" tests, which have to be done 
sequentially, in a fixed order. (The order matters because an exception 
may be in more than one tested class, because of inheritance. Or -- worse
-- multiple inheritance.)

Since Inform has real classes now, we *could* do exceptions that way, but 
it would be Reely Dumm(tm). So as long as exceptions are simple numeric 
constants, a switch statement is nicer.

> Now for the keywords.  Above I argued to use "catch" if we decide on
> C++ syntax, and "except" if we use switch-like syntax.

I have no strong objection to this, although if there's a consistency to 
Inform's design it's "almost C, but not quite." :-)

>  For "raise"
> vs. "throw", my linguistic intuition says to use "throw" with "catch",
> and "raise" with "except". 

Definitely.

> Finally, I agree that it is probably not
> wise to introduce "None" in addition to "NULL", with a different
> meaning.  The choice is therefore between re-using NULL as 'no
> exception raised', and introducing a new keyword like "NoExcept" for
> this.  I prefer the former for its simplicity.  (I think C++ and Java
> can give us no guidance here, or can they?)

Nope. 

> [As a separate issue, I think that "None" would be a good replacement
> keyword for "NULL" in Inform.  It describes more intuitively what that
> special value is used for.  E-mail Graham and/or me with your thoughts
> on this.]

Remember that NULL is a definition of the standard Inform library, not 
the language. The obvious compromise here is to make "None" be a 
language-defined constant, equal to -1, same as NULL. Then None and NULL 
will be interchangeable, and we can deprecate NULL in favor of None without 
breaking any existing code. 

Paranoia inspires me to say that 0 should never be an exception constant 
(because "nothing" is 0.) Further paranoia inspires me to suggest that 
exception constants be numbered from -2 downwards. That way they won't 
collide with object numbers. I know there's no reason for them *not* to 
collide with object numbers, or "nothing" for that matter, but it reduces 
the possibility of confusion by some tiny degree.

Other questions: In C++ and Java, "throw;" by itself re-throws the 
current exception. (This can only be done in an exception handler.) This 
is useful enough that I'd like to keep it. (If not, it can be simulated 
with "raise ExcNum;" or whatever the variable was.)

I'd rather not have "break" acquire additional meaning. "raise None;" 
does what you were saying "break" might, right?

Exception arguments are pretty cool. I'll lobby for them. 

  raise GameOver("You have drowned");

Yes, the exception mechanism variables should go in a small array, *not* 
in global variables. Global variables are something we're actually in 
short supply of.

--Z
-- 

"And Aholibamah bare Jeush, and Jaalam, and Korah: these were the
borogoves..."
