Re: New draft (#8) and last call for comments on SRFI 255: Restarting conditions Marc Nieper-Wißkirchen (13 Dec 2024 20:16 UTC)

Re: New draft (#8) and last call for comments on SRFI 255: Restarting conditions Marc Nieper-Wißkirchen 13 Dec 2024 19:52 UTC

Am Fr., 13. Dez. 2024 um 20:16 Uhr schrieb Wolfgang Corcoran-Mathe
<xxxxxx@sigwinch.xyz>:
>
> On 2024-12-11 09:14 +0100, Marc Nieper-Wißkirchen wrote:
> > To simplify further, "with-current-interactor" could probably be
> > removed. The "current interactor" would then be like Chez's
> > "base-exception-handler". Indeed, it doesn't seem to make sense to
> > nest "with-current-interactor", so it should be part of the exception
> > system.
>
> It would indeed be nice to standardize the ‘base-exception-handler’
> parameter as an interactor. But it’s not necessary to do this in
> SRFI 255. The definition of interactors is useful and portable,
> so that programmers can use SRFI 255 even if their implementation
> doesn’t provide an interactive handler. If it does, they can ignore
> SRFI 255’s interactor forms without issue.
>
> So I’d like to put off specifying ‘base-exception-handler’ to another
> SRFI.

It can make sense to specify the base-exception-handler in its own
SRFI, but then SRFI 255 should be postponed until this SRFI (from now
on called SRFI 257) is done and then built on top of it. The procedure
"with-current-interactor" is not useful (or too limited, depending
from the point of view one takes).

The perceived problem that SRFI 257 could not be implemented fully
portably needs its solution in that SRFI. It should not make SRFI 255
more complicated than necessary. SRFI 257 can export
"base-exception-handler" as a parameter (taking the role of
current-interactor) and a hander "default-exception-handler", which is
the initial value of "base-exception-handler".  The only thing that
users of unsupported implementations will then have to do is to wrap
their code in "(with-exception-handler (lambda (obj)
((base-exception-handler) obj)) (lambda () <actual code>))".

Related to this is that the examples of "with-current-interactor" can
be misleading. One may think that at every critical place, one needs
to wrap with "with-current-interactor".

>
> > Maybe we can discuss this in detail if the other model is not chosen.
> > In general, having only a "who" and a "description" field is limiting
> > in any case. This may be sufficient information for some interactors
> > but not for all.
>
> Yes, but restarter fields aren’t a great place for information about
> the triggering exception. Let us say you want to present the message
> of the original condition to the user before a restarter is chosen. If
> this requires storing it in some restarter field, then which restarter
> gets it? There may be many. This message, moreover, is not specific
> to any particular restarter, but rather to the *event* which is being
> restarted. It’s natural to describe that event with a single, composite
> condition including the original condition and all available restarters.

A problem that hasn't occurred to me yet is that the original
condition that triggered the addition of a restarter should remove the
original condition from the compound. Semantically, adding a restarter
should mean that the condition is handled (unless the restarter with
tag "re-raise the condition" is invoked). If not, say, if an assertion
violation is raised, all procedure calls in the call stack that are
protected via "restartable" would present a restarter (even with the
same tag) to the user. In case of a deep recursion, this would also
make the interface unusable.

>
> > Accessing the condition does not help much because the final condition
> > object may not be related to the condition object that was present
> > when the restarter was added so the interaction with a particular
> > restarter should not depend on the final condition object.
>
> I’m not sure I understand this. I think you mean that the final
> condition could contain information that’s irrelevant to some of the
> restarters, or perhaps confusing. How would you prune it, then?

It could contain some irrelevant information; it could also have the
original information removed. It could be solved together with above
problem (of stacked restarters): When a restarter is added, the
(handled part) condition is removed (and saved in the restarter/in the
invoker closures).

Then there is a serious problem I haven't thought about before:
"define-restartable" kills all proper tail calls; if a procedure
protected by "define-restartable" is part of a recursive algorithm, it
will never tail-call. This is bad; it should be safe to replace
"define" with "define-restartable" without changing the semantics. I
have to think of a solution.

I have one more question: Can you explain why the
restarter-condition-predicate could be helpful?

Marc