The interest in object-oriented languages has not dimmed since this
August 1986
article appeared. What new latest-greatest-hot te
chnologies will continue to evolve from these early beginnings?
Object-Oriented Languages for the Macintosh
An overview of the languages and their capabilities
by Kurt J. Schmucker
[Editor's Note: Please see the article on page 178 of the August 1986 issue for "Table 1.".]
Currently a large number of object-oriented languages are available, and more are being designed and implemented every year. Some of these languages now on the market or in development are for the Apple Macintosh, an ideal computer for object-oriented languages because of its processing power and the nature of its user interface. In this article I will survey some of the Macintosh object-oriented languages. I will also present a table detailing each language's object-oriented characteristics, such as whether it can access the MacApp class library (see my article "MacApp: An Application Framework" on page 189) or whether it provides for class methods. After describ
ing the languages, I will discuss the mechanics of programming with them on the Mac.
Smalltalk
The Smalltalk language is the ancestor of all object-oriented languages. It was implemented on the Macintosh by Apple as part of an experiment to demonstrate Smalltalk's portability and debug the Smalltalk specification. Apple currently distributes Smalltalk for the Mac as an unsupported. low-cost product, but a fully supported and greatly enhanced version is expected soon. A fact sheet on Smalltalk and the other languages I describe in this article is presented in table 1.
Smalltalk has a message-sending syntax that often seems unusual to the novice object-oriented programmer. but it quickly becomes the natural way of doing things. Smalltalk syntax and the syntaxes of all the languages I discuss herein are shown in table 2.
New classes and methods are defined by editing standard templates in an interactive source-code browser. The class library for the Macintosh version of Small
talk contains over 300 classes with special classes for accessing the Macintosh file system, the Macintosh Toolbox (including the QuickDraw routines), and the AppleTalk network added by Apple. Since Smalltalk has been described in previous BYTE articles and elsewhere, I will not elaborate on its language features.
Object Pascal
Object Pascal is Apple's second object-oriented extension of Pascal. (The first, Clascal, was only for the Lisa Office System and thus is no longer supported by Apple.) The syntax for Object Pascal was jointly designed by Apple's Clascal team and Niklaus Wirth, the designer of Pascal, who was invited to Apple's Cupertino headquarters specifically for this project. In addition to implementing Object Pascal on the Mac, Apple has put the Object Pascal specification in the public domain and encouraged others to implement compilers and interpreters for it. Several such developments are under way.
Object Pascal implements classes as an extension of Pascal's R
ECORD structure. In Pascal, records have only data as their component fields, but in Object Pascal, object types (as classes are called in Object Pascal) have data fields (instance variables) and method fields. Messages are sent using the same syntactic construct used in ordinary Pascal for field qualification--the period.
Thus, in Object Pascal, accessing an instance variable and accessing a method (that is, sending a message) are accomplished with the same syntax.
New classes are defined using one new compiler keyword, OBJECT. The basic schema is
TYPE
ClassName = OBJECT (SuperclassName)
< instance variable declarations >
< method header definitions >
END;
where < > denote optional portions of this schema. Methods are defined as ordinary Pascal procedures or functions that have been qualified with the name of the class:
PROCEDURE ClassName.ProcedureName(argumentList);
BEGIN
.
.
.
END;
Object Pascal is a "bare
bones" object-oriented language. It makes no provision for class methods, class variables, multiple inheritance, or metaclasses. These concepts were specifically excluded in an attempt to streamline the learning curve encountered by most novice objectoriented programmers.
The Object Pascal class library is MacApp.
Neon
The language Neon is, depending on your programming-language point of view, either an object-oriented extension to the FORTH language or an incisive and efficient implementation of Smalltalk as a threaded interpreted language. Regardless of which view you take, Neon is a remarkably concise language that nicely bridges the gap between the object-oriented languages (à la Smalltalk) and the threaded languages (à la FORTH). Neon was developed by Kriya Systems expressly for the Mac and was first shipped in 1984.
The basic Neon syntax shows its strong FORTH heritage: From the point of view of most of the other languages discussed in this article, Ne
on's syntax is backward. (To be fair, many programmers consider the Smalltalk syntax, which has the object precede the message, to be backward compared to the procedure call used in most languages, so perhaps Neon, with the message preceding the object, is one of the few object-oriented languages to get it right!)
New classes and methods are defined using special Neon compiler words that delimit class definitions (:CLASS and ;CLASS) and method definitions (:M and ;M).
The basic schemas are
:CLASS ClassName <Super SuperClassName < n Indexed>
<instance variable names >
< method definitions >
;CLASS
and
:M Selector: < { named arguments \ local variables - results } >
< method body >
;M
where < > denote optional portions of these schemas. One of the most useful features of Neon is the provision for both named arguments and local variables in methods. Named arguments let you associate a name with the
arguments placed on the stack prior to the invocation of the method and then simply refer to these arguments by name when you need them in the body of the method. Local variables let you declare and use temporary variables in the method body. Both features simplify the use of Neon compared to the complex stack manipulations often required in FORTH.
Neon allows you to choose between the efficiency of static binding and the flexibility of dynamic binding (called
early binding
and
late binding
in the Neon manual) on a message-by-message basis. Early binding will resolve at compile time a message sent to a given object into an invocation of a particular method in a particular class; late binding will leave this resolution until run time. The compile-time determination is made based on the declared classes for the reference variables, (Thus, Neon is like Object Pascal, which allows a reference variable to be declared of a certain class, and unlike Smalltalk, in which all object references a
re equal.) The Neon line
Get: myInt
will send the
Get:
message to the object referred to by
myInt
, with the resolution of that message determined at compile time by the declared class of
myInt
. The line
Get: [myInt]
will send the
Get:
message to the object referred to by
myInt
, with the resolution of that message determined at run time by the run-time class of
myInt
. Late binding can be used with any construct that generates an object reference, such as
Get: [i at: myArray]
to send the message
Get:
to the object referred to by the
i
th element of the array object
myArray
. with the resolution of that message determined at run time by the run-time class of the object stored at that element in the array.
The basic approach of the current Neon class library--unlike that of MacApp, which provides a completely functional application framework--is to "lift" the Toolbox data types to the level of classes.
Accordingly, Neon has classes like Point, Window, Dialog, and Event, which provide a more functional set of building blocks than do the basic Toolbox data types and procedures for the Pascal or C programmer, but not quite the type of building blocks that the MacApp classes provide for the Object Pascal programmer.
ExperCommonLISP
The language ExperCommonLlSP is one of the most comprehensive object-oriented languages for the Macintosh in that it implements all of the features of object-oriented languages (except unique instance methods), provides a set of classes that mirror the Toolbox data types, and, with the next release, will provide MacApp access. ExperCommonLISP was developed by ExperTelligence expressly for the Mac. It was derived from the ExperLISP product available for the Mac since early 1985.
ExperCommonLlSP syntax shows its strong LISP heritage: Message sending, setting object reference variables, accessing instance variables, and other object-oriented programming la
nguage features are accomplished with list functions.
(setq Triangle (send Object 'subclass))
defines a new subclass of
Object
. named
Triangle
, by sending the message
subclass
to the
Object
class.
(setq tri1 (send Triangle 'New))
instantiates a new instance of the
Triangle
class and stores a reference to this new instance in the variable
tri1
.
(send tri1 'height)
sends the message height to the object referenced by
tri1
.
Actually the definition of a new class in ExperCommonLISP can be much more detailed than this simple example shows. The full class-definition schema includes provisions for instance and class variables and instance and class methods.
Note: LISP users will observe that this schema uses terms like
arg_lists
rather than the traditional lambdalist style common to LISP The lists are written here in a nonrigorous, informal notation. This is to make this explanation of ExperCommonLlSP
more understandable to those who do not have a reading knowledge of LISP.
(setq Newclass(CLASS (superclass
1
superclass
2
...superclass
n
)
(IVS (iv
1
)(iv
2
). ..(iv
n
))
(Methods (method
1
(arg_list)(body))
(method
2
(arg_list)(body))
.
.
.
(method
n
(arg_list)(body)))
(CVS (iv
1
)(iv
2
)...(iv
n
))
(Metamethods(method
1
(arg_list)(body))
(method
2
(arg_list)(body))
.
.
.
(method
n
(arg_list)(body)))
where
--
IVS is a keyword for the instance-variable-definition clause. Each portion of that clause names an instance variable and provides its initial value and attributes.
--
Methods is a keyword for the method-definition c
lause. Each portion of that clause defines a message, its argument list, and the method that will be invoked when that message is received by an instance of this class.
--
CVS is a keyword for the class-variable-definition clause, Like the instance-variable-definition clause, each portion of the CVS clause names an class variable and provides its initial value and attributes.
--
Metamethods is a keyword for the class-method-definition clause. Each portion of that clause defines a class message, its argument list, and the class method that will be invoked when that message is received by the class object.
Even this detailed schema does not present a full picture of the facilities in ExperCommonLlSP. As one example of a capability in ExperCommonLlSP that is not exhibited by this schema and is not present in any of the other object-oriented languages discussed in this article, consider the more detailed format of the following instance-variable-definition clause:
(IVS (instance-variable
1
-definition) (instance-variable
2
-definition)...(instance-variable
n
-definition))
where an instance-variable definition has the form
(< instance-variable-name> < default-value-form > < set > < get >)
.
The keywords
get
and
set
specify whether the instance variable can be accessed from outside the object. If the keyword
get
is used, the variable can be read from outside; if the keyword
set
is used, the variable can be written. Thus, the degree of encapsulation can be set on a class-by-class basis, and within a class on an instance-variable-by-instance-variable basis. This is a much more flexible middle ground between the unrestricted access provided by Object Pascal and the total lack of access provided by Smalltalk.
The ExperCommonLLSP class library includes a set of classes that "lift up" the Toolbox data types to the level of objects as well as the MacApp classes. As with
Smalltalk, Neon, and Object Logo, this MacApp access is achieved by a reimplementation of the MacApp class functionality by ExperTelligence.
Objective-C
Objective-C brings the basic notions of object-oriented programming to the C language in a manner that is machine-independent. This is accomplished by a compiler that accepts Objective-C source code and outputs an equivalent source code. The resulting C source code can then be compiled for execution on the target machine. This has resulted in a language that can (and does) exist on both the IBM PC and the VAX-l 1/780 and on many machines in between. Objective-C was developed by Productivity Products International (PPI) and first shipped in 1983.
The Objective-C language is a strict superset of the C language. The object-oriented extensions are achieved by adding a new expression type to the C language, the message expression. Syntactically this message expression is delimited by brackets (
see table 2
). The
message expression brackets can be distinguished from the standard-array subscripting brackets used in ordinary C by context. The internal message syntax is similar to that of Smalltalk; it even follows Smalltalk's syntax for keyword messages. This new expression type exists on an equal level with all C expressions. The result is that an Objective-C statement message expression can be used anywhere that an expression can be used in C. A sample statement that shows the resulting flexibility is:
[Point x: foo( ) + 7 y: [box top]]
. In this statement, the keyword message
x:y:
is being sent to the
Point
class. The first argument (of the
x:
portion) is the result of a function call and an addition
(foo( ) +7)
. The second argument (of the
y:
portion) is the result of sending the message top to the object referred to by box.
New classes are defined in a special class-description file of the following form:
= ClassName: SuperClassName (PhylaList) { I
nstance Variable Declarations }
+ ClassMethodName (Method lmplementation}
= InstanceMethodName (Method lmplementation}
Only one class may be defined in any such file, although the number of class-method definitions and instancemethod definitions may vary.
One object-oriented programming concept that is unique to Objective-C is
phyla
. Phyla in Objective-C are groups of classes, just as phyla in biology are higher-order organizations than the biological notion of a class. When you indicate that a new class belongs to a particular phylum, you are stating that this class will often be used together with the other classes in that phylum. When the Objective-C source code is compiled, this information is used to generate a more efficient method table structure.
The Objective-C class library consists of some 25 classes that implement collection classes, basic geometric notions, and standard data structures--all in a machine-independent way. The fact that the Objective-C language is
available on a large number of machines and that its class library is machine-independent is perhaps its greatest strength. Productivity Products International coined the term "software-IC" to describe such a machine-independent class, although the term is now used to describe any well-designed class. (The concept of a software-IC has been described in "Software-ICs" by Lamar Ledbetter and Brad Cox, June 1985 BYTE.)
Object Assembler
Object Assembler is a set of macros for the Motorola 68000 assembly language that provides easy access to the MacApp class library and to class-definition facilities. It is built on top of the macro assembly language provided by the Macintosh Programmer's Workshop assembler. Object Assembler was developed by Apple expressly for the Macintosh and it will be officially shipped late in 1986. The Object Assembler macros let you define new classes, define method bodies, instantiate objects, easily reference instance variables by name, and invoke methods, incl
uding inherited ones. A few examples will demonstrate the use of these Object Assembler macros. The basic schema for defining a new class in Object Assembler, for example, is
MACRO
ObjectDef &TypeName,&Heritage,&FieldList,&MethodList
and an example of the use of this macro is:
ObjectDef Shape,Object, \
((boundRect,8), \
(borderThickness,2), \
(color;2)), \
((Draw), \
(MoveBy), \
(Stretch))
ObjectDef Arc,Shape, \
((startAngle,2), \
(arCAngle.2)), \
((Draw,OVERRIDE), \
(GetArea), \
(SetArCAngle))
(The backslash is required by the assembler when continuing a statement from one line to the next.)
Let me demonstrate defining a method and referencing an instance variable by name with some examples.
Defining a method:
Schema
MACRO
&ProcName ProcMethOf &TypeName
MACRO
EndMethod
Example
Draw ProcMethOf Arc
<code>
EndMethod
Accessing an instance variable:
Schema
MACRO
ObjectWith &TypeName
MACRO
EndObjectWith
Example:
ObjectWith Arc
MOVE.L startAngle(A1),-(SP)
PEA boundRect(A1)
EndObjectWith
In this example of accessing an instance variable,
Al
must already be loaded with an
arc
object reference. The
ObjectWith
macro simply qualifies
startAngle
and
boundRect
for you. Note that the
ProcMethOf
(and the corresponding
FuncMethOf
) macros automatically invoke the
ObjectWith
macro with the given class, making references to the instance variables of that class easy.
In terms of its object-oriented semantics, Object Assembler is just like Object Pascal. MacApp access is provided, as is access to any class implemented in Object Pascal. It also is possible to
subclass Object Assembler classes in Object Pascal. No easy access is possible to classes implemented in other languages.
Object Logo
Object Logo is the most unusual object-oriented language for the Macintosh because it is implemented as a classless language--an object-oriented language in which there is no firm distinction between an instance object and a factory object (a class) that makes those instances. Object Logo was developed by Coral Software Corporation expressly for the Mac, and it is scheduled to be shipped in the summer of 1986.
In designing a language that has no distinction between classes and instances, Coral Software's programmers left out a concept that is commonly used in the implementation of object-oriented languages. Classes, after all, are really an implementation convenience--a way of economizing on the amounts of memory required to write object-oriented programs. From Coral's point of view, the conceptual issues in using an object-oriented language are
more important than implementation efficiency concerns. By removing the class "artifact," Coral has designed a language in which all objects are treated uniformly which it believes is easier to learn than traditional object-oriented languages.
There are a number of technical consequences of this philosophical decision to remove distinctions between classes and objects. In Object Logo, objects can be given instance variables and methods "on the fly" during an interactive session. You could, for example, create an object, give it two instance variables, then define a couple of methods, use those methods, clone the object (i.e., copy all relevant object information),
add some instance variables
,
remove some methods
, and then clone the object. In terms of the vocabulary I have developed up to this point, you have created an instance (from no template), redefined the structure of an instance while it existed, added new methods while it existed, and then used it as a factory to produce a new
instance just like itself--all notions that don't make sense with the traditional object-oriented vocabulary. The problem isn't with the vocabulary. The problem is that many of the notions of object-oriented programming that we have spent so long acquiring just don't apply to Object Logo as well as they do to other languages. Consequently Object Logo is somewhat harder to learn than the other object-oriented languages described in this article,
if
you are already familiar with other object-oriented languages. Object Logo requires that you unlearn some concepts about object-oriented programming and learn some new ones that don't fit in with your conceptual model of how objects, classes, messages, and methods interrelate. For example, Object Logo is the only language described in this article that provides for unique instance methods--methods not associated with a data structure shared among objects with a similar format, but rather methods directly "attached" to objects. In Object Logo, such a concep
t is natural; in the other languages discussed here, it is most unusual.
Because conceptual simplicity was one of the major goals in the design of Object Logo, Object Logo adds only a few new primitives to the Logo language.
KINDOF anObject
creates a new object which inherits from
anObject
.
TALKTO anObject
makes
anObject
the "current object." (At any time during the execution of an Object Logo interactive session, there is exactly one current object. All references to variables and procedures are resolved in the context of this current object.)
HAVE word thing
adds the instance variable
word
to the current object. The initial value of
word
, in the context of the current object, is
thing
.
HOWTO procedureName
adds the method
procedureName
to the current object.
USUAL
invokes the inherited method. (This is essentially equivalent to the Object Pascal
INHERITED
and to sending messages to
super
in Smalltalk.) And
TELL anObject InstructionList
executes a list of instructions in the context of
anObject
without making
anObject
.
Object Logo is one of the few languages in this article that implements multiple inheritance. In Object Logo, a subclass can invoke
all
methods for a message common to its immediate ancestors. This style differs considerably from that of Smalltalk. (For legal reasons, the version of Smalltalk for the Mac does not have multiple inheritance. This is the only major technical difference with other Smalltalk implementations.)
At the time of this writing, no comprehensive listing of the Object Logo class library was available. However, the plans for Object Logo class library include a complete reimplementation of the MacApp classes using their Logo primitives for accessing the Toolbox. Like Neon and ExperCommonLISP this reimplementation will produce a semantically similar set of classes so that the MacApp programmer could move from Ob
ject Pascal or Neon to Object Logo with very little additional training about the MacApp class library.
Programming with a Mac Object-Oriented Language
Object-oriented languages for the Macintosh can be divided into two sets--those that have interactive interpreters and those that don't. The languages with interactive interpreters--Smalltalk, Neon, ExperCommonLlSP and Object Logo--have self-contained development environments consisting of a text editor, an interpreter, a compiler (sometimes), and other application building tools. These development environments are generally in accordance with the Macintosh User Interface Standard. New classes are developed interactively with reasonably functional debugging facilities. When debugged, the new classes are loaded into a working image that then can be saved in a snapshot. Many such snapshots can be saved on disk, each representing a different development effort, a different project, and so on. Classes are used as incremental building blo
cks; As soon as a new class is defined, it is available for use. The results of developments in different images can be combined in a single image, usually by recompiling the source code versions of the new classes and methods. None of these languages can use procedures written in standard languages like Pascal or C, or classes written in other object-oriented languages, with the exception of ExperCommonLlSP which can access Pascal and C procedures.
In the languages that do not currently have interactive interpreters on the Macintosh--Object Pascal, Object Assembler, and Objective-C--classes are developed first (using a standard text editor) and compiled with the appropriate compilers. Then a main program using these classes is written, compiled, and linked with the classes. All of these languages can access procedures and functions written in either Pascal, C, or assembly language. Most of these languages, whether compiled or interpreted, contain all the facilities to construct a stand-alone Macintosh
application. For example, they have special routines to construct menus and to link the choice of a particular menu item with the execution of a certain method. Each of these object-oriented languages has its particular strengths and weaknesses as an implementation language depending on your application and background.
A comparison of the syntax of each language. The message,
msg
, with
argument,
arg
, is sent to the object referenced by
obj
.
Syntax Language
=========================================================
obj msg: arg. Smalltalk
obj.msg(arg); Object Pascal
arg msg: obj Neon
(obj 'msg <arg> ) ExperCommonLISP
[obj msg: arg]; Objective-C
MOVE.W arg(A6),-(SP) Object Assembler
MOVE.L obj(A6),-(SP)
MethCall msg
tell :obj [msg "arg] Object Logo
photo_link (100 Kbytes)

Kurt J. Schmucker, director of educational services for Productivity Products International (Severna Park Mall, H & R Block Office, 575 Richie Highway, Severna Park, MD 21146), teaches seminars on object-oriented programming. Kurt has written three books on computer science, including the forthcoming Object-oriented Programming for the Macintosh (Hayden, 1986).