Thoughts on Standard ML as of 2023

Today marks one week since I started writing some Standard ML1 and I’d like to share some thoughts I’ve had during my journey. I should begin by addressing the standard (🥁) question people ask: “Standard ML, really? Why?!”. Well, there are a couple of reasons for that.


This is a double-edged sword, indeed. While offering a lot of stability over the whole ecosystem, it also slows down progress2 a bit (my opinion). Now, while I write my code, this has been a blessing. You have 40 years of code to run and you know that most of it will Just Work ™️.
Type System
Although not being a Type System aficionado myself, I’m really enjoying my $CURRENT_JOB writing F#. It has the best type system I have had the pleasure to work with. Standard ML has an even better type system and a better scenario regarding type inference (less typing!). This is noteworthy considering my primary experience lies in Python, Go, and Clipper. I believe this comparison alone speaks volumes.
Small ecosystem
Look at it yourself on some of the biggest forges: GitHub and sourcehut. Considering your goal, this might be a showstopper. However, I really like writing libraries and tooling in general, making this a huge plus.
Small language
This is topic is highly subjective. I mean, to the point of starting a war. Still, I personally consider Standard ML to be small and concise enough. When working with it, the syntax does not “slip your mind” and while possible, most people don’t implement a domain-specific language based on custom operators. It reminds me of Go in the sense that reading code is straightforward, and writing it doesn’t demand extensive symbol recollection (it does trade terseness for verbosity).

From zero to action

🗒️ Note that some of this might be easier or harder if you are not a Nix user.

How does it look like to start writing Standard ML nowadays? While you don’t really have powerful IDEs and a multitude of tools such as linters and debuggers, you can still go really far.

There’s the helpful #sml channel on Libera Chat, Project Savanna’s Discord server (mostly focused on tooling) and there’s also the r/sml subreddit.
Editor support
You can use the amazing language server for Standard ML called Millet. It works just fine with Emacs’ eglot and Millet also provides a Visual Studio Code extension that works without requiring any configuration.
Compilers and build systems
While installing a compiler is as easy as adding a new line on my devShell (see below), working with multiple compilers can be tricky. The most known, being MLton and SML/NJ, use different build systems. The former using MLBasis (.mlb) and the latter using Compilation Manager (.cm). For the time being, my solution has been to support both build systems, each on a separated file.
mkShell {
  buildInputs = with pkgs; [
    mlton smlnj

What I like and what I don’t

It is old and it shows
Can you imagine working without proper UTF-8 or Unicode support? You better prepare yourself to that surprise. There’s some discussion around this on Successor ML. Also, I’m not sure why, but makestring was removed from the standard. This leaves you without a polymorphic “print” function3, it’s quite hard to debug programs without this.
Type inference
Coming from F#, I used to think its type inference was good… Boy, was I wrong! Do I miss SML’s type inference when writing F#. It’s really hard to explain the experience to someone that never had contact with this kind of type inference.
The most known compilers are awesome (MLton and SML/NJ), they are quick to compile code and compile to fast native binaries. Honorable mention to SOSML, that allows you to write Standard ML on the browser.
Package manager
There’s a great question on Stack Exchange about ML-like modules and package managers and you should probably read it. There are two main package managers: Smackage (which seems to be more of an installer than what I’m referring to) and smlpkg. While I haven’t used none of them, there’s nothing like cargo or npm with a public registry and standardized manifest.

  1. I intend to write more about the challenges I faced with this project. ↩︎

  2. Check Successor ML to see more. ↩︎

  3. Poly/ML exposes a function that does just that: PolyML.print. The problem now being tied to a single compiler… ↩︎

Articles from blogs I follow around the net

The four tenets of SOA revisited

Twenty years after. In the January 2004 issue of MSDN Magazine you can find an article by Don Box titled A Guide to Developing and Running Connected Systems with Indigo. Buried within the (now dated) discussion of the technology…

via ploeh blog March 4, 2024

Building a demo of the Bleichenbacher RSA attack in Rust

Recently while reading Real-World Cryptography, I got nerd sniped1 by the mention of Bleichenbacher's attack on RSA. This is cool, how does it work? I had to understand, and to understand something, I usually have to build it. Well, friends, that is what…

via blog March 4, 2024

How to unbreak Dolphin on SteamOS after the QT6 update

A recent update to Dolphin made it switch to QT6. This makes it crash with this error or something like it: dolphin-emu: symbol lookup error: dolphin-emu: undefined symbol: _Zls6QDebugRK11QDockWidget, version Qt_6 This is fix…

via Xe Iaso's blog March 3, 2024

Generated by openring