The Mary Programming Language: A Retrospective Analysis of its Design, Features, and Impact
The 1970s were a period of rapid development in the field of computing, with several new programming languages emerging to meet the growing demands of both academic research and industrial applications. Among these, the Mary programming language, designed and implemented by RUNIT at Trondheim, Norway, stands out for its distinctive approach to machine-oriented programming. Though it has long since been eclipsed by more widely used languages, its design and features offer a fascinating glimpse into the evolution of programming languages, particularly in the context of early efforts to optimize code generation and simplify the programming process.

The Origins of Mary
Mary was conceived as a programming language capable of supporting machine-oriented programming, which emphasized efficient low-level operations and the ability to optimize code generation. Developed at the Norwegian Institute for Industrial and Technical Research (RUNIT) in the 1970s, the language was heavily influenced by ALGOL 68, a language known for its powerful features but also for its complexity and relative obscurity. RUNIT’s aim with Mary was to take the lessons of ALGOL 68 while simplifying the syntax and tailoring the language to better suit the needs of machine-level programming.
Although Mary was not one of the most widely adopted languages of its time, its development was significant due to its innovative features and its early experimentation with concepts that would later become more mainstream in programming language design. The language was primarily targeted for use on the Kongsberg Vรฅpenfabrikk’s SM-4 and the Norsk Data Nord-10/ND-100 mini-computers, with compilers written in NU ALGOL that were used to bootstrap native compilers for these systems.
Core Features and Syntax
Mary’s syntax and features set it apart from other programming languages of the time. At its core, Mary borrowed heavily from ALGOL 68, especially in its use of infix operators, but it also introduced several innovations that reflected the unique requirements of machine-oriented programming.
1. Dataflow Syntax
One of the most notable features of Mary was its use of dataflow syntax. This design philosophy meant that values flowed from left to right in expressions, including in assignments. This approach deviated from the more traditional programming style where assignment statements typically place the destination on the left side of the operator. Instead, in Mary, expressions like A := B + C
would evaluate from left to right. In this case, B + C
would be computed first, and the result would be assigned to A
. While this might seem unusual, it was in line with the language’s overall design goal of simplifying and streamlining the programming process.
2. Operators and Precedence
Another defining characteristic of Mary’s syntax was its treatment of operators. Unlike most programming languages that use varying precedence levels for different operators, Mary treated all operators as having equal precedence. As a result, the evaluation order in expressions was entirely dependent on the left-to-right evaluation rule, which meant that parentheses played a crucial role in controlling the evaluation order. This made the language simpler to parse and allowed for more consistent behavior across expressions.
Assignment in Mary, unlike in languages like C or Pascal, was also treated as an operator rather than a statement. The assignment operator was treated like any other infix operator, which meant that expressions could include assignments as part of larger expressions, a feature that was considered innovative at the time.
3. Support for Optimized Code Generation
Mary’s design was also notable for its focus on efficient machine code generation. Although the compiler used to generate code for Mary was relatively primitive compared to modern standards, the language included several features that helped developers write more optimized code. For instance, operators similar to Cโs +=
were available, which allowed for shorthand syntax when performing arithmetic operations. Furthermore, Mary included support for explicit register declarations, which enabled programmers to specify certain variables to be stored in specific machine registers, thus optimizing performance.
These features were particularly important because they allowed developers to write code that was more closely aligned with the underlying hardware, a necessity given the limited computational resources available at the time.
4. Macros and User-Defined Operators
Another significant feature of Mary was its support for text-based recursive macros. This allowed developers to define complex code patterns that could be reused throughout the program, similar to the macro systems found in modern programming languages like C and Lisp. These macros could be invoked recursively, further enhancing their power and flexibility.
In addition to macros, Mary supported overloaded user-defined operators, a feature that set it apart from languages like C and C++, which constrained operators to predefined identifiers. This flexibility allowed developers to define operators that suited their particular needs, further emphasizing the language’s focus on customization and adaptability.
5. Pointer Management and Type Context
Mary also had automatic pointer management, which included automatic building and dereferencing of pointers based on type context. This was a feature not commonly found in the programming languages of the time, which often required manual pointer manipulation. Maryโs approach made it easier for developers to work with pointers, reducing the chances of errors and improving code safety.
6. Array and Set Enumeration
The language included powerful support for working with arrays and sets. In particular, Mary allowed for array and set enumeration within loop iterators, a feature that made it easier to iterate over collections without needing to write complex loop constructs. This was a feature that would later become more common in languages like Python and JavaScript.
Additionally, Mary supported scalar range types, which allowed developers to define variables with ranges of valid values. This feature, while not common in many other languages of the time, provided a more flexible way of defining data types and was an early example of the trend toward more expressive type systems in modern programming languages.
Compilers and Platforms
The development of compilers for Mary was another key aspect of the languageโs history. The original Mary compiler was written in NU ALGOL and ran on the Univac-1100 series computers. It was used to bootstrap a native compiler for the ND-100/SINTRAN-III system, one of the platforms targeted by the language. This made it possible to generate optimized code for the Norsk Data mini-computers, which were a key part of Norway’s industrial computing infrastructure at the time.
In addition to the ND-100, later versions of the Mary compiler supported several other platforms, including the Intel 8086 and 80286 processors, as well as the VAX platform. A common backend was implemented for Mary and CHILL, another language developed at RUNIT, which allowed for easier porting of code between platforms. Eventually, backends were created for the i386 and SPARC architectures as well, expanding the reach of the Mary compiler.
The fact that the Mary compiler itself was written in Mary was a testament to the flexibility and power of the language. This self-hosting compiler model was an important milestone in the history of programming languages, demonstrating the language’s ability to be used to create compilers for a variety of systems.
Decline and Legacy
Despite its many innovative features, Mary was eventually discontinued and is no longer maintained. One of the key reasons for this decline was the emergence of more widely adopted languages that offered similar capabilities with larger user communities and better support. Languages like C, for example, quickly became dominant in the industry due to their combination of efficiency, portability, and widespread adoption.
Nonetheless, Maryโs influence can still be seen in several aspects of modern programming language design. Many of the features it introduced, such as operator overloading, pointer management, and support for low-level hardware manipulation, can be found in modern languages like C++ and Rust. Additionally, its emphasis on dataflow syntax and left-to-right evaluation was a precursor to the functional programming languages that gained popularity in the following decades.
Conclusion
Mary may not have achieved the level of widespread adoption of languages like C, ALGOL, or Fortran, but its design and features were ahead of their time. By emphasizing machine-oriented programming, efficient code generation, and a flexible, minimalist syntax, Mary offered a powerful toolset for its time. While it may have been eclipsed by other languages, its legacy continues to influence the design of modern programming languages, particularly in areas related to compiler construction, language optimization, and machine-level programming.
For those interested in the history of programming languages and the development of early machine-oriented languages, Mary remains a fascinating case study, offering a unique look into the challenges and innovations that shaped the landscape of modern software development.
References
- Conradi, Reidar, and Per Holager. Mary Textbook. 4th ed. 1979.
- “Mary (programming language).” Wikipedia, https://en.wikipedia.org/wiki/Mary_(programming_language).