The Long View
The Long View
MacApp - origins
The software supplements were three regular mailings sent to subscribers in the early days of Macintosh programming. There were 3 mailings; the first was in May 1985. The last was dated March 1986. On page 52 of the May 1985 mailing, was there was this statement:
MacApp
Apple is developing an object-oriented library called MacApp™, The Expandable Application™. MacApp implements the standard features common to most Macintosh programs. To write an application, you specify the differences between your particular product and MacApp. MacApp provides a substantial portion of a Macintosh Application, including standard objects like windows, menus, scroll bars and documents, and standard operations like scrolling, resizing, printing, and text editing...
At present, MacApp--and programs written to use it -- must be written in Object Pascal, and object oriented extension of Pascal. We currently have an "alpha" version of the Object Pascal compiler which runs on the Lisa Workshop 3.9 and generates code for the Macintosh. MacApp is also in an alpha-test state. To develop and application using the alpha Workshop version of MacApp you would need to have:
(1) A Lisa (Macintosh XL) with at least 1 MB of memory and 5 MB of hard disk storage (10 MB recommended).
(2) Lisa Pascal Workshop version 3.9 (Workshop 3.0 + 3.9 Update --> Workshop 3.9)
(3) Inside Macintosh
(4) The May 1985 Macintosh Software Supplement
(5)A 512K Macintosh or a Macintosh XL with MacWorks XL 3.0 (MacWorks XL 30 is included with the May Software Supplement)
If you have the hardware and software listed above and are interested in using MacApp, write to us at the address below; we will notify you when a released version of MacApp is available.
The third (March ’86) issue of the software supplement included an order form that listed MacApp for the Lisa Workshop, version 1.0A40, for sale for $40.00. If you were programming your Macintosh using the Lisa Workshop, you could have started using Object Pascal and MacApp in 1985, a lot sooner than most people did. But you would still have been a latecomer. MacApp and Object Pascal were under development at Apple for several years before they were released to the world. Larry Tessler developed Object Pascal’s predecessor Clascal for use on the Lisa, and presented it to the ACM (Association for Computing Machinery) conference in Personal and Small Computers in 1983. Had the Lisa made it, a MacApp-like system called the Lisa Toolkit would have been its standard programming framework.
A Language of Their Own
According to the story, Steve Jobs visited Xerox PARC in 1979, where he was shown three things: object-oriented programming, networked computers, and the graphical user interface. The story goes that he was so taken by the third that he barely noticed the other two. Maybe so, but in 1980 Apple hired Larry Tesler, who had spent plenty of time at PARC and understood all three.
There was a lot of complaining in the beginning about how hard it was to program the Macintosh. But programming the Macintosh was easy compared to the Lisa. Apple didn’t distribute good programming tools for the Lisa, not (only) because they wanted to control the Lisa software market, but also because their programming tools weren’t ready to use. The Lisa had all the user interface complexities of the Macintosh, but more complex process management and I/O systems. The Lisa 7/7 system of office software was written by the same people who wrote the operating system, and they must have known better than anybody how hard it was. The Lisa Toolkit was supposed to be the solution to all this. It was an object-oriented class library fashioned after Smalltalk-80, but built around the the specifics of the Lisa system.
Smalltalk-80 wasn’t just a class library, it was an operating system and object-oriented language designed as a whole from the ground up, the whole ball of wax. The Lisa was programmed using the m68k assembly language and Pascal, neither of which included support for classes, and so it was necessary to invent an object-oriented language for the Lisa, post hoc. But the Lisa’s system calls were designed to be called from Pascal. The best thing under the circumstances would be an object-oriented extension of Pascal that could use the existing software interfaces in an efficient manner, so if some system service was not (yet) implemented in the class library it could be called directly from Pascal. We are used to object-oriented extensions of standard languages now, but it had not been done much (at all?) before. For example, C++ was introduced in 1983, and first became available in 1985. Brad Cox’s famous book introducing Objective-C was published in 1986. I can’t think of an object-oriented extension of a standard programming language before Clascal, but there might have been one I guess. Apple might have been the first to do this, but even if they weren’t, Clascal and the Lisa toolkit were groundbreaking. Most of the object-oriented frameworks in common use today can be traced back directly to Clascal and the Lisa Toolkit. According to often repeated (but usually not well documented) accounts, Larry Tesler developed Clascal in collaboration with Niklaus Wirth, the legendary inventor of Pascal. My guess is that it was mostly Tesler. The experience did not apparently make a big impression on Wirth. He does not mention Object Pascal or Apple at all in his essay, Pascal and its Successors, written in 2002.
Pascal was designed to work with programmer-defined data structures called Records. A template for a Record could be declared and a programmer could assign a name to the new data type associated with the template. New instances of these user-defined Records could be allocated on the heap using the allocator function, new. Clascal extended the Record mechanism to allow declaration of classes of objects. A class was declared in a way similar to a Record, but included declarations for member functions (called methods, as in Smalltalk). Object-oriented systems pay a performance price in the dispatch of overridden methods, and this was worrisome on the Lisa with its ambitious operating system and modest processor. Clascal used some compile-time hints to make method calls as efficient as possible. Abstract methods had to be declared as such, and were not expected to have an implementation in the base class. Subclasses would be required to implement those. Default methods required a default implementations in the base class (called superclass), but were expected to be overridden in some or most subclasses. There were no metaclasses in Clascal, but objects are constructed using a single class method, called CREATE. Objects were created using a single global Pascal function, NewObject. I can’t find out how it was implemented. The Pascal heap allocator on the Lisa was not very sophisticated, and it seems unlikely to me that objects were allocated on the heap using that function, but maybe so.
The Lisa Toolkit was a single inheritance tree starting with the archetypal TObject. The user interface was implemented in a set of classes called the Application Base Classes, that included elements common to the user interface of all Lisa programs, like TWindow, TDocument, TView, TCommand, etc. Much of this ended up in MacApp only minimally changed.
I can’t find a copy of the Lisa Toolkit in any form. I think that Apple dropped the Lisa before the Toolkit could get out and be used very much. There was a Lisa Toolkit users group who continued to hang onto it after Apple dropped the Lisa and its tools, but all the links to that group seem dead now. Lisa’s are still around and are bought and sold on eBay, sometimes for a lot of money. But apparently this activity is about collecting, not about programming.
Object Pascal and MacApp on the Lisa Workshop, and then MPW
The version of MacApp that was advertised in the software supplements was an rewrite of the Lisa Toolkit for the Macintosh, and it came with a new version of Clascal, called Object Pascal. MacApp was designed for the Macintosh, not for the Lisa, but it was used on the Lisa, not the Macintosh. I know that sounds crazy. You could use MacApp it to build a Macintosh program using the Lisa Workshop, and then you would have to put that program on the Macintosh to run it. Or, if your Lisa could run MacWorks, you could restart your Lisa into the MacWorks environment and try out your program. This was inconvenient and expensive (a Lisa cost about $5000 at that time). But the Macintosh in 1985 didn’t have enough memory or disk storage to handle a large programming system like the Lisa Workshop, and Apple didn’t have a suitable programming system for use on the Macintosh. There were some great third party programming environments in those days, and one of them was an amazing object-oriented Forth-inspired language named Neon. But none of these systems could compile MacApp. For most people programming the Macintosh, use of MacApp would have to wait for the release of Apple’s Macintosh Programming Workshop, with its Object Pascal compiler, in September, 1986.
Although short on memory and disk space, the Macintosh had a number of features that made it easier to program than the Lisa. It had a well organized and well-documented Pascal-callable library, the Macintosh Toolbox, stored in ROM. It had a modest memory, but it had a great memory manager, so efficient allocation, storage and disposal of objects was easy. On the Macintosh, objects were relocatable, being allocated on the program heap as handles. Accessing a instance (member) variable actually involved a double dereference, but Object Pascal took care of that for you, so that it looked like myObject.myVariable, as in Lisa Clascal (although what was really happening was something like myObject^^.myVariable). Likewise, method (member function) calls hid their mechanistic details, being made as in myObject.myMethod.
MacApp for Macintosh Smalltalk-80
Smalltalk-80 for the Macintosh was an Apple product in the mid 1980’s. Like MacApp, it was more of a research project being shared with programmers than a regular product. During that period, Apple seemed to be intent on developing Smalltalk into some kind of real product that could be integrated into the regular Macintosh software catalog. An interest in Smalltalk-80 at Apple seems natural enough. Larry Tesler, the father of Clascal and no doubt a key figure in Object Pascal and MacApp development, had used Smalltalk at Xerox PARC. Smalltalk-80 was a major inspiration for the Macintosh. On the other hand, Smalltalk-80 wasn’t only a language, but also a user-environment that drew menus, windows, and dialogs with its own look and feel that was distinctively different from the native Macintosh. It was fun to run Smalltalk-80 on a Macintosh, but it was more like an alternative operating system, not a development system for Macintosh applications. Apple was apparently looking beyond that, at a Macintosh-native Smalltalk. Just before MacApp became available for MPW on the Macintosh, Kurt Schmucker (with cooperation from Apple) published a book about it, entitled “Object-Oriented Programming for the Macintosh” (Hayden Books, 1986). It showed a version of MacApp written for Apple’s Smalltalk-80. In the book, a MacApp based Smalltalk program was shown running in the Smalltalk-80 user environment. In a MacApp update disk distributed to the MacApp Developers Association, in 1987, Schmucker showed screen shots of a Macintosh native application developed using Smalltalk-80 and its version of MacApp. As late as November, 1987 Harvey Alcabes, MacApp Project manager, announced to MacApp users that “In 1988 we plan to release an interpreted Smalltalk system with a Macintosh user interface and access to MacApp classes translated into Smalltalk.” Then, about the time of the introduction of the Macintosh II, all talk from Apple about Smalltalk-80 stopped. I wonder what happened? Do you think it might have had to do with color video?
Although a Smalltalk-80 version of MacApp seems like a stretch, there was no reason that MacApp had to be used exclusively with Object Pascal. A key design feature of the MPW system was a standard object file format that could be used to link object code created in a variety of languages. Apple provided an assembler, Pascal and Object Pascal compiler, and a C compiler. MPW-compatible compilers from third parties followed. To the developers of these compilers, MacApp looked like a statically-linked library. Making and using MacApp objects just required a satisfactory syntax for referring to objects in the calling language. One obvious choice was C++, and almost from the beginning, the MacApp.TECH$ (Applelink) mail list was full of discussion about how to use MacApp from C++. Eventually, it would become the standard, practically the only way to use MacApp. But in 1986 there were other possibilities. There was even a way to use MacApp from 68k assembly language. This consisted of a set of macros that could do things like access an instance variable or create an instance of a MacApp object from assembly language. These macros were stored among the regular assembly language interfaces of MPW, in a file called ObjMacros.a. Looking at them is illuminating (once you get over the initial confusion), because it reveals the implementation details behind the runtime organization of the MacApp library. If you could do it from assembly language you could do it from anywhere. Basically, anybody could have invented his own object-oriented programming language (object FORTRAN?) and arranged it to compile into object assembly language, and run MacApp. So far as I can tell, this didn’t happen.
The MacApp Debugger
The debugger was contained in an Object Pascal unit. A programmer could build MacApp with or without the debugging code. Any program linked to the debugging code automatically gained an extra menu, entitled Debug, and the debugger was available at all times. By the standards of the time, it was a pretty great debugger. There was an inspector window that showed every object that was in memory. It looked a little like the Smalltalk-80 debug browser. The inspector window was a regular window in the program, and could be examined during the regular operation of the program. There was also a transcript window (transcript is what this kind of thing is called in Smalltalk-80), that the program could send debugging messages. The user could enter a console-driven debugging interaction with the program at any time by selecting “Enter MacApp Debugger” from the Debug menu. At that point, there were a lot of commands available from the command line, to examine the heap, do a stack walk, step through code, set breakpoints, etc. Execution of the host program could be restored from the command line, and the debugger would be reentered manually at a breakpoint. MacApp was not exactly Smalltalk, but it was close. Of course, all the debugging code was part of the program being debugged. If the program went really bad, you were back in Macsbug (or TMON), or you were crashed.
Once SADE was released, the MacApp debugger was less essential, and SADE’s successor, SourceBug, was even better for MacApp programmers. Over time, support for the MacApp Debugger was gradually phased out.
Mouser
Special Resources
One of the most important features of MacApp was its use of an advanced set of resources, especially for menus and views. The menu part was simple. The flow of execution in MacApp relied mainly on the creation of TCommand objects. For every discrete operation the user could ask the program to perform, the MacApp programmer would create a subclass of TCommand. The execution of the program then basically boiled down to creating the appropriate command objects at the right times and letting them do the thing they were supposed to do. This also made for the first unified implementation of Undo on the Macintosh. TCommand objects could know how to undo themselves. In the earliest versions of MacApp, a command object would be kept around until a new command object executed. As long as a command object was the most recently executed command, it could be asked to Undo itself. When a new command was generated, it superseded all previous ones, which were deallocated. This yielded one level of Undo. Later versions of MacApp kept a queue of recently executed command objects around, and they could be undone in reverse chronological order of execution.
Much of the user interface of any program consisted of methods for creating command objects. Command classes had unique 32 bit ID numbers. The easiest way to create a command object was to associated its class ID with a menu item. When the user selected a menu item, MacApp code would create the associated command object. To make this association, MacApp used a special resource for creating menus. Instead of using the regular MENU resource, MacApp programs used a substitute resource that included a command ID number. When that menu was selected, MacApp would look for a command object subclass with that ID, and create it for you. The new menu resources (cmnu) were not much different from the old ones. They didn’t have to know about command objects directly, but only their ID numbers.
The rest of GUI creation was harder, because it was necessary to identify particular objects, defined in code, with data in the resource file. Resources and resource editors were not originally GUI-creators in the sense that we are used to now (for example, in Interface Builder). In the Macintosh world, code could load and connect itself to resources, but resources were ignorant of the code that used them. MacApp had to use the original Macintosh resource mechanism, but it needed to overcome this one-sided relationship between code and resources. To do it, a new resource editor was required, and a new set of resources. Over the years, there were a series of MacApp resource editors, but the original was ViewEdit. The original (MacApp version 2) view resource format extended the Macintosh resource model in the smallest possible way. It allowed you to interactively draw views that would appear in a window, specify the values for all the fields that belonged to the base class of the view. The new thing was the ability to give the name and ID of your view class, allowing MacApp to initialize your view objects from their resource descriptions.
MacApp Source Code and Licensing
MacApp was an object-oriented class library, but it was advertised as an “expandable application”. A class library seems like a familiar idea now, but in 1985 most programmers might have heard or read the phrase, but few programmers knew what that meant. Outside of Apple, PARC, and other computer research sites, very few people had any experience with object-oriented programming. The idea of an expandable application was a little bit more familiar. An expandable application usually consisted of a library consisting of already-compiled code, to which a programmer could link application-specific code. This placed a lot of constraints on the resulting program. Parts of the program were specified by the library, and could not be altered. A class library is an entirely different thing, in that every method in any object could be overridden. Beyond that, Apple supplied the source code for the entire class library. Every part of MacApp was open to change by any programmer. But MacApp was not open source. In fact, if you used it, you were required to pay a licensing fee to Apple.
MacApp was distributed as source code. If you got MacApp, you got the whole thing, and you could modify it to your heart’s content. There was a fee charged, however. It cost $100 yearly for software companies to sell their Macintosh software made using MacApp. If a second publisher or distributing company distributed software made using MacApp to another company for sale, then the seller had to likewise have a license. In June 1988, Apple eliminated the requirement that publishers and distributors hold MacApp licenses and replaced it with the requirement that all programs made using MacApp say so in their “About...” dialog. This was not to make money from MacApp, but only to preserve Apple’s copyright to the program. They were basically giving it away, but wanted to preserve the rights to it.
The MacApp Legacy
The fact that MacApp was distributed as source code is responsible for its enormous impact on computing. It was copied everywhere, and was used for many purposes. Most example code that you got from Apple or elsewhere included a disclaimer saying it wasn’t a full-fledged Macintosh application and you shouldn’t use it as an example of how to write production code. MacApp was production code. It was Apple’s best statement about how to write a Macintosh program. Even if you weren’t using MacApp, if you wanted to know how to do something, you could just see how it was done in MacApp.
It was also used as the inspiration for just about every other class library of the time. Apple’s attempts to preserve their rights to MacApp couldn’t keep it from being used largely as the basis for new class libraries. Practically every class library in use in the 1990’s is clearly the child of MacApp. For a while in the 1990’s I tried my hand at programming Windows using the Microsoft Foundation Classes. I felt right at home.
-- BG (basalgangster@macGUI.com)
Wednesday, April 27, 2011