Worst Design Decisions You've Ever Seen

How about taking a look at some esoteric programming languages? I don't mean the ones are designed to be "bad" on purpose, which is kind of missing the spirit of the question. I mean the ones that were designed around a specific concept, and were willing to sacrifice everything else for that concept, including human usability. Which not only makes it a fun and liberating design exercise, occasionally it might even give useful insights into what does make a programming language good or bad for human consumption.

I probably should mention my own esoteric programming language: Rainbow Brainfuck (or RBBF for short). I designed it with the following two goals in mind:

  1. make it useful for genetic programming experiments
  2. explicitly do not worry about whether or humans can or would like to program in it, because ignoring that liberates the design space and might lead to better design choices when trying to achieve the first goal

Because of the first goal, one design guideline I came up with was "the principle of least semantic change". Although I have no proof of this, my intuition says that this is a good design principle for for genetic programming languages. It would be a horrible one for languages designed for human consumption though.

My reasoning is that if we design the language so that an individual mutation to the source code introduces minimal behavioral changes, then that makes it more likely that most mutations are harmless. This in turn should make it easier for mutations to accumulate and lead to sudden dramatic, complex shifts in behavior after a number of mutations. That would then result in a bigger likelihood of being able to evolve out of a local maximum.

One example of this design principle in practice is how functions work in RBBF. Let's say a section of RBBF code increments the cell by four:

++++

Turning that in a function a is as simple as wrapping it like so:

a++++#

So the function is simply defined in-line, terminated with a #. The important part is that a function definition is called when encountered. Compare that to function definitions in most "normal" languages, which are defined, but not run until explicitly called. Why? Because this introduces the least semantic change when a mutation wraps a section of code into a function.

The principle of least semantic change also means that we need to design the functions in such a way that loops can jump in and out of them, pretending they're simply not there:

a++[++#--]

I think I have a solution for that, but explaining it would take a few more paragraphs and this comment is already too long. Suffice to say however that the resulting language not pleasant to program in as a human being. And I haven't even mentioned the semantically significant colors yet.

(If you want to have a more complete picture of RBBF, here is a nearly-finished implementation I've been working on. I just have to figure out how to implement functions. For a more "unfiltered" experience, here is an interactive version of the first design doc I wrote over half a decade ago. Some design choices have changed, and I didn't explicitly formulate the "least semantic change" principle until much later, but it does do a deep dive into some of the ideas explored while designing the language. Just be warned: it is the product of two manic weeks of essentially being high on creative liberation, and it shows)

/r/ProgrammingLanguages Thread