TOM
 
Reasons for TOM
 
 
TOM Home
TOM Tasks

FAQ
News
Highlights
Publications
Documentation
Download TOM
TOM Software
Bug Database
Mailing Lists

Mail:
tiggr at gerbil.org

Short Cuts:
Tesla
TOM/Gtk
GP
MU

Snapshots:
all of 'em
tom [an error occurred while processing this directive]
tesla [an error occurred while processing this directive]
mu [an error occurred while processing this directive]
tomgtk [an error occurred while processing this directive]

Released:
all of 'em
tom 1.1.1
tomgtk 0.11
tesla 0.91
gp 0.5
mu 1.0

Misc:
GIF free NOW!

Below is a list of problems with (object oriented, procedural) programming languages that TOM attempts to solve, or at least address. The list is not exhaustive and TOM undoubtebly comes with its own problems solved by other languages. (This list was compiled while TOM was conceived in late 1995, early 1996. Though the wording and reasoning has improved since, this original list remains interesting reading.)

Extensibility

In Smalltalk and Objective-C methods can be added to an already existing class, but instance variables can not. In C++, Eiffel and Java a class is defined by its one and only definition.

In TOM, a class need not be defined by one monolithic definition: its definition can be split into multiple parts, called extensions. An extension can add instance and class variables; it can declare new superclasses from which to inherit; and it can add and replace methods. An extension is not a mere compile-time entity; an extension can be loaded into a running program for instance to load extensions for testing the software.

Usability

With TOM, the semantics of the language do not change with the availability of sources. Put more strongly, the possibilities of the language are not restricted in any way if sources are not available or modifiable. This allows one to adjust library classes in case subclassing does not suffice, increasing the usability, as opposed to reusability, of the library class.

In Cecil a superclass can be added to an existing class, providing some of the functionality offered by TOM. A counter-example of usability is Eiffel, where the availability of only the short form of a class severly hampers the possibilities of subclassing.

As another example, given a C++ library of which one wants to replace a class by a different one. In that case, the member variables must remain identical if referred to from within one of the other objects in the library. The same is true for virtual methods if invoked from the other objects. If any of the member functions of the class to be replaced is inlined in the other objects, the possibility of successfully completing this venture within the original goals is further reduced.

Uniformity

C++ provides signatures, Java calls them interfaces, and Objective-C refers to them as protocols. Apart from some of the more obscure problems, such as an Objective-C class object not being able to adhere to a protocol, these constructs are orthogonal to the normal class hierarchy. In Java and Objective-C, they provide a means for multiple inheritance of interface declaration; in C++ it is an attempt to cover some of its many deficiencies.

In TOM, the functionality of protocols (and signatures and interfaces) is simply provided by the class hierarchy itself; it follows logically from TOM's use of dynamic binding, multiple inheritance, and deferred method declarations.

Static

TOM is strongly type checked at compile time; various (builtin, static) basic types and the (user defined, dynamic) classes are discerned. Methods are overloaded on both the argument types and the types of the return values. Since multi-dispatching is considered too troublesome, especially in the context of dynamic loading, method overloading is restricted to what a compiler can guarantee: the basic types are discerned and all objects are considered equal.

Dynamic

At runtime TOM provides full typing information on objects, their instance and class variables, and arguments to and return value from methods. All methods are dynamically bound. Methods are provided to read and set instance and class variables given their name; to retrieve an object's class; to query a class for its position in the inheritance hierarchy; to send an object a message of which the selector need not be known at compile time (a bit like function pointers in C++, but being dynamically bound much more flexible; more like perform in SmallTalk and Objective-C, but without restrictions on the types and number of arguments).

Storage Management

All objects are allocated from the garbage collected heap. This implies that it is impossible to have problems with dangling references, previously valid pointers having become invalid, memory leaks, etc.

In TOM, an object can not be a part of an entity of which the lifetime is unrelated to, and possibly shorter than, the lifetime of the object. This containment rule dictates that objects can not be allocated from the stack and they can not be part of another object.

Exceptions

In most languages (C++, Java, NeXT's Objective-C libraries, to name but a few), an exception handler is executed in its own context instead of the context of the exception raiser, implying that it is impossible for the handler to direct the actions of the condition raiser---the stack has already been unwound and nothing can be done about that.

The TOM exception mechanism is modeled after Common Lisp conditions. A TOM condition can be signaled; if none of the condition handlers is interested in handling this condition, execution continues in the context of the condition signaler, as if the signal were a normal method invocation. A condition handler can direct the condition signaler by setting the value to be returned from the signal invocation. It can also decide to perform a non-local exit, the equivalent of a C longjmp.

It is of course possible for a method not to be able to continue execution after a condition. In this case it can force the condition to be handled, by raising it instead of signaling. Failure to handle a raised condition through a non-local exit results in program termination.

Return Values

In most procedural object oriented languages, there is an arbitrary limit on the number of values a method or function can return. This limit is 1, and pointer arguments, struct returns, or other tricks are needed to return more than one value. In Common Lisp, multiple-valued returns are possible, but they are special.

TOM imposes no limit on the number of values that can be returned from a method.


Up: TOM Documentation
 
Copyright © 1997-2002 Programmers Without Deadlines