METHODS in Slate are basically annotated code blocks (documented in 2.1.1), coupled with annotations of the objects' roles that dispatch to them.
A relatively unique concept in the language is that objects relate to their methods via an implicit idea called a ROLE. A role is an association between an object and a method that applies to it that is similar to a slot, but not directly a slot as it is in Self. Instead of simply being a storage reference, a role associates the object with a position in the signature of a method. This is a way of stating that the object ``plays a role'' in a certain behavior, reinforcing the idea that behavior arrives through cooperation. Furthermore, the behavior is shared among the cooperators, so methods are not ``owned'' by particular objects; they are not properties.
However, because dispatch can happen on many combinations of arguments, a method name plus the object's position is not sufficient to identify a single method; instead, a group of methods of the same name may be associated via a role with an object at a certain signature position. During method lookup, the appropriate method is found through knowing all of the objects in the signature and knowing which take precedence over others. So a specific role consists of a triple-association between an object, its position in a signature for a method, and the method itself.
When referring to an object's ``roles'' in general, it usually means the collection of these associations as a whole; what relates the object to the behaviors it participates in.
Method definition syntax is handled relatively separately from normal precedence and grammar. It essentially revolves around the use of the reserved character ``@''. If any identifier in a message-send argument position is found to contain the character, the rest of the same send is examined for other instances of the Symbol, and the whole send-expression is treated as a template. The parser treats the expression or identifier to the right of the @ characters as dispatch targets for the method's argument positions; the actual objects returned by the expressions are annotated with a role for their positions.
After the message-send template, there is expected a block expression of some kind, whether a literal or an existing block. Whichever is specified, the parser creates a new block out of it with adjustments so that the identifiers in the dispatching message-send become input slots in the closure. The block should be the final expression encountered before the next stop (a period).
There is a further allowance that an input slot-name specifier may be solely an underscore (but not an underscore followed by anything else), in which case the argument to the method at that position is not passed in to the block closure.
This syntax is much simpler to recognize and create than to explain. For example, the following are a series of message definitions adding to boolean control of evaluation:
The latter method appears to have a slightly-different syntax, but this is an illusion: the parentheses are just surrounding a Slate expression which evaluates to an object, much as True and False evaluate to particular objects; really, any Slate expression can be placed there, assuming that the result of it is what is wanted for dispatch. As a side note, this last method is defined in terms of the first two and is shared, since True and False both delegate to Boolean traits (the object carrying the common behavior of the boolean objects).
The specialized syntax using the ``@'' special has an equivalent in regular Slate syntax which is often useful for generating new methods dynamically in a non-ambiguous way. This is a reflective call on the evaluator to compile a method using a certain symbolic name and a sequence of objects that are used for dispatching targets. For example:
Message dispatch in Slate is achieved by consulting all of the arguments to that message, and considering what roles they have pertaining to that message name and their position within the message-send. Slate's dispatch semantics are termed ``multiple dispatch'' to distinguish from ``single dispatch'' which is typical of most languages based on objects and messages. Whereas most languages designate on object as the receiver of a message, Slate considers all objects involved cooperating participants. During the dispatch process, more than one method can be discovered as a potential candidate. The most specific candidate is chosen as soon as its place in the order is determined.
The algorithm achieves a full ordering of arguments: the specificity of the first argument counts more than the second, the second more than the third, and so on. However, where normal multiple dispatch looks at each argument and uses the most specific supertype to determine specificity (or rather, the most specific parameter type of which the argument is a subtype), Slate instead interprets specificity as DISTANCE in the directed graph of delegations, starting from the particular argument in question as the root.
The DISTANCE notion has the following properties:
The resulting dispatched method satisfies the property that: for any of the arguments, we can find the method on some role reachable by traversing delegations, and that is the closest such method we can find, where former arguments count as being ``closer'' than any subsequent arguments, and NoRole behaves like an ``omega distance'', as far away as possible.
The mechanism in Slate for specifying optional input arguments uses optional keywords for a syntax. They can be added to a method definition, a message-send, or a block header equally. Also, optional keywords can apply to unary, binary, and keyword message syntaxes equally. However, optional arguments cannot affect dispatch, can be provided in any order, and when not provided will start with a Nil value, due to their being incidental to the core semantics of the given block or method.
Method definitions may be annotated with optionals that they support by extending the signature with keyword-localname pairs in arbitrary order as ``&keywordName: argName''. This compiles the method to support argName as a local, with optional input.
An optional keyword argument is passed to a method by forming keyword-value pairs as ``&keywordName: someValue'' after the main selector and arguments as normal. Following keywords that have the &-prefix will be collected into the same message-send. A following non-optional keyword will be treated as beginning a new surrounding message-send, but in general, optional keywords raise the precedence of the basis message signature to a keyword level, instead of just unary or binary. Again, the order of the keyword-value pairs is ignored.
A block can declare optional input keywords in its block header in any order, using ``&argName'' as an input variable declaration, called with the normal convention (when using the block with do/applyTo:/etc.), whenever the block is invoked with a message-send.
Because Slate's methods are not centered around any particular argument, the resending of messages is formulated in terms of giving the method activation itself a message. The following are the various primitive protocols involved in resends:
The multiple dispatch system has an extended dynamic signature form which can be used to give a ``subjective'' or ``layered'' customization of the Slate environment. This is an implementation and slight modification of the Us language features conceived of by the Self authors[Smith 96].