In this post I want to make this kind of simplicity more precise and talk about some reasons it’s important. I propose five key ideas for simple programming languages: ready-at-hand features, fast iteration cycles, a single way of doing things, first-order reasoning principles, and simple static type systems. I discuss each of these at length below.
Aside: simplicity in languages is interesting. I’d say most popular languages, from Rust and Haskell to Python and JavaScript, are not simple. Popular PL research topics, such as linear types and effect systems, are also not simple (I suppose all the simple concepts have already been done over and over).
Making a simple language which is also practical requires a careful selection of features: powerful enough to cover all of the language’s possible use-cases, but not too powerful that they encourage over-engineered or unnecessarily-clever (hard-to-understand) solutions (e.g. metaprogramming). The simplest languages tend to be DSLs with very specific use-cases, and the least simple ones tend to have so much complexity, people write simpler DSLs in them. But then, many simple DSLs become complex in aggregate, to implement and to learn…so once again, it’s a balance of “which features have the broadest use-cases while remaining easy to reason about”?
As someone with an odd relationship with programming, I suspect we have different definitions of simple. Though in fairness the problem with some languages (that I’d call simple) for me is with performance particularly when parallelism can’t really be used, and I guess you could say that I expect too much.
The most programming I’ve done (admittedly, not a lot) was with Nim-lang because that seems to be the only thing I’ve seen that has style+performance that I want. I’m sure if you look inside the machines it’s not simple for a lot of reasons, but it can be used simply if you pretend those things don’t exist (particularly if you didn’t know of them in the first place) and just make something script-like. And even stuff like memory management is tunable and optional. So yeah, a language that’s simple-to-use and simple-to-maintain (create? understand? or just minimalist in general?) seem different to me. To take it to an extreme, something like Brainfuck seems like it’d the best example of a simple/small interpreter without being simple to read.
This is an example of the last code I tinkered with (input text example). I like the different ways of doing things (or just something like UFCS), maybe that’s not simple for the language but it allows me to make my code simpler.
EDIT: Also watching an explainer for Gleam maybe it’s less about flexibility but just some of the things looking odd (/not intuitive), which for sure could largely be on me. (maybe that would be a preference thing even for people who understand it)
Personal note, I stopped there because I wasn’t quite sure on usage/implementation with different polygon types. Plus, part of me wanting the language to get out of the way would be for supplemental editors to exist (like a game engine) so I could do basic things (art, animations, GUIs) visually and save the code for actual logic. Still no bindings for Godot 4 (Godot 3 had production-ready bindings) which I suppose is due to Nim being niche. I could possibly use Raylib (or Godot 3) with 3D instead, but I have less motivation to do so (esp. learning/using Blender, though maybe I should given details). For context, this animated eye is an example of the aesthetic I’d go for (if it were viable, which it might not be). Also if that link looks broken, for whatever reason for me it loads as expected in a private window.