[plt-scheme] Creating a suspended thread

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Apr 13 17:59:34 EDT 2009

At Mon, 13 Apr 2009 16:39:32 -0400, Marc Feeley wrote:
> Does PLT support SRFI 18? 

It seems that we don't. (Any volunteers to implement it?)

At Mon, 13 Apr 2009 16:43:03 -0400, Matthias Felleisen wrote:
> local comment: I don't understand why you lock the done-mutex twice.

You're not thinking low-level enough. :) It's to wait for one of the
threads to finish setting `x', after which it unlocks `done-mutex'.

> global comment: I'd program this kind of situation with cml-style  
> sync primitives (available in PLT Scheme) not with mutexes and an  
> imperative style.

Yes, I'd more likely write

 (define (amb thunk1 thunk2)
   (let ([ch (make-channel)])
     (let ([t1 (thread (lambda () (channel-put ch (thunk1))))]
   	[t2 (thread (lambda () (channel-put ch (thunk2))))])
       (channel-get ch)
       (kill-thread t1)
       (kill-thread t2)))))

and wouldn't think of putting the kills in the threads. Putting the
kills in the threads makes sense when you're locking a shared variable
with a mutex, but it doesn't seem natural with channels.

Actually, I'd more likely write

 (define (amb thunk1 thunk2)
   (let ([ch (make-channel)]
         [cust (make-custodian)])
     (parameterize ([current-custodian cust])
       (thread (lambda () (channel-put ch (thunk1))))
       (thread (lambda () (channel-put ch (thunk2)))))
      (channel-get ch)
      (custodian-shutdown-all cust))))

to clean up more consistently (in case the thunks themselves used this
`amb', for example). Interestingly, this implementation moves even
further from the mutual references.

So, I agree with Matthias which that we tend to use CML in a way that
makes state-sharing less common. Also, with most of the ways that we
use use threads, I think having to explicitly start each one would be
tedious. But the other abstraction is easy to build if you need it.

Posted on the users mailing list.