Here is a collection of some of my own (recent) ideas on how things should
work. I thought I'd see if anyone has any reactions or suggestions based on
what I can throw together. I haven't thought at all about compatibility or the
more esoteric aspects, just simplicity.
I haven't thought about proceeding much, but the bit about whether to prompt or
not sounds bogus. Why not just have different proceed types, some that prompt
that the debugger uses, and some that don't for normal handlers? The first can
call the second. I do think that proceed types deserve some special mechanism.
----
I basically agree with the idea that signalling a condition makes an explicit
condition object of some form, and that handling a condition consists of
performing operations on this object. Proceed types are a kind of operation.
Condition objects naturally have some internal state (if nothing else, the
arguments to signal), which I will call instance variables, not to be confused
with those found in Flavors.
I propose that we not get into the idea of "combining" operations, since that's
messy. I propose the only rule we adopt is that operations of more specific
conditions shadow the more general ones. I propose that an error be signalled
when there are two candidates for inheritance (as in A and B have operations
:foo, and C is a kind of A and a kind of B); usually the desired operation is a
hybrid, and having the system pick one is just one more pointless thing to
remember and abuse. [Operations will be normal functions, in which case you
would be able to stick the same one two different places easily.] Operations
can still interact by calling eachother.
A condition has some required and some optional arguments, some of which may be
inherited from more general conditions. In addition, some more specific
conditions may be able to construct the more general arguments, so that
arguments previously required are now optional, or what were supplied are now
computed. In fact, computed arguments are indistinguishable in function from
values cached in instance variables. I propose that rather than trying to
untangle these things, we just use a disembodied property list as the
internal state. If the arguments to signal are just paired argument name -
value, all we need to do to get the condition object is make it a list.
A cursory investigation has shoen other approaches to be either complicated or
gross.
Of course, this does need some discipline. I think that all that really needs
to be done is to help the user figure out what's required and what's optional.
This can be accomplished with describe and by warning at compile time about
either missing required arguments or unknown arguments. Also, if Flavors users
can keep from tripping over other instance variables, then there shouldn't be
much problem with condition instance variable conflicts.
Something that would be nice would be a standard (automatic) way of specifying
how various optional instance variables are calculated from the supplied ones.
A simple mechanism would be to have the iv-referencing primitive send the
condition a message [the variable name] if it isn't in the plist. A more
specific condition that no longer requires some argument simply provides an
operation that can calculate it.