We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.

User:Aadenboy/Blog draft

From Esolang
Jump to navigation Jump to search

I'm sure you've at least heard of the term "esolang" or "esoteric programming language" before if you've been in the programming community for some time. They're these languages which go out of the norm and are all weird and wacky and stuff, or at least that's how it's told. Come across any majorly popular video and the common examples are the weird syntax language and the weird syntax language and the weird syntax language and brainfuck, the minimal weird syntax language. It's played off as a fun little thing! A toy to play with!

Like with any niche, though, you really can't rely on the surface level observable stuff. Be around the esolanging community for long enough and your perception on what an "esolang" is changes drastically from "weird". Sure, esolangs can be "weird", but that's not actually the point. It's a bit of contention as to what an esolang really is, but there's some common themes among esolangs, of which everyone's beloved LOLCODE doesn't have (well, mostly).

Searching downwards

A major topic of esolanging is computation: how a program is able to achieve a result given what it has. Mainstream programming languages want to make the process of computation as easy as possible, but a good esolang in my opinion will typically hinge on hindering or translating computation in some way. LOLCODE without its memey syntax is really not that different from a mainstream languages,[note 1] but brainfuck can't be translated like that as its computation is restricted heavily. You are restricted to a "limited" memory model for your computations, and the only operations on the memory are two distinct ways to access, read, and write to it. Trying to compute anything in brainfuck requires you treat it as its own model of computation and interpret problems through this lens; not that you can't rebuild higher primitives like arrays and such, but you really need to understand the fundamentals of how brainfuck's computation actually works.

From that, we can degrade further, with Turing tarpits making a really good example, as there are many different approaches to minimizing the apparent power. brainfuck is of course a tarpit itself, but it's generally on the larger side when it comes to instruction count. More minimal languages tend to take very different directions. Some of my favorites include:

  • ///, a string-rewriting language. It's based on the s/pattern/replacement/ scheme, and serves as a good example of observation making an esolang. Its power comes from its self-modifying ability, and you really need to leverage that.
  • BitChanger, a brainfuck variant. Obviously brainfuck variants aren't usually the most interesting, but this one can be a standout because it makes what would be the strange choice of combining a move and write operation together in only one direction. I believe that any asymmetry between two otherwise related commands is a good thing at this scale, and as it turns out, it's not hard to translate to Boolfuck.
  • Bitwise Cyclic Tag, a cyclic tag system with only two instructions. I love BCT so much. Since it's a cyclic tag language, the program infinitely loops and wraps, meaning that there's not a presently available way to "loop" or perform "conditions". All you can do is add conditionally and remove unconditionally—hey, there's asymmetry again! BCT really leans more into the data manipulation rather than control of the program, and it does take multiple steps for a meaningful result, with many loops of the single program. Since BCT is so simple, it makes for an extremely reliable proof target. /// was proven TC via this language!
  • Countable, an increment-only language. I know this is my own esolang, but it's just so worth mentioning, especially with what it teaches. Each register is an unbounded integer that the program is only ever able to increment; there is no way to ever decrement or reset a register. This sounds like a no-go for doing anything, but through dereferencing many layers deep and an infinite number of registers to travel to, programs rely on increasingly clever ways of managing memory so that there's always fresh space to compute. I like to compare it to building spaceships in cellular automata since it manages itself. You really have to think hard about memory management.
  • Mhm!, a tree-based language. Another one of mine, and it is based on Countable, but it is very unique. The construction is simple: take a tape of cells, then turn each of those cells into its own tape, then each of those subcells is its own tape, and so on and so forth—this is better visualized as a tree. The only way to store value is by the positions of each tape's pointer, and by what is again asymmetry, entire branches can be removed from the tree and that is what is actually tested. The computation comes from the shape of the tree itself since that is the only actually discernible feature available.
  • QX, a two-instruction language. This one is extremely simple: you can change the value of each cell freely, then moving the tape and jumping across the program are merged into a conditional check. Modifying a single cell is trivial, but trying to handle multiple cells requires clever tricks to enforce that the values of cells are where you expect them to be. This one I was able to prove Turing complete by translation to brainfuck!
  • Thue, a string-rewriting language. Like ///, Thue requires being able to manipulate data effectively. Unlike /// however, Thue isn't self-modifying and on top of that is also nondeterministic! Nonetheless, it is still Turing complete, since it's a semi-Thue grammar. Lots of use of delimiters when programming!
  • Ultimate bf instruction minimalization!, a two-symbol minimization of brainfuck. It is of the smallest ignoring OISCs, and simply can only move left, or move right, flip, and skip if zero at the same time, all in a while non-zero loop. More asymmetry! I wish I had more to share here.

All of these languages are fun, and minimization is a good example of what makes an esolang, but I don't mean to say that that's the point. Looking at them all, they're more like puzzles in the sense that the "puzzle" gives you a set of primitive "pieces" that you need to achieve some goal with. A good puzzle is one that is not only unique but fun to try and work within the restrictions.

Searching sideways?

Again, minimization isn't the point, and there can definitely be more use with a broader esolang. The same idea of a puzzle still remains, however.

Take my esolang Iterate. It's a language where everything is controlled by loops, and the memory model is the loops themselves, by how much they've been visited. This isn't important, though. What is important is that there are a finite amount of loops, therefore a finite amount of accessible memory, right? Turns out, not really: the amount of times a loop can be visited is unbounded, which can be exploited by encoding "arbitrary memory" as a really large integer through something like a numeric base or multiplying primes (something I've dubbed "arbitrary memory emulation"). This, as it turns out, is an important revelation that doesn't only make Iterate Turing-complete, but also already occurs in other preexisting esolangs. Computation can be limited in either direction so long as one is unbounded: bounded values means unlimited data; limited data means unbounded values. In order to solve the puzzle that was Iterate, we had to identify a core theory which also extends to other similar puzzles.

Searching upwards

And like with any good puzzle, it helps to formalize its own theory and abstract away basic principles. Iterate was extended to make "Compiled Iterate", a flavor of the language which allows macros that are expanded into raw Iterate. Funciton is a much grander example this, though, as its function creation has led to an extremely large library of functions available for use. Computation at the core is still the same limited, shifted model, but as aforementioned at the beginning of the article, higher primitives were rebuilt and made accessible for use.

Notes