views:

717

answers:

3

I've been trying to understand how Ruby blocks work, and to do that I've been trying to implement them in C (^_^).

One easy way to implement closures is to pass a void* to the enclosing stack to the closure/function but Ruby blocks also seem to handle returns and break statements from the scope that uses the block.

loop do
  break i if (i >= 4000)
  i *= 2
end

I think one of the closures proposals for Java works like this also.

So, how would you implement Ruby-blocks/Java-closures in C?

+7  A: 

The concept of closures requires the concept of contexts. C's context is based on the stack and the registers of the CPU, so to create a block/closure, you need to either need to be able to manipulate the stack pointer in a correct (and reentrant) way, and store/restore registers as needed.

The way this is done by interpreters or virtual machines is to have a context structure or something similar, and not use the stack and registers directly. This structure keeps track of a stack and optionally some registers, if you're designing a register based VM. At least, that's the simplest way to do it (though slightly less performant than actually mapping things correctly).

wvdschel
+1  A: 

There's a good set of slides on Ruby Blocks as part of the "Rails with Passion" course:

Ruby_Blocks.pdf

This covers representing a block, how they get passed arguments and executed, and even further into things like Proc objects. It's very clearly explained.

It might then be of interest to look at how the JRuby guys handled these in their parsing to Java. Take a look at the source at codehaus.

Andrew Harmel-Law
+1  A: 

I haven't actually implemented any of this, so take it with a sack of salt.

There are two parts to a closure: the data environment and the code environment. Like you said, you can probably pass a void* to handle references to data. You could probably use setjmp and longjmp to implement the non-linear control flow jumps that the Ruby break requires.

If you want closures you should probably be programming in a language that actually supports them. :-)

UPDATE: Interesting things are happening in Clang. They've prototyped a closure for C. http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html might prove to be interesting reading.

Pramod