NewtonScript
Apple's prototype-based language for the Newton MessagePad, designed by Walter R. Smith, whose double inheritance through _proto and _parent slots kept user-interface objects in ROM and showed that a classless object model could work for everyday application programmers
Created by Walter R. Smith, Apple Computer (Newton group)
NewtonScript is the language Apple created to program the Newton, the pen-based “personal digital assistant” platform that debuted with the MessagePad in August 1993. Its principal designer and implementor was Walter R. Smith, who also designed the Newton’s persistent object store. Unusually for a commercial product of its time, NewtonScript was prototype-based. It had no classes. Objects, called frames, inherited directly from other frames through two special slots, _proto and _parent. That design let a handheld with very little RAM keep most of its user interface in ROM, and it gave thousands of ordinary application developers their first experience of a classless object model.
History & Origins
The language thrash
Smith joined Apple’s Newton group in 1988, when it was still a research organization called the Special Projects Group. In his July 1994 essay “SELF and the Origins of NewtonScript”, he recalls that choosing a language for the device turned into a long detour, “not-so-fondly remembered as the ’language thrash’”. The team ran “a series of objective evaluations that showed we should really be using Smalltalk, or Eiffel, or Trellis-Owl, or even C++”, but conversation “would often wishfully turn to SELF”. At that point the group was deliberately not designing its own language: “Leave language design to the experts, we thought, and we’ll just choose one.”
That is not what happened. In Smith’s words, “during the development effort that brought you the MessagePad, a new language—now called NewtonScript—evolved in parallel with the view system and object store.”
From forms to a two-language architecture
Smith’s OOPSLA ‘95 paper explains how the project ended up there. At one stage the Newton was meant to run simple form-based applications on a built-in database, and “a low-level language like C++ was the obvious choice”. As the design matured, the application framework needed more flexibility than C++ made easy, and “a two-language architecture evolved”. C++ stayed in low-level components, and much of the core Newton software was written in it. NewtonScript took over the higher-level software, “including much of the user interface toolkit”, and third-party developers worked almost entirely in it.
When the MessagePad and the Mac-hosted Newton Toolkit (NTK) shipped in August 1993, TidBITS reported that the device’s own user interface amounted to about 47,000 lines of NewtonScript.
Design Philosophy
Smith’s papers set out a small number of firm ideas.
- Prototypes suit user interfaces. Most UI objects are one-offs, such as a particular dialog box or a particular menu that sets a font. In a class-based framework each one needs a new subclass, or its behaviour has to be pushed into some nearby object that already has a class. In NewtonScript you just make the object. Smith compares it to “assembling a bicycle instead of writing the assembly manual for a bicycle.”
- Trade ROM for RAM. PDAs had to be cheap, and fast RAM was the most expensive part. Inheritance therefore doubled as a memory-saving device (see below).
- Interpret, and drop to C++ when speed matters. Smith argued that most application work is coordinating the user interface, not crunching data, so “a bytecode interpreter is fast enough most of the time.” The system supplied fast C++ library functions for jobs like searching and sorting.
- Familiar syntax. “It will be obvious that none of SELF’s syntax was used in NewtonScript,” Smith wrote. He chose a “Pascal-like (or, to give credit where due, Algol-like)” syntax as easier for most programmers to learn. TidBITS described it in 1993 as “an amalgam of Pascal and C”.
Key Features
Frames and slots
Most NewtonScript data is ordinary values: integers, strings, symbols and arrays. Frames, collections of named slots, are the one kind of object that can receive messages. Smith called this an “impure” object model. A frame can be used as a plain record, or it can hold functions and receive messages:
Point := {
New: func (x, y) {_parent: Point, x: x, y: y},
Add: func (pt)
begin
x := x + pt.x;
y := y + pt.y;
end,
};
p := Point:New(1, 1);
q := Point:New(2, 3);
p:Add(q);
This listing is adapted from Smith’s own OOPSLA ‘95 paper. It shows the main syntax: := for assignment, {slot: value} frame literals, func ... begin ... end function objects, pt.x for slot access, and receiver:Message(args) for message sends.
Double inheritance: _proto and _parent
A frame inherits through up to two slots:
_proto, prototype inheritance: a chain of refinement from a specific object to progressively more general ones._parent, container inheritance: in views, the link from a subview to the view that encloses it.
Lookup searches the receiver, then its whole _proto chain, then moves one step up the _parent chain and searches that frame’s _proto chain, and so on. _parent slots inside _proto frames are never followed. Smith called the resulting shape the NewtonScript “comb”: a refinement relation embedded inside a containership relation.
Two rules make the comb useful:
- Copy-on-write through
_proto. Assigning to an inherited slot never changes the prototype. It creates a new slot in the receiving frame instead, so a value can be given a default in the prototype and overridden per object. - Container scoping through
_parent. A view’s slots are visible to its subviews and nowhere else. The layout of the user interface therefore also sets the scope of its variables. Smith says this idea was “inspired in part by HyperCard”, where unhandled messages travel up from button to card to background to stack.
Inheritance as memory management
The _proto rule is what made NewtonScript fit on a PDA. Smith’s OOPSLA ‘95 paper explains that a Newton application contains view templates: real frames, mapped into read-only memory, that serve as prototypes for views at run time. When a view opens, the RAM frame created for it holds little more than a _proto slot pointing to its template and a _parent slot pointing to the enclosing view. The templates in turn inherit from standard prototypes such as protoTextButton and protoLabelPicker in the system ROM. RAM grows only as slots are actually assigned, so “RAM is used only for the information that changes.”
Message sends versus variable access
Self merges variables and messages, so reading a variable might run a method. NewtonScript keeps them apart: a variable reference always reads a slot, and running code always takes an explicit send with :. Smith was frank that “there’s no fancy theoretical explanation for this decision; I was just being conservative with space, time, and implementation complexity.”
Other features
- Automatic garbage collection. There are no allocation calls, and references point to objects rather than raw pointers or handles (TidBITS, 1993).
- Run-time type checking. TidBITS described “latent typing”, with types checked before an operation runs.
- Exceptions. Exceptions are named by hierarchical symbols and caught with
try ... onexception. NEWT/0’s test samples catch|evt.ex.fr|for a built-in division error and|evt.ex.foo|for a user-defined exception. - Soups. Persistent data lives in soups, stores of frames kept in the Newton object store, which Smith designed together with the language.
Simulated classes
NewtonScript has no classes, but Smith’s January 1994 article “Class-based NewtonScript Programming” showed how to get one. You make a frame whose slots are the methods and give each “instance” a _parent link to it, as in the Point example above. Using _parent rather than _proto lets class slots act as shared class variables without hitting the copy-on-write rule. It also leaves _proto free to point at a “prototypical instance” holding default values.
Evolution
| When | Milestone |
|---|---|
| Aug 1993 | Newton MessagePad and Newton Toolkit (Mac) released; NewtonScript runs as bytecode in ROM |
| Jul 1995 | Newton Toolkit 1.5: native ARM compilation of selected functions, plus a profiler |
| Dec 1995 | Newton 2.0 becomes available, first on the MessagePad 120 |
| Jan 1997 | Newton Toolkit for Windows reaches beta 1.6b9 |
| Feb 1998 | Apple stops Newton OS development |
The 1993 toolkit compiled NewtonScript to compressed bytecode. TidBITS compared it to p-code and noted two interpreters: one for the MessagePad’s ARM610 and a 680x0 version for debugging inside NTK. Smith said in 1994 that the “relatively simple bytecode interpreter” did not approach “the speed of C or even an industrial-quality Smalltalk interpreter”. Neither he nor Apple’s announcements gave benchmark figures. Apple’s answer was NTK 1.5 in 1995, whose compiler could turn selected routines into ARM machine code. Its profiler timed individual functions to show which were worth compiling; Apple’s July 1995 announcement pitched it as a way to find the routines that would benefit from ARM compilation.
Smith listed the language’s weak points himself. Slot lookup is hard to make fast without classes. There are no private slots, so changing a prototype can break objects that inherit from it. And the lack of enforced structure encouraged ad hoc programs. He wrote that the team was investigating better compiler and toolkit support for the class-based style, but the Newton was cancelled before any such work shipped.
Current Relevance
Official development ended when Apple dropped the Newton in February 1998. NewtonScript survives through preservation projects:
- Einstein, Paul Guyot’s emulator, open-sourced in July 2007 and still being released in October 2026, runs a Newton ROM on macOS, iOS and Ubuntu Linux, with partial support for Android, Raspberry Pi and Windows. Users have to supply the ROM themselves, because it cannot be distributed.
- NEWT/0, Makoto Nukui’s NewtonScript compiler and interpreter (source marked copyright 2003-2004), runs
.newtscripts from the command line. Its README lists Mac OS X, Linux, FreeBSD, Windows (MinGW) and BeOS, and MacPorts packages it. - NEWT64, Matthias Melcher’s 64-bit rework of NEWT/0, has been active since 2020.
No Docker image exists for any of these.
Why It Matters
Smith himself suggested NewtonScript’s main contribution might be “simply a demonstration that a prototype-based language can be practical”, and that “real” programmers would accept it. Self had shown that prototypes were elegant. NewtonScript put them in a shipping consumer product and in front of thousands of commercial developers. Smith reported that many of them were unhappy at having to “return to traditional languages.”
Its most traceable legacy is Io. Steve Dekorte’s language guide credits NewtonScript with Io’s differential inheritance, and notes that “like NewtonScript, slots in Io are create-on-write.” NewtonScript is also often mentioned alongside Self as background to JavaScript’s prototype objects. Smith’s papers make no such claim, though, and NewtonScript is better seen as a parallel example of the same idea than as a documented ancestor.
Smith’s argument has outlasted the device: user interfaces are full of one-of-a-kind objects that fit badly into class hierarchies, and an inheritance scheme can double as a memory strategy.
Timeline
Notable Uses & Legacy
Newton MessagePad system software
Apple used NewtonScript for much of the Newton's own user-interface toolkit and built-in applications, keeping C++ for low-level components. TidBITS reported in 1993 that the MessagePad UI was about 47,000 lines of NewtonScript
Third-party Newton applications
NewtonScript was the language for Newton application development, written in the Newton Toolkit and downloaded to the device as packages. In 1994 Smith said it was the only language publicly available for Newton, with several thousand developers using it
Newt (Steve Weyer)
An on-device development environment that let users write and run NewtonScript and save packages directly on the Newton, with no desktop toolkit. It grew from a turtle-graphics environment (Newt 1.0) into a package builder (3.x), and was last updated in January 1999
NEWT/0 and NEWT64
Open-source NewtonScript compilers and interpreters that run NewtonScript source from the command line on desktop operating systems. MacPorts packages NEWT/0, and its build options include generating bytecode that can run on a real Newton
Einstein emulator
A GPL-licensed emulator, released by Paul Guyot in 2007 and still updated in 2026, that runs a Newton ROM on modern systems. It is probably the most common way to run NewtonScript applications today