I try to compare use cases for using the “ocaml” version of ml versus the “standard” version of ml.
And what is best for writing error free code, without having to re-invent the wheel, and why ?
They’re great for educational purposes. But if you hope to use an ML in industrial/corporate/business setting, then OCaml is the best (and only viable) option.
There are also some mature and established tools like HOL which involve using Standard ML to good effect. But for general purpose programming, the practical activity is heavily centered around OCaml.
(I must admit that I do sometimes pine for a whole-program compiler with as aggressive a mindset as MLton, but whole-program compilers are fantastically hard to get to run in available memory.)
Some of the features SML# ships with are quite interesting. the most interesting of which IMO is what appears to be their ability to infer type variables at the right hand side of a function arrow. This helps a lot with using combinators under value restriction.
Maple is a parallelism-capable mlton fork with excellent performance
1ML is all about this cool concept of unifying records and modules
These are the most interesting to me, none of them are what I’d consider “best” at use-cases which may be comparable to OCaml. OCaml has many convenience features that advance beyond SML and has the benefit of much larger selection of libraries.
I’m so old I remember when it was the “Standard ML” variants (PolyML, esp. SML/NJ) that had the “industrial support” and caml-light was that weird French dialect that “wasn’t even standard (shudder)”.
My original reason for using caml-light was that the runtime was mad more memory-efficient than SML/NJ (and the Moscow ML folks basically capitulated on that); once caml-light got modules/functors, it was simply no contest, and the native-code compiler really did nail that coffin shut.
I guess the only reason I can think of for wanting to mess with SML/NJ, is if I wanted to do something like Concurrent ML, and wanted the proper “garbage-collects stuck threads” stuff that John Reppy implemented so long ago. From time-to-time I’ve wished for that, but not enough to go find an up-to-date SML/NJ distribution.
P.S. Until sometime in late 1991, I was a confirmed SML/NJ bigot; my conversion to caml-light was completely due to “gosh, I can run caml-light on 20+ machines in the lab, but SML/NJ only runs adequately on my boss’ fancy new workstation” (and of course, the languages were close enough that really, the work of porting massive amounts of code was no biggie).
I’m interested in how OCaml’s Event
module compares to a proper CML implementation btw, since you have the experience!
I haven’t digged into it for a long a time but I’m actually circling around it again for affect. The comparison is that OCaml’s Event
module synchronises system threads rather than lightweight runtime threads in CML. In CML you use a lots of threads to structure your concurrency and data structures but it’s rather impractical to treat system threads that way.
[I’m sure that @dbuenzli has better insight than I do; I haven’t looked at this issue for a few years]
The last time I used CML was in 1991, so I can’t say that I have anything concrete to offer. What I remember is this:
- John (Reppy) spent a lot of energy to make sure that “blocked threads that could never unblock” were GCed
- At least from a cursory inspection,
Event
doesn’t do this - But (IIRC) the implementation was meant as a demonstration, not as something to actually be used.
- When I was hacking on Golang, I remember that this issue came up there, also[1]: there were easy-to-arrive-at situations where you could have scads of threads that would never move again, but weren’t GCed.
The idea of CML is that (again, as @dbuenzli said) you use threads like they’re a cheap, cheap resource. Very, very fine-grained concurrency (I remember John Reppy’s demo of a bunch of floating heads in an X window, while something else was going on in some other window – everything proceeding concurrently). The idiom was that you simply didn’t worry about threads that wouldn’t proceed further, b/c they were just so much dead data, and the GC would pick them up and recycle them. Obviously, that’s an artifact of the implementation of CML, and if you don’t have it, you can’t use threads ad libitum: you have to actually care about them, make sure they never get “stuck forever”.
That’s really all I remember, sorry.
no worries, and thanks for sharing these stories, I absolutely love hearing about those early days.
OCaml and F#, yes. I do a lot of F#, but keeping an eye on the modernization of OCaml before jumping over.