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

Error Proposal #5: difficulties and suggestions



I'm surprised there has been so little mail on this topic, which last
year was said to be something that was vital to standardize right
away.  I'd like to comment on two points in the conversation.  I hope
you'll forgive me for butchering the original text in order to gather
related conversations together and edit out irrelevant material.

    Date: Fri, 18 Apr 86 01:27 EST
    From: Kent M Pitman <KMP@SCRC-STONY-BROOK.ARPA>

	Date: 16 Apr 86 13:15 PST
	From: Daniels.pa@Xerox.COM

	Proceed functions appear to serve two purposes: they are a repository
	for default information for that proceed type (test, report,
	parameter-gathering), and they provide a simple way to find and invoke
	proceed cases. These two functions are somewhat at odds with one another
	when you are invoking a proceed case from an interactive debugger. In
	this situation, the user has picked a particular proceed case that
	should be invoked, so the obvious thing to do is call
	INVOKE-PROCEED-CASE. Unfortunately, this will not use the
	parameter-gathering mechanism specified in the proceed function. If
	instead you see if there is a proceed function defined for that proceed
	case and invoke it to get the parameter-gathering done, the proceed
	function can end up invoking the wrong proceed case if there are others
	with the same name that are more recently bound.

	To fix this problem I propose giving proceed functions another implicit
	parameter, PROCEED-CASE. If this is NIL then the proceed function
	behaves as it does now: it finds the most recently bound proceed case
	with that name and invokes it. If a proceed-case is supplied, it will
	invoke that one specifically if it is currently enabled.

	I just haven't been able to find any good place
	to put it. The obvious place is after the implicit condition argument.
	The problem I have with that is that almost all callers of proceed
	functions will be condition handlers, and it seems like a nuisance to
	have to always put in an extra NIL, like in (USE-VALUE CONDITION NIL
	NEW-VALUE).

    Ugh. I understand the problem. I'll have to study the syntax of 
    this implicit parameter idea and get back to you. I'll note just
    for fun that you could do something like the following....

I think you're both standing on your head to find some indirect way to
do this.  Why not just tell the computer directly what you want?
(PROMPT-AND-INVOKE-PROCEED-CASE proceed-case condition) would be a
reasonable syntax to say "prompt the user for the arguments to this
proceed case and then invoke it."  But let's look a little more
carefully at what you're asking for.

The exact division of labor between language (standardized) and
environment (not standardized) could be improved here.  There are three
basic mechanisms: selecting a proceed case, gathering arguments to it,
and invoking it.  Only two of these three operations were provided as
separate primitives in Kent's proposal.  To make the set complete, you
need something like (READ-PROCEED-ARGUMENTS proceed-function-name
condition).  Perhaps the first argument should be proceed-case.

In addition to the primitives, for convenience facilities that package
together several primitives should be provided.  Calling a proceed
function packages all three together.  PROMPT-AND-INVOKE-PROCEED-CASE
would package two of them, but leave selecting the proceed case to its
caller.  Other packaged facilities, such as the debugger itself, aren't
explicitly part of the language.

    Date: 16 Apr 86 13:15 PST
    From: Daniels.pa@Xerox.COM

    I believe there should be a way to set default handlers, report
    methods and default tests for proceed cases other than redefining the
    object in question. This isn't a big deal, but it does provide the user
    some flexibility. This can cause problems if you're depending on default
    handlers to ensure that SERIOUS-CONDITION ends up in the debugger if it
    isn't handled, but I'd rather handle that directly in the code. That is,
    ERROR always calls debug after signalling the condition and SIGNAL calls
    debug after signalling if the condition is of type SERIOUS-CONDITION. 

    I was suggesting that SIGNAL check the
    type of the condition it signalled and go to the debugger if it was a
    SERIOUS-CONDITION instead of depending on a default handler to do it.
    Then there wouldn't be any fundamental problem with allowing a user to
    change a default handler on the fly.

There is a significant confusion about default handlers here and in Kent's
proposal.  The problem is the idea there is only one default handler for
a given condition, and defining a new default handler replaces any old one.
This is contrary to the idea of conditions, which is that when an exceptional
event happens the condition system searches the environment and gives all
interested parties a chance to try to do something about it.

I think the :HANDLE option to DEFINE-CONDITION should be removed.  Instead
default handlers should be defined by

(DEFINE-DEFAULT-CONDITION-HANDLER name-of-handler
				  condition-type-or-list-of-types
				  argument-list
   body)

Executing this form replaces any previous default-condition-handler
named name-of-handler, regardless of what condition it was for, just
like executing a DEFUN with the same name as a previously-defined
function.  When a condition is signalled and all bound handlers decline,
all default handlers whose condition-type-or-list-of-types matches
the condition get a chance.  Unless someone has a better idea, it is
an error to depend on the order of invocation of default handlers.

This way the user can define all the default handlers he wants without
unintentionally damaging the built-in ones on which the system's correct
functioning depends, just as the user can define all the functions she
wants without unintentionally damaging the built-in ones.

I don't think defining the :TEST or :REPORT for DEFINE-PROCEED-FUNCTION
separately from doing the DEFINE-PROCEED-FUNCTION makes as much sense.
Do you have examples of how this would be used?