Chapter 2
Syntax
Expressions
An expression is a construct that is executed for the values
it returns and/or the side-effects that it performs. The active
portions of a Dylan
program are expressions. An expression is either a literal constant, a named value
reference, a function call, a unary operator call, a binary operator call, an element
reference, a slot reference, a parenthesized expression, or a statement.
An operand is a restricted expression: it cannot be a unary or binary operator call nor a symbol literal. The other seven forms of expression are allowed. Operands appear in situations in the grammar where an expression is desirable but the full generality of expressions would make the grammar ambiguous.
A literal constant directly represents an object. Literal constants are available for numbers, characters, strings, symbols, boolean values, pairs, lists, and vectors. For example:
|
|
|
|
|
|
|
|
|
|
Literal constants are immutable. Attempting to modify an immutable object has undefined consequences. Immutable objects may share structure. Literal constants that are equal may or may not be identical.
A symbol can be indicated in two ways: as a keyword (for
example, test:
) or as a unique string (for
example, #"red"
). The difference is purely syntactic; the choice is provided to
promote program readability.
A string literal can be broken across lines by writing two string literals in a row, separated only by whitespace; they are automatically concatenated (without a newline character).
A named value reference returns the value of a visible binding
given its name; for example, foo
. The referenced binding can be a module
binding (either constant or variable) or a local binding established by a local declaration
or by a parameter list. The value of the binding must not be a macro.
A reserved word is a syntactic token that has the form of a
name but is reserved by the Dylan language and so cannot be given a binding and cannot be
used as a named value reference. There are seven reserved words in Dylan:
define
,
end
,
handler
,
let
,
local
,
macro
, and otherwise
.
A function call applies a function to arguments, and returns
whatever values the function returns. The function is indicated by an operand and can be a
generic function, a method, or a function macro. The arguments are separated by commas and
enclosed in parentheses. For example, f(x, y)
. For readability, the comma can
be omitted between the two arguments in a keyword/value pair, for example element(c,
k, default: d)
is a function call with four arguments.
A unary operator call consists of
an operand preceded by one of the two unary operators: -
(arithmetic negation)
or ~
(logical negation); for example, - x
. A unary operator call
is actually an abbreviated notation for a function call.
A binary operator call consists of two expressions separated
by one of the binary operators: +
(addition), -
(subtraction), *
(multiplication), /
(division), ^
(exponentiation), =
(equality), ==
(identity), <
(less than), >
(greater than), <=
(less than or
equal), >=
(greater than or equal), ~=
(not
equal), ~==
(not identical), &
(logical and), |
(logical or), or :=
(assignment). When binary operator calls are chained
together, they are grouped by rules of precedence and associativity and by parentheses
— for example, (a - b) * x + c * x ^ 2
. A binary operator call is
actually an abbreviated notation for a function call or function-macro call. The rules of
precedence are given in Table 4-1, Operators,
on
page 37.
An element reference consists of an operand that indicates a
collection and an expression in square brackets that indicates a key. Instead of a key,
there can be multiple expressions separated by commas that indicate array indices; for
example, c[k]
or a[i, j]
. This is actually an abbreviated notation
for a function call.
A slot reference is another abbreviated notation for a
function call. It consists of an operand that indicates an object, a period, and a named
value reference that indicates a one-argument function to apply to the object. Typically the
function is a slot getter but this is not required, as
in airplane.wingspan
.
A parenthesized expression is any expression inside
parentheses. The parentheses have no significance except to group the arguments of an
operator or to turn a general expression into an operand; for example, (a + b) *
c
.