topical media & game development

talk show tell print

object-oriented programming

The object paradigm

subsections:


The object paradigm is embodied in numerous programming languages.  [Sau89] presents a survey of 88 object-oriented languages, of which 69 are standalone and 19 incorporated into either multi-paradigm or database systems. (A multi-paradigm system, in this context, means a system embedding an environment for window programming or knowledge-based reasoning.) In this section, we will first look at the classification of object-oriented languages (as given in Saunders, 1989). Most of the languages mentioned are based on a distinction between classes and objects. However, alternative object models (without classes) are also being employed. Finally, we will review a number of object extensions of the languages Lisp, C and Prolog.

On the notion of object

Before our comparative study of object-oriented programming languages, we may well reflect on some issues of language design (specifically the motivations underlying the development of a programming language) and in particular on the notion of object underlying our conception of object oriented programming languages. Language design is an intricate issue. The motivation to develop a programming language may come from the desire for experimentation (as it has been for the author,  [Eliens92]), from governmental policy (in the case of Ada), corporate policy (as for PL-1), the wish to improve programming habits (which lies at the basis of Pascal and Modula,  [Wirth83]), the wish to provide more adequate programming constructs (as, for instance, C++ was originally meant to be a better C), the efficient implementation of a theoretically interesting model of computing (as has been the case for Prolog), or circumstantial forces (of which Java may be considered an example).

Whatever motivation lies behind the development of a programming language, every language is meant to serve some purpose. Whether implicitly or explicitly stated, a programming language is characterized by its design goals and the applications it is intended to support. A fortiori this holds for object-oriented programming languages. The impetus to research in object-oriented programming may be traced back to the development of Simula, which was originally intended for discrete event simulation. As observed in  [Tai], Simula has since served as a valuable source of ideas in several research areas in computer science. See slide 5-simula.


The notion of object -- Simula


slide: The heritage of Simula

These areas include abstract data types (that play a prominent role in software engineering,  [Parnas72b];  [Liskov74]), frames in artificial intelligence (which have become an invaluable mechanism for knowledge representation,  [Fikes] and  [Minsky]), semantic data models (which are widely used to develop information systems,  [Hammer78]), and capability-based computing (that plays a prominent role in distributed computer systems,  [Levy]). The research efforts in these areas in their turn have had a strong impact on our conception of object-oriented computing. With regard to object-oriented programming we may differentiate between three (partially distinct) viewpoints from which to characterize the notion of an object.

object-oriented


structurally

  • - capability of representing arbitrarily structured complex objects

operationally

  • - the ability to operate on complex objects through generic operators

behaviorally

  • - the specification of types and operations (data abstraction)

slide: Perspectives of object orientation

From a structural viewpoint, object-oriented means the capability of representing arbitrarily complex objects. This viewpoint is of importance for implementing object-oriented languages and the development of adequate runtime models of object-oriented computing. From this perspective, an object is (in the end) a structure in memory. From an operational viewpoint, object-oriented means the ability to operate on complex objects through generic operators. This viewpoint is closely related to the notion of semantic data models, and is of particular importance for conceptual modeling. From this perspective, an object represents (an element of) a conceptual model. From a behavioral viewpoint, object-oriented means the support to specify abstract polymorphic types with associated operations. This viewpoint is primarily of importance for software engineering and the development of formal methods of specification and verification. From this perspective an object is like a module, to be used for data abstraction. From the inception of Simula, there has been a close relation between object-orientation and modeling, that is a tendency to regard a program as a physical model simulating the behavior of either a real or imaginary part of the world, see  [Knudsen]. However, as observed in  [Tai], there seems to be a division between the European interpretation of object orientation (which remains close to the original notion of conceptual modeling) and the American interpretation (which is of a more pragmatic nature as it stresses the importance of data abstraction and the reusability of program components).

A classification of object-oriented languages

To be characterized as {\em object-oriented}, a language must minimally support an object creation facility and a message-passing facility (message-passing in the sense of method invocation). In addition, many languages provide a mechanism to define classes together with some form of inheritance. See slide 5-classification.

Objects -- language characteristics

  • object creation facility
  • message-passing capability
  • class capability
  • inheritance features

Classification

  • hybrid -- C, Lisp, Pascal, Prolog
  • frame-based -- knowledge-based reasoning
  • distributed, concurrent, actor -- parallel computing
  • alternative object models -- prototypes, delegation

slide: A classification of languages

Actually, as we will see in section dimensions, one may have a lively debate on the proper design dimensions of object-oriented programming languages. An important issue in this respect is what makes a language object-oriented as opposed to object-based. Other issues in this debate are whether an object-oriented language must support classes (in addition to a mechanism to create objects) and whether (static) inheritance should be preferred above (dynamic) delegation. This debate is reflected in a number of research efforts investigating alternative object models and object communication mechanisms. See section prototypes.

Of the 69 (standalone) object-oriented languages surveyed, 53 were research projects and only 16 were commercial products. Of these, 14 were extensions of either Lisp (10) or C (4). Among the remaining languages, quite a number were derived from languages such as Pascal, Ada or Prolog. There is a great diversity between the different object-oriented languages. However, following  [Sau89], they may be divided among subcategories reflecting their origin or the area of application for which they were developed (as shown above).

Hybrid languages

These, having originated out of (an object-oriented extension of) an already existing language, are likely to be applied in a similar area to their ancestor. In practice, this category of languages (which includes C++ and CLOS) seems to be quite important, partly because their implementation support is as good as the implementation support for their base languages and, more importantly, they allow potential software developers a smooth transition from a non object-oriented to an object-oriented approach.

Frame-based languages

in contrast to the previous category, these were explicitly developed to deal with one particular application area, knowledge-based reasoning. A frame is a structure consisting of slots that may either indicate a relation to other frames or contain the value of an attribute of the frame. In fact, the early frame-based languages such as FRL,  [FRL], and KRL,  [KRL], may be considered as object-oriented avant la lettre, that is before object orientation gained its popularity. Later frame-based systems, such as KEE,  [KEE], and LOOPS,  [LOOPS], incorporated explicitly object-oriented notions such as classes and (multiple) inheritance.

Concurrent, distributed and actor languages

To promote the use of parallel processing architectures a number of parallel object-oriented languages have been developed, among which are the language Hybrid (which supports active objects with their own thread of control,  [Nierstrasz]), Concurrent Smalltalk (a concurrent extension of Smalltalk), Orient-K (a language for parallel knowledge processing) and POOL-T (which may be characterized as a simplified version of Ada), see  [YT87]. More recently sC++, an extension of C++ with synchronous active objects has been proposed in  [Petitpierre98]. A realisation of the same concept in Java has also been proposed, albeit without compiler support, in  [Petitpierre99].

POOL-T also supports the notion of active objects. Active objects have a body which allows them to execute their own activity in parallel with other active objects. To answer a request to execute a method, an active object must explicitly interrupt its activity (by means of an answer or accept statement as in Ada). POOL-T is interesting, primarily, because it is complemented by extensive theoretical research into the semantical foundations of parallel object-oriented computing. See  [BRR90] and also section semantics. The idea of simultaneously active objects leads in a natural way to the notion of distributed object-oriented languages that support objects which may be located on geographically distinct processors and which communicate by means of (actual) message passing. Examples of such languages are Distributed Smalltalk (a distributed extension of Smalltalk that introduces so-called proxy objects to deal with communication between objects residing on different processors,  [Bennett]) and Emerald (that supports primitives to migrate objects across a processor network,  [Black]). All parallel/distributed object-oriented languages introduced thus far are based on a traditional object model insofar as an object retains its identity during its lifetime. In contrast, the so-called actor languages support a notion of object whereby the parallel activity of an object is enabled by self-replacement of the object in response to a message. Self-replacement proceeds as follows. Each actor object has a mail-queue. When a message arrives for the actor object, the object invokes the appropriate method and subsequently creates a successor object (which basically is a copy of itself with some modifications that may depend upon the contents of the message). Message handling occurs asynchronously. This scheme of asynchronous message passing enables an actor system to execute in parallel, since during the execution of a method the replacement object may proceed to handle other incoming messages. In actor systems, object identity is replaced by what may be called mail-queue or address identity. From a theoretical viewpoint this allows us to treat actor objects as functions (in a mathematical sense) that deliver an effect and another object in response to a message. However, pragmatically this leads to a complicated and quite low-level object model which is hard to implement in a truly parallel way.

Alternative object models

Since the introduction of Smalltalk, the predominant notion of objects has been based on the distinction between classes and objects. Classes serve to describe the functionality and behavior of objects, while objects are instance of classes. In other words, classes serve as templates to create objects. Inheritance, then, may be regarded as a means by which to share (descriptions of) object behavior. It is generally defined on classes in terms of a derivation mechanism, that allows one to declare a class to be a subclass of another (super) class. The distinction between classes and objects leads to a number of difficulties, both of a pragmatic and theoretical nature. (See also sections dimensions and meta for a discussion of the theoretical problems.) For example, the existence of one-of-a-kind classes, that is classes which have only one instance, is often considered unnatural. An example of a class-less language is the language Self. Self has a Smalltalk-like syntax, but in contrast to Smalltalk only supports objects (containing slots) and messages, and hence no classes. Slots may be designated to be parent-slots which means that messages that cannot be handled by the object itself are delegated to the parent object. In contrast to inheritance, which is static since the inherited functionality is computed at object creation time, delegation to parent objects as in Self is dynamic, since parent slots may be changed during the lifetime of an object. Objects in Self may themselves be used to create other objects (as copies of the original object) in a similar way as classes may be used to create instances. However, the changes made to an object are propagated when cloning object copies. Single objects, from which copies are taken, may in other words be regarded as prototypes, approximating in a dynamic way the functionality of their offspring, whereas classes provide a more static, so to speak universal, description of their object instances. Self employs runtime compilation, which is claimed to result in an efficiency comparable to C in  [US87]. In section prototypes we will discuss the use of prototypes and the distinction between inheritance and delegation.

Alternative object models may also be encountered in object-oriented database managements systems and in systems embedding objects such as hypertext or hypermedia systems.

Object extensions of Lisp, C and Prolog

The notion of object is to a certain extent orthogonal to, that is independent of, language constructs around which programming languages may be constructed, such as expressions, functions and procedures. Hence, it should come as no surprise that a number of (popular) object-oriented programming languages were originally developed as extensions of existing languages or language implementations. See slide 5-extensions.

Object extensions

  • Lisp -- LOOPS, FLAVORS, CLOS, FOOPS
  • C -- Objective C, C++
  • Prolog -- SPOOL, VULCAN, DLP

Commercial products -- languages

  • Smalltalk, Eiffel, C++, Objective C, Object Pascal, Java

slide: Object-oriented languages

The advantage of extending an existing language with object-oriented constructs, from the point of view of the user, is that the object-oriented approach can be gradually learned. However, at the same time this may be a disadvantage, since a hybrid approach to software development may give rise to sloppy design. Many proponents of an object-oriented approach, therefore, believe that learning to use object-oriented constructs is best done in an environment as offered by Smalltalk, where classes and objects are the sole means of developing an application. It is noteworthy that, with the exception of Smalltalk, Eiffel and Java, many commercially available languages are actually extensions of existing languages such as Lisp, C and (to some extent) Prolog.

Lisp-based extensions

In  [Sau89], ten Lisp-based object-oriented languages are mentioned, among which are LOOPS (introducing a variety of object-oriented constructs, see  [LOOPS]), Flavors (which extends Lisp by adding generic functions that operate on objects, see  [Moon]), and CLOS (which is actually a standardization effort of the ANSI X3J13 group to define the Common Lisp Object Standard). CLOS is a widely used system containing some non-trivial extensions to the object model and the way in which polymorphic methods may be defined.

C-based extensions

Another very important class of object extensions is those of C-based object-oriented languages, of which the most well-known are Objective-C and C++. The concepts underlying these two extensions are radically different. Objective-C introduces objects as an add-on to the constructs (including structs) available in C, whereas C++ realizes a close (and efficient) coupling between the struct (record) notion of C and the concept of a class. In other words, in Objective-C there is a clear distinction between conventional C values and data types such as int, float and struct on the one hand, and objects on the other hand. Objects have a special data type (id) which allows them to be treated as first class elements. To define an object class, both an interface and implementation description must be given. These descriptions are preceded by a special sign to designate Objective-C specific code. Also, method declarations (in the interface description) and method definitions (which are to be put in the implementation section) must be preceded by a special sign to designate them as methods available for clients of object instances of that class. The object model of Objective-C is similar to the object model of Smalltalk. In contrast, C++ quite radically departs from this object model in order to achieve an as efficient as possible implementation of objects. The key to an efficient implementation lies in the integration of the struct (record) construct originally provided by C with the class concept, by allowing functions to be members of a struct. As explained in  [St91], the equivalences depicted in slide 5-structure hold.

Object structure -- efficient mapping

C++


  struct A { ... }  ==  class   A { public: ...  } 
  class   A { ... }  ==  struct A { private: ... } 
  

slide: The equivalence between class and struct

This interpretation allows an efficient mapping of object structures to the memory of a computer, provided that the compiler is clever enough. Nevertheless, the efficiency of C++ comes at a price. C++ does support micro-efficiency but does not necessarily lead to the design of efficient code. In particular, hand-crafted memory management will not necessarily offer the most efficient solution when compared with built-in support, but is almost certainly detrimental to the quality of the code.

Prolog-based extensions

A quite different class of object-oriented extensions, used primarily in research laboratories, consists of attempts to incorporate object-oriented features in (high-level) logic-based languages, such as Prolog. Among these are languages such as SPOOL (developed in the context of the Japanese fifth-generation computing project, see  [Fukanaga]), Vulcan (that provides a preprocessor giving syntactic support for embedding objects in concurrent logic programming languages, see  [Kahn]) and DLP (a language combining logic programming with object-oriented features and parallelism developed by the author, see appendix DLP). The list of research articles covering the subject of combining logic programming and object-oriented programming is quite extensive. An overview and discussion of the various approaches is given in  [Davison93] and also in  [Eliens92].

Script languages -- integration with Java

Scripting has become a popular way to create applications, in particular GUI-based applications and Web applications. Tcl/Tk and Python are extensively used for GUI-based applications. For Web applications, scripting may be used at the client-side, for example to customize HTML pages using Javascript, or at the server-side, for writing CGI-scripts in (for example) Perl.

Script languages

Java embedding


  • Javascript -- Dynamic HTML
  • Perl -- CGI/Web library
  • JPL


  • Tcl/Tk -- tclets
  • Jacl, Tcl Blend


  • Python -- Grail
  • JPython



slide: Script languages

Most of the scripting languages, including Tcl/Tk, Perl and Python, have an extensive library for creating (server-side) Web applications. For Tcl/Tk, there exists a Netscape plugin which allows for the inclusion of so-called tclets (pronounce ticklets), applets written in Tcl/Tk, in a HTML Web page.

Scripting has clear advantages for rapid prototyping. Disadvantages of scripting concern the lack of efficiency, and the absence of compile-time checks.

Script languages may be extended using C/C++, and more recently Java. The impact of Java becomes evident when considering that there exists a Java implementation for almost each scripting language, including Tcl/Tk, Perl and Python. JPython, which is the realization of Python in Java, even offers the possibility to integrate Python classes with Java classes, and is announced as a candidate scripting platform for Java in  [JPython].

Java has also in other respects stimulated programming language research, since it appears to be an ideal platform for realising higher level programming languages.

Objects in Javascript

Originally, objects were not part of the languages Tcl/Tk and Perl. For these languages, objects have been added in an ad hoc fashion. In contrast, Python has been developed as an object-oriented language from its inception.

Javascript is a somewhat special case, since it allows for the use of built-in objects, in particular the objects defined by the Document Object Model (DOM), and its precursors. Nevertheless, due to its dynamic nature, Javascript also allows for creating user-defined objects, as indicated in the example below.


  
  <script language=Javascript> 
javascript
function object_display(msg) { // object method return msg + ' (' + this.variable++ + ')'; } function object() { // object constructor this.variable=0; this.display = object_display; return this; } var a = new object(); // create object document.write(a.display("a message")); document.write(a.display("another message")); </script>
The trick is to define a function that allocates the storage for instance variables, which may include references to functions. Using the keyword new, a new structure is created that may be used as an object.

Which objects are available as built-in objects depends on the environment in which Javascript programs are executed. In the example, there is an invocation of the write method for a document object. The document object, as well as other objects corresponding to the browser environment and the contents of the page loaded, are part of the Document Object Model, which is discussed in more detail in section DOM.

As an aside, Javascript has become surprisingly popular for writing dynamic HTML pages, as well as for writing server-side scripts. It is also supported by many VRML (Virtual Reality Modeling Language) browsers to define script nodes. See section DIVA. A reference implementation of Javascript is available, for embedding Javascript in C/C++ applications.



(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.