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.
