[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

conditions



I haven't been able to participate in the discussion on conditions over
the last week. Meanwhile, Richard did a great job of explaining the
rationale for conditions (thanks Richard!). Still, from the discussion
it's not clear that everyone buys the rationale, so here's my take.

  Disclaimer: My views do not necessarily represent the views of the
  other three authors.

  Note: Section 3 addresses specific questions on conditions in the
  current SRFI, so skip down to there when the rest gets too tedious.

1. Why Have Them?
-----------------

Perhaps the best way to explain the motivation behind conditions in the
SRFI draft is to imagine an example.

Suppose Per provides a fancy image-manipulation library, "bothner.scm".
Suppose also that Dave provides an elegant networking protocol library,
"mason.scm". Suppose, finally, that I want to implement the
image-viewing part of a web browser using "bothner.scm" and
"mason.scm".

Although "bothner.scm" and "mason.scm" were implemented by different
authors, in the post-SRFI utopia they both signal errors via
exceptions. This makes my job much easier in writing the web browser. I
can freely interleave calls to the libraries to download and display a
particular image, all the while assuming that nothing goes wrong. If
something goes wrong, I can catch the exception at the point where I
started trying to download the file, give up on the download, and
report a helpful error message to the user.

But how can I report a helpful error? In other words, how do I get a
useful error message from the value that "bother.scm" or "mason.scm"
provides to my exception handler?

Well - duh! - I read the documentation. Here's what the documentation
for "bothner.scm" says:

 If something goes wrong processing an image file, an exception is
 raised, represented by a value of the form
   (list <bad-file-name-string> <error-message-string>)

The documentation for "mason.scm" is equally helpful:

  If something goes wrong in network communication, an exception is
  raised, represented by a value of the form
   (list <error-message-string> <server-name-string>)

Uh-oh. The error string is not in the same place, and I can't
distinguish the formats.

Quoting Jimmy Kneecricket, freshman at Whatsamatta U.:
> Surely your example is contrived. The Scheme community would never
> foster such gratuitously incompatible interfaces, would it?

Serious questions only, please.

Quoting Paige Turner, litrary critic at the Bookings Institute of Werms:
> Both "bothner.scm" and "mason.scm" are pure ficton. Everyone knows
> that Schemers don't share code.

You've got me there, but I think that's what we're trying to solve with
SRFIs.

Quoting Lisa Commons, denominator at the Division Foundation
> Ok, so SRFIs are supposed to fix this problem, but not *this* SRFI.
> Can't it wait until the next one? Let's agree on a core mechanism,
> first.

At a minimum, I think the initial SRFI needs to provide programmers
with a mechanism for dealing with implementation-supplied information
(when a Scheme implementation raises an exception). I'd hope this SRFI
provides, at the very least, access to a user-friendly error message.

In that case, we have to deal with the issue of conditions right from
the start. We should spend a some effort, in this SRFI, to design a
flexible and extensible system, ensuring that implementation- and
library-raised exceptions can be handled the same way.

Quoting Cantwee Moovan, numerator at Runtimes International:
> I have to disagree with Lisa. Individual Scheme programmers can
> already build exception systems for their own code using
> continuations. But we want to share code, hence the SRFI.
> Unfortunately, an exceptions SRFI is useless for that purpose
> without a common means of expressing information about exceptions.
> Indeed, Richard already said as much:
>
> Quoting Richard Kelsey:
> > The quick answer is that exception systems are used to communicate
> > between programs. Within a single a program you can use whatever
> > method you want for catching exceptions and whatever values you
> > want as conditions. If two or more programs are involved they need
> > to agree on both the exception-raising mechanism and on the kind of
> > values that are passed to the handler.
>
> And besides, "denominator" is not a real occupation, is it?

No, I don't think it is.

2. Why Like That?
-----------------

Quoting Per Bothner:
> * Why do we need a new condition type, disjoint from other Scheme values,

For the same reason that `procedure?' is disjoint from `pair?'.

Seriously!

We all know that a procedure is a pair, combining a code pointer with a
set of free-variable bindings. But the advantage of distinguishing
pairs and procedures is that we can write code such as

  (cond
   [(procedure? x) ...]
   [(pair? x) ...])

and it won't break in SuperScheme (the latest, greatest Scheme
implemetation) when I happen to create a list that looks like
SuperScheme's representation of procedures.

Quoting Icy a'Paturn, penguin at the Antarctic Linux Research Center:
> You're still harping on portability and sharing code, aren't you?

Yes, still echoing Richard. But out of respect for real individuals, no
more questions from fictional characters, please.

Quoting Per Bothner:
> But I don't see any need to support signaling anything *else*, and
> thus we don't need a disjoint datatype.

Since conditions are first-class values, they'll surely flow to more
places than the argument position of an exception handler. For example,
a program might keep a log of exceptions using conditions in a list.
The log might contain non-exception entries as well as exception
entries.

Quoting Per Bothner:
> * What is the purpose of composite conditions?

It's a simple mechanism to get the flexibility and extensibility we
want.

Again, Richard has already explained this, but I'll repeat for
completeness. The usual example goes something like this:

 * Filesystem errors are supposed to raise the exception BadFile.

 * Network errors are supposed to raise the exception BadConnect.

 * What exception do you raise when something goes wrong in a
   network-backed filesystem?

The ideal answer is "both". That's what composite conditions are for.

Quoting Dave Mason:
> It seems to be unnecessarily complicated to see if an exception is
> the one you were expecting. It's so much more convenient if you
> simply use a normal scheme value (most likely a symbol).
> Interestingly, the examples for HANDLE-EXCEPTIONS (quite rightly) use
> simple scheme values rather than making condition values. If this was
> done for pedagogical reasons (because it was simpler to explain),
> doesn't that make a compelling reason for using them in programs too?

In prototype code, I sometimes use simple values, such as symbols, to
represent exceptions. But for sharable code, I don't see a system
simpler than the proposed one that provides the flexibility and
extensibility we need. Of course, the SRFI authors may have overlooked
a better alternative. Specific suggestions, such as Dave's more recent
post, are welcome.

Quoting Richard Kelsey:
> CONDITION? is needed unless either 1. only conditions can be
> passed to handlers or 2. there are no operations specific to
> conditions.  I can see doing 1 but not 2.  Hopefully the authors
> of SRFI-12 will enlighten as to why they allow values other than
> conditions to be raised.

I don't think there were stong reasons. Simplicity of specification and
ease of prototyping (see previous paragraph) are possible reasons to
keep the current convention.

Quoting Matthew Flatt, second assistant chief monkey at Hogle Zoo, SLC:
> Why do you keep making up questions from fictional characters?

It was a feeble attempt to break up a lengthy and otherwise dry post.
But I said no more questions from fictional characters!

3. Details, Details
--------------------

Quoting Richard Kelsey:
> Question 1: What predicate is used to compare prop-keys?
> 
> The implementation uses `eq?' (via `assq' and `memq') for both
> kind-keys and prop-keys. The specification says that kind-keys are
> compared using `eqv?' and says nothing about how prop-keys are
> compared.

I believe they should all be `eqv?'. We'll have to correct the SRFI.

Quoting Richard Kelsey:
> The rest of the questions relate to the following condition:
> 
>   (define condition
>     (make-composite-condition (make-property-condition #f 0 'a 1 'b)
>                               (make-property-condition #f 0 'c 1 'd 2 'e)))

Although the SRFI doesn't disallow it, the intent is that the above
condition is not well-formed. Each key should appear in only one
subcondition.

> Question 2: What happens if I ask for a property that the condition
> doesn't have?

The SRFI should say that the implementation "signals an error". (A
later SRFI should specify the details of the ensuing exception.)

> Question 3: What if I ask for a property that only one of the two
> subconditions has?
[in the case that a composite condition contains the key in two
subconditions]

Good question. I don't know offhand.

> Question 4: Will the accessor always use the same subcondition?
[in the case that a composite condition contains the key in two
subconditions]

Another good question. Any suggestions?

Quoting Per Bothner:
> I also think the word "condition" is a bit of a mis-nomer. I see
> nothing conditional about them.

I'm not a fan of the term "condition", either. I'd prefer to confuse
the exception and the value representing the exception, and just call
them both "exception". Someone else will have to speak up and remind me
why we should go with "condition".

Matthew