[racket] Places, Channels as Events. Labeling Places.
At Fri, 14 Dec 2012 09:15:48 +0100, Tobias Hammer wrote:
> On Fri, 14 Dec 2012 07:25:36 +0100, David T. Pierson <dtp at mindstory.com>
> wrote:
>
> > I've wondered about this. What is the rational behind these
> > differences? Wrapping events is cumbersome.
> >
> > For instance, my first intuition is that the synchronization result of a
> > place channel would be the place channel itself, just like the
> > synchronization result of a thread is the thread itself. Why aren't
> > these analogous?
>
> I would guess it prevents race-conditions. Channels and place-channels may
> be accessed from any number of threads, and therefore it would be possible
> that the data on the channel is removed between the sync and the
> *-get-call. Thread channels are different in that it's guaranteed that
> only one thread can access them.
> Input-ports for example suffer from these races and the user has to make
> sure to prevent or handle the them correctly.
Right.
I'll add that the intended pattern is not
(define r (sync
(handle-evt e1 (lambda (v) (cons 1 v)))
(handle-evt e2 (lambda (v) (cons 2 v)))))
(match r
[(cons 1 v) ... handle e1 result ...]
[(cons 2 v) ... handle e2 result ...])
but instead
(sync
(handle-evt e1 (lambda (v)
... handle e1 result ...))
(handle-evt e2 (lambda (v)
... handle e2 result ...)))
This pattern works even if you want to continue a loop after handling
an event, since the function in a `handle-evt' is called in tail
position with respect to the `sync'.
The Guide needs a chapter on concurrency. Racket's approach to
synchronization is from Concurrent ML, so if you're interested in the
design rationale, then see _Concurrent Programming in ML_ by John
Reppy. Some examples in Racket notation can be found in a paper about
"kill safety": http://www.cs.utah.edu/plt/publications/pldi04-ff.pdf