New draft (#2) of SRFI 226: Control Features Arthur A. Gleckler (10 Sep 2022 01:26 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (30 Sep 2022 07:32 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (30 Sep 2022 19:15 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (30 Sep 2022 20:08 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (30 Sep 2022 21:22 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (01 Oct 2022 13:14 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (01 Oct 2022 18:56 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (01 Oct 2022 21:10 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (03 Oct 2022 11:39 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (03 Oct 2022 13:21 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (03 Oct 2022 14:59 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (07 Oct 2022 16:22 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (07 Oct 2022 21:36 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (08 Oct 2022 00:13 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (09 Oct 2022 16:07 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (09 Oct 2022 20:30 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (10 Oct 2022 06:26 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (10 Oct 2022 16:48 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (12 Oct 2022 06:27 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (13 Oct 2022 00:02 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (13 Oct 2022 06:40 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (13 Oct 2022 15:31 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (13 Oct 2022 15:51 UTC)
Re: New draft (#2) of SRFI 226: Control Features Arthur A. Gleckler (30 Sep 2022 23:35 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (27 Oct 2022 06:01 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Feeley (29 Oct 2022 02:54 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (29 Oct 2022 08:13 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Feeley (29 Oct 2022 12:49 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (29 Oct 2022 13:49 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (29 Oct 2022 18:49 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (03 Nov 2022 17:02 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (04 Nov 2022 19:54 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (29 Oct 2022 15:38 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (29 Oct 2022 16:31 UTC)
Re: New draft (#2) of SRFI 226: Control Features John Cowan (29 Oct 2022 21:52 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (30 Oct 2022 08:35 UTC)
Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen (28 Oct 2022 15:17 UTC)

Re: New draft (#2) of SRFI 226: Control Features Marc Nieper-Wißkirchen 29 Oct 2022 08:13 UTC

Am Sa., 29. Okt. 2022 um 04:54 Uhr schrieb Marc Feeley
<xxxxxx@iro.umontreal.ca>:
>
> > On Oct 27, 2022, at 2:01 AM, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote:
> >
> > I am also still hoping for a reply from Marc in the discussion about
> > "weak threads".
> >
> > [...]
>
> Sorry for not getting back sooner.  I have continued my reading of the SRFI 226 spec.  Unfortunately my time is still constrained and the spec is huge so my comments are bound to be more superficial than I’d like.  Here's what stands out.

There's no need to apologize. I am very grateful to all that take the
time to read and think about the specification.

> (call-in-continuation cont thunk) misses an opportunity of having the more general form (call-in-continuation cont proc arg1...) so that it can be called with a procedure and as many arguments as needed.  Instead of (call-in-continuation k (lambda () (values tmp ...)) you could write (call-in-continuation k values tmp ...).  See the definition of the continuation-graft form that you cite:

I will generalize call-in-continuation in this respect.  Thank you for
the suggestion.

[...]

> Note also that one of the main points of the "Better API" paper is to treat continuations as a specific type different from procedures so that the burden of the procedure representation can be avoided (conceptual and also run-time cost for creating the procedure), and also have other operations such as (continuation? obj), (continuation-length k), etc.  I view "continuations as procedures" to be a historical blunder that was motivated by CPS style.  If you have ever tried to explain how call/cc works to students you will probably understand what I'm talking about: "call/cc receives a procedure and calls this procedure with a procedure that represents the continuation".  Too many procedures for most students.  With SRFI 226 there's an opportunity to correct this by making (call-with-non-composable-continuation proc) call proc with a continuation object that is separate from procedures.  It changes very little to the API, except that those continuations have to be called with (call-in-continuation k values ...) or some new more specific procedure (return-to-continuation k ...).

From a theoretical point of view, I agree with you, and I also see the
point of teaching.  For historical reasons (call/cc), however, I would
like to leave the API as is. Given the presence of call/cc and
existing code, I feel that introducing a new, theoretically more
appealing approach while the historical one is still there leads to
its own share of problems and confusion.

If you want, you can view a continuation (as created by call/cc) as an
element of a new abstract datatype, which, however, happens to be
callable.  To enforce this point of view, SRFI 226 has introduced the
procedure `continuation?`, which checks for whether an object is a
continuation.

> Concerning (thread-terminate! thread), the part "the current thread waits until the termination of thread has occurred" is not ideal.  This was also specified by SRFI 18, and it is OK in a single processor system (because the scheduler is centralized), but I now think it causes issues in a multiprocessor system because it is impossible to predict how long the wait might be.  It is better to have an asynchronous termination, and to use (thread-join! thread), possibly with timeout, when it is necessary to ensure the thread has terminated before proceeding.

I see your point. And adding an extra timeout parameter to
thread-terminate! would make the interface more complicated. The only
problem I see is that this change would introduce a silent
incompatibility with SRFI 18.  Thus, it may be better to drop the name
thread-terminate! and replace it with a different name, like
thread-kill!.

> An alternative to thread-terminate! that is similarly powerful and more elegant is to have an asynchronous (thread-interrupt! thread thunk) procedure that causes thunk to be called at a safe point at the current point of execution of the target thread.  The thunk could then call raise or abort-current-continuation to terminate the thread “from within”, allowing the target thread to do some cleanup.

I don't yet see how this is equally powerful.  What I have in mind is
an implementation of a Scheme REPL where the user starts a program (in
some thread) that goes astray and wishes to abnormally terminate it.
This must work with no cooperation from the program thread.  Raising
an exception or aborting a continuation doesn't necessarily do it.

Also, thread-interrupt! breaches abstraction barriers. Given the code
(begin foo1 foo2) and assuming that evaluating foo1 does not raise any
exception (nor invokes a previously captured continuation), there is a
guarantee that foo2 will always be evaluated once after foo1 (bar
abnormal termination).  Now, using thread-interrupt!, one could
capture a continuation between evaluating foo1 and foo2 and using it
to break the invariant.

> Concerning the addition of (mutex-owner mutex) as a companion to (mutex-state mutex), this has introduced a race condition.  If (eq? (mutex-state mutex) 'owned) is true then extracting the owner thread with (mutex-owner mutex) may return #f.  The API of the SRFI 18 (mutex-state mutex) was designed to not have this race condition.

Yep. I somehow had in mind to query mutex-owner and mutex-state the
other way around, but this actually has the same problem.  Working
around this problem would need unpleasant looping.

I will revert it to the SRFI 18 API or something equivalent.

> The mutex-unlock! procedure's parameter list does not have a timeout parameter, but the description talks about that parameter.  Timeouts are important on all blocking operations.

Indeed.  This oversight has already been reported by Shiro and fixed
in my personal repo.

> The section on thread locals is rather vague and unconvincing.  The thread-specific field has been removed because "If these are needed, weak hash tables could be used instead." but the same can be said for thread locals which are a thin wrapper around weak hash tables indexed by thread.  The point of thread-specific was to have constant time (with small constant) access to thread specific data.

Thread locals are natively supported on, for example, POSIX or C11
platforms, thus it makes sense for efficiency reasons to provide them
as a primitive.  The thread-specific field of SRFI 18 has the problem
that it really needs another high-level API to administer it.  On the
other hand, weak hash tables compose well when several libraries in a
program need thread-specific fields.

There is another difference between thread locals and the
thread-specific field: A thread local is really local to the current
thread and a thread can only query its own copy of the value, while a
thread-specific field can be queried for any thread.  Of course, a
high-level API can provide the respective abstraction.  But even then,
a program could break this high-level API by accessing or mutating the
thread-specific field through direct access.

Note that SRFI 226 does not forbid the "specific" fields; an
implementation is free to provide them as an extension.  The usual
data types do not have "specific" fields (e.g. there is no
hash-table-specific), so there are no fundamental reasons why mutexes,
etc., should have specific fields.  One should use wrapper objects
instead.

The latter is a bit different for thread objects because they are
returned by procedures in the SRFI 18/226 API, and the API won't
return wrapper objects.  Still, a single specific field can only be
application specific, not library-specific.  Thus weak hash tables are
the better solution.  If you can think of an even better approach, I
would like to hear about it.

> I’ll have to address weak threads at some other time… (and also the initial continuations section which I have to read carefully).

I am looking forward to reading your comments.

Thanks again,

the other Marc