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.
The simplest piece of Newspeak code is a literal. Literals include things like numbers, strings of characters and a few others.
Whole numbers, aka integers, are written as you'd expect.
You can write decimal fractions in the obvious way as well.
A simple piece of text is called a string, and is written between single quotes.
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.
In order to cause an object to compute something, you send it a message. Message sends come in three forms.
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.
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
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.
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.
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.
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.
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.
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
.
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.
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.