Chapter 4
Program Control
Order of Execution
Order of execution is defined for the constituents within a body. With some exceptions noted below, this execution order is left-to-right.
Definitions form the overall structure of a program and are not said to execute. In particular, module bindings are not created in any order, but all exist when program execution commences. To the extent that these bindings must be initialized by the values of some expressions that cannot be analyzed at compile time, references to the bindings are constrained by the execution order of the expressions within the surrounding body.
Dylan implementations are encouraged to allow forward references to module bindings whenever possible.
The order of execution of the components of a call to a user-defined macro is determined by the macro.
Execution Order Within Expressions
In general, execution within an expression proceeds left-to-right. The chief exception to this rule is the assignment operator, which is executed right-to-left.
- In a standard function call, the function operand is executed
first, followed by the argument expressions. (Remember, the function need not be a named
value reference, but can be a more complex operand). After the function operand has been
executed and each of the argument expressions has been executed, the function is applied
to the arguments.
one(two, three, four)
- In slot references, the object operand is executed first,
followed by the function named value reference. Then the function is applied to the
object.
one.two
- In element references, the collection operand is executed
first, followed by the key expressions in order. Then the element access is performed. The
execution time of the binding
element
oraref
is unspecified.one[two, three]
- In an operator call, the operands are executed
left-to-right. The execution time of the binding specified by the operator
(e.g.
+
or*
) is unspecified.one + two - three
- In an assignment to a place that represents a function call, the order of execution is
largely the same as it would be in a call to the corresponding setter function. The
new-value expression is executed first, followed by the argument expressions. The
execution time of the binding named by the setter function is undefined.
function-setter(one, two, three) function(two, three) := one slot-setter(one, two) two.slot := one element-setter(one, two, three) two[three] := one aref-setter(one, two, three, four) two[three, four] := one