Monadic expressions are expressions with monadic operators, together with a few more specialized notations:
monadic-expression: term monadic-operator monadic-expression array [ expression ] of data-type array [ expressionopt ] of { init-list } list of { expression-list } chan of data-type data-type monadic-expression monadic-operator: one of + - ! ~ ref * <- hd tl len
The - operator produces the negative of its operand, which must have an arithmetic type. The type of the result is the same as the type of its operand.
The + operator has no effect; it is supplied only for symmetry. However, its argument must have an arithmetic type and the type of the result is the same.
The ! operator yields the int value 1 if its operand has the value 0, and yields 0 otherwise. The operand must have type int.
The ~ operator yields the 1's complement of its operand, which must have type int or byte. The type of the result is the same as that of its operand.
If e is an expression of an adt type, then ref e is an expression of ref adt type whose value refers to (points to) an anonymous object with value e. The ref operator differs from the unary & operator of C; it makes a new object and returns a reference to it, rather than generating a reference to an existing object.
If e is an expression of type ref adt, then * e is the value of the adt itself. The value of e must not be nil.
For example, in
Point: adt { ... };
p: Point;
pp: ref Point;
p = Point(1, 2);
pp = ref p; # pp is a new Point; *pp has value (1, 2)
p = Point(3, 4); # This makes *pp differ from p
*pp = Point(4, 5); # This does not affect p
The operand of the hd operator must be a non-empty list. The value is the first member of the list and has that member's type.
The operand of the tl operator must be a non-empty list. The value is the tail of the list, that is, the part of the list after its first member. The tail of a list with one member is nil.
The operand of the len operator is a string, an array, or a list. The value is an int giving the number of elements currently in the item.
The operand of the communication operator <- has type chan of sometype. The value of the expression is the first unread object previously sent over that channel, and has the type associated with the channel. If the channel is empty, the program delays until something is sent.
As a special case, the operand of <- may have type array of chan of sometype. In this case, all of the channels in the array are tested; one is fairly selected from those that have data. The expression yields a tuple of type (int, sometype ); its first member gives the index of the channel from which data was read, and its second member is the value read from the channel. If no member of the array has data ready, the expression delays.
Communication channels are treated more fully in §§9.8 and 9.12 below with the discussion of the alt and spawn statements.
In the expressions
array [ expression ] of data-type array [ expressionopt ] of { init-list ,opt }
init-list: element init-list , element element: expression expression => expression * => expression
If an element of the form * =>e2 is present, all members of the array not otherwise initialized are set to the value e2. The expression e2 is evaluated for each subscript position, but in an undefined order. For example,
arr := array[3] of { * => array[3] of { * => 1 } };
If the expression giving the size of the array is omitted, its size is taken from the largest subscript of a member explicitly initialized. It is erroneous to initialize a member twice.
The value of an expression
list of { expression-list }
The value of
chan of data-type
ch: chan of int; # just declares, sets ch to nil . . . ch = chan of int; # creates the channel and assigns it
An expression of the form
data-type monadic-expression
In arithmetic casts, the named type must be one of byte, int, big, or real, and the monadic-expression must have arithmetic type. For example,
byte 10
Here the named data type is string. In a first form, the monadic expression has arithmetic type (byte, int, big, or real) and the value is a string containing the decimal representation of the value, which may be either positive or negative. A real operand is converted as if by format %g, and if the result is converted back to real, the original value will be recovered exactly.
In a second form, the monadic expression has type array of byte. The value is a new string containing the Unicode characters obtained by interpreting the bytes in the array as a UTF-8 representation of that string. (UTF-8 is a representation of 16-bit Unicode characters as one, two, or three bytes.) The result of the conversion is undefined if the byte array ends within a multi-byte UTF-8 sequence.
In a first form, the monadic expression is a string, and the named type is an arithmetic type. The value is obtained by converting the string to that type. Initial white space is ignored; after a possible sign, conversion ceases at the first character not part of a number.
In a second form, the named type is array of byte and the monadic-expression is a string. The value is a new array of bytes containing the UTF-8 representation of the Unicode characters in the string. For example,
s := "Ångström"; a := array of byte s; s = string a;
Here the named type is that of an adt or ref adt, and the monadic expression is a comma-separated list of expressions within parentheses. The value of the expression is an instance of an adt of the named type whose data members are initialized with the members of the list, or whose single data member is initialized with the parenthesized expression. In case the type is ref adt, the value is a reference to the new instance of the adt.
The expressions in the list, read in order, correspond with the data members of the adt read in order; their types and number must agree. Placement of any function members of the adt is ignored. For example,
Point: adt {
x: int;
eq: fn (p: Point): int;
y: int;
};
. . .
p: Point;
p = Point(1, 2);
p := Point(1, 2);