October 13th, 2008
Is the world Class oriented?
When programming we in some sense try to model the world, or model our understanding of an aspect of the world. Or maybe even specifically model a piece of the world in a way that makes it easier for us to work with. But the world isn’t everything. We are also modeling ideas and abstractions that have no physical counterpart. Of course, we aren’t just modeling physical objects, “things”. We also have to model processes, relations, work flows and interactions.
How do we model these things? In most cases we generally use either object orientation or functional programming. Structured programming without explicit object orientation support in the language can still be divided into actions that operate on data, in something that looks a bit like object orientation. I won’t touch on the functional approach here, since it’s too tangential to what I want to discuss.
When I talk about object oriented languages here, many will probably associate mostly to languages like Java, C#, C++ or maybe Python or Ruby. These are all quite firmly in the category of class based object oriented languages. Is that all there is to object orientation? Not really. In fact, there are several ways to look at OO. Depending on what part you emphasize, you will get object systems that vary quite drastically.
For example, Scheme was originally an attempt to understand the Actor model, where the way actors work will look like OO (at least with tinted glasses). Common Lisp has CLOS, where generic methods aren’t associated with a specific class, but instead can be specialized on zero or more arguments. (Of course, you can mimic regular class based OO in CLOS, by only ever specializing on the first argument, but that diminishes the power a lot).
And then there is Self. Self was a programming language and environment based on Smalltalk, that introduced prototype based object orientation. This model basically removes the distinction between classes and other objects. Even in really open systems, where classes are instances just like other objects, classes still is the only thing you can make instances of in a class based OO language. In Self you clone an object to create a new one. Both values and methods are slots, and all slots of an object is copied when an object is cloned.
Self influenced several other languages, most notably JavaScript, NewtonScript, Io and REBOL. All of these have their own special take on prototyping, but the general distinction between prototype based and class based languages is easy to make.
I’m currently working on Ioke, and just like Io, Ioke will be a prototype based language. It will use differential delegation, which means that a new clone of something doesn’t get any copies of slots, but instead has a pointer back to the object it was cloned from. If you try to call a method on the object and that method isn’t found, the search will continue to the object it was created from, and so on. Since Ioke will allow you to have more than one prototype, I’ve decided to not use the word prototype, but instead call them mimics (an object mimics zero or more other objects).
We, as programmers, need to have powerful ways to model the world. But as I mentioned in the beginning, we also need to be able to model abstract concepts. I’m getting more and more convinced that prototype based OO is easier to work with and reason around than class based OO. The world around is can definitely be categorized, but the that is a side effect of the way our minds work. There is no real world equivalent of Plato’s Theory of Forms, but yet we insist in programming like it was true.
Working with ideas categorized as classes constrain us. As an example, most programs start out as some vaguely formed thoughts, and these thoughts get clearer and clearer as we continue developing the system. In most cases we end up refining the class definition in a source file and recompiling. But working with a prototype based system, this isn’t the only choice. You can instead create an initial set of objects and then continue to refine and refine with new objects. This is especially powerful when doing exploratory programming.
Is the world really class oriented? No. Is it prototype based? Not really. (Although a case could definitely be made for calling evolution, DNA and genetics for prototype based.) We can see the world in class oriented glasses, or we can see it using prototype based lenses. Both choices work well for certain things, and when modeling it’s nice to have both. So the question is this – can you express the one naturally in the other?
Class based system generally have a hard time looking like prototype based languages (although Ruby actually is very close). Prototype based systems on the other hand can very naturally congeal some of the core concepts into classes, and it’s easy to work with these as if they were real classes. (Some of the proposals for EcmaScript 4 added class oriented OO on top of the prototype based system).
I choose to make Ioke prototype based, since this gives me more power and flexibility.