On Fri, Sep 30, 2022 at 4:07 PM Marc Nieper-Wißkirchen <
[email protected]> wrote:


>
>> 1. I strongly recommend that a faithful implementation of CL's
>> `unwind-protect` be added to this SRFI.  Scheme programmers have a tendency
>> to treat `dynamic-wind` as if it served the same purpose, which it does
>> not; making it available under its own name will encourage its proper use.
>> The definition is available at <http://clhs.lisp.se/Body/s_unwind.htm>.
>>
>
> I have never taken a look at CL's `unwind-protect`.  You seem to imply
> that it is different from a `dynamic-wind` without a BEFORE thunk.  Can you
> explain the purpose/mechanics of `unwind-protect`?  I can then add it.u
>

See Kent Pitman's note at <
http://www.nhplace.com/kent/PFAQ/unwind-protect-vs-continuations-original.html>
and Dorai Sitaram's paper at <
https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.79.3107&rep=rep1&type=pdf>.
The general idea is that any exit from the main thunk causes the
after-thunk to be executed once and only once.  The paradigm case is
opening a file in the main thunk and closing it in the after-thunk.


> Instead of returning a thunk that raises an error, we could also specify
> that #f is delivered as a "thunk" instead.  Calling #f would also raise an
> error, but it would also enable to use this particular iterator protocol
> for lists that contain the value #f (not relevant here, but possibly
> somewhere else).  What do you think?
>

It's a less specific error: "#f is not a procedure" is mysterious compared
to "attempt to iterate the empty list".  I recommend that a general version
of iterators return a Maybe as well as the next iterator.


> 3. I recommend switching timeouts from seconds to jiffies, so as to
>> maximize the use of cheap fixnum arithmetic.  Exact integers are real, of
>> course, but a second is a long time.
>>
>
> Technically, I agree entirely.  This would, however, produce an
> incompatibility with SRFI 18 that may be hard to detect (because the types
> are not disjoint).
>

I agree: silent breaking changes (even in another package) are Bad Things.
Concedo.


> 4.  I don't think that &thread-timeout is necessarily an &error or even
>> &serious; for example, you may be running a background thread to do work
>> for a while, but want to cut it off if it runs too long.  It should be a
>> direct subtype of &condition.
>>
>
> I have to think about it.  Wouldn't your reasoning apply to
> `&uncaught-exception` and `&thread-already-terminated` as well?  From the
> definition of the conditions in R6RS, `&serious` seems to be a better fit
> than `&error`.
>
> Looking at it from a different perspective: What could go wrong if we left
> it as is?
>

The CL definition of `serious-condition` (CL is the source of much of the
R6RS hierarchy) says: "All conditions serious enough to require interactive
intervention if not handled should inherit from the type
serious-condition."  But whether this is true of any of these three
conditions (I only noticed &thread-timeout, but you are right that the same
logic applies to all) is implementation-dependent.

Whether this makes a difference depends on the behavior of the primordial
exception handler.  If there is a debugger, the primordial handler should
always invoke it if the condition is serious; a non-serious condition,
however, might simply be logged and the program continued.

Editorial note: &uncaught-exception-error -> &uncaught-exception.  There
may be other mistakes of this type.


> A thread runner is a procedure that takes one argument, a thread.  When a
> thread runner is called with such an argument, the thread is registered
> with the thread runner.
>

It is not clear what should happen if a thread is registered with more than
one thread-runner.  Tying the thread's creation to a specific thread-runner
avoids that problem, although if the thread were marked as being registered
or unregistered that would work as well.

> (This works well because the creation and the start of threads are
> separated.)  When the thread runner is called with no argument, we could
> make it unregister and return an arbitrary thread it holds.
>

This defeats the scoping for which thread-runners were devised.  However,
the concerns could be separated by providing (register-thread thread-runner
thread), which fails if the thread is already registered, as well as
(with-thread-runner proc).


> The dynamic environment holds the current exception handler (according to
> the Scheme reports); it is not part of the parameterization, though.
>

Fair enough: in this case, that should be noted in the SRFI.

> I don't think this incompatibility is a big problem as we already have the
> incompatibility in the dynamic environment, in which a promise is forced.
> I propose something like `(scheme promise)` and deprecating the old
> `(scheme lazy)`.
>

Concedo.

Reply via email to