I cam across this thread last year (or maybe the year before?
) while looking up CML, and I’ve been wanting to reply for a little while because I think CML is pretty cool! There isn’t much information online about its usage [1] so I don’t know how idiomatic my usage is, but I can take a stab at the question at least.
There are basically two different concurrency models provided out of the box with CML (although Futures/Promises can be implemented on top): CSP Channels (which seems to be used in Go?) and Actor Model Mailboxes (Erlang, Elixir, etc.).
The main difference I’ve seen is that “receive message” and “send message” operations block when using Channels. When trying to send a message to a Channel, the calling thread will block until another thread reads the message; when trying to read a message, the calling thread will block until another thread send a message to this channel.
The Mailbox only blocks on the “receive” operation by default (although there is a function to receive a message option
, which doesn’t block and returns SOME message
if there is a message to be read or NONE
otherwise).
If you wanted non-blocking IO, you could send a message (probably an ADT or record with fields like which file path to save to and what string contents to save) to a Mailbox. The main thread won’t wait for the Mailbox to perform the IO before continuing to execute the rest of the program.
I think there is some (limited?) form of process supervision in this module but I’ve never had a need since I’ve only been developing locally-run GUI programs with it (not as excited about building web services even though Go and Elixir/Erlang specialise in them; sorry
).
I usually stick with Mailboxes since I don’t want/need the blocking that comes with Channels, but the main concurrency model people seem to care about when it comes to CML is overwhelmingly CSP/Channels. Michael Sperber mentioned in a talk that only Channels are composable (and John Reppy’s book focuses mainly on them), Andy Wingo wrote that Channels are strictly more expressive, and the Racket documentation on concurrency talks about its inspiration from CML Channels but doesn’t mention Mailboxes at all.
I have some simple code I can go through to explain how CML informs my programs’ basic architecture, but I’m not sure if anyone would bother to read if this message was too long. 
[1] There is John Reppy’s book on Concurrent ML which I’ve not read, as well as this PDF from 2002 which contains a section on CML and this other 2002 PDF which focuses on it, but I’ve spent little time with any of these.