Archive for September, 2008

First-class closures

Tuesday, September 30th, 2008

I have implemented first-class closures in my experimental language Church/State. Until recently I was using partial closures (also called “downward funargs”) because I thought full closures would not be necessary to bootstrap the system. I found, however, that my implementation of OMeta in Church required full closures. Unlike partial closures which were stack allocated and could not escape the dynamic extent of the call that created them, full closures are heap allocated.

One of the consequences of this is that there is no longer such a clear separation between Church and State. (I named these languages as I did because I thought I could maintain a clear division between them). Previously State was supposed to implement a “static” language with very little run-time features. Now, however, because closure creation requires heap allocation, the State compiler has to call out to an allocation routine and create a runtime structure called a “closure-record”.

Since I wanted closure objects to look like other objects in Church, each closure record has a class-pointer and slots that are compatible with the Church object system. To implement this the State compiler essentially has to call out to Church runtime code, which makes the two systems mutually dependent, instead of having only Church rely on State.

Below is the Church code declaring the closure related classes. Each closure-record has a parent pointer to create a chain a closure-records. These closure-records are passed as a “hidden” argument to all State functions, meaning that the State calling convention is no longer compatible with the C calling convention. To call C routines from State, I have provided the “call-c” operator.

class closure-record
        with-slots
                parent
                slot-count

class closure
        with-slots
                closure-record
                function
        closure?
                true