Newspeak by Example
Ministry of Truth

1. Introduction

In this tutorial, we'll go through the basics of Newspeak syntax. The examples in this document are live. You can change the code and see how your changes impact the results right away.

Each result is a link; if you click on it, it will open an object inspector. An object inspector shows you the object's class and instance variables and lets you evaluate further expressions in the context of the object.

2. Literals

The simplest piece of Newspeak code is a literal. Literals include things like numbers, strings of characters and a few others.

2.1. Numbers

Whole numbers, aka integers, are written as you'd expect.

You can write decimal fractions in the obvious way as well.

2.2. Strings

A simple piece of text is called a string, and is written between single quotes.

2.3. Booleans

There are two predefined boolean values: true and false.

There are additional literals, but these will do for now.

Literals are a special case of expressions. In addition to literals, Newspeak expressions include message sends, described below.

3. Message sends

In order to cause an object to compute something, you send it a message. Message sends come in three forms.

3.1. Unary Sends

Notice that there is no dot between 16 and sqrt.

A message send always involves a receiver (16 above) and a message (in our example, sqrt). The receiver is the object to whom the message is being sent, though sometimes the receiver can be implicit. The message always includes a selector, which is a symbol such as sqrt.

The selector determines how many arguments the message can have. If the selector is an identifier, then the message has no arguments; the send is then called a unary send because it only involves one object, the receiver.

3.2. Binary Sends

Binary sends involve two objects, as you might expect. The first is the receiver, and the second is an argument, which is part of the message.

Above, 3 is the receiver, and + 4 is the message. The selector is + and 4 is an argument. In binary messages, the selector is always an operator. Operators are often the standard ones like + or *, but they can be more complicated.

All binary sends have the same precedence

Binary sends have lower precedence than unary sends

3.3. Keyword Sends

The most general kind of send is a keyword send, where the message can include one or more arguments.

Here, 5 is the receiver and between: 3 and: 7 is the message. The selector is between:and: and the arguments are 3 and 7.

Keyword sends use keyword selectors, which are made out of one or more keywords. A keyword is an identifier with a colon at the end. Each colon marks a place where an argument can appear.

Keyword sends have lower precedence than binary sends.

You can see that 5 is between 3 and 12.

4. Closures

Closures allow us to declare functions in line.

A closure is delimited by square brackets. The code inside the closure isn't evaluated until the closure is sent the message value.

Closures can take parameters

Each parameter is declared via an identifier with a leading colon. The parameter list ends with vertical bar, which is then followed by the body of the closure. Our example has only one parameter, :x, but there can be many.

4.1. Declaring variables

One can declare variables at the beginning of a closure. The variable declarations appear between vertical bars.

You may initialize a variable at its declaration by following it with ::=, an expression that gives the initial value and a dot. The dot serves to separate the initializer from the next variable declaration, if any.

4.2. Statements

A closure's body can contain multiple statements.

Statements are separated by dots. The value returned by a closure is the value of the last statement.

5. Tuples

Tuples are literal collections.

You can access the elements of a tuple using the selector at:

The elements of tuples need not be literals however - they can be arbitrary expressions.

6. Conditionals

Conditional expressions in Newspeak are just message sends.

We just sent the message ifTrue: [3] ifFalse: [4] to the object true (which we happened to compute by evaluating the expression 1 < 2, as you can see below).

ifTrue:ifFalse: is defined on booleans. So is ifFalse:ifTrue:. If you only want something done if a test is true, use ifTrue: by itself.

There is also ifFalse:

If the condition does not hold, the single-keyword conditionals ifTrue: and ifFalse: return nil.

7. Loops

Loops are of course message sends as well.

Notice how we declared the variable x in the evaluator itself, and assigned it an initial value in its declaration.

8. Mapping and Filtering

In the following example, we filter a tuple, so we get only those elements that are greater than 2.

The selector select: is defined for all collections as are several others. For example, one can compute mappings of collections. Below we compute the squares of a tuple of integers.