Any Rust implementations of Concurrent ML?

Hi Rust folks,

Sorry if this has been answered already, but I tried searching the forum and didn't find anything. Are there any implementations of Reppy's Concurrent ML for Rust floating around out there on the interwebs? I am doing a research project focused specifically on trying out Concurrent ML for something it hasn't been applied to before (to the best of my knowledge).

I would really like to include Rust in the group of languages that I am testing, but it looks like so far the closest that Rust gets is the Crossbeam-Channel crate. It's most of the way there in that it has channels and selection over those channels, but doesn't appear to provide any of the combinators that are a key aspect of Concurrent ML.

If anyone is curious, there aren't many active languages out there that come with something similar. The most notable right now would be probably OCaml, which a CML implementation in its Event module. The next most notable is perhaps Racket's Events (but see also Guile Scheme's Fibers library). After that, the only two others I'm aware of are Manticore and MLton (well, technically Standard ML too, but I think there's much more work goes into Manticore and MLton these days). There was also Hopac in F#, but it's more-or-less unmaintained these days.

I would consider trying to create a CML implementation for Rust myself, but that's a bit out-of-scope for my current work, and would probably take time I can't really spare right now. Please let me know if you are aware of a Rust implementation :slight_smile: (also, feel free to ask about Concurrent ML too, not that I'm anywhere close to an expert in the slightest) Thanks!

1 Like

It would help if you said what specifically you need in order to include Rust in your test. You mentioned combinators, but that isn't particularly specific. Maybe going into more detail on what it is you're testing would help.

The particular application is in Computer Vision, but the relevant aspects are CML's concepts of Events, and the functions that apply to them. It might be worthwhile taking a look at OCaml's, Racket's or CML itself's listings of relevant types and functions to get some more idea of it.

Essentially, an event creates a value on top of a send or receive over a channel, where said value represents the possibility of the send or receive operation (it's a quite like a future or promise in this regard). One can then synchronise (i.e. await) on this event to make it happen. The combinators allow one to compose different events together, as well as ensure that certain operations happen immediately before or after the message is passed on the channel, as well as providing some capacity for cancelling operations that are no longer needed. Furthermore, Concurrent ML's selection capabilities select over various events, rather than just exchanges over channels.

It is these extra elements that are of interest for me right now, as I'm specifically investigating how well they work for the Computer Vision task I'm looking at. So, at a minimum, what I would need is some way to create these event types over the top of the channel synchronisations, and select across them in much the same way normal select does over channels, and the guard and wrap functions, which arrange some computation to take place respectively before or after the synchronisation.

Does that help to clarify things?

As an aside, Aaron Turon's Reagents were (to my understanding) partially inspired by CML.

Oh, also, just in case it sounded like it to anyone (I just realised it could), I wasn't meaning to criticise Crossbeam at all! It's a great set of libraries, but so far as I can tell they just weren't created with this particular idea in mind.

Perhaps you are looking for Rust's futures? You can .await them to wait for them, and you can combine two futures with either join or select to wait for several futures in various ways.

Additionally you can consider the async-enabled channels as a stream, which you can put combinators on, e.g. you can map() a stream to receive modified items from the stream.

1 Like

I'm not real familiar with CML, but looking at Reppy's cml implementation in smlnj svn,
one of the things that sticks out is in event-sig.sml there is a field
wrapHandler : ('a event * (exn -> 'a)) -> 'a event,
and in rep-types.sml in the thread_id type exnHandler : (exn -> unit) ref,

which makes me think that there might be usage of exceptions as control flow going on.
given rusts lack of exceptions it might not be straight forward to do a direct 1:1 port of cml.
Anyhow, I don't know it is just what sticks out to me as a potential hurdle.

2 Likes

:thinking:

That definitely looks quite similar in many respects to CML (I haven't kept up at all with Rust's futures these days). I might just be able to use Futures & Crossbeam to achieve what I'm looking for - I'll have to look into it in more detail. Thanks for the suggestion, @alice :slight_smile:

You could be right, I'm not overly familiar with the guts of the implementation. That being said, I think other implementations have been able to achieve the requisite effects without exceptions, so I believe it is possible - though, like you said, it probably wouldn't be an exact replication. Still, I don't think that the handlers are strictly part of the 'user interface' part of CML, so it should be fine to change the background implementation so long as the main functions still do their normal thing.

Even if I can't work with Rust for my current project, I definitely would like to come back and have a go at implementing CML for it in the future (assuming nobody else does it first) :smiley: