Factor Language Blog

FactorCon wrap-up

Sunday, August 26, 2007

Today is my last day in Austin. On Friday, we went jet-skiing; as it turns out, I’m not so good at driving one, so after a brief attempt which climaxed in me tipping over the jet-ski (with all three people on it), I delegated driving responsibilities to Doug’s friend, also named Doug (common name in Texas?).

Eduardo had to go back to work. Me and Doug did a did a bit more hacking, Ed-less – we got non-blocking UDP working on Windows, and Doug started working on a directory entry change notification binding for Windows. This won’t be ready until Factor 0.91, but I’m going to implement the Unix side; kqueue on BSD, inotify on Linux, and whatever crap Solaris has on Solaris. Having a cross-platform directory change notification API is something I’ve wanted for a while; many other language implementations don’t bother with features like this, but I consider it essential.

I also optimized the MD5 library a little bit, and improved the locals library (you can have local word definitions, and locals are writable). Doug updated the libs/math library for the new module system. There’s a lot of cool code there; quaternions, polynomials, combinatorics, numerical integration… indispensable tools for hard-core programming.

I’d like to elaborate on one point regrading writable locals. Consider the following Lisp function:

(defun counter (n)
  (values
    (lambda () (prog1 n (setf n (1- n))))
    (lambda () (prog1 n (setf n (1+ n))))))

This returns a pair of closures which increment and decrement a shared counter. Each closure returns the current value of the counter before changing it. The initial value of the counter is the value passed to the function, and each pair of closures has a unique internal counter value.

Using the locals library, the Factor equivalent is:

:: counter | n! |
  [ n dup 1- n! ]
  [ n dup 1+ n! ] ;

The ! suffix in the list of local parameter names indicates the local should be writable; now, the n! local word can be used to write to it. The Factor code is almost identical to the Lisp code, except with fewer parentheses.

In both cases, you see that we differentiate between binding and assignment, and also we are able to write to a local closed over in an outer scope; the n! word does not create a new internal variable in the counter quotation, but modifies the value in the lexical environment of the counter word.

On the other hand, some languages, such as Python, claim to support lexical closures, however the essential property of closures – that they close over the lexical scope – is not preserved, and assigning to a local simply creates a new binding in the innermost scope! Guys, that is retarded! Look at the workarounds these people use. It is really no better than Java’s anonymous inner classes, and if you want to call those “closures”, you may as well say that C# is a “dynamic” language.