The Challenge of the New
Vector 9:4, page 120
Transcribed from the printed issue; not yet reviewed. Read it in the PDF of the issue, page 120
Until about two years ago there was fairly common agreement on what was good practice in the coding of APL systems. What would come out was generally a system navigated by a simple menu function which would call at each stage a number of small black-box functions that would do fairly simple specific things to their arguments and return the results. What you were doing (and what you were doing it to) would be fairly well defined by your position within a hierarchy of functions at the bottom of which would be GO or ∆LX.
The interaction with the user was very well controlled. He could choose an option from a menu or edit some data (usually a small subsection of the whole). Even with this small choice we would quite often end up with a few large functions in which we would interrogate the user then branch to one of say ten labels depending on his choice. Having done what he asked we might return him to the menu and ask him what he wanted to do next. This would continue until he chose to leave that part of the application. At each stage the option that he chose would probably act on data local to that part of the system. So far so good.
Now imagine a situation in which the user can choose one of two hundred different actions. As I sit in Word for Windows I have at least that many from which to choose. What is more I spend over 90% of my time in the base state — editing the document. How do you manage it? Do you have great wadges of global data which is all manipulated by two hundred different little functions, and have a two-hundred-and-three-line function which loops round deciding which of these little functions to call? No, what you do is to associate with everything the user can do a ‘callback’ function which will automatically be called whenever that action (such as pressing a button or selecting an item on a menu) occurs.
This is the standard Windows approach to the problem and it gets rid of your 203-line function. However, as you never know which of these functions will be called next, or what condition the system will be in when it is called, you must do something to ensure that any data it needs is readily available. The easy but dangerous approach to this (adopted by Manugistics for their APLGUI — see the review in this issue) is to leave everything lying around globally in the workspace. This leaves you with a new problem. How do you, as a developer starting to maintain someone else’s broken system, know what the hell does what, with what, when?
One well trumpeted approach to this problem is to use data objects and pass messages to them to update them. I can well believe that if a system is designed from the bottom up using this approach then the problems of maintenance would be dealt with. One of the difficulties of the use of object methods within the Windows GUI offered by the current APL systems is that the object paradigm extends only as far as the management of the GUI. The main area where benefits are to be reaped is in being able to define a new data object class and then to generate instances of that object class as and when they are required. Not only is the object paradigm restricted to the GUI but only the standard supplied graphics objects are true object classes. In Dyalog APL the ‘button’ is a standard class of graphics object of which it is simple to define instances, but if for example I want a class of specialised buttons that change the cursor when it crosses them, then I need to define a special function with which to generate instances of that class.
The basic GUI is the obvious place for object programming to start, but it leaves the programmer a nasty choice of either generating a number of hybrid systems using only the GUI object classes defined in the interpreter, or of implementing a complete object definition and management system in APL. Why, one might ask, not just program in Smalltalk and be done with it. Roger Hui made a telling comment in his talk to the BAA in February: when asked if he found all those funny letter combinations in J to be a hindrance to programming he said that it wasn’t the language that you used but the way that you thought — one in the eye for the ‘symbols are everything’ brigade. If we cannot program for the new user environment effectively without having to create an artificial ‘programming environment’ layer then perhaps we are in the wrong language.
Which would take more work and give a more durable and flexible result, putting the programming environment of Smalltalk into APL or putting the array capabilities of APL into Smalltalk?