Next: 3.5 Magnitudes and Numbers
Up: 3 The Slate World
Previous: 3.3 Traits
Contents
Index
Subsections
Slate's interpreter primitively provides the
objects True and False,
which are clones of Boolean, and
delegate to Boolean traits. Logical methods are defined
on these in a very minimalistic way. Table cap:Basic-Logical-Operators
shows the non-lazy logical methods and their meanings.
Table 2:
Basic Logical Operators
Description |
Selector |
AND/Conjunction |
/\ |
OR/Disjunction |
\/ |
NOT/Negation |
not |
EQV/Equivalence |
eqv: |
XOR/Exclusive-OR |
xor: |
|
Logical
methods are provided which take a block as their second argument (/\,
\/, and:, or:, xor:,
eqv:). By accepting a block as the second argument, they
can and do provide conditional evaluation of the second argument only
in the case that the first does not decide the total result automatically5. Blocks that evaluate
logical expressions can be used lazily in these logical expressions.
For example,
-
- (x < 3) /\ [y > 7].
only evaluates the right-hand block argument if the first argument
turns out to be True.
-
- (x < 3) \/ [y > 7].
only evaluates the right-hand block argument if the first argument
turns out to be False.
In general, the basic of booleans to switch between code alternatives
is to use ifTrue:, ifFalse:,
and ifTrue:ifFalse: for
the various combinations of binary branches. For example,
-
- x isNegative ifTrue: [x: x negated].
ensures that x is positive by optionally executing code to
make it positive if it's not. Of course if only the result is desired,
instead of just the side-effect, the entire expression's result will
be the result of the executed block, so that it can be embedded in
further expressions.
Conditional evaluation can also be driven by whether or not a slot
has been initialized, or whether a method returns Nil. There
are a few options for conditionalizing on Nil:
- expr ifNil: block
- and
expr ifNotNil: block execute their blocks based
on whether the expression evaluates to Nil, and returns the result.
- expr ifNil: nilBlock ifNotNil: otherBlock
- provides
both options in one expression.
- expr ifNotNilDo: block
- applies
the block to the expression's result if it turns out to be non-Nil,
so the block given must accept one argument. ifNil:ifNotNilDo:
is also provided for completeness.
3.4.3 Looping
Slate includes various idioms for constructing basic
loops.
- loop
- executes the block repeatedly,
indefinitely.
- n timesRepeat: block
- executes
the block n times.
- condition whileTrue: block
- and
condition whileFalse: block execute their blocks
repeatedly, checking the condition before each iteration.
- whileTrue
- and
whileFalse execute their blocks repeatedly, checking
the return value before repeating iterations.
- a upTo: b do: block
- and
b downTo: a do: block executes the block with
each number in turn from a to b, inclusive.
- upTo:by:do:
- and
downTo:by:do: executes the block with each number
in turn in the inclusive range, with the given stepping increment.
- a below: b do: block
- and
b above: a do: block act identically to the
previous method except that they stop just before the last value.
This assists in iterating over array ranges, where the 0-based indexing
makes a difference in range addresses by one, avoiding excessive use
of size - 1 calls.
Slate's looping control structures can easily be extended without
concern due to the fact that the interpreter unrolls properly tail-recursive
blocks into low-level loop code that re-uses the same activation frame.
So basically structuring custom looping code so that it calls itself
last within its own body and returns that value will avoid the need
for increasing stack space per iteration.
Next: 3.5 Magnitudes and Numbers
Up: 3 The Slate World
Previous: 3.3 Traits
Contents
Index
Brian Rice
2004-10-30