The SmalltalkAgents foreign-function interface
[info]chanson
I learned object-oriented programming first by reading the introductory materials shipped with Digitalk Smalltalk/V and then by using QKS SmalltalkAgents on my Centris 610 and my PowerBook 520. I think that's had a profound influence on my career and outlook compared to those who learned with C++ or Java, for example, almost as profound as the fact that I originally learned to program using Logo instead of AppleSoft BASIC.

One of the great things about SmalltalkAgents compared to most other similar environments was its great integration with the Macintosh System Software. It accomplished this by creating a great foreign-function interface that let you call arbitrary non-Smalltalk code from within SmalltalkAgents easily, efficiently, and in a way that Just Worked when it came to interacting with the operating system. And the fact that it could do this with the 68000-based Macintosh was a pretty interesting feat, due to the multiplicity of runtime models and calling conventions that wouldn't be unified until the release of the Power Mac.

Here's how it worked: SmalltalkAgents extended normal Smalltalk syntax with an additional construct, the ExternalMethod invocation which was effectively a function call with inline type information wrapped in «double angle brackets». (On a Mac, those are option-\ and option-shift-\ respectively; you could also use << and >> if you wanted.) Not only that, but SmalltalkAgents also supported a concept of structured storage for objects that would allow you to pass around C-style structures and pointers to them very easily.

So an invocation of a foreign function would look like this:
  sayHello
    | result |
    
    result := «printf(('Hello, world!' asCString):Ptr):Int».
    
    [result < 0] ifTrue: [ Exception raise: 'Error calling printf.' ].

    ^self
This is a method, sayHello, that invokes the ExternalMethod listed in the module-global ExternalMethodDictionary under the key symbol #printf. It declares the argument and return value types and uses some of the object coercions built into the SmalltalkAgents frameworks to get values that will be passed to the foreign code properly.

Creating a new ExternalMethod is very easy, too, especially if you can rely on it to follow one of a couple standard calling conventions. SmalltalkAgents defines all of the basic machine-style parameter types you'd expect, and you pass them at the call site rather than when creating an ExternalMethod, so you don't have to do all sorts of complicated header file parsing that many other similar technologies require you to use. Instead, you can just create what amounts to a list of the external methods you want to support and provide some way to hook them to their actual code (whether via a load of a code resource or a pointer in an external library), and then you can Just Use Them in your Smalltalk code.

It worked great, and I think it's something a lot of modern systems could learn from.

Croquet has a new wiki!
[info]chanson
I'm not sure when it happened, but OpenCroquet.org is now a fancy MediaWiki for the Croquet Consortium.

In case you haven't seen it, Croquet is a bit like Second Life, but instead of being a client that connects to a server, it's a node that can talk to other nodes and that provides an immersive 3D environment for building Interesting Stuff. The difference is that, unlike Second Life, it's tools for building Interesting Stuff aren't stone knives and bearskins primitive. Why? Because it's built on top of Squeak Smalltalk!

Don't worry, though — it's plenty fast, too, though certainly rougher around the edges at the moment than Second Life. The Croquet environment leverages native platform technologies for things like 3D and audio, and Squeak Smalltalk is also getting some extensive performance work done lately — check out the Exupery dynamic optimizing compiler for an example of the kind of work Croquet will be able to leverage.

Really, Croquet seems likely to be the first step in bringing about some of the good parts of Snow Crash like the distributed, immersive Metaverse. After all, we're already well along in bringing about the bad parts of Snow Crash — see the classic essay Grim Meathook Future by Joshua Ellis for some details.

Reading through the current Croquet FAQ, one thing Croquet definitely needs soon is NAT traversal. Otherwise, how are people going to be able to collaborate on improving Croquet from their home wireless networks? I bet someone who knows their way around the common traversal protocols could put together some classes for handling it fairly easily...

It's not the dynamic dispatch!
[info]chanson
Joel has decided to blame the use of dynamic dispatch for Ruby's speed issues:
Without knowing much about the implementation of Ruby, I would guess that the biggest issue is around late binding and especially duck typing, which prevents type inference or strong typing, which means that function calls will always be slow because you can never get something compiled down to the point where a function call is just a single CALL instruction (on x86)... you always have to be exploring the object, possibly even scanning a hash table to find the function you want to call.
In other words, "it's always going to be slow because if it's not strongly-typed it can't be statically compiled to the most minimal possible instruction sequence!" Which is, simply put, a bullshit argument even if you ignore the fact that he said right up front it was bullshit.

There's a lot that you can do to optimize dynamic dispatch. If you don't believe me, take a look at the implementation of the Apple/NeXT Objective-C runtime, objc4. Go ahead, it's Open Source. (The link is for the version that's part of Mac OS X 10.4.7 for Intel processors.) It implements full Smalltalk-style dynamic dispatch — the same type of dynamic dispatch that Ruby uses. And what's more, Ridiculous Fish also wrote a great article on how dynamic dispatch is implemented in the objc_msgSend() primitive — with particular attention focused on its performance characteristics!

No, it's not message-based dynamic dispatch or "duck typing" (runtime polymorphism) that makes Ruby slow. It's the fact that Ruby is a single-pass interpreted language. It's not compiled to bytecode. It's not compiled to native code. It's scanned, parsed, and then immediately executed.

Imagine if your C compiler, or your Fortran compiler, or your Java compiler — or your Visual Basic compiler, for that matter — had to be invoked every time you ran your program. Imagine how slow that would be! That's essentially what Ruby is doing, and that's why it's slow. Ruby 2.0 is planned to run on the YARV virtual machine, and there has also been work to compile Ruby code for LLVM. There's nothing in Ruby's nature that makes this a particularly difficult problem, especially since all of the issues of efficiently compiling dynamic languages with reflection and self-modification features were solved by Lisp in the 1960s and Smalltalk in the 1970s.

Incidentally, this is why I react so vehemently when people talk about "Lisp interpreters." Lisp is almost never interpreted, specifically to avoid these types of performance issues. At the least most Lisp systems compile to a custom bytecode and then use an optimized bytecode engine to execute that. That way they can eliminate the scanning and parsing overhead — yes, it does exist for Lisp, because contrary to what Lispers may say, the language does have syntax — while still stay portable.

Others have also been piling on, such as Avi Bryant and Obie Fernandez. As Obie points out, Avi knows what he's talking about. And so do folks who work with Objective-C intimately, day in and day out.

Programming language terminology lesson: Closures
[info]chanson
In reading Beyond Java by Bruce Tate, I saw the following:
Java's syntax lacks features like closures and code blocks (which let you pass a block of code as an argument).
Argh!

In the vast majority of languages that support them, a block is a closure! Blocks, closures, lambdas — they're all just different words for the same thing! A closure is just a piece of code that carries around ("closes over") definitions from the environment in it was defined, and can be executed later using those definitions, possibly taking some arguments as input as well.

The terminology distinction between blocks and closures probably comes from the days when Smalltalk blocks weren't closures. That is, they would reference the environment in which they were executed rather than the environment in which they were defined. However, since at least the early 1990s, I believe all major Smalltalk environments have switched to representing blocks as closures.

Steve Yegge describes what's wrong with Lisp
[info]chanson
Steve Yegge, Lisp is Not an Acceptable Lisp:
You've all read about the Road to Lisp. I was on it for a little over a year. It's a great road, very enlightening, blah blah blah, but what they fail to mention is that Lisp isn't the at the end of it. Lisp is just the last semi-civilized outpost you hit before it turns into a dirt road, one that leads into the godawful swamp most of us spend our programming careers slugging around in. I guarantee you there isn't one single Lisp programmer out there who uses exclusively Lisp. Instead we spend our time hacking around its inadequacies, often in other languages.
Steve does a very good job of articulating a lot of the things I dislike about Lisp, especially Common Lisp. One interesting thing, though, is that a lot (but not all) of the issues he raises are addressed by Dylan.

One of the more interesting things about Dylan in this context is that, despite not adopting a traditional message-based object system like Smalltalk or Objective-C (or their more static cousins C++ and Java), Dylan does push objects all the way down, but in a functional style. It appears to work pretty well, making it easy to define both nouns and verbs in the combinations a developer might need, and even (through its hygienic macro system) allow developers to extend language syntax too.

Cooperative User Threads vs. Preemptive Kernel Threads
[info]chanson
James Robertson, Cooperative Threading:
Well, in Cincom Smalltalk, this model gives you predictability - you know exactly what a thread is going to do. The issue with runaway threads rarely comes up for a simple reason - most processes end up pausing for I/O (user input, db access, file access, sockets - what have you). That wait for I/O state is what prevents a problem from arising.
This is a classic problem and I'm honestly surprised to find out that Cincom Smalltalk implements cooperative user-level threads rather than supporting preemptive kernel threads.

Here's what I posted in response to James, unattributed thanks to the torturous comment interface on his blog:
One issue with cooperative threads relative to preemptive OS-supplied threads is that you get far less opportunity for true concurrency within an application. In an era when multi-core processors are becoming significantly more common, this is becoming exceptionally important to application developers. It's not just about doing I/O concurrently with other operations or allowing an application to perform multiple tasks at once; it's about allowing a task to be completed faster because more efficient use is being made of machine resources. This is why I take an extremely skeptical view of user-level threading packages, especially in software built on platforms that have reasonable kernel-level threading.
You'll note that the various threading APIs in Mac OS X are all built on kernel threads.

Furthermore, the Mach microkernel schedules exclusively in terms of threads. The microkernel doesn't even have a conception of processes! It only knows about collections of resources — tasks — such as address spaces and IPC ports, and flows of control — threads — that it can schedule on processors.

Dylan
[info]chanson
From the Introduction to the The Dylan Reference Manual:

Dylan is a general-purpose, high-level programming language, designed for use in application and systems programming. Dylan includes garbage collection, type-safety, error recovery, a module system, and programmer control over runtime extensibility of programs.

The name "Dylan" is a portmanteau of the words "dynamic" and "language." Dylan is designed to allow efficient, static compilation of features normally associated with dynamic languages.</p>

There's a lot more information at Gwydion Dylan. I became interested in the language back in the early 1990s, when Apple sent copies of the original book on the original version of the language to any developer that asked.

A lot of top-notch Lisp hackers worked on Dylan, including a lot of people who came from the Lisp machine community. Take a look at these screenshots of a project browser and a class browser from Apple's Dylan environment.

A reasonable way of describing Dylan would be as Scheme plus the Common Lisp Object System (CLOS), cleaned up quite a bit, with a Pascal-style infix syntax. I much preferred it before the change to the infix syntax. It makes code much more needlessly verbose, and it made both the macro system itself and Dylan implementations much more difficult than the original Lisp-style syntax would have.

After reading The Art of the Metaobject Protocol, I have to say that Lisp-syntax Dylan is a much cleaner language than Common Lisp. The price of that is, of course, that Dylan isn't compatible with the existing body of Lisp code, whereas Common Lisp strove for portability.

Like CLOS, Dylan is based on interacting with objects which are instances of classes and are made up of slots. Classes can inherit from other classes, even more than one, and there are fairly straightforward rules describing what happens when inheriting from multiple classes that declare slots with the same name, or from multiple classes that share base classes.

The most significant difference between CLOS and Dylan on one side and Smalltalk and C++ on the other side is that interacting with objects isn't done by sending them messages. Instead, objects are strictly data; they have generic functions applied to them. Generic functions are essentially collections of methods whose arguments are specialized on the classes of the objects they interact with. When a generic function is applied to some objects, the most specific method that is specialized on those objects' classes is invoked; that method can, in turn, invoke the next-most-specific method, and so on.


Resurgence
[info]chanson
Is it just me, or has the accelerating growth in weblogs, the accelerating growth in computing power, and the accelerating exposure of normal programmers to highly dynamic languages like Perl, Python, and Ruby combined to bring about a resurgence of interest in Lisp?

In preparation of welcoming our new parenthetical overlords, I've been reading The Art of the Metaobject Protocol and over the weekend I installed OpenMCL:
% openmcl
Welcome to OpenMCL Version 1.0 (DarwinPPC32)!
? (require "cocoa")
For more Lisp fun, and a convenient Lisp blog aggregator, check out Planet Lisp.

I think languages that follow the lead of Common Lisp, Dylan, and modern Smalltalk have the most potential as Singularity enablers due to their abstraction and complexity-management features. At some point, I want to write a bit about why they haven't so far seen the kind of uptake that either the C-family languages or the (so-called) "scripting" languages have.

Yes, I know all about Richard Gabriel's Lisp: Good News, Bad News, How to Win Big which gave us the Worse Is Better aphorism. I don't have quite the same take on it though I certainly think Gabriel's perspective is valuable.

Model/View/ViewModel
[info]chanson
This guy must be kidding. Introduction to Model/View/ViewModel pattern for building WPF apps (John Gossman):
Model/View/ViewModel is thus a refinement of MVC that evolves it from its Smalltalk origins where the entire application was built using one environment and language, into the very familiar modern environment of Web and now Avalon development.
Yeah, because Model-View-Controller is just so inadequate when you're using visual human interface construction tools to create desktop applications or web applications.

I mean, it's not like anyone else has had an "interface builder" as an integral part of their platform. Or tools for creating web applications out of reusable and composable "web objects."

Good Reads Online
[info]chanson
A while back, I saw on Lambda the Ultimate that Smalltalk-80: Bits of History, Words of Advice was available online.

There are quite a few more worthwhile language books on the Web. For example, Tim Budd's A Little Smalltalk is also available at Professor Ducasse's site.

You can also find Common Lisp: The Language, Second Edition in various places online, and Paul Graham has made On Lisp available.

I started down this route because I'm reading Graham's Hackers & Painters right now and in some ways it reminds me of Patterns of Software by Richard P. Gabriel which, it turned out, Gabriel posted online once it went out of print.

Time-and-Materials Versus Fixed-Bid
[info]chanson
There's a great discussion taking place right now on the Cocoa-Dev mailing list about custom software development. (The original poster called it "freelance programming.") One of the posters said they always try to work on a fixed bid, where their bid is based on the value to their client. This is what I posted in response, very lightly edited for formatting.

I prefer not to work on fixed-bid projects. I do time-and-materials, because of the methodology I use. I've run into too many situations where attempts to fully-specify systems up front just aren't realistic. So I work according to an agile development methodology inspired by Extreme Programming.

I work in very short iterations and incrementally deliver functionality to my clients, using the Planning Game to determine their needs in the form of user stories. They're only paying for what they get, and they're getting the most important stuff first. That's first according to their most current business needs, rather than what they thought their business needs would be three or six months from when they first contacted me about the project.

http://c2.com/cgi-bin/wiki?ExtremeProgramming
http://c2.com/cgi-bin/wiki?PlanningGame
http://c2.com/cgi-bin/wiki?TestDrivenDevelopment

One of Cocoa's hidden strengths is that it plays very nicely with Extreme Programming. There are several great unit testing frameworks that you can use with Project Builder to do Test Driven Development. The rapid turnaround of Cocoa makes it feasible to do even significant features in one- to three-week iterations. And the dynamism of Objective-C almost perfectly matches that of the Smalltalk environment Extreme Programming was developed in.

I'm still surprised that the Extreme Programming crowd hasn't latched on to Cocoa and Objective-C.

AppleScript and Cocoa applications
[info]chanson
Adding AppleScript support to Mac applications has always been difficult. AppleScript is built on a complex object model and a data-driven mapping between an application-defined terminology and that object model; this determines what events get sent to an application and how they're constructed, what the replies look like, how they should be represented to the user, and so on. And then you had to actually implement all the low-level details of responding to the events and managing the object model. Frameworks like Metrowerks PowerPlant and MacApp helped, but you still had to do a lot of work to make anything significant happen.

Enter Cocoa. Because Cocoa was designed around the Smalltalk-like Objective-C object model, there are all sorts of nifty run-time introspection features available to developers. Therefore, to make a Cocoa application scriptable, all you need to do is make sure your model objects are accessible via Key-Value Coding — which most tend to be due to the common idioms and design patterns Cocoa developers use — and define your terminology. The terminology has been extended slightly to describe how to map from AppleScript-level entities & commands to classes & messages in an application; however, you don't generally have to write the code to actually handle all the individual events associated with AppleScript, interpret the various object specifier forms, and so on. Cocoa does that stuff for you.

What's more, Don Briggs wrote a great application called SuiteModeler that lets you edit the script suite & terminology files very easily and directly. The files are already easy-to-edit property lists (either in the old ASCII or new XML format), but SuiteModeler will keep them consistent for you, and make the process of developing or tweaking your scripting support go so much faster. It's definitely worth the $25 shareware fee.

So something that used to be so heinous that very few applications did it and that applications had to be almost entirely re-architected to support is now nearly free and has a very minimal impact on your codebase. I love this new world.

Simonyi Leaves Microsoft
[info]chanson
Steve Lohr, A Microsoft Pioneer Leaves to Strike Out on His Own (New York Times) - Charles Simonyi, a computer scientist who joined Microsoft when it had 40 employees and who helped set its technical strategy for years, is leaving the company to found his own software start-up.

Simonyi's the guy who came up with the winning idea that to make code more maintainable you should make it less readable. Of course, it wasn't actually put that way; the idea is that you prefix the names of all of your variables with the types of those variables and that somehow helps you maintain the code more easily. This is called, of course, "Hungarian notation." It's one of the things that makes Windows code damn near illegible, because like everything else Microsoft does Windows programmers treat it as gospel.

I was sort of hoping he'd stay with Microsoft. Keep the damage confined to the Microsoft sphere, you know?

I don't get the obsession with variable typing that lots of developers seem to have. Do they really make that many type errors? Even when I was doing lots of work in C++, I didn't make nearly enough type errors that such bondage & discipline techniques as Hungarian notation and templates were worth the time they took to learn and use and debug. (In the case of templates, they also get in the way of writing good object-oriented code since they're actively hostile to object-oriented programming.)

Using languages like Smalltalk and Objective-C that leave types to values instead of variables I'm far more productive and wind up writing far less code. And every line of code you don't have to write is a line of code that can't have an error in it. (That's also why you shouldn't hard-code graphical human interfaces - or web interfaces, for that matter. Use tools that can automatically wire up your controller objects to your views based on data.)

For those who don't know the language yet, Objective-C's type system is essentially the same as C's with one additional type: id. An id represents a pointer to any kind of object; it's like a void * for objects, and it's necessary because while Objective-C only has single-inheritance of classes it supports multiple root classes. Even so, you can declare a variable as having type Foo * and if you send a message to the object referenced by it that neither the Foo class nor any of its superclasses understands, you'll get a compiler warning.

Yes, a warning, not an error. Sometimes it's valid to send a message to an object that doesn't declare it can handle it. For instance, you might have a proxy object that's standing in for a distant object on the other side of a Distributed Objects connection. Or an object that acts as a bridge to another language or object system by translating messages it receives into whatever the other system requires.

Tools, Refactoring, Java
[info]chanson
I'm an unabashed Objective-C fan. I think it's one of the best languages around: The Smalltalk object model with complete access to C. On the other hand, the fact that it's C makes it harder to develop high-end Objective-C tools.

I'm reading Refactoring by Martin Fowler right now, and it's totally obvious how not having a preprocessor or header files can really help in creating tools like a refactoring browser. (Of course, I learned object-oriented programming with Smalltalk, so I know firsthand how useful tools like that can be.)

I want some of this stuff for Objective-C but unfortunately it's going to be a whole bunch more work for the tool vendors to ship. Not as much work as it would be for C++, but definitely more than it is for Java. (Maybe someone needs to create a new language, like Objective-C but without the C baggage like header files, machine pointers, or a preprocessor. Sort of like WebScript with classes. It could be called "Objective" or maybe "Smalltalk"...)

Model-View-Controller
[info]chanson
Back in the 1970s, when Alan Kay's team at Xerox PARC (now "Palo Alto Research Center Incorporated") was inventing object-oriented programming, the Smalltalk language and the basis of the modern graphical human interface, they invented a design pattern that every software developer should know, understand, and use today: Model-View-Controller.

In an MVC application, there are three primary types of objects: Model objects, view objects, and controller objects. Each type of object has its own role to play, and by keeping objects' roles separate an application can be designed to be much more maintainable and extensible than if everything is intermingled.

A model object typically represents a single piece of data or knowledge. It may have relationships to other model objects, but it is not directly linked to anything in the application's human interface. Keeping human interface knowledge out of model objects helps them to be very reusable between different applications. For instance, model objects can be shared between a desktop and a web application, even though those applications may have radically different interfaces.

A view object represents an interface element in your application's human interface. This includes both display-only elements like windows, pictures and static text strings, and editable elements such as edit fields, checkboxes, buttons, and pop-up menus. View objects are "dumb"; they have no knowledge of the information they present, they only know how to show it. By keeping views dumb, views can often be made extremely reusable between different applications. A slider is a slider and a checkbox is a checkbox and a window is a window, no matter what they represent in your application.

Controller objects are the glue that binds an application together. Controllers have deep knowledge about both your model objects and your view objects, and control the interaction between the two. When you pick an item from a popup menu, the popup sends a message to a controller, which determines which item was picked and how that should modify your data model. The controller modifies the data model, and then modifies other elements as necessary based on the data model changes. Controller objects are often not reusable between different applications because they represent the bulk of the application-specific behavior.

It's disturbing how many people write applications without thinking about how to break them down into model, view, and controller objects. I've seen applications -- and written some, before I understood MVC -- that do things like rely on interface elements for data storage, subclass interface elements to represent an element that manipulates or displays a particular type of object, and so on. You may be able to write and debug an application this way fairly easily, but extending it down the line will be tough.

Why did I write this? I just added a feature to a non-MVC application. It had a popup menu that needed to display a human-readable version of some raw data, instead of the just displaying the raw data. Changing the popup menu to display the human-readable version was easy. Changing the places in the code that relied on being able to extract the raw data from the popup menu was a pain. If instead there was just a little bit more abstraction, it would have been a lot easier. And if this feature needs to change again, it's going to be a whole bunch harder...