StandardML is a very underrated language that was decades ahead of its time.
It's the pragmatic ML. Unlike Haskell, it believes in side effects, optional mutation, and eager evaluation, but within a type system that is much more sound than the ones used in any of the most common languages.
It was designed with students and student implementors in mind, so is quite easy to learn (and implement). Despite this, it has the potential to be very fast with MLton compiling fast code (I'd say about as fast as golang).
It's also interesting in being pretty much the only unpopular language with very good threading support. Perhaps this is due to academic use, but CML (or PolyML's version) are very powerful, but decently easy to use (and I'd consider them a straight upgrade from golang's version of channels).
If a major company invested in the SML ecosystem, it would take over the programming world.
> If a major company invested in the SML ecosystem, it would take over the programming world.
I like SML both out of nostalgia and for its actual merits, but I don't think that's true. SML was far ahead of its time, but it's showing its age now. Its simplicity is also correlated with an absence of handy features (e.g. ad-hoc polymorphism). Many companies invest in OCaml, which is slightly more crufty but with a (much) more healthy ecosystem, yet it hasn't taken over the world.
I do wonder what would have happened if SML had "won". In many ways it was pragmatically engineered in the early 90s, at a time where no other functional language was comparable (except maybe Caml). Its much-vaunted formal specification does leave a few pragmatics-shaped holes, however. For example, SML has no standardised way of splitting programs into multiple files. Each compiler does their own thing (although at least MLton and MLKit both support MLB files).
I think it's a pity that SML didn't take over the world, but these days, as an OCaml user, I'd rather see OCaml gain popularity. OCaml now is a lot more advanced and "modern", I think — GADTs, first class modules, etc. and there's a good LSP server, build system, and package manager.
SuccessorML is an ongoing work in progress. It looks to add (among other things) misc syntactic niceties (beginning | in matches, string interpolation, do notation, etc), builtin unicode support, and modular type classes for ad-hoc polymorphism (hopefully somewhat discouraging Haskell's typeclass soup).
We haven't hit the limits of what the language is capable of and a major investment would drastically speed up the process.
University Of Copenhagen who previously used SML for introductory programming courses (Now uses F#) have made a package manager for SML modules with MLB files: https://github.com/diku-dk/smlpkg
> If a major company invested in the SML ecosystem, it would take over the programming world.
I agree. I think about this a lot, and the hard part is that you need to either have an already existing ecosystem, or to have the resources to build one. If you want to leverage an existing ecosystem, the best bet would be Go I think, as .Net already has F#, Java has Scala (they are not the same but too close and would eat each other), JS has TS, some OCaml, Purescript. The other option could be to have an easy interop with Rust, as it's becoming quite big too, and perhaps fits SML more.
I'm a big fan of SML as well (I worked on a hobby compiler for SML, and I've written some programs in it).
Investing in the ecosystem (tooling, VSCode support, packages) would vastly improve it, but it still has some warts compared to Haskell - no ability to auto derive implementations (like debugging/printing structures!), and lack of typeclasses can be painful at times.
I really like Rust because of how similar it is to what I believe SML could be - just take away ownership and change the syntax, and bam!
As always, there's a good group of folks on reddit.com/r/sml and StackOverflow is surprisingly active as well (maybe due to the number of students still using Standard ML). There may be some good IRC channels but I'm not as familiar with them.
New functional languages emphasize current research, such as dependent types or algebraic effects, as if the best of the past has naturally been saved. Sometimes the best of the past gets forgotten.
I loved SML; a language designer would do well to internalize its module signature design. One wants to do at least this well, while incorporating current ideas.
I personally want to use SML as a base to develop a new language, one which eschew's side effects. Personally I think such a thing would be 100x more approachable than Haskell for newcomers, and could provide a basis for pure functional programming to make a significant impact on the industry.
The main thing that SML brings to the table IMO is its definition. This specifically forces things to be well-defined, and hence well-thought-out, and thus prevents the adding of a bunch of bad features that later need to be maintained for the lifetime of the language.
There are many areas in which I think formal methods are overkill, but PLs are one of the exceptions. Any mistakes early on in the language are usually VERY hard to resolve.
I'm curious about how your new language would work. From my (limited) understanding, the big differences between Haskell and SML are the type system and stictness/lazyness. I think a Haskell-like type system would be necessary if you want to eschew side effects (although I may be wrong), so the big difference would be that it's strict?
Flix might be this next ML. It is a new programming language with a Hindley-Milner type system notable for having effect polymorphism. It has an otherwise well-rounded design inspired by OCaml (among others).
Flix looks interesting, the Java interop seem to be a great feature too, but I'm wondering if they'll have traction. The JVM already has Scala, and while it's not exactly the same thing it will be "good enough" for most people. Considering Scala has usually lots of churn and already a split ecosystem, plus the upcoming transition to 3, it's going to be hard to find a place. Especially since Java itself is gaining pattern matching, records and the like.
So if I understand everything correctly effect systems are another way of encoding side effects into the type system? If so, why are they preferable to monads? That's the part I don't understand. For the strictness, I think now most people agree that a bit of lazyness is great when you need it (iterators, streams) but the vast majority of the language should be indeed strict.
> Maybe it'll even be named OCaml if the efforts to bring effect typing into it are eventually merged :-).
From what I read recently that's the plan, although they'll focus first on domains for 5.0, and merge the effects later.
Effect systems are both a runtime thing (similar to exceptions or lisp's conditions, in some sense), and a type-level thing (have a set of effects attached to an arrow, with type inference that is able to infer the effects and compose them nicely). Both are necessary for the future ML™, I think: the runtime part gives semantics to effects and composes super well (better than monad transformers, afaict: no need to `lift` everything); the typing part keeps the code honest. The effects also have to compose nicely with higher-order functions (so that `map` carries over the effects of its functional parameter).
> From what I read recently that's the plan, although they'll focus first on domains for 5.0, and merge the effects later.
Yes indeed! The timeline for typed effects is not clear to me, it might take a long time, especially with the stringent constraints of backward compatibility.
That said I'm not an expert, I'm just very hyped :-)
Thank you for the explanation! I feel like I understand this better now.
> The timeline for typed effects is not clear to me, it might take a long time, especially with the stringent constraints of backward compatibility.
From what I understand, the "long time" will be probably less than modular implicits, which are estimated at at least a few years away. There are a few informations here https://discuss.ocaml.org/t/multicore-ocaml-may-2021/7990 and here https://discuss.ocaml.org/t/multicore-ocaml-june-2021/8134, where at least we can see that the effect branch is up to date with 4.12. The performance seems really good, I can't find it anymore but they had the same performance as Go's net/http with http/af. It's a very exciting space!
the big issue is that you have to do a LOT of complex shuffling of types and values in order to deal with effects.
You can actually avoid a ton of this by thinking about purity in a less expression-level way, like how Koka does it. And, I think I'd probably try implementikng something like it (or eff) in my language.
You can always replicate laziness by making your own thunks. But this just isn't as convenient.
If you took SML and removed reference cells and the parts of the standard library that involve IO, then you'd have a pure language (depending on whether you consider exceptions to be effects). It would not be useful for application programming, but would be fine for teaching functional programming.
That's true. I think it also ties into best practices such as hexagonal architecture, DDD, and the "functional core, imperative shell" idea. You design the core of your program as data and pure functions, and then call that part from parts of the program that use IO. Maybe something like when scheme is used for teaching could work, with different "language levels", where some part disallow IO and reference cells. Or maybe a different file extension that's checked by the compiler to be pure. This could be a great way to teach functional programming but also software engineering.
It's the pragmatic ML. Unlike Haskell, it believes in side effects, optional mutation, and eager evaluation, but within a type system that is much more sound than the ones used in any of the most common languages.
It was designed with students and student implementors in mind, so is quite easy to learn (and implement). Despite this, it has the potential to be very fast with MLton compiling fast code (I'd say about as fast as golang).
It's also interesting in being pretty much the only unpopular language with very good threading support. Perhaps this is due to academic use, but CML (or PolyML's version) are very powerful, but decently easy to use (and I'd consider them a straight upgrade from golang's version of channels).
If a major company invested in the SML ecosystem, it would take over the programming world.