💾 Archived View for denisthiessen.de › blog › brainfuck captured on 2024-08-18 at 17:10:52. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2022-03-01)
-=-=-=-=-=-=-
Ahoy and welcome to this blog entry.
Today I'd like to start out with some kind of 'series' about so called esoteric programming languages in which we will explore the wacky and unnecessary when it comes to programming languages.
It's called "Why..." and is actually an acronym for (W)acky (h)euristic novelt(y).
You see.... There are of course your C's, your Java's and your <insert your favorite "serious" programming language here> which have the intent of being somewhat viable in creating cool/useful applications. But some people with a computer science background thought to themselves.... (Nah... That would be boring) and they went on to create the more wacky side when it comes to this topic.
So this is basically how this genre of programming languages was created. (not really but yeah... I'm not really giving you a history lesson here... Sorry.)
Since this topic kinda interested me here and there and I know a thing or two about some esoteric programming languages I'm starting this series as an introduction to those thingies.
If you talk about esoteric programming languages the one most people are at least familiar with is Brainfuck so let's start this series out with this absolute classic. (finally... This took way too long...)
Well... What is this 'Brainfuck' about?
Created by Urban Müller in 1993 Brainfuck is a fully Turing complete (in short this means that it can be used to emulate a 'Turing machine') programming language, which only consists of the eight symbols "+", "-", "<", ">", "[", "]", "." and ",". Crazy I know...
But I don't wanna get into the further historic details and other properties. Let's get into how this strange language works.
As I previously mentioned Brainfuck consists of only eight different instructions that you just concatinate by another. But how on earth can we get any meaningful programming done with this....
Actually a lot of people seem to think that Brainfuck is quite complicated hence the name "Brainfuck" but it is actually quite simple if you understood the basic concept.
You see.... You can imagine how Brainfuck executes it's code kinda like a conveyor belt, paper tape with some spaces/slots with integer values you can put inside them or for the more technical person it's kinda like this Turing machine that I've mentioned before but with only integer values in its slots.
This imaginary tape has a pointer to the current slot which it is currently at.
At that is basically it when it comes to explainations to understand Brainfuck and its operations. Now we can divide those eight different instructions into four different groups which all do kinda the same thing. So let's go over them.
The first group involves the current value of each slot. The "+" operation just increases the current value in the slot the pointer is pointing to by 1. The "-" operation does exactly the same but it decreases the current value by 1.
Two down, six to go. The next group involves the pointer and how it points to different slots. The "<" operation moves the pointer one slot to the left and the ">" operation moves the pointer one slot to the right. Quite simple isn't it.
So let's make it a bit more difficult with the next group which involve loops. Yes... You can loop stuff/code with Brainfuck but how does that work?
The "[" operation marks the beginning of the loop and the "]" end. In between you can put whatever you want in between, even other loops. But every loop needs some sort of exit condition, otherwise the loop would just go on forever. You see.... Every time the program gets to the "[" operation it checks whether the slot where the pointer is pointing is zero. If it isn't zero it just continues normally with the code inside the loop. However if it is zero the program will jump forwards to the matching "]" operation of that loop. The "]" operation works kinda the same but in the opposite. If the value of the slot which the pointer is currently pointing at is zero the code continues normally with the code outside the of the loop. But if it isn't zero the program will jump backwards to the matching "[" operation which basically provides the looping mechanic. That's how looping in Brainfuck is done...
(Phew) That one was kinda a bit much but I promise, these were the most difficult to understand operations in Brainfuck. I'd say we finish it off with the rest. Those are just some operations concerning Input/Output.
The "." operation outputs the current value of the slot the pointer is currently pointing to but not normally. It outputs the ASCII value of the integer value of the slot. If you don't know what that is, to put it very very veeery simple, it's a table where an integer value corresponds to a character or other kinds of values. For example the integer value of 65 corresponds with this system to the character "A". So that is how that one works. The "," operation works quite similar but instead of outputting the value of the current slot it puts it's integer value according to the ASCII table to the current slot the pointer is pointing to.
With that we are done. We went through everything Brainfuck has to offer when it comes how it basically works. I might have left out a detail here and there but basically this is more than enough to understand the basic principles of Brainfuck.
So let's get started actually doing stuff with Brainfuck. The first thing that most programmers do is a "Hello World" program. It's simple, it's easy and it quickly done. This sounds great doesn't it, so let's a go.
Our goal is to print the text "Hello World". The only way to print stuff to the console is to use the "." operation. Although we can only print one character at the time and this is kinda annoying it is the only way to get this done, so our goal is to print each individual letter of our text "Hello World". If you remember the "." operation prints the ASCII value of the current slot value. Now our goal is to generate each of the letter's corresponding ASCII value. For our goal this means we need to generate the values 72, 101, 108, 108, 111, 32, 87, 111, 114, 108 and 100 corresponding to the letters "H", "e", "l", "l", "o", " ", "W", "o", "r", "l", "d" in some slot according to our trusty ASCII table.
This is where our other operations and our creativity comes in. You see... To accomplish this you could (insert doubletime here..) put 72 "+" operations, then a "." operation to print the character "H", then put 29 more "+" operations, then another "." operation for the "e", then add 5 more "+" operation, following two "." operations for the two "l" characters, add three more "+" operations with a "." for the "o", theeeeen do 79 "-" operations to get the value '32' in our slot with a "." operation.... (and so on...)
I don't want to continue anymore. I think you got the idea. This is very annoying, waaaay to time-consuming and most importantly not very efficient. If you look at the Wikipedia article you can (hopefully) find another "Hello World" example and this one is a lot shorter. So how is that one done?
Well... Let me introduce you to multiplication. You see... Previously we used a loooot of individual symbols but just like you can let's say use 20 add operations, you can add by five times four. Both equal 20, but it's a different representation. We can use this concept to cut our code down by a lot of operations. Let me look at this example. We want to put the value of 20 into a slot. Normally we wanna just use 20 "+" operations and our task is done... But this isn't that efficient. What we can do is the following. We say that 20 is equal to four times five. We just set the value of one slot to four by using four "+" operations. Then we can start a loop using the "[" and "]" operations. Inside this loop we wanna do the following. We go to a different slot using either the "<" or ">" operation. Then we increment the value by five using five "+" operations. Then we go back to our initial slot with the current value of four and decrease it by one with the "-" operation. Now happens the magic. Since the value of this slot isn't zero but three we go into our loop block again and the same thing happens. We go to our slot with the current value of five, increase it by five and go back to our initial slot and decrease it by one to two. This now happens two more times until the value of our initial slot is zero but now the value of our slot is the result of our multiplication, exactly 20. It's just like magic. (whoaaaaa)
If you were to code something like this, this would look roughly like this.
++++[>+++++<-]
As you can see. Instead of 20 operations we've only used 14 operations to accomplish the same thing. We've saved 30% of program space. The great thing about this concept is that depending on which kind of multiplication you use on different sizes of numbers you can save even more space.
And it's this kind of memory management you can do in Brainfuck which makes it quite fun to program with. There are a lot of these little concepts / program blocks which let you do cool things like moving values, copying, setting the value of a slot to zero and even more. The possibilities you could do are quite a lot, even though you only have eight operations. 😁
There's one thing that I'd like mention before we conclude this post. Besides Brainfuck there are a lot Brainfuck-esque languages since it is basically one of the most popular esoteric programming languages. A lot of those variations replace the text/characters of the Brainfuck operation. Let's take Ook! for example. The functionality behind Ook! is basically equivalent to Brainfuck but the name of each operation is different. For example let's take the "+" operation. In Ook! this operation is called "Ook. Ook.". I don't wanna talk too much in detail about this. The main takeaway should be that there are a lot (!) of Brainfuck variations, but don't be scared. These are most likely just the same and a lot of other esoteric programming languages work with the same principles as Brainfuck with a tape and slots and so on.
Well... This isn't really the THE ULTIMATE BRAINFUCK GUIDE OF DOOOOM or anything. This series should be rather an entrypoint to those languages. (this blog post is already way too long)
The main thing I wanna teach you is to look up stuff and inform yourself. Chances are, you view this blog post via a great medium called the I N T E R N E T and everything there is within the reach of your fingertips.
With these words I'd like to conclude this little story about Brainfuck; an esoteric wonderland in the world of programming languages. If you wanna read up on even more Brainfuck I've linked to some further resources where you can at least start your journey. I take no responsibility in the content linked to these webpages or generally every link. At least at the time of writing this post these pages contained said resources. (just in case the webcontent changed there 😉)
See you hopefully soon
Denis