Befunge (Wikipedia article, Esolang article) is a family of esoteric programming languages which managed to pique my interest near the end of 2005, and ended up being a part of my life for a longer while than I had expected.
My dealings with Befunge resulted in an interpreter named CCBI. I believe it to have the best language support of all interpreters, having tested it with my Mycology test suite. Feel free to prove me wrong, of course.
About Befunge
The interesting part about Befunge is that programs are written on a two-dimensional grid, along which moves an instruction pointer, or IP. The IP may be moving in any direction at a given time. For instance, the hello world program can be written as follows:
"!dlrow ,olleH",,,,,,,,,,,,,55+,@
The IP starts in the upper left corner, moving right. " toggles stringmode, where characters encountered are pushed on the stack (hence the reverse order of the string). , outputs a single character, 55+, outputs a line terminator (ASCII 10), and @ terminates the IP, ending the program.
Another way of writing “hello world” is as follows:
v
v"Hello, world!"<
>:#,_25*,@
Here, the IP turns to move downwards, then left, as it hits the v and <. (Likewise, ^ and > cause the IP to move upwards and right, respectively.) The string is pushed on the stack as before and then the common >:#,_ sequence is used to output the string. : duplicates the top of the stack, # jumps over the next character, _ makes the IP move right if the top of the stack is zero and left otherwise. I’ll leave figuring out why that works as an exercise to the interested reader.
My dealings with Befunge
Near the end of 2005 I decided to play around with Befunge a bit, and soon discovered that there were two standards: Befunge–93 and Befunge–98. (Apparently, a Befunge–97 also exists, but almost all information regarding it has disappeared from the face of the ’Net.) Befunge–93 is relatively simple, and many programs existed which interpreted Befunge–93 code, all doing it practically identically.
But after discovering the complexity of Befunge–98, I was entranced. I tried some interpreters but noted that they behaved somewhat differently in many, even simple, cases. I soon came upon the ‘Fungus’ tests and ran all the interpreters I could find on them.
I discovered that the Befunge–98 “support” of all the interpreters was flaky, at best. First I thought I would document the results of the various interpreters and then just pick one for my own uses. However, it soon became clear to me that the Fungus tests were:
Limited. At this point I had managed to crash at least one interpreter (I forget which), but Fungus didn’t pick up on it.
Uninformative. I had not (yet) read the Befunge–98 specification and was thus unaware of what was the expected result of each test—sure, it tells me what happens, but it doesn’t tell me whether that’s a good thing or not.
I also noticed that due to this aspect, some interpreters which had been using these tests were of differing opinions regarding some matters. I.e. a given Fungus test resulted in different behaviour with two interpreters, but they both had documented themselves as passing said test.
Unforgiving. Many things were expected to work despite being untested. If, on the way to the actual test, something went wrong, Fungus wouldn’t notice.
I decided to write my own interpreter, and thus CCBI was born (though that wasn’t its name yet). I read through the spec many, many times. I soon realized that the limits of Fungus were too great: if I wanted to write a proper interpreter, I had to write my own tests. Hence, the Mycology suite.
It took a while, but I eventually finished both (although there are bound to be bugs, of course). When all was done, I did a final run on Mycology with all the interpreters I could find, and thus begat the Mycology results comparison.