Expressions in Slate mostly consist of message-sends to argument objects. The left-most argument is not considered an implicit receiver as it is with most message-passing languages, however.
An important issue is that every identifier is case-sensitive in Slate, that is, there is a definite distinction between what AnObject, anobject, and ANOBJECT denote even in the same context. Furthermore, the current implementation is whitespace-sensitive as well, in the sense that whitespace must be used to separate identifiers in order for them to be considered separate. For example, ab+4 will be treated as one identifier, but ab + 4 is a message-send expression.
There are three basic types of messages, with different syntaxes and associativities: unary, binary, and keyword messages. Precedence is determine entirely by the syntactic form of the expreesion, but it can of course be overridden by enclosing expressions in parentheses. An implicit left-most argument can be used with all of them. The default precedence for forms is as follows:
A UNARY MESSAGE does not specify any additional arguments. It is written as a name following a single argument; it has a post-fix form.
Some examples of unary message-sends to explicit arguments include:
A BINARY MESSAGE is named by a special non-alphanumeric symbol and 'sits between' its two arguments; it has an infix form. Binary messages are also evaluated from left to right; there is no special precedence difference between any two binary message-sends.
These examples illustrate the precedence and syntax:
A KEYWORD MESSAGE is an alternating sequence of keywords and expressions, generally being a continued infix form. Keywords are identifiers beginning with a letter and ending with a colon. Keyword messages start with the left-most argument along with the longest possible sequence of keyword-value pairs. The SELECTOR of the message is the joining-together of all the keywords into one symbol, which is the name of the message. For example,
Keywords have the lowest precedence of message-sends, so arguments may be the results of unary or binary sends without explicit grouping required. For example, the first expression here is equivalent to the latter implicitly:
Expressions occur between stop-marks, which are periods. At the top-level, expressions aren't evaluated until a full stop is entered. The stop mark also means that expression results aren't directly carried forward as an argument to the following expression; side-effects must be used to keep the results. More specifically, each expression in the sequence must be evaluated in order, and one expression's side-effects must effectively occur before the next expression begins executing and before any of its side-effects occur.
Slate provides for a bare expression sequence syntax that can be embedded within any grouping parentheses, as follows:
Slate> (7 factorial. 5
negated) min: 6.
-5
Within methods, blocks, and even at the top-level, some expressions may take the surrounding context as the first argument. There is a precedence for the determination of which object becomes the first argument, which is entirely based on lexical scoping. So, within a block, an implicit send will take the block's run-time context as argument, and then at lesser precedences will be the next outer contexts in sequence, up to the top-level and what it inherits from.
Specifically, any non-literal expression following a statement-separator or starting an expression within parentheses or other grouping is an implicit-context send.
There are some very common uses of implicit-context sends. In particular, accessing and modifying local variables of a block or method is accomplished entirely this way, as well as returns. For example,
In some cases, it may be necessary to manipulate the context in particular ways. In that case, it can be directly addressed with a loopback slot named thisContext, which refers to the current activation. The essence of this concept is that within a block, x: 4. is equivalent to thisContext x: 4.1