~glorifiedgluer/gluer.org

222e805904dc996ff578f8c986dd23e96c591aff — Victor Freire 4 months ago 232df0c
article: thoughts-on-standard-ml-as-of-2023
1 files changed, 118 insertions(+), 0 deletions(-)

M content-org/content.org
M content-org/content.org => content-org/content.org +118 -0
@@ 5304,8 5304,126 @@ testList "api tests" [
]
#+end_src

** Thoughts on Standard ML as of 2023                          :sml:thought:
:PROPERTIES:
:EXPORT_DATE: 2023-07-17
:EXPORT_FILE_NAME: thoughts-on-standard-ml-as-of-2023
:EXPORT_HUGO_SLUG: thoughts-on-standard-ml-as-of-2023
:END:

#+begin_description
How it feels to be 40 years late to the party and still find you a
seat.
#+end_description

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
that.

*** Why?

- 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
#+begin_alert
Note that some of this might be easier or harder if you are not a [[https://nixos.org][Nix]]
user.
#+end_alert

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.

#+begin_src nix
mkShell {
  buildInputs = with pkgs; [
    mlton smlnj
  ];
}
#+end_src

*** 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/.

* Footnotes

[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
project.

[fn:45] Fun fact: I introduced the dotnet module on devenv!

[fn:44] Absolutely nothing related to procrastination!