This Code is Such a Brainf*ck — No, Really!

While languages such as Brainf*ck and the more kid-friendly Ook! (in name only) are generally left to the realm of toys and bragging rights, their real beauty is having an extremely simple turing complete interactive environment in which to learn underlying computer science concepts.

Engineers like to do things differently, and nothing demonstrates this more than the plethora of esoteric programming languages available. Usually relegated to research projects of debatable value, toys and bragging rights the ability to strip back to the bare metal of the computer hardware, of even an emulation thereof, can be of huge educational value for the legion of high level software developers who have no understanding on exactly a pixel is actually rendered on a screen.

For example, a code sample in the unfortunately named Brainf*ck.

++++++++++        // Set first cell (counter) to 10
[
        >         // Move to next cell (output)
        +         // Increase value of current cell
        .         // Display value of current cell
        <         // Move to previous cell (counter)
        -         // Decrease value of current cell
]

The above commented code simply displays the value 1 to 10 on the output. A few things to note:

  1. Memory cells can be used for any purpose, their use as described in the above comments, is to aid in understanding only.
  2. Code blocks (defined by ‘[' and ']‘) continue to execute while the current memory cell is greater than zero.
  3. Brainf*ck compilers/interpreters typically display output as ASCII symbols, so running this program will not display actual characters.
  4. Seven of the eight available operations, with the exception of read value to current cell indicated by a comma (‘,’), are represented in the example program.
  5. Layout, whitespace and unknown characters are (or at least should be) ignored.

The program can be executed with an online interpreter. To see the output rendered in a human readable form you will need to use debug-mode as the ASCII symbols for number 1 to 10 are control characters and do not normally display anything on screen.

Using only eight instructions with an implicit operand makes this an excellent model for understanding memory allocation and for thinking about how these operations can be completed at the basic level. The use of ASCII output highlights the relation between the decimal value of a memory cell and it’s on screen representation. Parallels can also be drawn with assembly language programming. The highly reduced instruction set, again, coupled with implicit operands and pointer, provides a deeper insight to how a modern microprocessor might carry out instructions and introduces the thought processes required to understand memory addressing and operations.

While such and intricate understanding of the underlying implementation details of computer hardware is arguably not essential, and as such only peripherally taught in many modern degree level computer science course, esoteric programming languages such as Brainf*ck can help developers understand these underlying concepts of the digital computer by giving them an interactive path for investigation and have the potential to bring about a more enlightened, openminded and flexible developer workforce if their educational value is properly exploited — despite some rather institution unfriendly names.

Going Loopy with Loops

Reinventing the wheel can often give a deeper understanding of the problem and highlight some of the esoteric features of your chosen programming language — however, remember to go back to using the standard method and style in your production code!

I like loops, they are predictable, reliable and relatively easy to understand. For many common algorithms there are much more efficient ways of computing the solution, however loops often provide an easy to understand approach to getting to the right answer — eventually.

Recently, when demonstrating looping constructs to a beginner I provided the following three examples which spit out 1 to 10 on the terminal.

// Traditional
for(int i = 1; i <= 10; i++) {
    System.out.println(i);
}

// Unorthodox
int i = 0;
while(i < 10) {
    System.out.println(i+1);
    i = i + 1;
}

// Too smart for own good
for(int i = 0; i < 10; System.out.println(++i));

Each sample was slightly more complex, conceptually, than the next. The final sample demonstrating how the for could be abused to show the desired output on only one correctly formatted line. In it we use my favourite pre-increment operator to push the the 0 up to 1 before we output the number to the display. Of course we could have used 1 and 11 as our bound with the post-increment operator, but any sane programmer would agree that numbering should start at zero.

Extending the code abuse further, while browsing over at Stack Overflow I discovered that while is largely redundant, if you are happy to abuse for some more. Turns out that for, as typically defined, assumes the test condition to be true when omitted and all three sections of the for statement are in fact optional. As one of the moderators put it:

This answer pretty much proves the awesomeness of the “No question is too simple” policy. :) — Bill the Lizard

Likewise, while browsing an interesting article on The Daily WTF which highlights a simple method for square root calculation my muse overcame me. The article makes it quite clear that such iterative approximations are not highly regarded (unless you are John Carmack), however, it reminded me of a simple pi calculator that I wrote using JavaScript a number years ago when similarly inspired.

Armed with new knowledge about the abuse of for and an entirely redundant algorithm to code I set about developing a square root function.

double sqrt(double n) {
    for(double r = 1; r != n; n = r == (r = 0.5 * (r + (n < 0 ? -n : n) / r)) ? r : n);
    return n;
}

There are so many things wrong with this I’m not sure where to start. How about the blatant abuse of the parameter n as both the input and output, simply to avoid declaring another variable? This requires the break condition to determine whether the usually untouched n contains the currently calculated value of the result.

The final chunk of code actually does the calculation of the square root while deterministically assigning the value to n to terminate the loop and return the result. The calculation itself is relatively simple: is the average of our calculated root, r, and n / r equal to the previous value of r? If not, further refine r in the same way.

r == ( 0.5 * ( r + n / r ) )

The calculation, as implemented in my sqrt() function, is complicated somewhat by the embedded assignment of the new value to r, the poor-mans error handling of negative numbers (who wants to deal with imaginary numbers anyway?) and the inline if used to assign the final value to n.

Of course, we could always use the built in Java Math.sqrt() method which efficiently passes the calculation off to the hardware, but where’s the fun in that!?