And also why I cry when people create languages that are one simple regex away from brainfuck and call those esoteric.
Soo also: Malbolge, so evil that the only non-stupid programs in it were generated by LISP scripts
It's a broad church.
Embedded within this language is an incredibly powerful string pattern matching facility, which predated regex popularity. I think regex is probably as expressive, but I find SNOBOL more comprehensible.
One of my favorite books from the late 70s/early 80s was the SNOBOL book by Griswold, Poage and Polonsky: http://www.thriftbooks.com/w/snobol-4-programming-language-a.... Short, clear, and a great user guide and reference to this bizarre language. I rank it with K&R as one of the great programming language books. (Or maybe nostalgia is getting the better of me.)
I took two compiler courses from R. B. K. Dewar, who was on the team that built the SPITBOL implementation of SNOBOL for IBM mainframes, a really fantastic set of courses from a great teacher. He talked about implementing SPITBOL, in the days when you could get maybe one run a day from the mainframe. By being exceedingly thoughtful and careful, they got the compiler implemented and running in twenty compile/debug cycles.
> ...we thought that our Controller subsystem should also be as simple as possible. We spent quite a bit of time looking at the simplest implementation of a Turing machine, running the simplest possible language, BrainF[uck] (also called BF) - the smallest Turing-equivalent language in existence, having only eight instructions.
As another example, the "minimalism" of Brainfuck has been used to minimise bias when measuring the performance of AI systems: http://arxiv.org/abs/1109.5951
However, when it comes to minimalism, Brainfuck is actually rather complicated. As mentioned above, it has 8 instructions ("+", "-", ",", ".", "<", ">", "[" and "]"), but there are several languages which only require one instruction http://esolangs.org/wiki/OISC
Brainfuck also separates code from data, which causes it to bloat (eg. we have an instruction pointer into the code and a cursor into memory). Many languages don't do this, for example Turing machines, lambda calculus, and even some of the languages on the OISC link above like BitBitJump http://esolangs.org/wiki/BitBitJump
Brainfuck also has built-in IO primitives ("," and "."), whereas other languages like Lazy K ( http://esolangs.org/wiki/Lazy_K ) encode their IO as streams or monads.
Brainfuck also requires arbitrary implementation decisions like word size and memory size, unlike eg. Flump ( http://esolangs.org/wiki/Flump ) which allows any amount of numbers of any size, written in unary (eg. "11111" for 5) and delimited by zeros (eg. "0111011" for 3 followed by 2).
Brainfuck requires an instruction pointer to keep track of which instruction it's up to in the program, unlike purely functional languages which can be evaluated in any order, like Binary Lambda Calculus http://en.wikipedia.org/wiki/Binary_lambda_calculus
There are also arbitrary implementation decisions like what happens when integers overflow, what happens when the cursor overflows the memory, etc. which are complete non-issues when there's no word size, no external memory, etc.
The code is at http://chriswarbo.net/js/optimisation/levin_bbj.js and is mostly dedicated to the search algorithm. The BitBitJump implementation is just these two lines, inside one of the loops:
mem[read_address(counter, m)] = mem[read_address(counter+m, m)];
counter = read_address(counter+2*m, m);
True enough, but I would say the crucial difference is that Brainfuck's eight instructions have no parameters, whereas all single-instruction languages use one or more operands in order for their lone instruction to have multiple effects.
I tend to produce ugly Piet programs :)