@@ 5304,8 5304,126 @@ testList "api tests" [
** Thoughts on Standard ML as of 2023 :sml:thought:
How it feels to be 40 years late to the party and still find you a
Today marks one week since I started writing [[https://github.com/PerplexSystems/smltest][some Standard ML]][fn:46]
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
- Standardized :: This is a double-edged sword, indeed. While offering
a lot of stability over the whole ecosystem, it also slows down
progress[fn:47] 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 /[[https://en.wikipedia.org/wiki/Type_system][Type System]] aficionado/ myself,
I'm really enjoying my ~$CURRENT_JOB~ writing [[https://fsharp.org][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: [[https://github.com/topics/sml?l=standard+ml][GitHub]] and [[https://sr.ht/projects?search=%23sml&sort=recently-updated][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
#+attr_shortcode: :class info
Note that some of this might be easier or harder if you are not a [[https://nixos.org][Nix]]
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.
- Community :: There's the helpful ~#sml~ channel on [[https://libera.chat/][Libera Chat]],
Project Savanna's [[https://discord.gg/hgPSUby2Ny][Discord server]] (mostly focused on tooling) and
there's also the [[https://www.reddit.com/r/sml/new/][r/sml]] subreddit.
- Editor support :: You can use the amazing language server for
Standard ML called [[https://github.com/azdavis/millet][Millet]]. It works just fine with Emacs' [[https://github.com/joaotavora/eglot][eglot]] and
Millet also provides a [[https://github.com/azdavis/millet/tree/main/editors/vscode][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 [[http://mlton.org/][MLton]] and
[[https://www.smlnj.org/][SML/NJ]], use different build systems. The former using [[http://mlton.org/MLBasis][MLBasis]]
(~.mlb~) and the latter using [[https://www.smlnj.org/doc/CM/index.html][Compilation Manager]] (~.cm~). For the
time being, my solution has been to support both build systems, each
on a separated file.
buildInputs = with pkgs; [
*** 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 [[https://github.com/SMLFamily/Successor-ML/issues/29][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~" function[fn:48],
it's quite hard to debug programs without this.
- Type inference :: Coming from [[https://fsharp.org][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.
- Compilers :: 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 [[https://github.com/SOSML/SOSML][SOSML]], that allows you to write
Standard ML on the browser.
- Package manager :: There's a [[https://softwareengineering.stackexchange.com/questions/445747/does-a-programming-language-with-ml-style-modules-need-packages][great question]] on [[https://softwareengineering.stackexchange.com/][Stack Exchange]] about
ML-like modules and package managers and you should probably read
it. There are two main package managers: [[https://github.com/standardml/smackage][Smackage]] (which seems to be
more of an installer than what I'm referring to) and [[https://github.com/diku-dk/smlpkg][smlpkg]]. While I
haven't used none of them, there's nothing like [[https://doc.rust-lang.org/cargo/][cargo]] or [[https://www.npmjs.com/][npm]] with a
public registry and standardized /manifest/.
[fn:48] [[https://www.polyml.org/][Poly/ML]] exposes a function that does just that: [[https://www.polyml.org/documentation/Reference/PolyMLStructure.html#print][PolyML.print]].
The problem now being tied to a single compiler...
[fn:47] Check [[https://smlfamily.github.io/successor-ml/][Successor ML]] to see more.
[fn:46] I intend to write more about the challenges I faced with this
[fn:45] Fun fact: I introduced the dotnet module on devenv!
[fn:44] Absolutely nothing related to procrastination!