Mops
Mike Hore's public-domain, native-code object-oriented Forth for the Macintosh - a complete reimplementation of Kriya Systems' Neon that added multiple inheritance and an optimising compiler, and that followed the Mac from the 68000 through PowerPC (PowerMops) to Intel (iMops) over almost four decades
Created by Michael (Mike) Hore, Australia (Sydney in the 1990s, later Darwin, Northern Territory); iMops, the x86-64 version, is credited to long-time contributor Nao Sacrada; other named contributors are Doug Hoffman (Quick Edit editor), Greg Haverkamp, Xan Gregg, Ed Williams and Arthur W. Green (documentation). Mops reimplements Neon, designed by Charles Duff at Kriya Systems (1984-1985)
Mops - Mike’s Object-oriented Programming System, though its author never wanted it capitalised as an acronym - is a public-domain, object-oriented dialect of Forth for the Apple Macintosh. It was written by Mike Hore, an Australian programmer, as a complete reimplementation of Neon, the commercial “Forth meets Smalltalk” language sold by Kriya Systems in the mid-1980s. Where Neon and its conservative descendant Yerk kept the classic threaded-code Forth interpreter, Mops compiled native code - first for the 68000, then for the PowerPC (PowerMops), then for x86-64 (iMops) - and extended the Neon object model with multiple inheritance, temporary objects on the stack and an optimising compiler. Distributed with full source from its first release and developed by one person, part-time, for almost four decades, it is one of the longest-lived Macintosh development systems and the most complete example of the “Neon model” of object-oriented Forth.
History and origins
Neon: Forth meets Smalltalk (1984-1985)
In 1984 the Macintosh had almost no native development tools, and most software for it was still being cross-developed on the Lisa. Charles (Chuck) Duff and Norman Iverson of Kriya Systems in Chicago set out to change that with Neon, which they described in a 1984 Journal of Forth Application and Research paper titled “Forth Meets Smalltalk”. Neon took a Forth kernel - Forth being small enough to bring up on a 128K machine - and added classes, methods, instance variables, inheritance, SANE floating point and a library of classes wrapping the Macintosh Toolbox: windows, menus, controls, dialogs and QuickDraw. Bruce Horn, a member of the original Macintosh team, reviewed Neon 1.0 in Club Mac News (May 1985), reprinted in Dr. Dobb’s Journal in October 1985: it cost $155, ran on a 128K Mac, and with “the basic classes, examples, and tutorial, you could be writing interesting programs that support the Macintosh User Interface Standard in a matter of weeks”. MacTutor’s first object-oriented programming column (1985) reportedly called Neon and Smalltalk the only “true object oriented environment[s]” then available on the Mac.
Neon’s syntax placed the selector before the object - put: myRect, draw: theWindow - a choice Bob Loewenstein defended as reading “verb noun” rather than “noun verb”. Kriya sold Neon until the end of the 1980s (FOLDOC’s Neon and Yerk entries give 1985-1988 and 1985-1989 respectively); Duff went on to create the Actor language for Windows around 1987-1988, reportedly “an offshoot of some object-oriented extensions to the Forth language he had been working on”.
Two descendants: Yerk and Mops
When Kriya discontinued Neon it released the source code into the public domain, keeping only the name. Two lines grew out of that release. Bob Loewenstein, an infrared astronomer at the University of Chicago’s Yerkes Observatory who had beta-tested Neon in 1984, kept the original code alive as Yerk (“I wanted a name that no one would sue me for”), using it for telescope control and issuing versions 3.6x through the mid-1990s.
Mike Hore’s Mops was, in his own words, “more radical”: “a complete reimplementation which compiles native (68K) code instead of the usual Forth threaded variety. It’s very fast - about as fast as anything on the Mac in fact. It has a few other improvements over the original Neon, such as multiple inheritance, and temporary (local) objects.” The Mops manual is candid that it was “derived from the Neon language developed by Charles Duff and sold by Kriya, Inc.” - the tutorial and much of the manual descend directly from Neon’s. When Hore started is less clear than one would like: the project’s news page says he created Mops “way back in 1986”, its FAQ says he had “been doing it for 30 years now”, Japanese Wikipedia says 1988, and Ed Williams wrote in March 2002 that the system had been developed “over the past 13 or 14 years”. Hore’s own FAQ of November 1996 says “I’ve been doing it for 6 years now” - probably counting from the first public release. Whatever the exact date, versioned releases (2.3.1; 2.4, which Macintosh Garden dates to 1994; and 2.7, which it dates to 1995 and which Hore’s November 1996 FAQ lists as current) were circulating on taygeta.com and ftp.forth.org by the mid-1990s, and Mops appears alongside Yerk in the comp.lang.forth FAQ and in Rodriguez and Poehlman’s 1996 survey of object-oriented Forths.
Hore was clear about the scale of the enterprise: “As a one-man, very part time operation, Mike can’t hope to singlehandedly compete with all the commercial outfits producing gargantuan bells and whistles encumbered development systems for the Mac”. The 1996 FAQ, posted from a Sydney dial-up Unix host, fends off requests for code review (“I’m doing this in my spare time, remember”) and answers the inevitable question “Why an oddball language that isn’t C++?” with “Try it and see how quickly you can get things done. The most popular way isn’t always the best way. After all, you’re using a Mac, aren’t you?”
PowerMops (1996-2009)
The 68k version ran on anything from a Macintosh Plus or 512KE with 4 MB of RAM, according to the 1996 FAQ. When Apple moved to the PowerPC, Hore wrote a new code generator rather than a threaded port; by November 1996 “the basic code generation now seems pretty solid” and the next step was to have the generator recompile itself for the PowerPC. The result, PowerMops, shipped as a beta in the late 1990s and, with Mops 4 (whose manual is dated September 2000), as a mature system that could build “fat” applications for both processors. Doug Hoffman’s Quick Edit editor became the front end from 2.7 onwards, turning Mops into an integrated environment in which any line in an editor window could be executed.
Mac OS X and Carbon brought a burst of work in the early 2000s, much of it by Nao Sacrada, a Japanese user who (according to Japanese Wikipedia) had started by translating documentation and reporting bugs: PowerMops 5.5 added calls to OS X frameworks and direct Mach-O calls; 5.6, whose new features Hore’s release notes credit “largely” to Sacrada and Doug Hoffman, added calls into Cocoa code written in Objective-C, NIB-based Carbon menus, cascaded messages and an OSX? flag. 68k Mops stopped changing at 4.0.4, and the 6.0 release notes say it is “completely unchanged from 4.0.4, and so is no longer included with this distribution”. The project moved to SourceForge in November 2005. PowerMops 6.0 (23 June 2006) added 64-bit arithmetic on the G5 and Mach-O executables; 6.1 (7 July 2007) brought “dozens of bug fixes” and 6.2 (24 October 2009) a few more plus a new mechanism for creating arrays and lists of objects. 6.2 is still the final PowerPC version.
The Intel question and iMops (2006-2022)
The 6.0 release notes contain a small piece of Forth history. Asked whether Mops would compile native code on the new Intel Macs, Hore answered: “No, it won’t. PowerMops will run as it always has, under Rosetta … but to run natively the code generator would need to be rewritten to target the Intel architecture.” The PowerPC generator “could be adapted to another RISC architecture in a fairly straightforward way”, but “the Intel architecture, however, is basically early-1980s vintage and is CISC, not RISC”, and he was not going to put the effort in, “especially as I strongly dislike the Intel architecture.”
The x86-64 port nonetheless arrived, as iMops, in 2014 - a “subroutine threaded, optimizing Forth compiler … linked with Cocoa/Objective-C”. Japanese Wikipedia credits it to Nao Sakurada (Sacrada); the powermops.org site describes it as “an offspring of PowerMops” without naming an author. A 1.23 build and an “iMops 2b” beta appeared on SourceForge in March and April 2014, 2.0 on 27 July 2014, and maintenance releases followed through 2.2 (12 November 2016, the first developer-signed build), 2.21 (2017), 2.22 (2018) and 2.23 (5 February 2022), which fixed a launch crash on macOS Monterey and, lacking a signature, ships with a “Read Before Launching” note about Gatekeeper. iMops reportedly requires an Intel 64-bit Mac running OS X 10.6 or later and, according to a comp.lang.forth post by Doug Hoffman in April 2022, defines all of the Core and Core Extension words of the Forth 200x draft.
aMops, MAX and the end of Hore’s involvement (2017-2024)
Hore’s last projects were experiments run inside iMops. MAX, a runtime with floating-point and capability-based addressing, went through versions 1.1 (January 2017) to 6.1 (3 January 2023). The aMops code generator, “the next development of iMops to run natively on Arm processors (Apple silicon)”, went from alpha-1 (31 July 2020) to 3.4 (23 April 2023) and could compile and target-compile itself under an instruction emulator; from 3.3 (November 2022) it anticipated Arm’s Morello prototype of the CHERI capability architecture, with its 129-bit tagged registers. Hore, writing from Darwin in January 2022, described the generator as a project “that has already had several incarnations spanning 18+ years”.
On 5 December 2024 he formally ended his involvement. Still using an Intel iMac, he had no way to progress the Arm version, “but the main reason is that Mops just doesn’t represent the state of the art in system-level programming any more. Object orientation has fallen out of favor as unnecessarily complex. With hindsight multiple inheritance wasn’t worth the complexities of implementation and simply wasn’t such a good idea.”
Design and features
Forth underneath
Mops is a Forth: a data stack and a return stack, postfix notation, colon definitions and a dictionary of words, an interpreter that executes what you type and a compiler that turns definitions into machine code. The 1996 FAQ recommends knowing Forth basics, but the manual, inherited from Neon, “assumes a very basic level of knowledge about programming, and none about the Mac”. Mops is case-insensitive, uses \ and ( ... ) comments, and by 2002 could “readily be converted to a standards-compliant ANSI Forth compiler, and just as readily back again”; iMops reportedly defines the full Forth 200x core word set.
| |
What distinguishes Mops from most Forths is the code it produces. Rather than the indirect- or direct-threaded code of classic Forth, Mops compiles subroutine-threaded native code and optimises it - the 1996 FAQ, for instance, documents a bug in the optimisation that folds a partial-word fetch, an add and a second fetch into shorter code, with the workaround of inserting a dummy operation to block it. Hore’s claim that Mops was “about as fast as anything on the Mac” comes without benchmarks, and no independent measurements are known; what is documented is the mechanism, and that the PowerPC and x86-64 compilers are self-hosted.
The Neon object model
On top of Forth sits a Smalltalk-inspired class system. A class is declared with :class ... ;class, names a superclass (or, in Mops, several), declares instance variables - which are themselves objects of other classes, such as int, var or string - and defines methods with :m ... ;m. Messages are sent with a selector ending in a colon, written before the object:
| |
Inside a method, get: x sends a message to the instance variable x of the current object - a name Mops resolves at compile time (early binding), so the call is a direct jump. Sending a message to an object whose class is only known at run time uses late binding: print: [ someObjectAddress ], where the bracketed code leaves an object address on the stack and the selector is looked up in that object’s class at run time. Hore removed the implicit form (sending a message to a Value holding an address) in 2.7 because it was “too easy to invoke this feature accidentally … The result was usually a horrible death”; the explicit [ ... ] form makes “much more obvious from the code what’s happening”.
Anton Ertl, surveying object-oriented Forths in 1998, called the Neon/Yerk model - “which is also implemented in Mops, Win32Forth and in ANS Forth” via Andrew McKewan’s package - one that “currently (in 1998) appears to be the most popular one”, while noting the costs of its selector-first syntax: selectors must parse the input stream at compile time, which makes passing objects on the stack awkward and makes selectors state-smart. Mops lives with those trade-offs in exchange for readability and speed.
What Mops added to Neon
- Multiple inheritance. A class can name more than one superclass in
super{ ... }; this was the headline difference from Neon and Yerk, and the feature Hore repudiated in his 2024 farewell. - Temporary objects.
temp{ ... }declares objects allocated on the stack for the duration of a definition, giving cheap local objects without heap management. Rodriguez and Poehlman note that Mops, unlike Neon, “does not support persistent dynamically allocated objects, but does allow ’temporary’ objects that are allocated on a stack” - later versions added heap objects and, per the project site, garbage collection. - Named parameters and locals. Definitions can declare named input parameters and local variables with a
{ x y -- }style list, replacing stack juggling inside definitions. - Public instance variables and object references (listed in the FAQ), cascaded messages and a right-arrow operator (5.6), and, in iMops, message cascading (added in 2.01) and an object system supporting what Doug Hoffman reportedly described as duck typing alongside multiple inheritance.
- Relocatable addresses. Because an execution token in Mops is an absolute address and the dictionary can load anywhere, the manual warns against saving tokens at compile time and provides
DicAddr,X-AddrandX-Arrayclasses for relocatable references. - Modules. Code such as dialog support is packaged in modules that load on demand and must be flagged with
true setInstall: myModuleto be included in an installed application. - Inline assembler. Mops includes an assembler written in Mops, so assembly code is also written in postfix form with operands before opcodes.
The Macintosh class library and Install
The reason to use Mops rather than another Forth was the class library. Neon’s classes for windows, menus, controls, dialogs, rectangles, QuickDraw pens and files were re-implemented and extended: colour windows (true setColor: myWindow), the Toolbox event loop, resources, and later AltiVec vector arithmetic on the G4, OpenGL, Carbon events, NIB-based menus and direct calls into Cocoa. A program is developed interactively - Quick Edit lets you select and execute any line - and then written out with Install as a standalone application that a user double-clicks like any other. Hore’s 1996 FAQ was equally clear about what Mops could not do: “Mops only does applications” - no XCMDs, control panels or extensions, though on the PowerPC “everything’s done via shared libraries” and PowerMops supported those.
Distribution and licence
Every Mops distribution has included the complete source. In the 1990s only the nucleus was shipped as a binary “to save download time” and the user compiled the rest from source by following Readme.1st; a recurring FAQ item explains the crash you get when a new dictionary is loaded on top of an old nucleus. Mops has always been described as public domain (SourceForge lists the licence as Public Domain), and the current site and manual carry a Creative Commons Attribution 4.0 notice, “Copyright 2003-2025 Mike Hore and the Powermops community”.
Evolution
| Period | Version | Platform | What changed |
|---|---|---|---|
| mid-1990s | Mops 2.3.1-2.7 | 68k Macintosh (Plus/512KE and up) | Native 68k compiler; multiple inheritance; temporary objects; Quick Edit interface in 2.7 (1995-1996) |
| late 1990s-2000 | PowerMops beta; Mops 4 | 68k and PowerPC | Self-hosted PowerPC code generator; fat applications; new manual (September 2000) |
| early 2000s | PowerMops 5.x | Mac OS 9 and Mac OS X (Carbon) | Framework, Mach-O and Cocoa/Objective-C calls; 68k Mops frozen at 4.0.4 and dropped from the distribution in 6.0 |
| 2006-2009 | PowerMops 6.0-6.2 | PowerPC, including G5 | 64-bit arithmetic; Mach-O executables; runs on Intel only under Rosetta |
| 2014-2022 | iMops 1.23-2.23 | x86-64 macOS (reportedly 10.6 or later) | Native Intel compiler linked with Cocoa; Forth 200x core words; signed builds 2016-2018 |
| 2017-2023 | MAX 1.1-6.1; aMops code generator alpha-1 to 3.4 | run inside iMops | Capability-based runtime; Arm/Apple silicon code generator with Morello support; never a finished compiler |
Current relevance
Mops is dormant. The last shipping compiler, iMops 2.23, dates from February 2022; the Arm code generator stopped at 3.4 in April 2023 without becoming a usable aMops compiler; and its author retired from the project in December 2024. Because Apple has said that macOS 26 (Tahoe) is the last version to support Intel Macs, iMops has a limited future even on the hardware it targets, and PowerMops already needs a PowerPC Mac or an emulator such as SheepShaver. The SourceForge project (last touched in January 2025), the mailing list and the powermops.org site with its 22-lesson tutorial and full manual remain online, and Macintosh Garden preserves the 68k and early PowerPC releases (2.4 through 5.4.1) for emulation.
The community was never large, but it was loyal: the same names - Doug Hoffman, Nao Sacrada, Jim Tittsler, Xan Gregg, Ed Williams - recur across thirty years of release notes, and the project’s 10,000-plus downloads earned a SourceForge Community Choice badge. On comp.lang.forth Mops is still cited as the example of a full native-code, object-oriented Forth with real GUI integration.
Why it matters
Mops matters for three reasons. First, it is the most developed implementation of the Neon object model, the “selector: object” style that Anton Ertl in 1998 judged to be apparently the most popular way of doing objects in Forth and that spread, via Yerk and McKewan’s ANS Forth package, to Win32Forth and beyond. Second, it demonstrated that Forth need not mean threaded code: from the 68000 onwards Mops was an optimising native compiler that could recompile itself for each new architecture Apple adopted, and it went on doing so for 68k, PowerPC and x86-64 while a fourth generator for Arm was in progress. Third, it is a remarkable piece of one-person software history - a complete Macintosh development environment with an IDE, class library and manual, kept current through System 7, Carbon, Mac OS X, 64-bit and Cocoa by a part-time author who gave it away with full source for nearly forty years, and who was honest enough at the end to say which of his design decisions he no longer believed in.
Further reading
- Mops project site, manual, tutorial, FAQ and news: powermops.org
- Downloads (Mops 4.0.4, PowerMops 6.2, iMops 2.23, aMops, MAX): sourceforge.net/projects/powermops
- Mike Hore, “Mops FAQ - Nov ‘96” (comp.lang.forth.mac, 5 November 1996): forth.org/literature/mopsfaq.txt
- Ed Williams, “The Mops Programming Language”, parts 1 and 2, ATPM 8.03-8.04 (March-April 2002): atpm.com/8.03/mops.shtml
- Bruce Horn, review of Neon 1.0, Dr. Dobb’s Journal, October 1985: archive.org
- Bradford J. Rodriguez and W. F. S. Poehlman, “A Survey of Object-Oriented Forths”, SIGPLAN Notices 31(4), April 1996: bradrodriguez.com/papers/oofs.htm
- Anton Ertl, “On Standardizing Object-Oriented Forth Extensions” (1998): complang.tuwien.ac.at/forth/objects/opinion.html
- GEnie Forth RoundTable conference with Bob Loewenstein on Yerk (19 September 1991): yerk.txt
- Mops on Macintosh Garden (68k and PowerPC archives): macintoshgarden.org/apps/mops
Timeline
Notable Uses & Legacy
Mops itself (self-hosted for nearly forty years)
Apart from an initial nucleus written in assembler, Mops has been written in Mops since the beginning: the 68k compiler, the PowerPC code generator (which in 1996 was about to 'recompile the code generator itself, targetting the PowerPC'), iMops (described in 2022 as 'self-hosted, written in iMops') and the aMops Arm code generator and MAX runtime, which are loaded and run inside iMops
Macintosh application development by individual programmers
Mops' stated niche was 'the kind of applications which might be developed by one programmer': it shipped a class library covering windows, menus, dialogs, controls, QuickDraw graphics and files, an Install command that wrote out a standalone double-clickable application, and later AltiVec, OpenGL, Carbon and Cocoa/Objective-C bridges. Hore himself had by 1996 written two 'real' applications in it whose source he was not free to distribute
Quick Edit and the Mops IDE
Doug Hoffman's Quick Edit, a System 7 source-code editor built specifically for Mops, lets typed Mops commands be executed directly from an editor window and communicates with the compiler so the two form an integrated development environment; from Mops 2.7 (1995-1996) it became the standard front end, and later the 'Open Me First' document was itself a live Quick Edit file
MacQForth
The comp.lang.forth FAQ (1995) lists MacQForth, an adaptation of the Apple II QForth to the Macintosh, as 'created with Mops and accompanied by the Mops sources' - an introductory Forth package with 'witty and instructive material proselytizing on behalf of Forth'
Teaching Mac programming and OOP
Because the manual descends from the original Neon tutorial, which 'assumes a very basic level of knowledge about programming, and none about the Mac', Mops was widely recommended as a free way to learn both object-oriented programming and Toolbox programming; Ed Williams' two-part ATPM series (2002) and the 22-lesson tutorial on powermops.org are the best-known examples