The power of general arrays is used to provide APL2 with object-oriented capabilities, which are used to generate user interface object classes such as windows, menus, dialog boxes and messages, among others, all of which can be created as persistent objects. This makes very straightforward the development of user interfaces for real applications.
According to Peter Wegner [Weg 95], there are three steps towards Object-Oriented Programming (OOP in short):
Systems that only provide the first step are called object-based. Those that also provide the second step are called class-based. Inheritance is required for an object-oriented system. Thus, the Microsoft COM standard is object-based, while the CORBA standard is object-oriented.
OOP systems provide three important characteristics:
Object Method Parameters
If messages are the only means for object collaboration, we have pure OOP or programming without call.
There are currently two different Object-Oriented paradigms:
The system proposed here applies the prototype-instance paradigm to the construction of user interfaces in APL2, and is a complete remake of a previous work by the author [Alf 89].
Objects are represented in APL2 by matrices of two columns. The first column defines the name of a slot, the second contains its value. There are four kinds of slots:
The first two slots (which are unique) allow us to reconstruct the object hierarchy, whose root is a special object, named OBJECT, whose PARENT slot has an empty value, and which contains 10 methods for general use, since they will be automatically inherited by every object:
Four additional APL2 functions are applicable to every object:
MESSAGE 'OBJECT VALUE MUSIC'MESSAGE 'OBJECT' 'VALUE' 'MUSIC'ASSIGN 'OBJECT' 'MUSIC' 'CDEFGAB'The syntax of the MESSAGE and related functions is somewhat cumbersome. Besides, MESSAGE acts as a message interpreter, locating the requested method either in the object that receives the message or in one of its ancestors. This interpretation slows the process, since it has to be executed on top of another interpreter. In general, a message compilation would accelerate the applications, at the same time allowing us to simplify the syntax.
For this reason, a message compiler has been developed that translates simplified messages into the appropriate APL2 function call. The only restriction introduced is the fact that a message must be the first operation to the left of a function line. Its general syntax is:
[label:] [variable assign]
MESSAGE object method [parameters]
If the compiler has enough information about the objects to deduce the appropriate function call, the preceding line is replaced by
[label:] [variable assign | quadWA assign ]
object object_method [parameters]
where object_method is the name of the APL2 function, which may be defined for the same object or for one of its ancestors.
If the compiler cannot resolve the message into a function call, it generates a call to the message interpreter (function MESSAGE).
The compiler also accepts instructions with the following syntax:
[label:] [variable assign]
ASSIGN object attribute value
and converts them appropriately.
Finally, the compiler accepts two kinds of simplified conditional instructions and replaces them by their APL2 equivalents. Those two instructions are of the form:
label IF condition (condition)/label
instruction IF condition (condition)/'instruction'
The compiler replaces the function being compiled by a new copy where it has included the appropriate changes, as indicated above. A decompiler makes it possible to recover the original function. In fact, a full-screen editor is provided (a modification of function EDIT in the EDIT workspace, which comes with APL2/PC for DOS), that automatically decompiles a function when invoked and compiles it again at the end, so that the user may forget about the existence of the compiler and write OOP functions with the simplified syntax.
In many applications it is important to have persistent objects, i.e. objects that remain in existence after the application is closed and/or the machine is shutdown. In this system, persistent objects are stored inside apl2 object files (managed by the AP211 auxiliary processor) and can be created using any object as a prototype, by means of the general use method CREATE, whose syntax is:
MESSAGE 'OBJECT1 CREATE OBJECT2 [FILE filename]'
where OBJECT1 is the object to be used as a prototype and OBJECT2 is the object to be created. If the FILE filename parameters are omitted, the object is created in the workspace and is not persistent. Otherwise, the object is persistent and is added to the indicated object file. If the file did not exist, it is created.
Two additional functions are required to make available one or more sets of persistent objects to the application. They are:
The system has been used to define different object prototypes that may be used to develop user interfaces. These objects are:
WINDOW:defines a general text window object. This object owns two methods and five attributes. The methods are:
The attributes are:
MENU:defines a menu or a list box. This object owns two methods and five attributes. The methods are:
The attributes are:
MENUBAR: defines a horizontal menu or action bar. This object owns two methods and three attributes. The methods are:
The attributes are:
PANEL: defines a panel or a dialog box. This object owns one method and six attributes. The method is:
The attributes are:
BUTTONBOX: defines a special type of panel: a message box with buttons. This object has PANEL as a prototype and owns one method and six attributes. The method is:
The attributes are:
As a spectacular proof of the power of OOP for the development of reusable, extensible, easily adjustable and modifiable applications, two complete different interface systems have been developed:
Both systems are completely equivalent and allow the same application to work with a text or a graphic user interface with no change at all. The interesting thing is that only four methods (APL functions) had to be reprogrammed to perform such a drastic change. Those methods were:
All other methods, including those that belong to the remaining user interface objects, are exactly the same for both the text and the graphic versions. This is due to the fact that menus and button boxes (and, to a certain extent, panels too), make use of windows to represent themselves on the screen, which makes them screen mode independent.
The application coded in figure 1 has been written in the simplified OOP syntax described in this paper. This application is an object editor that uses the following user interface objects:
Figures 2, 3, and 4 show different instants during the execution of the application, in the case of the text interface. Figures 5, 6 and 7 show the equivalent situations for the graphic interface. Figure 8 is a different application (an educational program in Chemistry to teach the periodic table). The screen in the figure contains 112 different windows (one per element, plus the background and two information windows).
The prototype-instance object-oriented approach is easy to implement in APL2, as demonstrated by the application described in the paper. The performance impact caused by double interpretation may be compensated by means of a partial precompilation.
Object-orientation has proved to be a proper way of handling reusable user interfaces. Our APL2 approach makes it very easy to program them in such a way that the same interface may be used for both text and graphic applications.
[Alf 89] Alfonseca, M.: Frames, semantic networks and object-oriented programming in APL2, IBM J. of Res. and Devel., Vol. 33:5, p. 502-510, Sep. 1989.
[Alf 92] Alfonseca, M.: OOPI/OOL/OODE: An Object-Oriented Program Interface and Integrated Development Environment, 3rd European Symposium on Object-Oriented Software Development, Böblingen, Oct. 1992.
[McD 95] McDaniel, R.; Myers, B.A.: A Dynamic and Flexible Prototype-Instance Object and Constraint System in C++, Carnegie-Mellon University Technical Report, 1995.
[Weg 95] Wegner, P.: Interactive Foundations of Object-Based Programming, Computer, pp.70-72, Oct. 1995.
VIEW;NAME;RESULT;METHODS;VALUE;PARM NAME'OBJECT' FILE_USE 'VIEW.OOP' MESSAGE BG OPEN MESSAGE TW OPEN MESSAGE MW1 OPEN LOOP:NAME'OBJECT' IF~EXIST NAME ASSIGN NW TEXT NAME MESSAGE NW OPEN METHODSMESSAGE NAME METHODS ASSIGN MW LIST METHODS RESULTMESSAGE MW OPEN END IF 0=½RESULT LOOP IF(RESULT)>½METHODS PARMMESSAGE PW1 OPEN VALUEMESSAGE NAME((RESULT)METHODS)(PARM) NEXT IF 0¹½VALUE VALUEVALUE IF 1<VALUE ASSIGN RW TEXT VALUE RESULTMESSAGE RW ACTIVATE MESSAGE RW CLOSE 'NR' NEXT:MESSAGE MW CLOSE 'NR' MESSAGE NW CLOSE LOOP IF 0¹½VALUE LOOP IF 4 12RESULT LOOP IF RESULT[4]>½VALUE VALUE(VALUE¬' ')/VALUEVALUE[RESULT[4];] LOOP IF~EXIST VALUE NAMEVALUE LOOP END:MESSAGE MW CLOSE 'NR' MESSAGE NW CLOSE 'NR' MESSAGE MW1 CLOSE 'NR' MESSAGE TW CLOSE 'NR' MESSAGE BG CLOSE FILE_RELEASE 'VIEW.OOP'
Manuel Alfonseca
Professor at the Universidad Autonoma of Madrid
Escuela de Ingenieria Informatica
Universidad Autonoma de Madrid
Ciudad Universitaria de Cantoblanco
28049 Madrid SPAIN
Telephone: (34) 1 397 4467; FAX: (34) 1 397 5277
Email: Manuel.Alfonseca@ii.uam.es
Figure 2
Figure 3
Figure 4
Figure 5
Figure 6
Figure 7
Figure 8