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

Condition System Rewrite

This message is just about the issues of the order of searching handlers
and restarts.  I'll reply to the rest separately.

    Date: Fri, 2 Jun 89 17:45:36 PDT
    From: Richard P. Gabriel <rpg@lucid.com>

    While doing this I noticed some omissions. I wonder whether
    we need to go to X3J13 to fix these or whether we can simply add the
    right stuff. 

I'm glad you're checking this for omissions.  I think Kent's document
is much more appropriate as a tutorial introduction to the ideas than
as a language standard.  As with the rest of Common Lisp, we must be
very careful that no unintended changes to the language definition
are introduced while improving the way that that definition is described,
but at the same time we need a much less ambiguous definition now that
we are exposing the langauge to a wider audience.

As for the process, I think anything that might conflict with current
practice should go through X3J13, since a lot of implementations have
already jumped the gun and implemented some version of the ANSI CL
condition system.  Where it's only a clarification of something, and
either all known current practice agrees with what you wrote, or we're
confident no user programs care, I think we might be justified in
bypassing the process in the interests of time.

    First, the precise order of search for handlers is not specified. It
    states that a dynamically inner handler-bind, for example, establishes
    handlers that are more specific than outer ones, but there is no order
    specified within a handler-bind. Because the order matters only when
    two handlers apply to the same condition, I suggest the rule be the
    same as the class precedence list order.

I'm convinced this is wrong.  The order of searching handlers should be
the order that they are written, not a more "intelligent" order that
might or might not be what the programmer intended.  I don't buy the
analogy to methods here:  To me, the type-specifier in front of a
handler in handler-bind is just a convenient abbreviation for a typep
test in the body of the handler, and should be semantically equivalent.
The fact that nested handler-binds are searched in the order of nesting,
not in an order based on type hierarchy, indicates that there is no
strong analogy to methods.

    ...He also punts the cluster if the handler
    simply returns and searches the next one. His comment on this line of
    code is

            (return nil) ;?

    I think this is wrong.

I agree.  Every applicable handler should get a chance to handle the
condition.  That's how the Symbolics condition system, which this proposal
is supposedly based on, does it, and no one has claimed that that is wrong.
I think that (return nil) is just a bug in Kent's model implementation.

    Lucid continues within the cluster, but in the
    same random order as Pitman's code would if the (return nil) were

I agree that Lucid's implementation is doing the right thing, and I
disagree with the judgement that the order is random.

    It is not specified what happens if handler-bind supplies two handlers
    for the same type. 

They should both run.  The effect should be the same as if there was one
handler with both bodies in it, connected with PROGN in the order written.
In my view 

  (handler-bind ((cond-1 #'(lambda (x) body-1...))
                 (cond-2 #'(lambda (x) body-2...))
                 (cond-3 #'(lambda (x) body-3...)))

is syntactic sugar for the semantically equivalent

  (handler-bind ((t #'(lambda (x)
                          (when (typep x 'cond-1)
                          (when (typep x 'cond-2)
                          (when (typep x 'cond-3)

    Same for handler-case.

This should be the same as a TYPECASE with duplicated clause keys.
The first of the two duplicates is reached, the second is unreachable,
and the compiler is justified in issuing a style warning.

In fact the semantics of duplicates are fully specified for handler-case:

  The cases are searched sequentially from top to bottom. If there is type
  overlap between the cases, the earlier of the two cases will be selected.

    It is also not specified what happens if restart-bind supplies two
    restarts with the same name (nil doesn't count). Same for
    handler-case. [I assume you mean restart-case]

Since restarts are objects and the name is just incidental, there is nothing
wrong or special about name duplications for restarts.  All the restarts
are established.  The order in which they appear in the result of
compute-restarts needs to be specified.  The only stuff I could find
relevant to this is:

  It is possible to have more than one clause use the same CASE-NAME.
  In this case, the first clause with that name will be found by
  FIND-RESTART. The other clauses are accessible using COMPUTE-RESTARTS.

The specification consistent with this is that compute-restarts lists
restarts in left to right order within a cluster and in inner to outer
order among clusters.  That's consistent with handler-bind's order too.

    I suggest ``unspecified'' for what happens in these cases.

None of these should be unspecified in my opinion.

    Date: Sun, 4 Jun 89 19:47:08 PDT
    From: Richard P. Gabriel <rpg@lucid.com>

    On further reading I see that handler-bind conditions are searched in
    left-to-right order, as is handler-case.  On further reflection, I
    think handler-case should do this, but not handler-bind, especially
    when there is the type-hierarchy-imposed order that is more
    interesting than left-to-right.  handler-BIND isn't especially
    reminiscent of <anything>-CASE.  Presumably implementations can
    CLOSize conditions using multiple inheritance, which makes this

There seems to be a line missing here.  I still maintain that the order
for handler bind should be the order that the programmer wrote, and not
anything derived from type hierarchy.  Do you agree or disagree?