One True Message Send

One True Message Send

Grace is a pure object-oriented language. Everything in the language is an object, and all computation proceeds by sending (dynamically dispatched) messages to objects. In this, Grace follows most strongly in the Smalltalk tradition. Like Smalltalk, Grace has “One True Message Send” rule that explains how expressions are evaluated: a message that is sent to a receiving object is looked up in the receiving object’s definition, and if a matching method is found, that method is executed. (What happens when a message is not found will be the subject of another note). This “One True Message Send Rule” is followed for all types of Grace objects, whether the builtin Strings, Booleans, and Numbers, or objects defined in libraries or by user code.

Message-send is the principal operation in Grace; as far as possible, other operations in the language (especially control structures) are phrased as message-sends. This is important because, if classes introduced by libraries are going to be “first class”, it must be possible for them to define their own control structures, and have those control structures be the social equals of the built-in control structures. In effect, we can extend the syntax of Grace in the libraries.

The syntax of message-send is more like Java or C# than Smalltalk: a receiver (sometimes implicit), then a message name (an identifier), then any arguments in parenthesis. As in Smalltalk, however, it is possible to break up a long argument list and distribute it throughout the message name, so one can define both of the following

It is up to the designer of an interface to decide on the best syntax for the language of messages that she is creating. One the interface designer has made her decision, clients have to follow along; it’s important that two sends of the same message look alike.

Arguments are always passed by object reference, and no implicit conversions or copying ever takes place.

Grace uses the keyword self to refer to the current object – what Simula, C++, and Java refer to as this. As in Java, Eiffel, and Self, the receiver of a message can be left implicit if it is self. Why self rather than this? Because it’s impossible to lecture about a language without using the English pronoun “this” in its ordinary sense!

Messages that take no arguments don’t get any parenthesis. This is because Grace has one shared namespace for method names and variables in objects. Thus, count could be either an access to a local variable or a send of the message count to self; to decide which one need only look at the declaration of count.This is a deliberate choice: the syntax abstracts away the implementation detail of whether a particular attribute is implemented by a variable or a method, and changing from one to the other does not require code that accesses the attribute to be modified. This is in contrast to C++ and Java, which use separate namespaces for variables and methods, and separate syntax for variable access and message send.

The motivation for allowing the arguments to be distributed through the name of a message is primarily to allow libraries to implement readable control structures. So

which looks like a conventional while loop, is actually a send of the message while()do() to self. To promote this usage, we allow the parameter parenthesis to be omitted if they would be adjacent to the pair of braces that create a closure. Moreover, because of Grace’s layout syntax, the above example can also be written as

where the braces are themselves replaced by layout.

This will allow libraries to implement constructs for things like atomicity, finalization and locking using messages. For example:

Grace’s One True Message Send rule has a number of consequences. One of the most important is that Grace does not allow overloading on argument type as in C++ or Java and their descents (C#, Scala): static type information never affects the execution of correct programs in Grace. So, if you want two methods on the same object to behave differently, you will have to give them distinct names. We expect sales of Roget’s Thesaurus to rocket.

At present we are not sure whether to support variadic methods. Most languages that started without variadic methods have added them; not having them may force the programer to create a tuple.

Let’s Start With Syntax

We all know that syntax is unimportant — in theory. However, it is quite important in practice, because we all have our pet loves and hates. Moreover, to even discuss competing ideas for the more substantive parts of the language, we need a syntax. So, let’s start by talking about it.

Brackets, Semicolons, and Blocks

We propose that Grace use curly brackets for grouping, and semicolons as statement terminators, However, we also plan to use indentation (layout) for grouping, and allow semicolons to be omitted at the end of lines.

The reasons for this is that it is really important for students to learn to use indentation correctly, if their programs are going to be readable. Having the compiler ignore indentation makes this hard to reinforce: the eye believes the indentation, even though the compiler does not. Making indentation significant means that student programs mean what they appear to mean.

The following code uses both semicolons and curly brackets:

while this example uses only layout:

and this uses both

Over the last 20 years, a major innovation in programming language syntax has been the reduction in separator and grouping symbols; we are following that trend. The most visible change has been from Algol and Pascal’s beginend to C’s “{-}”. Python and Haskell are the two main examples that Grace follows here, although CLU, Scala and Go allow statement separator semicolons to be omitted.

Why retain semicolons and brackets at all, even as options? There are for several reasons. For programmers converting from languages that use semicolons and brackets, they will provide important familiarity. Some pedagogical approaches may prefer explicit grouping and separation; supporting both implicit layout and explicit syntax means that students can learn about the differences and programmers can choose whatever is most appropriate. Perhaps most importantly, having explicit constructs will also make formal description of Grace easier to manage. That is, if you are trying to write a formal semantics for semicolon, it’s handy to have a semicolon operator to write about.

Block Semantics

Brackets and layout are enmeshed in one potentially more controversial aspect of Grace’s design: Grace’s bracket or layout blocks are in fact the same as Smalltalk’s square-bracket block: they are parameterless lambda expressions.

Grace does not have macros or quotation (like Scheme or Lisp), nor implicit proceduring conversions (like Algol-68 or Scala). Rather, like Smalltalk, any expression whose evaluation needs to be deferred must be wrapped explicitly in a block. So, both the control expression and the block to be repeated in a while statement must be inside either explicit brackets or layout indentation.

Apart from the curly brackets, Grace’s blocks differ from Smalltalk’s in one other respect: a zero-argument block that is at the “top level” of a statement list, that is, one that not passed as a parameter to a method or stored in a variable, will be evaluated as soon as it is created. This ensures that nested blocks in Grace that are used in the traditional Java, C, or Pascal way have the same semantics as the Java, C, or Pascal nested blocks. However, “first class” blocks — those that are passed as arguments to a method or assigned to a variable — will represent functions. That is, they will be like Smalltalk blocks or Lisp or Scheme lambdas. (For afficionados, this proposal for Grace design is the same as the deproceduring coercion in Algol-68).

Comments

While we’re on the topic, in today’s design, Grace’s comments are introduced by the same characters as Java:

(this means comment characters cannot be used as operators: Andrew would like other comment characters, perhaps || |* *|).

Comments will be attached to syntactic elements of the program, either where they appear, or for definitions, before the definition to which they apply, following Newspeak and several other languages.

Tabs

According Guido van Rossum’s (“Python’s Regrets”) Python’s support of both tab and space characters has caused many, many problems in practice. We propose to address this by treating all tab characters as syntax errors in Grace. String literals will support an escape sequence for tabs, so Grace programs should have no tab characters whatsoever. Grace editors or programming environments should transliterate all tabs to spaces. (Fortress does the same thing.)

Kim Comments: I’m slightly uncomfortable by having different semantics of blocks depending on whether or not they are at the top level. On the other hand, it gives you the right behavior

Hello World

The first Grace program is of course Hello World.   In Grace, we expect this to be written simply and straightforwardly, as follows:

No semicolons, no brackets, no method, no class, no package, no “public static void main(magic incantation goes here)”.  Just the core of the code is all that should be need for such a simple program.