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”?

-1 points

I honestly don’t think there’s a single language out there that’s more approachable and straightforward than PHP - it has the perfect amount of built in functionality… it’s not overwhelming like Java but also doesn’t make you constantly reinvent the wheel like C++ - both Go and Python have similarly right-sized STLs.

The stand out though (which I admit is becoming less relevant) is in its natural habitat. It was a language designed to produce HTML and it is extremely trivial to casually start programming in it. Do you have a table and want to splat out 10 trs without writing them one by one - write it once and wrap it in <? for($i = 0; $i < 10; $i++) { ?> and a closing brace and, well, look ma I’m a hacker!

It is amazingly accessible and a large number of people had their first programming experience messing around with PHP.

permalink
report
reply
1 point

You have to manually explain to the computer how to count to ten, in 2024, and you call that simple? Simple would be something like

<? 10.times { ?>
permalink
report
parent
reply
2 points

Even simpler is repeat 10 { }

} just stands for done.

permalink
report
parent
reply
16 points

You mention that Haskell isn’t simple. That may be so. However, all of Haskell compiles down to Haskell Core which is incredibly simple. It’s similar with many languages. Purescript back end is being rewritten in Chez Scheme which is also incredibly simple.

My point is, if you stack enough simple layers on simple layers, things get very complex.

permalink
report
reply
3 points
*

That’s sort of obvious and seems to kind of miss the point of a programming language. A language is an abstraction over the capabilities of a (possibly virtual) machine. The machine itself can generally only do relatively simple things; but writing assembly code is usually more difficult than writing the same functionality in a higher level language, because individual machine instructions are such a small building block for designing higher-level behaviors. So it’s hardly surprising that simple layers stacked on each other result in complexity. The point of the article (and of language design in general) is about how to balance expressive power versus simplicity of language concepts.

permalink
report
parent
reply
4 points

The machine itself can generally only do very simple things

That really hasn’t been true for at least 2 decades. And nowadays assembly code is no more that another abstraction layer, as microcode in the processor becomes increasingly complex. It’s as out-of-date an idea as the idea that C code is ‘close to the metal’.

permalink
report
parent
reply
1 point
*

I should have said “relatively simple”, not “very simple”. Yes, modern assembly instructions can often be relatively complex (though not on all architectures). But the point is that every abstraction layer presents a simpler API compared to what’s below, but must be implemented in terms of complex combinations of the fundamentally simple units of functionality in the layer below it. This is true of assembly, yes, but that doesn’t make it less true of higher level languages.

permalink
report
parent
reply
5 points

The machine itself can generally only do very simple things

I disagree. Assembly languages for modern architectures are a complexity hell. You need books with thousands of pages to explain how they work. In comparison the lambda calculus is much simpler.

permalink
report
parent
reply
1 point
*

I should have said “relatively simple”, not “very simple”.

https://programming.dev/comment/8548915

permalink
report
parent
reply
1 point

Haskell is simple in some ways and complicated in others.

It doesn’t have optional or named parameters. There are no objects or methods. No constructors. It doesn’t distinguish syntactically between procedures and functions. There are no for loops or while loops. && and || aren’t treated specially. It doesn’t even have functions with more than one argument. Every function takes one argument and returns one result.

permalink
report
parent
reply
1 point

The Koka language has a stated goal to be as simple as possible. The language definition even has something like scheme’s “feature on top of feature” verbiage. However it’s a very different language than you’re thinking of.

permalink
report
reply
4 points

It seems Rabbit has followed several of these principles…

permalink
report
reply
5 points
*

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.

permalink
report
reply

Programming Languages

!programming_languages@programming.dev

Create post

Hello!

This is the current Lemmy equivalent of https://www.reddit.com/r/ProgrammingLanguages/.

The content and rules are the same here as they are over there. Taken directly from the /r/ProgrammingLanguages overview:

This community is dedicated to the theory, design and implementation of programming languages.

Be nice to each other. Flame wars and rants are not welcomed. Please also put some effort into your post.

This isn’t the right place to ask questions such as “What language should I use for X”, “what language should I learn”, and “what’s your favorite language”. Such questions should be posted in /c/learn_programming or /c/programming.

This is the right place for posts like the following:

  • “Check out this new language I’ve been working on!”
  • “Here’s a blog post on how I implemented static type checking into this compiler”
  • “I want to write a compiler, where do I start?”
  • “How does the Java compiler work? How does it handle forward declarations/imports/targeting multiple platforms/<other tricky feature>?”
  • “How should I test my compiler? How are other compilers and interpreters like gcc, Java, and python tested?”
  • “What are the pros/cons of <language feature>?”
  • “Compare and contrast <language feature> vs. <other feature>”
  • “Confused about the semantics of this language”
  • “Proceedings from PLDI / OOPSLA / ICFP / <other large programming conference>”

See /r/ProgrammingLanguages for specific examples

Related online communities

Community stats

  • 1

    Monthly active users

  • 281

    Posts

  • 450

    Comments