The Last Five Years

Sometimes it’s easy to forget how much Grace has changed over the last five years. Most of the major language design decisions were made early, and since then … what?

Quite a lot, actually! I just had cause to re-visit some binary tree code that I wrote in the summer of 2015 as an example for a data structures class. It’s nothing special, but does illustrate the power of Grace’s λ-expressions, which, unlike those in Java, let you close over variables, not just constants. We can therefore use a λ-expressions to abstract over the command that is required to update a field in a parent node to refer to a new child. I described this “trick” in a previous post on this blog.

Of course, the original code no longer compiled; too much has changed. What exactly? Comparing the two versions in git gives us a good summary:

  • The “math” module has been removed. Mathematical operations are now methods on numbers.
  • The “random” module has been added, to give access to various random number generators.
  • factory method has been replaced by class.
  • Type parameters are now enclosed in double square brackets, rather than in angle brackets.
  • Interfaces are defined with the reserved word interface, rather than with type
  • inherits has been changed to inherit
  • The standard dialect now defines Proceduren and Functionn instead of Blockn
  • Traits have been added to Grace, and the standard dialect redefined using them. This makes it possible to combine and re-combine dialects, and pieces of dialects.
  • The == operator is no longer defined on graceObject and inherited by all other objects. Instead, graceObject defines isMe(_) and myIdentityHash, and a trait identityEquality is available for reuse to define the ==, and hashmethods.
  • Patterns and types are somewhat less confused than formerly. Arbitrary patterns can be used in match statements, but not in type declarations.
  • We have rigorously defined Grace’s indentation rules, and minigrace is a bit pickier about correct indentation that it used to be.
  • Square brackets now denote Sequence constructors. ”Lineups”, are gone, collections now understand >> and << for pipelining.
  • Variable-arity methods are no longer part of Grace. Instead, the programmer can define independent methods with the same name and different numbers of arguments—so sequence, sequence(_), and sequence(_,_) can co-exist.

There are probably some other language changes too, and certainly additions to the libraries, but these are the changes that made it necessary to modify formerly-correct code from 2015 so that it compiles and runs in 2020.

The last change—eliminating variable-arity methods—although small in itself, is probably the change with the biggest consequences, because it necessitated changing the interface for constructing collections.

All of these changes have a rationale. In some cases, the change was made for consistency, in others, to make Grace easier to teach. In the case of trait use, it was to make reuse simpler and more powerful than was possible with inheritance alone. Grace continues to evolve, but I feel that we are converging on a language that is pleasant to use, communicates well, and has as much expressiveness (in its target space) as its competitors.

2 thoughts on “The Last Five Years

  1. Are variable arity methods the same as generalised method names from OOPSLA 2015? If so, has the Grace team documented why they backed off the design?

    I poked around the Grace repository for a bit but couldn’t find any trace of generalised method names.

    From the outside, the idea of generalised method names seems like it has pretty nice power-to-weight ratio. In a typed ML-like language it amounts to syntax sugar for passing algebraically-typed data. The main stumbling block I had/have is how to pick/derive/determine quality names for the implicitly defined algebraic data types? One possibility might be define the interface with explicit data structures (instead of annotations on pieces of method names) and have the compiler figure out the right mapping from the method-name sublanguage to the user-defined data type.

  2. Good question, Ben! The short answer is “no”. (Generalised method names)[https://dl.acm.org/doi/abs/10.1145/2816707.2816708] from DLS 2015 were an interesting research idea, but were never part of the Grace Specification. I don’t recall ever discussing them as a prospective addition to Grace. Not only would they make the language more complex in general, they would add complexity to what is currently a particularly simple part of the language: matching of method requests to methods. Currently, any two methods that have different names are different; the DLS 2015 proposal said that only the prefix of the method name distinguished methods. I would not like to try to explain the name-matching rules to novice programmers.

Leave a Reply

Your email address will not be published. Required fields are marked *