Grace

Grace is an object-oriented programming language intended for use in education. It uses gradual structural typing and a pure OO approach.

I built two implementations of Grace, and worked on the design of some language features using the language.

Minigrace is a self-hosted Grace compiler that generates C to run as native code and JavaScript to run in the browser . The design goal of Minigrace was to behave correctly on correct input

Kernan is a reference interpreter that aimed to conform to the Grace specification, and to behave correctly for both correct and incorrect code. Kernan is written in C#, compiles to the CLR, and runs through Mono or the .Net runtime on all platforms.

Tiled Grace is a drag-and-drop combined visual and textual editor for Grace using the Minigrace compiler as a backend. The visual editor is similar to Scratch, but the user can switch to editable textual code by pressing a button, and switch back at will later on.

Related Publications

Seeking Grace: A New Object-Oriented Language for Novices. Andrew P. Black, Kim B. Bruce, Michael Homer, James Noble, Amy Ruskin, Richard Yannow. In SIGCSE, 2013. (bibtex, author copy)

Grace is a new object-oriented language that supports a variety of approaches to teaching programming. It integrates accepted new ideas in programming languages into a simple language that allows students and teachers to focus on the essential complexities of programming rather than the accidental complexities of the language. We motivate Grace, review its design, and evaluate it against Kölling’s criteria.


Graceful Dialects. Michael Homer, Timothy Jones, James Noble, Kim B. Bruce, Andrew P. Black. In ECOOP, 2014. (bibtex, author copy)

Programming languages are enormously diverse, both in their essential concepts and in their accidental aspects. This creates a problem when teaching programming. To let students experience the diversity of essential concepts, the students must also be exposed to an overwhelming variety of accidental and irrelevant detail: the accidental differences between the languages are likely to obscure the teaching point. The dialect system of the Grace programming language allows instructors to tailor and vary the language to suit their courses, while staying within the same stylistic, syntactic and semantic framework, as well as permitting authors to define advanced internal domain-specific languages. The dialect system achieves this power though a combination of well-known language features: lexical nesting, lambda expressions, multi-part method names, optional typing, and plug gable checkers. Grace’s approach to dialects is validated by a series of case studies, including both extensions and restrictions of the base language.


Brand Objects for Nominal Typing. Timothy Jones, Michael Homer, James Noble. In ECOOP, 2015. (bibtex, author copy)

Combinations of structural and nominal object typing in systems such as Scala, Whiteoak, and Unity have focused on extending existing nominal, class-based systems with structural subtyping. The typical rules of nominal typing do not lend themselves to such an extension, resulting in major modifications. Adding object branding to an existing structural system integrates nominal and structural typing without excessively complicating the type system. We have implemented brand objects to explicitly type objects, using existing features of the structurally typed language Grace, along with a static type checker which treats the brands as nominal types. We demonstrate that the brands are useful in an existing implementation of Grace, and provide a formal model of the extension to the language.


Object Inheritance Without Classes. Timothy Jones, Michael Homer, James Noble, Kim Bruce. In ECOOP, 2016. (bibtex, author copy)

Which comes first: the object or the class? Language designers enjoy the conceptual simplicity of object-based languages (such as Emerald or Self) while many programmers prefer the pragmatic utility of classical inheritance (such as Simula and Java). Programmers in object-based languages have a tendency to build libraries to support traditional inheritance, and language implementations are often contorted to the same end. In this paper, we revisit the relationship between classes and objects. We model various kinds of inheritance in the context of an object-oriented language whose objects are not defined by classes, and explain why class inheritance and initialisation cannot be modelled purely by delegation.


Transient Typechecks are (Almost) Free. Richard Roberts, Stefan Marr, Michael Homer, James Noble. In ECOOP, 2019. (bibtex, author copy)

Transient gradual typing imposes run-time type tests that typically cause a linear slowdown. This performance impact discourages the use of type annotations because adding types to a program makes the program slower. A virtual machine can employ standard just-in-time optimizations to reduce the overhead of transient checks to near zero. These optimizations can give gradually-typed languages performance comparable to state-of-the-art dynamic languages, so programmers can add types to their code without affecting their programs’ performance.


Graceful Patterns for Patterns in Grace. Michael Homer, James Noble. In PLoP, 2012. (bibtex, author copy)

Grace is a new object-oriented programming language aimed at education. Here we describe patterns relating to pattern-matching in this language.


Patterns as Objects in Grace. Michael Homer, James Noble, Kim B. Bruce, Andrew P. Black, David J. Pearce. In DLS, 2012. (bibtex, author copy)

Object orientation and pattern matching are often seen as conflicting approaches to program design. Object-oriented programs place type-dependent behavior inside objects and invoke it via dynamic dispatch, while pattern-matching programs place type-dependent behavior outside data structures and invoke it via multiway conditionals (case statements). Grace is a new, dynamic, object-oriented language designed to support teaching: to this end, Grace needs to support both styles. We explain how this conflict can be resolved grace- fully: by modelling patterns and cases as partial functions, reifying those functions as objects, and then building up complex patterns from simpler ones using pattern combinators. We describe the implementation of this design as an object-oriented framework, and a case study of its effectiveness.


Object Creation in Grace. Michael Homer, James Noble. In EuroPLoP, 2013. (bibtex, author copy)

We are engaged in the design of Grace, a new object-oriented open source programming language aimed at instructors and students in introductory programming courses. Grace aims to include features that have been found useful in software practice, while allowing multiple different teaching approaches without requiring that concepts be introduced to students before they are ready. While many aspects of Grace’s design will be familiar to most object-oriented programmers, Grace cleanly separates the concepts of “object”, “class”, and “type”, and so Grace offers more options for creating objects than most other languages. We have written these patterns to explain how Grace programmers should go about creating objects.


A Tile-based Editor for a Textual Programming Language. Michael Homer, James Noble. In VISSOFT, 2013. (bibtex, author copy)

“Jigsaw puzzle” programming environments manipulate programs primarily by drag-and-drop. Generally these environments are based on their own special-purpose languages, meaning students must move on to another language as their programs grow. Tiled Grace is a tile-based editor for Grace, an educational programming language with a conventional textual syntax. Using Tiled Grace, programmers can move seamlessly between visualising their programs as tiles or source code, editing their programs via tiles or text, and continuing on to traditional textual environments, all within the same programming language.


Combining Tiled and Textual Views of Code. Michael Homer, James Noble. In VISSOFT, 2014. (bibtex, author copy)

“Jigsaw puzzle” programming environments manipulate programs primarily by drag-and-drop. Generally these environments are based on their own special-purpose languages, meaning students must move on to another language as their programs grow. Tiled Grace is a tile-based editor for Grace, an educational programming language with a conventional textual syntax. Using Tiled Grace, programmers can move seamlessly between visualising their programs as tiles or source code, editing their programs via tiles or text, and continue on to traditional textual environments, all within the same programming language. We conducted a user experiment with Tiled Grace, and present the results of that experiment showing that users find dual views helpful.


From APIs to Languages: Generalising Method Names. Michael Homer, Timothy Jones, James Noble. In DLS, 2015. (bibtex, author copy)

Method names with multiple separate parts are a feature of many dynamic languages derived from Smalltalk. Generalising the syntax of method names to allow parts to be repeated, optional, or alternatives, means a single definition can respond to a whole family of method requests. We show how generalising method names can support flexible APIs for domain-specific languages, complex initialisation tasks, and control structures defined in libraries. We describe how we have extended Grace to support generalised method names, and prove that such an extension can be integrated into a gradually-typed language while preserving type soundness.


Grace's Inheritance. James Noble, Andrew P. Black, Kim B. Bruce, Michael Homer, Timothy Jones. In JOT, Volume 16, no. 2, 2017. (bibtex, author copy)

This article is an apologia for the design of inheritance in the Grace educational programming language: it explains how the design of Grace’s inheritance draws from inheritance mechanisms in predecessor languages, and defends that design as the best of the available alternatives. For simplicity, Grace objects are generated from object constructors, like those of Emerald, Lua, and Javascript; for familiarity, the language also provides classes and inheritance, like Simula, Smalltalk and Java. The design question we address is whether or not object constructors can provide an inheritance semantics similar to classes.


Co-located Collaborative Block-Based Programming. Ben Selwyn-Smith, Craig Anslow, Michael Homer, James R. Wallace. In VL/HCC, 2019. (bibtex, author copy)

With the increasing need to teach programming to novices using collaborative methods like pair programming, it is important to understand how different input devices can help support collaborative learning. In this paper we present Multi-Device Grace, the first application to explore block-based programming in a cross-device environment consisting of digital tabletops, mobile tablets, and laptops. We conducted a user study (n = 18) to explore how cross-device environments can support co-located collaborative block-based programming. The study used Tiled Grace, an existing block-based programming language, and our extensions: Tabletop Grace (designed for tabletops) and Mobile Grace (designed for tablets). Our results show that the majority of participants felt they were able to collaborate quickly and easily, and the cross device interaction would be particularly beneficial in an education setting.


First-Class Dynamic Types. Michael Homer, Timothy Jones, James Noble. In DLS, 2019. (bibtex, author copy)

Since LISP, dynamic languages have supported dynamically-checked type annotations. Even in dynamic languages, these annotations are typically static: tests are restricted to checking low-level features of objects and values, such as primitive types or membership of an explicit programmer-defined class.

We propose much more dynamic types for dynamic languages — first-class objects that programmers can customise, that can be composed with other types and depend on computed values — and to use these first-class type-like values as types. In this way programs can define their own conceptual models of types, extending both the kinds of tests programs can make via types, and the guarantees those tests can provide. Building on a comprehensive pattern-matching system and leveraging standard language syntax lets these types be created, composed, applied, and reused straightforwardly, so programmers can use these truly dynamic first-class types to make their programs easier to read, understand, and debug.


Grace: the Absence of (Inessential) Difficulty. Andrew P. Black, Kim B. Bruce, Michael Homer, James Noble. In Onward!, 2012. (bibtex, author copy)

We are engaged in the design of a small, simple programming language for teaching novices object-oriented programming. This turns out to be far from a small, simple task. We focus on three of the problems that we encountered, and how we believe we have solved them. The problems are (1) gracefully combining object initialization, inheritance, and immutable objects, (2) reconciling apparently irreconcilable views on type-checking, and (3) providing a family of languages, each suitable for students at different levels of mastery, while ensuring conceptual integrity of their designs. In each case our solutions are based on existing research; our contribution is, by design, consolidation rather than innovation.


Designing Grace: Can an Introductory Programming Language Support the Teaching of Software Engineering?. James Noble, Michael Homer, Kim B. Bruce, Andrew P. Black. In CSEE&T, 2013. (bibtex, author copy)

Many programming language constructs that support software engineering in the large — explicit variable declarations, explicit external dependencies, static types, information hiding, invariants — provide little benefit to the small programs written by novice programmers, where every extra syntactic token has to be explained and understood before novices can succeed in running even the simplest program. We are designing Grace, a new educational object-oriented language that we hope will prove useful for teaching both programming and software engineering. This paper describes some of the tradeoffs between teaching programming and teaching software engineering that we faced while designing Grace, and our attempts to address those tradeoffs.


Naïve Transient Cast Insertion Isn't (That) Bad. Erin Greenwood-Thessman, Isaac Oscar Gariano, Richard Roberts, Stefan Marr, Michael Homer, James Noble. In ICOOOLPS, 2021. (bibtex, author copy)

Transient gradual type systems often depend on type-based cast insertion to achieve good performance: casts are inserted whenever the static checker detects that a dynamically-typed value may flow into a statically-typed context. Transient gradually typed programs are then often executed using just-in-time compilation, and contemporary just-in-time compilers are very good at removing redundant computations.

In this paper we present work-in-progress to measure the ability of just-in-time compilers to remove redundant type checks. We investigate worst-case performance and so take a naïve approach, annotating every subexpression to insert every plausible dynamic cast. Our results indicate that the Moth VM still manages to eliminate much of the overhead, by relying on the state-of-the-art SOMns substrate and Graal just-in-time compiler.

We hope these results will help language implementers evaluate the tradeoffs between dynamic optimisations (which can improve the performance of both statically and dynamically typed programs) and static optimisations (which improve only statically typed code).


Which of My Transient Type Checks Are Not (Almost) Free?. Isaac Oscar Gariano, Richard Roberts, Stefan Marr, Michael Homer, James Noble. In VMIL, 2019. (bibtex, author copy)

One form of type checking used in gradually typed language is transient type checking: whenever an object “flows” through code with a type annotation, the object is dynamically checked to ensure it has the methods required by the annotation. Just-in-time compilation and optimisation in virtual machines can eliminate much of the overhead of run-time transient type checks. Unfortunately this optimisation is not uniform: some type checks will significantly decrease, or even increase, a program’s performance.

In this paper, we refine the so-called “Takikawa” protocol, and use it to identify which type annotations have the greatest effects on performance. In particular, we show how graphing the performance of such benchmarks when varying which type annotations are present in the source code can be used to discern potential patterns in performance. We demonstrate our approach by testing the Moth virtual machine: for many of the benchmarks where Moth’s transient type checking impacts performance, we have been able to identify one or two specific type annotations that are the likely cause. Without these type annotations, the performance impact of transient type checking becomes negligible.

Using our technique programmers can optimise programs by removing expensive type checks, and VM engineers can identify new opportunities for compiler optimisation.


Towards collaborative block-based programming on digital tabletops. Ben Selwyn-Smith, Michael Homer, Craig Anslow. In B&B, 2017. (bibtex, author copy)

Block-based programming environments are typically designed for desktop machines or mobile devices. Desktops and mobiles are generally designed for single users to interact with, which makes it hard for multiple users to collaborate effectively. In this paper we explore the possibilities of digital multi-touch tabletops to foster collaborative programming in a block-based paradigm. We note both the different challenges afforded in this new interaction model and the potential benefits unique to collaborative programming with tabletops.


Lessons in Combining Block-Based and Textual Programming. Michael Homer, James Noble. In VLSS, Volume 3, 2017. (bibtex, author copy)

Tiled Grace is a block-based programming system backed by a conventional textual language that allows switching back and forth between block-based and textual editing of the same code at any time. We discuss the design choices of Tiled Grace in light of existing research and a user experiment conducted with it. We also examine the sorts of task preferred in each mode by users who had the choice of editing either as blocks or as text, and find both positive and cautionary notes for block-based programming in the results.


Toward Virtual Machine Adaption Rather than Reimplementation. Richard Roberts, Stefan Marr, Michael Homer, James Noble. In MoreVMs, 2017. (bibtex, author copy)

We adapt SOMns, a Truffle-based interpreter for Newspeak, to the Grace programming language. We highlight differences between the semantics of these languages and offer preliminary results showing that adaption is possible while retaining performance. The similarities between the languages promote the potential for adaption and code sharing between implementations. Through experimentation we intend to explore how the design of the tailored implementation; the flexibility of the underlying framework; and similarities between languages affect adaptability, and by doing so hope to realize a set of mechanisms that can be easily extended to create optimized virtual machines for object-orientated languages.


Beyond Types: Extending the Gradual Guarantee. James Noble, Michael Homer, Timothy Jones, Sophia Drossopolou, Andrew P. Black, Kim B. Bruce. In STOP, 2016. (bibtex, author copy)

The gradual guarantee lets us understand gradual typing: a system is gradually typed if removing a type annotation cannot change the semantics of a correct program. We extend the gradual guarantee beyond types: privacy annotations or inheritance restrictions, for example, may be gradual if changing them does not change the semantics of a correct program.


Modules as Gradually-Typed Objects. Michael Homer, James Noble, Kim B. Bruce, Andrew P. Black. In DYLA, 2013. (bibtex, author copy)

Grace is a gradually typed, object-oriented language for use in education. Grace needs a module system for several reasons: to teach students about modular program design, to organise large programs, especially its self-hosted implementation, and to provide access to resources defined in other languages. Grace uses its basic organising construct, objects, to provide modules, and is then able to use its gradual structural typing to obtain a number of interesting features without any additional mechanisms.


Michael Homer — 2023 d38f60fb