[Next] [Previous] [Up] [Top] [Contents] [Index]

2.5 Statements and Expressions

2.5.6 Message Sends

The syntax of a message send is as follows:

message	::=	msg_name "(" [exprs] ")"
exprs	::=	expr { "," expr }
unop_msg	::=	op_name unop_expr
binop_msg	::=	binop_expr op_name binop_expr

A message is written in one of three forms:

Normally, a message whose name begins with a letter is written in named prefix form, while a message whose name begins with a punctuation symbol is written in unary prefix form or in infix form.[7] To invoke a named message as an operator, or to invoke an operator as a named message, the name of the message is prefixed with an underscore (the leading underscore is not considered part of the message name). For example, the following two expressions both send the + message to 3 and 4:

3 + 4
_+(3, 4)

and the following two expressions both send the bit_and message to 3 and 4:

bit_and(3, 4)
3 _bit_and 4

The precedence and associativity of infix messages is specified through precedence declarations, described in section 2.6. The semantics of method lookup is described in section 2.7. Resends, a special kind of message send, are described in section 2.8.

Syntactic sugar exists for several common forms of messages. Dot notation allows the first argument of the message to be written first:

dot_msg	::=	dot_expr "." msg_name ["(" [exprs] ")"]

If the message takes only one argument, the trailing parentheses can be omitted. Consequently, the following three expressions all send the x message to p:

x(p)
p.x()
p.x

The following two expressions both send the bit_and message to 3 and 4:

bit_and(3, 4)
3.bit_and(4)

This syntax may suggest that the first argument is more important than the others, but in fact the semantics is still that all arguments are treated uniformly, and any subset of the arguments might be dispatched at method-lookup time.

Other syntactic sugars support message sends written like assignments. Any message can appear on the left-hand-side of an assignment statement:

assign_msg	::=	lvalue_msg ":=" expr	sugar for set_msg(exprs...,expr)
lvalue_msg	::=	message
	|	dot_msg
	|	unop_msg
	|	binop_msg

In each of these cases, the name of the message sent to carry out the "assignment" is set_ followed by the name of the message in the lvalue_msg expression, and the arguments to the real message are the arguments of the lvalue_msg expression followed by the expression on the right-hand-side of the "assignment." So the following three expressions are all equivalent:

set_foo(p, q, r);
foo(p, q) := r;
p.foo(q) := r;

as are the following two expressions:

set_top(rectangle, x);
rectangle.top := x;      -- frequently used for set accessor methods

as are the following two expressions:

set_!(v, i, x);
v!i := x;

Note that these syntactic sugars are assignments in syntax only. Semantically, they are all messages.


[6] All arguments to the message must be listed explicitly; there is no implicit self argument.
[7] Named prefix form is always used for method declarations.