On Scheme

Thoughts on Scheme and teaching Scheme

Why Scheme Shouldn’t Have An Official Object System

Posted by Peter on April 3, 2006

Obviously object systems can be created in Scheme, even I created one, but objects are not part of the language specification itself. I don’t pretend to know the motivations behind the design of Scheme, but I think that fundamentally Scheme may lack objects because it is a minimalist language. Here however I will defend the benefits of not having an object system built into the language, whatever the designers’ real reasons are.

As you may know some Lisp languages, most notably Common Lisp, and some dialects of Scheme, such as Bigloo, do have a built in object system. Other distributions, such as PLT, come packaged with modules that implement an object system if you choose to include them. Individuals have also devised their own flavors of object systems for scheme, ranging from imitations of CLOS, to prototype based systems, to slot based systems, to message oriented systems, and many which are some mixture of these features and more. Clearly then objects seem to be desired by programmers even in Lisp family languages.

The best, and most basic, use of objects is to abstract a set of related data and operations upon this data from the rest of the program. Obviously anything an object can do could be done with a properly structured list and some operations that act on it, but the beauty of using objects is that all these functions can be conveniently tied together allowing the programmer to easily alter implementation of the object without breaking other parts of the program unintentionally. Ideally objects can result in smaller and more elegant programs, in terms of the code written, although they may have more run-time overhead. Admittedly there are drawbacks to the object oriented style of programming, which have been already covered extensively by others wiser than me. Although I recognize that the over-use of objects can be a problem, it also seems clear that objects, used in a more limited fashion, can be an excellent programming tool. Why else would developers create object systems over and over again for Scheme?

So if objects can be useful why leave them out of Scheme? There are obviously drawbacks to their omission, as object systems invented independently of each other function and look different, which can make reading code that employs an object system difficult. One advantage of not having a standard system is that it leaves out a lot of clutter from the language in its bare specification form. When object system are built into the language you end up with not only a new keyword for defining a class, but you end up with special ways of defining member functions (how else can you access the “this” reference), special functions to describe inheritance relationships, calling member functions of an object, determining the type of an object, getting and setting member variables, ect. Depending on who designs the built-in system there may be more or less added syntax, but on some level you have added a new “black box” to the language. A black box is a construct that can’t be described in terms of other constructs available in the language. For example if you consider if to be a black box construct then cond is not since it can be described in terms of the if statements. Part of the elegance of Scheme is that it only has a few of these black box constructs, and adding an object system could possibly double the number of “black boxes” in the language.

More important however is that object oriented programming is still young. Admittedly we have had object oriented systems for many years, but even so object oriented languages are still finding new ways to approach objects, both syntactically and conceptually. Compare this to functional programming, which has only a few styles of implementation, and a mathematical foundation to boot. The problem with adopting “officially” one object system into the language is that it discourages experimentation with new ideas. Consider for example CLOS in Common Lisp. Because it is already incorporated in the language, and an official standard, few Common Lisp programmers would consider using a different object system. Despite this CLOS is primitive in several ways, for example it handles name clashing in multiple inheritance poorly*, and unfortunately programmers who have become accustomed to one style of object oriented programming are unlikely to see the benefits of other styles or to dismiss them merely “syntactic sugar”, much the way programmers who are accustomed to a procedural style often react to functional programming at first.

So while Scheme’s lack of an official standard for handling objects may seem to lead to some confusion and inefficiency these shortcomings are offset by the cleanness of the language and the acceptance of the community of different approaches to the problem. Perhaps when object oriented programming matures, and it becomes clear that one way of handling objects that is superior to any others should it be incorporated officially into Scheme, but until that day I feel it is best to let homebrew solutions be the norm.

* according to a conversation concerning inheritance I had with a CLOS user, when a class inherits from multiple classes that contain variables of the same name the new class must explicitly override get and set methods for that variable so that they address a new variable internally. I don’t know how conflicts between method names are resolved. I claimed that this put an unnecessary burden to the programmer, i.e. to ensure that every time any parent class is revised no new variables have been added which might conflict with any of the other inherited classes. To defend CLOS they added that this system could handle both the case when only one copy of a parent class found more than once in the inheritance tree is needed and the case when multiple copies of such a parent class is needed. When I in turn pointed out that such problems had been solved in C++ with the distinction between virtual and non-virtual inheritance with no need to worry about conflicting variable names they seemed insulted, which I think is a case of programmers used to one system seeing any improvements as mere syntactic sugar.


4 Responses to “Why Scheme Shouldn’t Have An Official Object System”

  1. Abhijat said

    To me, the lack of object orientation has more to do with the fact that Scheme has true first classness. There is no distinction between data and code. The origins are in the lambda calculus anyway. But introducing some OO support feels like an imposition, an artificial framework, especially if environments are first class objects. As a consequence, the OO layer over Scheme appears to straight-jacket the variety of ways in which abstraction barriers can be erected in a program. Perhaps the core motivations for OO systems in the Turing based imperative world emerge more due to the difficulties in handling temporal variations in the state of the system. The functional world can deal with programs without the need to deal with the state. That leaves the four characteristics of OO – encapsulation, inheritance, overloading and polymorphism – more as particular implementation techniques of erecting abstraction barriers especially over the environment. The minimalist nature of Scheme provides this freedom. Maybe OO needs to be re-thought from a functional perspective a bit more deeply from ground up.

    The situation is similar to the view of C as the minimalist imperative language, and then onto C++ or Java. Java overcomes the problems of state management through GC, but not the temporal behaviour of the state due to it’s imperative base. Object heirarchies are needed to manage the correct time evolution of the system state. In a Scheme world, these heirarchies would appear more as ‘a program organisation strategy’ than any basic programming need.

  2. Peter said

    If you think object oriented programming is the wrong solution to problems of abstraction I suggest that you propose a better solution. I know as well as anybody that object oriented programming has its flaws, but as far as I can see it is still one of the best ways for organizing large programs, or programs that have multiple authors. Object oriented programming isn’t just about creating Lisp like closures in other languages, it is also about organizing the program by relationships between data and function. Fundamentally though I know we need objects because people keep inventing them for Scheme (for example there are 9 systems here: http://community.schemewiki.org/?object-systems, and PLT comes with one built in). If objects are as useless (or unneeded) as you claim why do these object systems exist?

  3. Abhijat said

    I do not claim that objects are useless. Au le contraire, they are a technique to manage scale, and for the lack of any other alternative, are the best bet today. I do not say that they are the “wrong solution to problems of abstraction”. I say that they need to be re-thought within the functional world. The lack of distinction between code and data supports an “all processes” view of the program – e.g. Church numerals. This is especially seen through the mathematical basis in the pure lambda calculus. (In practice, we use the extended lambda calculus.)

    The two key notions, IMHO, that motivate us to create OO are modularity and state, or rather, it is the need to modularise given explicit state. Functional programming does not need state in principle, but in practice, we do not know how to avoid it completely. That is why the assignment operations finds it’s way in. Once the assignment operation exists one is required to face the issues of time evolution of the state. It is the management of this time evolution of the state for large systems that demands an organisation effort. If people keep inventing OO systems, then we need to see the reason behind it.

    The problem boils down to the determination of the correct binding context. Inheritance, for instance, prescribes a set of rules of arranging the frames towards this goal. In programming systems where frames/environments are not available to the program, such rules are required to think about the process that the program evolves under interpretation. Scheme, on the other hand, provides environments and permits experimentation. In particular, rules of environment construction that are prescribed in other languages as well as other rules, can be experimented with in Scheme. A young field like OO needs more experimentation to arrive at the “best way”. My argument is: Scheme is not only minimal, but flexible due to the first classness and hence is a reasonably good testbed for experimenting with. Hence let’s experiment with OO rules rather than imposing them right away on Scheme. That is why they appear as one of the program organisation strategies rather than a basic programming need as required in the imperative world.

    You present two reasons to suggest leaving OO out of Scheme for the moment:

    Scheme would have too many black boxes, and
    OO is still young.

    If OO were so important, then it would be better to have more black boxes rather than a variety of OO implementations. That is what a language for large scale programming would require anyway.
    Irrespective of how young OO is, it is still not clear to me how to handle the issue of time evolution of mutable entities despite some effort. Consider, for instance, the problems of dealing with instantiation of mutable objects to reason about process generation from a program.

    I am just trying to see some other reasons into not having OO at present in Scheme.

  4. vsync said

    The issue of conflicting slot names in CLOS is less of an issue than one might think, given that slot names are symbols and each package should be defining its own namespace. The FOO and BAR packages might both subclass BAZ and define a QUUX slot, but those slots will actually be named FOO:QUUX and BAR:QUUX respectively and so not conflict.

    A convention for accessors I find useful to follow is CLASS-SLOT, where CLASS is the class at the level I’m defining the accessor, not some ancestor superclass that might be called the “base class”. So if my BAZ subclasses were called FOOMATIC and BARMATIC, FOOMATIC-QUUX and BARMATIC-QUUX. If I then subclass either of those it’s apparent where the accessors are derived from. In the case of conflicts, it also allows me to USE both packages without issues or ambiguity.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: