Monday, March 31, 2003

Continuations and VMs

Dan Sugalski:

Anyway, a continuation is essentially a closure that, in addition to closing over the lexical environment, also closes over the control chain. (Well, OK, control stack, but if you’re doing continuations odds are it’s a singly linked list rather than a real stack.) CS texts generally go on about continuations being “the rest of the program” or “gotos with arguments” or suchlike stuff. If those float your boat, great—they never made sense to me.

Yeah, I think it depends on whether you are looking at this from the angle of implementation or theory. If you’re writing a VM, then you think in terms of closing over the control chain. If you’re doing denotational semantics, you think in terms of lambdas for the rest of the program.

Update: Here’s part 2.

Open Source StackViews

Alexei Kosut:

So I rewrote this thing yet again. I didn’t use any of Omni or Camino’s code, although having seen their implementations did make mine go pretty quickly. And now I’m relatively happy, since my table-like view works, and the licensing works out the way I wanted. But still, it seems like there’s something wrong that there’s all that source code out there that does exactly what I want, and that I can even download and look at, but cannot use. Were I a more philosophical or political person, I might even have something Important to say about it.

IMO, this kind of view should really be part of Cocoa to begin with, as it is in Java.

Objective-C Code

Apparently there are archives of NeXT source code here and here.

Interview: Brent Simmons

John Gruber interviews Brent Simmons, the author of NetNewsWire.

Quote of the Day

I will now sell five copies of the Three EPs by The Beta Band.High Fidelity

Sunday, March 30, 2003

Reference to Kinds in English

Kai von Fintel:

This is exciting. Greg Carlson has made a pdf-version of his 1977 dissertation Reference to Kinds in English available on the semanticsarchive.

(In this case, kinds means nouns like dogs, where the meaning depends on context.)

Blocks in Objective-C

Joe Osborn’s OSFoundation framework adds blocks to Objective-C. The context for the block is passed in manually, and the code is specified as a string that’s interpreted at runtime.

Chris Kane mentions that you can do something similar using GCC 3.1’s nested functions and statement expressions. Blocks created in this way have lexical scope, but not dynamic extent, and the syntax is not great.

Eric Raymond on Metadata

Harold Martin:

So Eric Raymond says that meta data or, as he puts it, file attributes, are important. Just as Mac OS X drops support for such meta data. So the Linux community learns this from Mac OS X, but where did OS X learn no meta data from?

Iterators

Erik Barzeski posted about iterators in Cocoa, so I thought I’d give some perspectives from other languages. I think there are really two concepts here: iteration and generation.

I don’t know that everyone agrees with these definitions, but to my mind iteration is about obtaining a sequence of values, without caring about how those values are produced. This is embodied by the NSEnumerator interface, java.util.Iterator, and the Python iteration protocols. Iteration is about how you get the values that you want to consume.

Here’s what iteration looks like in Cocoa:


NSEnumerator *enumerator = [objectStructure objectEnumerator];

id o;

while ( o = [enumerator nextObject] )

    // do something with o

I use a C macro so that I can write it like this:


foreach ( o, [objectStructure objectEnumerator] )

    // do something with o

Some languages, like Python, have a syntax for iteration:


for o in objectStructure:

    # do something with o

In the above example, Python will call objectStructure’s __iter__() method to get an iterator object.

Generation is about how to produce the values. The generator returned by -[NSArray objectEnumerator] probably keeps a reference to the array and remembers an index into that array. When you send it -nextObject, it increments its counter and returns another object. java.util.Iterator is similar. This is straightforward to implement for list-like things. For instance, my SQLite wrapper includes an NSEnumerator subclass for rows in a database table. It took seconds to write. But how do you write this kind of generator for the nodes in a tree? Or the interesting tokens in a mail message? You need to remember more state than just an index, and it can be a real pain. In practice, people often perform a full traversal of the structure, stuffing the objects into an array, and then return the array’s generator. That makes the code much simpler, but inefficient.

I’ve seen two other ways of writing generators, which work better in the more complex cases. What I call the closure approach inverts the problem. Instead of writing code that gets values from a generator object and then does something with them, you put your code in a closure (a.k.a. lambda or block) and give the closure to the generator. This is the approach taken by Smalltalk and Ruby, and it could also work in other languages with closures, such as Lisp and Perl. From the caller’s perspective, we get something like this (in Ruby):


objectStructure.each { |o|

    # do something with o

}

Here, the block (in curly braces) becomes an argument to the method call. The each method traverses objectStructure and evaluates the block many times, passing in different o’s.

Other languages use what I call the yield approach, which was popularized by CLU in the mid-70s. Under this approach, generation is handled by a function that can, in effect, return multiple times. Instead of using a return statement to return, it uses a yield statement. yield is like return, except that the next time the function is called, it resumes after the last-executed yield statement.

Here’s an example in Python:


# A recursive generator that generates Tree leaves in in-order.

def inorder(t):

    if t:

        for x in inorder(t.left):

            yield x

        yield t.label

        for x in inorder(t.right):

            yield x 

Is that beautiful or what?

Interestingly, the keyword that Ruby uses to evaluate a block parameter is also called yield. It’s used for roughly the same reasons, but what’s going on under the hood is quite different. Ruby’s yield is like a function call, whereas CLU/Python’s is like a function return.

I like return-style yield better. It can even be used to create infinite generators (a.k.a. streams):


def odds():

    i = 1

    while True:

        yield i

        i = i + 2

Unfortunately, there is no yield, of either kind, in the C family. You can kind of fake it using macros.

Quote of the Day

Facts do not cease to exist because they are ignored. —Aldous Huxley

Friday, March 28, 2003

iAppViews

Nicholas Riley links to iAppViews, code by Evan Jones that apparently demonstrates best practices for alternating background colors in NSTableView and NSOutlineView.

Can You Hear Me Now? I Hope Not!

Lee Bennett:

If I’m pissed off, I assure you that I won’t leave it to an ambiguous sentence for you to infer my mood. I will let you know it.

bbhexdiff

Eric Blair:

bbhexdiff is a Perl script that uses the command-line hexdump tool and BBEdit’s Find Differences command to compare hex dumps of files. As the name suggests, it’s somewhat based on John Gruber’s bbdiff command.

Teststands

Jonathan Rentzsch:

Create a new, empty project. Set it up as you like it, so it’s easy for you to use. Include your favorite libraries, and turn off the optimizers (which slow down compilation and make low-level debugging more difficult). Now leave it, empty, sitting there. This is your teststand.

XML Doesn’t Suck

Tim Bray:

Recently in this space I complained that XML is too hard for programmers. That article got Slashdotted and was subsequently read by over thirty thousand people; I got a lot of feedback, quite a bit of it intelligent and thought-provoking. This note will argue that XML doesn't suck, and discuss some of the issues around the difficulties encountered by programmers.

(Perl|Python|Ruby) on (.NET|JVM)

Parrot architect Dan Sugalski explains why the two big VMs are poorly suited for dynamic languages. He then demystifies closures without mentioning Lisp and promises a similar treatise on continuations (which the JScheme folks also decided not to support on the JVM).

Copying and Equality

Kent M. Pitman:

Operations in Lisp, Scheme, and other dynamically-typed languages typically dispatch on representational type information rather than intentional type information. Several broad classes of bugs and confusions can be traced to improper attempts to recover intentional type information from representation types.

Studying Programming Languages

I just heard about this paper by languages guru Daniel P. Friedman.

Continuations

John C. Reynolds:

In the early history of continuations, basic concepts were independently discovered an extraordinary number of times. This was due less to poor communication among computer scientists than to the rich variety of settings in which continuations were found useful.

Cocoa Widgets

Stephane Sudre shares his code for implementing Mail.app-style search fields and Date & Time–style text fields.

Ben & Mena

Steven Frank has written a song about blogging. It’s clever. Right up there with James Dempsey’s songs about EO and reference counting.

Maya

Alias|Wavefront:

Maya Personal Learning Edition™ is a special version of Maya®, which provides free access to Maya Complete™ software for non-commercial use.

MagicHat

MagicHat reconstructs @interfaces from Objective-C frameworks and attempts to find the corresponding header files and documentation. Unlike class-dump, it provides a real human interface, although it’s more difficult to use MagicHat on arbitrary files.

Algorithmic Information Theory

Gregory Chaitin:

Most work on computational complexity is concerned with time. However this course will try to show that program-size complexity, which measures algorithmic information, is of much greater philosophical significance. I’ll discuss how one can use this complexity measure to study what can and cannot be achieved by formal axiomatic mathematical theories. In particular, I’ll show (a) that there are natural information-theoretic constraints on formal axiomatic theories, and that program-size complexity provides an alternative path to incompleteness from the one originally used by Kurt Gödel. Furthermore, I’ll show (b) that in pure mathematics there are mathematical facts that are true for no reason, that are true by accident. These have to do with determining the successive binary digits of the precise numerical value of the halting probability W for a “self-delimiting” universal Turing machine. I believe that these meta-theorems (a,b) showing (a) that the complexity of axiomatic theories can be characterized information-theoretically and (b) that God plays dice in pure mathematics, both strongly suggest a quasi-empirical view of mathematics. I.e., math is different from physics, but perhaps not as different as people usually think. I’ll also discuss the convergence of theoretical computer science with theoretical physics, Leibniz’s ideas on complexity, Stephen Wolfram’s book A New Kind of Science, and how to attempt to use information theory to define what a living being is.

Real World Adobe GoLive 6

Jeff Carlson and Glenn Fleishman:

We seem to have incurred a huge bandwidth bill.

MulleEOInterface

Mulle kybernetiK:

The MulleEOInterface framework is a binary replacement for the EOInterface framework that Apple delivered in their Objective-C version of WebObjects (4.5). It's the link between EOControl and AppKit. With EOInterface you could conceivably - if you had a IB palette - easily create fairly complex desktop applications using Interface Builder and no code at all!

Hungarian Notation

Joel on Software has a discussion about Hungarian notation, which I think is generally counterproductive.

C++ Templates: The Complete Guide

Slashdot says this is a great book.

Source Code In Database

Roedy Green:

We have been teaching our customers to regard their data as a precious resource that should be milked and reused by finding many possible ways of summarising, viewing and updating it. However, we programmers have not yet learned to treat our source code as a similar structured data resource.

Generalizing Polymorphism With Multimethods

David Mertz:

Object-oriented programming gains much of its versatility through polymorphism: objects of different kinds can behave in similar ways, given the right contexts. But most OOP programming is single dispatch; that is, just one designated object determines which code path is taken. Conceptually, a more general technique is to allow all the arguments to a function/method to determine its specialization. This article presents an implementation of multiple dispatch in Python, and shows examples where this makes for better programs.

DiskWarrior Rocks

Good thing my Mac can boot into OS 9. DiskWarrior 3, which is OS X–native, isn’t out yet, and last week I had to use DiskWarrior 2 to fix my internal drive before the Mac would even boot. So much for a stable operating system protecting against catalog damage. DiskWarrior is great, but with all the files Mac OS X installs it takes hours and hours to run. I wonder what Alsoft plans for PlusOptimizer.

Meta-CVS

Here’s an interesting alternative to Subversion.

Meta-CVS is a version control system built around CVS. Although it retains most of the features of CVS, including all of the networking support, it is more capable than CVS, and easier to use.

LaTeX

Kai von Fintel links to information about using LaTeX with Keynote and using PostScript fonts with LaTeX.

PyTextile

Mark Pilgrim:

PyTextile is a Python port of Textile, Dean Allen’s Humane Web Text Generator. It supports all the features of the original, with the exception of converting high-bit characters to their HTML numeric entity equivalent, because that’s some bad-ass PHP goin’ on and I don’t pretend to understand it.

By the way, Pilgrim’s Dive Into Python is fabulous.

Java Programming Guidelines

Bruce Eckel’s Thinking In Java includes some guidelines that apply to other languages as well.

Software Development

Seth Dillingham:

While it is certainly beneficial to pattern some software after real-world objects, it really doesn’t make sense to think of developing software as constructing buildings.

CVS

Aaron Swartz has posted a tutorial for setting up CVS.

Dockless

Dockless is a freeware application for controlling which applications show their icons in the Dock.

Bowling for Columbine

Jerry Kindall:

David Hardy says that the film that just won an Oscar® for Best Documentary isn’t a documentary. In fact, Hardy goes so far as to call it “deliberately, seriously, and consistently deceptive.” And provides evidence.

Peter Schmies’s Word Classification Test

This looks like fun, but it also looks like it would take a long time to get through all 200 words.