Next: 3.6 Symbols
Up: 3 The Slate World
Previous: 3.4 Traits
Contents
Index
Subsections
Slate's evaluator 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 automatically7. 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
assign a positive form 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.
There is also a ``case-switch'' style idiom:
- expr caseOf: cases otherwise: defaultBlock
- takes
the result of the first argument and the cases array of Associations
(made with ->) from objects to blocks and executes the first
block associated with a value equal to the expression. If none match,
the last argument is executed; the otherwise: clause may be omitted,
to just do / return nothing.
3.5.3 Early Returns
Control-flow within methods
can be skipped with a return value using the ^
message to the context. ^ takes its second
argument and exits the nearest surrounding lexical scope that is a
named method (and not an anonymous code block) with that value. This
message is a real binary message with no special precedence, so disambiguation
is often needed. For example,
-
- ^ 4
^ n factorial
return the expressions on the left as a whole, but
-
- ^ 3 + 4
^ (3 + 4)
^ set collect: [| :each | each name]
^ (set collect: [| :each | each name])
represent expression variations where a lack of disambiguation results
in returning an unintended answer.
3.5.4 Looping
Slate includes various idioms for constructing basic
loops. These are all built from ordinary methods which work with code
blocks, and any ordinary code may define similar idioms rather quickly.
- loop
- executes the block repeatedly,
indefinitely8.
- 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 (implying
that the body block will not be executed if the condition is initially
false).
- whileTrue
- and
whileFalse execute their blocks repeatedly, checking
the return value before repeating iterations (so that they will always
execute at least one time).
- 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.
- below:by:do:
- and
above:by:do: vary on the previous methods with the
given stepping increment.
Slate provides some powerful methods for operating on Method
(block) objects themselves. The answers of these operations are also
fully-fledged Method objects which respond to all of the
normal queries and are useful anywhere that a Method is accepted.
- **
- composes
two Methods in a functional manner, so that
;
basically the result of applying the first to the result of the second
(which in turn consumes the input). This operation is associative,
so grouping of continued applications should not be a concern. This
semantics assumes that the inner/right function may take any
number of arguments, and that takes 1. If both of these are false,
then there is an extended form of the semantics where the arity of
is used to group the results of applying to each element
in the argument array. The groups are then passed as a whole to one
invocation of .
- `er
- takes a literal Symbol
taken as a message selector and expands into an appropriate Method
which takes an appropriate number of arguments for the selector and
sends the selector to those arguments, answering the result. E.g.
#+`er expands into [| :x :y | x + y] and #name`er
expands into [| :x | x name].
- converse
- takes a Method
and answers a new Method with the same body but with input
argument order reversed.
- `commutatively
- takes a literal
MethodDefinition and defines it with two signatures, one
reversed from the original definition, with the same body.
Next: 3.6 Symbols
Up: 3 The Slate World
Previous: 3.4 Traits
Contents
Index
Brian Rice
2005-11-21