\( \DeclareMathOperator{\tr}{tr} \newcommand\D{\mathrm{d}} \newcommand\E{\mathrm{e}} \newcommand\I{\mathrm{i}} \newcommand\bigOh{\mathcal{O}} \newcommand{\cat}[1]{\mathbf{#1}} \newcommand\curl{\vec{\nabla}\times} \newcommand{\CC}{\mathbb{C}} \newcommand{\NN}{\mathbb{N}} \newcommand{\QQ}{\mathbb{Q}} \newcommand{\RR}{\mathbb{R}} \newcommand{\ZZ}{\mathbb{Z}} % For +---- metric \newcommand{\BDpos}{} \newcommand{\BDneg}{-} \newcommand{\BDposs}{\phantom{-}} \newcommand{\BDnegg}{-} \newcommand{\BDplus}{+} \newcommand{\BDminus}{-} % For -+++ metric \newcommand{\BDpos}{-} \newcommand{\BDposs}{-} \newcommand{\BDneg}{} \newcommand{\BDnegg}{\phantom{-}} \newcommand{\BDplus}{-} \newcommand{\BDminus}{+} \)
UP | HOME

Implementations - SML

Table of Contents

This is just a cursory "How to build [SML implementation] on Raspberry Pi" post.

1. Moscow ML

This is the easiest implementation to build, if you have a C compiler available. The homepage has some documentation, and you ultimately just need to clone the github repo.

Moscow ML has about half of the Standard Basis library implemented. It's missing about 8 required signatures and 5 required structures (possibly more). So if you want to implement anything involving floating-point arithmetic, or certain tricky IO code, then you are in trouble.

Unfortunately, the documentation is a little out of date. My experience has been the following works:

~$ git clone https://github.com/kfl/mosml/
~$ cd mosml
~/mosml$ cd src
~/mosml/src$ make
...
~/mosml/src$ sudo make install

This will install mosml to /usr/local/bin/ and all the libraries are placed where needed in the /usr/local/ prefixed directories.

Note: You may need to update Max_stack_size in mosml/src/runtime/config.h. Some people need more, but I never needed that much memory.

2. Poly/ML

This seems to work fine. If you have a 32-bit ARM computer, then it will simply compile bytecode, which will run considerably slower. The basic steps seems to be:

~/src/$ git clone https://github.com/polyml/polyml.git
~/src/polyml/$ cd polyml
~/src/polyml/$ ./configure
~/src/polyml/$ make
~/src/polyml/$ make compiler
~/src/polyml/$ sudo make install

It may be worth considering upgrading to a Raspberry Pi 3B+ or 4, since Apple has transitioned to 64-bit ARM (we will end up piggie-backing off opensource projects transitioning to support 64-bit ARM).

Note: since commit 15c840d4, the ARM64 performance has improved drastically.

3. MLton

This needs an existing SML compiler for the bootstrap process.

I think make polyml-mlton may work as well. Although the make bootstrap-polyml command may be the intended command.

I have tried make MLTON_COMPILE_ARGS="-codegen c" all. I think -codegen llvm may produce better results?

It seems a better approach may be to cross-compile MLton on another computer. Basically, on my x64 machine with 12GB of RAM, I ran the following:

alex@x64:~/src/$ git clone https://github.com/mlton/mlton
alex@x64:~/src/$ cd mlton
alex@x64:~/src/mlton/$ make
...
alex@x64:~/src/mlton/$ make REMOTE_MACHINE=alex@raspberry.local remote-bootstrap
...

If you do this, you might want to have your pubkey on your Raspberry Pi, otherwise you'll end up logging in several dozen times over the course of an hour or so. But it works! (I learned about this REMOTE_MACHINE trick from github issues.)

Well, right now, it breaks on the $(MAKE) remote--make-all step for me (c.f., steps in the remote build process).

In fact, you might want to run scp ~/.ssh/id_rsa.pub alex@raspberrypi.local:.ssh/authorized_keys to avoid signing in repeatedly. And if you don't have an RSA key, you might want to follow these instructions.

3.1. On Raspberry Pi

This is actually harder than I realized to get this working on a Raspberry pi 4. What I ended up doing is modifying my /etc/apt/sources.list to include a Debian repo, then I was able to sudo apt install mlton. (There is some trickiness here, with pubkey errors.) I then used this to compile MLton from scratch.

Another caveat is that this will run into problems if your /boot/config.txt includes the line specifying it to run in 64-bit mode. In fact, this borked my installation, and I had to reinstall Raspbian lite.

3.1.1. Remote Compiling

The exact failure is during the remote--make-all step:

Compiling mlton
"/tmp/mlton-20210117.153942-gb1f1f0f09/boot/bin/mlton" \
	@MLton ram-slop 0.7  gc-summary -- \
	 -verbose 2 	\
	-target self -output mlton-compile			\
	mlton-stubs.mlb
MLton 20210117.153942-gb1f1f0f09 starting
   Compile SML starting
      frontend starting
         parseAndElaborate starting
make[2]: Leaving directory '/tmp/mlton-20210117.153942-gb1f1f0f09/mlton'
Segmentation fault
make[2]: *** [Makefile:72: mlton-compile] Error 139
make[1]: Leaving directory '/tmp/mlton-20210117.153942-gb1f1f0f09'
make[1]: *** [Makefile:75: compiler] Error 2
make: *** [Makefile:19: all] Error 2
make: *** [Makefile:666: remote--make-all] Error 2

4. SML/NJ

Doesn't support 32-bit ARM, and intends to support 64-bit ARM in the next release (2022.1), so it's impossible at the moment (as of January 15, 2022).

This is yet another incentive to upgrade to a 64-bit Raspberry Pi…

5. MLKit

Only supports x86 and Javascript, so I couldn't get it working on my Raspberry Pi. Formerly, MLKit had a bytecode interpreter, but this was removed to support Javascript.

6. Hamlet

If you already have a Standard ML implementation (including Moscow ML!), then you can build the Hamlet interpreter. See the github repo for details, but it's "follow your nose": clone it, then run make, and enjoy.

You can even have Hamlet build itself, if you can tolerate the sluggish performance.

Last Updated: Wed, 23 Sep 2026 07:55:29 -0700