archives

LL4 Call for Presentations

LL4 will be held at MIT on Saturday, Dec. 4. The due date for presentation proposals is Nov. 12.

We solicit abstracts of talks to be given at the workshop. Go for it -- convince us. Talks will be 30 minutes long, including time for questions and answers. Presenters are not expected to submit papers, but slides will be published on the workshop web site. We will also consider proposals for talks of different lengths.

Interesting? closure/object idea

I've been designing a language for my kids to use (goal: low barrier to entry, gentle learning curve up to serious power); one of the design choices has been to make closures easy to write. {x: x+5} is equivalent to Scheme's (lambda (x) (+ x 5)); {x*y} is a closure with no arguments. A Graham accumulator would be Acc={var x=0; {x++}} (declare a variable and return a closure over it).

After reading Paul Graham's ILC 2003 talk, I started wondering how much I would need in the language to permit objects to be done as a library. Objects are equivalent to closures, but I wanted to leave room for a convenient syntax. (If nothing else, a lot of the system facilities I'll want to bind to, such as GUI toolkits, are OO, so being able to speak OO lowers the impedance mismatch.)

So, the first thing I thought of was to break encapsulation (again, this was triggered by Graham's talk), to expose the bindings contained in a closure. So, if we do C=Acc(), creating an accumulator as above, then C.x is the current value of x in the closure. Obviously, since bindings in C can also be functions, this also gives us method calls with the usual sort of syntax.

OK, so that can be used to make objects convenient. Then I started wondering about inheritance. After some false starts, I hit upon the idea of letting the right-hand argument of "." be a general expression. So, for example, C.(x+y) would be equivalent to (C.x)+(C.y). Then I could provide a closure constructor as the right-hand argument:

C2=C.{var double={x*=2}}

creates C2 as a closure created within the context of C, with access to C's bindings. This will let me (eventually) do an object library where:

class Point(x,y) {
  to moveBy(dx,dy) {
    x+=dx; y+=dy;
  }
  to abs() {
    sqrt(x*x+y*y);
  }
}
maps to:
Point=
{x,y: {
       var moveBy={dx,dy: x+=dx; y+=dy;};      
       var abs={sqrt(x*x+y*y);};
       }
 }

and:

class PointWithFlip(x,y): Point(x,y) {
  to flip() {
    var tmp=x; x=y; y=tmp;
  }
}

maps to:

PointWithFlip=
{x,y: Point(x,y).{
  var flip={var tmp=x; x=y; y=tmp;}
  }
 }

That is, to create a PointWithFlip, create a Point, and then create a new closure, containing the flip function; that new closure is the PointWithFlip.

I'm pretty happy with this idea; it should let me teach my kids closures, rather than objects as such, but without blocking them from doing OO should it be useful. And, of course, I suspect that being able to get an arbitrary expression evaluated within a closure will turn out to be pretty powerful--with that, you could do things on the fly for which OO requires a subclass. And it doesn't distort the core language much, because you have to be able to construct closures inside closures anyway.

Is this something that's been studied before? If it has, of course, I'd like to read about it before trying to implement it.