Archive for the ‘Miscellaneous’ Category

Naive Brainf**k to Java compiler

Some time ago the brainf**k language caught my eye (I still don’t feel comfortable spelling it right).

It’s a turing tarpit, but one not very complicated at that (for something more esoteric see Malbolge or Whitespace).

The language is very simple, it has eight instructions. So I had to write a compiler for it. It turns out to be quite easy to do:

import static java.lang.System.out;

public class BrainFk
{
    public static void main(String[] args) {
        out.println("public class " + args[0] + "{");
        out.println("public static void main(String args[]) throws Throwable {");
        out.println("int[] memory = new int[30000];");
        out.println("int data = 0;");
        final String code = args[1];
        for(int i = 0; i < code.length(); i++) {
            char c = code.charAt(i);
            switch(c) {
                case '>':
                    out.println("++data;");
                    break;
                case '<':
                    out.println("--data;");
                    break;
                case '+':
                    out.println("++memory[data];");
                    break;
                case '-':
                    out.println("--memory[data];");
                    break;
                case '.':
                    out.println("System.out.print((char)(0xFF & memory[data]));");
                    break;
                case ',':
                    out.println("memory[data] = System.in.read();");
                    break;
                case '[':
                    out.println("while(memory[data] != 0) {");
                    break;
                case ']':
                    out.println("}");
                    break;
            }
        }
        out.println("}}");
    }
}

You can use it to compile the hello world sample from the Wikipedia page:

~>java BrainFk Hello "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>." > Hello.java
~>javac Hello.java
~>java Hello
Hello World!

Sometime I’ll have to post the Forth interpreter in Java I wrote (I know some might consider sacrilege to use both languages in the same sentence, but you can’t please everyone!).

Wednesday, December 2nd, 2009

Building 3D models using a Web Cam

Incredible technology to build a 3D model from a video of the desired object. Just watch the video:

You can go to the project site for more details.

Wednesday, November 25th, 2009

Great Quotes

“My definition of an expert in any field is a person who knows enough about what’s really going on to be scared.” - P. J. Plauger, Computer Language, March 1983

From Stackoverflow.

Tuesday, February 3rd, 2009

Phrase of the Day

“The devil is in the details, but exorcism is in implementation, not theory.” – (author unknown)

Tuesday, August 12th, 2008

Trying out ecto

I’m doing this post by using ecto which is a desktop blogging client for the Mac. It seems easy enough to use, and I’ll probably have a clearer opinion of it in a few days.

Update 08-Feb-2008: So far so good. I’m still trying to find an advanced mode where I can insert/edit html.

Thursday, February 7th, 2008

Juggling Chainsaws

Andrew writes probably one of the funniest and most elocuent articles I’ve read about thread programming. His opening line:

 Writing multithreaded code is like juggling chainsaws; amazing when it works and truly sucky when it doesn’t.

Truly summarizes the feeling when you’ve had to deal with a multithreaded system. He argues that probably one of the most difficult thing to achieve is “avoiding doing nothing”. I agree with his thoughts in the sense that if you are even considering multithreading something, you are trying to achieve maximum utilization (i.e. not wasting resources). But I’m not sure that getting maximum utilization is the hardest part by itself.

Besides the usual problems, like avoiding deadlocks or protecting shared data, I always found that the hardest part was, to paraphrase Andrew, “avoid doing something”.

What I mean is that in multithreaded applications (it also applies to distributed applications), probably the hardest part is coming up with ways to avoid needing synchronization.

At least in my experience, figuring out ways to make the system exhibit consistent and predictable behavior without relying on atomicity, has always been the part that most of the design effort is invested in, and if done properly, where the greatest gains in scalability is achieved.

Take for example the Google File System, a massive, multi-petabyte storage filesystem. It is designed to work on clusters of several thousand machines, distibuted across several datacenters (even on different countries).

To achieve the expected performance, they had to throw away the usual file semantics, and think completely out-of-the box. But don’t take my word for it, go, fetch the paper (if you haven’t already done so), and read it yourself.

Wednesday, February 6th, 2008

A better way to do concurrent programming (Part 1)

A while ago (I think round 2005), some guys from Microsoft Research published a paper about Composable Memory Transactions.

After reading it, I began doing a small implementation in Java (quite ugly, btw), and I was astonished by the possibilities. So quite naturally (being the geek I am), I started toying with the idea of implementing a set of extensions for Java.

In this and other posts, I’ll try to make an introduction to the basic idea. Note that I will probably change existing posts quite often to correct mistakes or ommissions. In this post I’ll focus on an overview of the basic idea, in a future post I’ll address composition of transactions (the C in CMT), static checking for side effects, and alternatives to implement the runtime part of this. If you’re really curious, I recommend reading the original paper.

The gist of the idea is to replace common locking based semantics with in-memory transactions, so instead of writing complex locking semantics, you rely on optimistic locking handled by the runtime.

The following example shows how a producer-consumer problem can be solved with a queue of fixed size using Java with CMT:

public class BufferedQueue {
    private LinkedList list;
    public BufferedQueue() {
        list = new LinkedList();
    }
    public Object consume() {
        Object value;
        atomic {
            if(list.isEmpty()) {
                retry;
            }
            value = list.removeFirst();
        }
        return value;
    }
    public void produce(Object value) {
        atomic {
            if(list.size() > 10) {
                retry;
            }
            list.add(value);
        }
    }
    public Object peek() {
        Object value;
        atomic {
            if(list.isEmpty()) {
                retry;
            }
            value = list.getFirst();
        } else {
            value = null;
        }
        return value;
    }
}

Take a look at two keywords: atomic and retry

The atomic keyword demarcates a transaction. That means that this block is all-or-nothing (well get to the else later). For example let’s take a closer look at the consume method.

public Object consume() {
    Object value;
    atomic {
        if(list.isEmpty()) {
            retry;
        }
        value = list.removeFirst();
    }
    return value;
}

The atomic statement starts a transaction. In this transaction we first check to see if the list is empty. If it is, we issue a retry statement.
The retry statement, rolls-back all changes and suspends the transaction until at least one of the fields used in the block (either directly or indirectly) is modified by another transaction committing. When this happens, the execution is restarted in a new transaction at the beginning of the enclosing atomic block.
If this time the list is not empty, the first element is removed from the list, and the transaction is committed. If at the time of the commit there is a conflict with another transaction, the execution is rolled back and retried.

Note that it is very important that the atomic blocks do not have side-effects (such as creating files, etc.) outside of the control of the transaction manager.

(to be continued…)

Monday, November 5th, 2007