Some Esoteric Languages
I was basically flat with an illness (yes, that one) on my back for two weeks in March. I could do little more than read articles on my tablet, and for reasons I cannot explain, I began chainsmoking the documentation for as many little-known languages as I could find.
I honestly don’t know why. In the fog of illness, it just seemled a fun thing to do. I’m weird.
I am both less familiar with and less impressed with systems languages. I’ve coded professionally in C++ and Rust and I’ve written a bit of C and Go here and there, enough to know that I could write production apps in them if I needed to. Other than Go, which seems civilized, I think they leave a lot to be desired.
Most recently, I’ve been fascinated by concurrent-first languages, and most of the languages in this article fall in that bucket. As a hard-core Python developer, I’ve spent much of my career battling the limits of what Python can do with respect to parallel computing. Asyncio solves the IO-bound concurrency problem very well, but there is always that perplexing question of what to do when you have a problem that is “almost-but-not-quite-CPU-bound”. Those things that take too long to reasonably block the event loop, but not really long enough to spin up a multi-processing task. (This problem exists with the other GIL-weilding languages as well). So the Erlang family of languages got a look as well as some of the weirder ones out there.
At this point, I have at least dabbled in most of the languages I have summarized below, installing their compilers and building something a bit more complicated than “hello world”. But I haven’t learn any of them well, and most of my knowledge is academic.
Table of Contents
If you find my content valuable, please do consider sponsoring me on Patreon account. I write about what interests me, and I usually target tutorial style articles for intermediate developers.
Historically, I’m a Python programmer and author, but Python has enough people blogging about it these days, so as you see, I’ve turned my attention to more esoteric languages.
Rescript, Reason, and OCAML
I didn’t actually look at these as part of my recent investigation, but I wanted to link to my previous article on them. I love Rescript, as evidenced by my many articles on it. I didn’t ever actually build anything in Reason or OCAML, and can’t speak to them with any confidence, but they look interesting.
Obligatory “On Rust”
Lately, no discussion of programming languages is possible without encountering vehement opinions about Rust (both for and against). I coded for two years in the language, and I mostly think it’s overhyped and causes more problems than it saves.
Rust starts from a faulty premise that garbage collection is bad. There are actually only a few cases (operating systems, occasionally embedded, maybe realtime) where this is true, especially with some of the more interesting modern garbage collectors that are able to do what they do without the dreaded “pause the world”.
The best parts of Rust (RAII and move semantics) have been a part of C++ for years. The worst part of it (the borrow checker) is, while fascinating, like Java’s checked exceptions, be documented as a “what not to do” as newer languages are developed. It does the job and does it well, but surely it is just an iteration to motivate language designers to find something better.
The Esoteric Languages
The languages below are structured roughly in the order of how interested I am in them, with the least interesting first and most interesting last. The more interesting they are, the more likely that there will be future articles on them!
I’m not going to link to it because it’s been well documented as a scam, but I think it’s worth discussing V as a warning of “what not to do” when designing a new language.
As far as I can tell, V is just a fork of Go that was kickstarted by someone who made a lot of promises without enough engineering or compiler design background to keep (and indeed, many of them were impossible to keep). I don’t think there was any malicious intent; rather he was just a relatively junior engineer on the wrong end of the Dunning-Kruger scale, but his handling of the situation when asked for clarification on his claims was immature at best. Unfortunately, money was involved, with a Kickstarter funding initial development, so acrimony ensued.
That said, V is still actively developed, but I don’t think it will ever do anything that Go doesn’t already do better, and I didn’t bother to install or try it.
Julia isn’t actually that esoteric, as it has strong support in the data science community. However, it isn’t used all that much for programming in other domains, which I think is a damn shame. It tends to clock in as comparable to C++ on benchmarks, which is, considering how much higher level Julia is to work with, an impressive feat.
It isn’t used only for data science, of course. The Genie framework, for example, is a very nice HTTP framework that I enjoyed playing around with. But I found that tooling for “software development” was weak with Julia, while tooling for “data science” (Jupyter notebook starts with “Ju” for a reason!) is rock solid.
Julia is at just the wrong mix of compiled and interpreted. You need Julia to be installed in order to run it (you can’t build a static binary; I spent quite a bit of effort trying to get it to work with XAR archives). It has a REPL, but the structure is such that using an LSP or code formatter is obscenely slow.
I started reading about Julia with a vague intention of better supporting general purpose programming needs, but ultimately decided it wasn’t interesting enough.
Pony is an absolutely fascinating language, and I think everyone should study it just to open their mind to what is possible. It uses a unique “capabalities-based” system for memory management that I would need an entire article to describe. The basic idea is that any given variable carries extra detail with it at compile time as to whether you can read from or write to the data, both within a thread and across actors.
I like that Pony compiles to a self-contained binary. Like Go, it builds a runtime into said binary. The runtime is largely comprised of a task scheduler and an innovative garbage collector that, due to the capabilities design, doesn’t carry the drawbacks often associated with garbage collection.
Pony implements an actor model, and I find it the most lucid actor language that I’ve worked with. If you’ve never seen an actor model “work”, this might be a good place to understand it.
Concurrency in Pony “just works”, in the sense that if it compiles, you are guaranteed not to have data races. Similar to Rust, Pony’s capabilities system guides you to write guaranteed safe concurrent code. The rules for doing so are much more ingrained in the language and intuitive to learn, however. I enjoyed resolving capabilities issues in my Pony code rather than the feeling when I have to bang my head against Rust’s borrow checker.
I very much encourage people to write some non-trivial code in Pony just for the joy of the ride (One of the best things about Pony is how many metaphors the name allows you to use). My personal pet project when trying out a new systems language is to implement capnproto bindings for it. I’ve never actually successfully done so before I got bored, but it’s usually a fun project and gives a terrific understanding of how the language manages bytes and how to generate the structures it needs.
Vale is more interesting for what it might be than for what it currently is. They have done a lovely job of documenting the current state of the language as well as their plans for where it will go, and they actively maintain a roadmap. But the current state is a far cry from where they want it to go, so at the moment it’s a “keep your eyes on it” kind of thing. If you are thinking of getting into language design yourself, this might be a good place to start, (but I can’t speak for the contributor experience).
I admit I haven’t actually tried the language, but I delighted in reading all the feature descriptions. Many of the features are very much forward looking, but they are documented in a way that indicates the language author has put a lot of thought into them, is aware of the problems and knows how they will solve them. That’s the hard part, really; now they just have to finish implementing it. If you want to know what designing a language looks like, Vale’s documentation is the place to go.
If it fulfills all promises, Vale will be a clear winner over Rust for almost all scenarios, as it is much easier to code, but just as fast and safe (in fact, it claims it will be safer).
In its current form, Vale might be a good alternative to C or C++, but it is too young to recommend for any sort of production deployment. I want to experiment with it more and you may even see some articles here.
In fact, I think I just convinced myself to go ahead and install the compiler and see for myself!
Gleam is my favourite of the languages I researched. It looks a lot like Rescript in all the best ways. It is a functional language with a view to practicality over purity.
Syntax wise, Gleam is strongly and soundly typed. It looks a lot like Rust if Rust didn’t have mutable values or a borrow checker. In other words, very clean and elegant.
I’m really looking forward to experimenting with this language more, and you can definitely expert some articles on it in the future. Stay tuned!