=item Local Session
=item Remote Session
=head2 Tuples and patterns
A I<tuple> is an ordered set (or simply: an array) of zero or more elements.
Each element may be of a different type. Allowed types are:
=item * Integers
=item * Floating point numbers
=item * Strings
=item * Arrays with elements of allowed types
The elements of the array do not have to be of the same type. A tuple itself is
therefore also an array.
=item * Mapping between strings and allowed types
This includes hash tables and structs. The order of the key/value pairs should
not matter. The values in a map do not necessarily have to be of the same type.
=item * Wildcards
A I<pattern> is similar to a tuple, but has a smaller set of allowed types:
=item * Integers
=item * Strings
=item * Wildcards
That is: Arrays and maps are not allowed in patterns. Neither are floating
point types, but see below on how they are handled.
A string should always be encoded in UTF-8.
An integer must be representable in a signed (two's complement) 32-bit integer.
Thus anything in the range of C<-2^31> to C<2^31-1> constitutes a valid integer
value. It is recommended that implementations extend this definition to 64-bit
integers, but portable applications should not assume these to be available.
The maximum precision and range of floating point numbers is dictated by the
implementation, but should at least be a double precision IEEE 754 floating
point. The special values C<NaN>, C<-Inf> and C<+Inf> are not allowed, and
C<+0> and C<-0> should be considered as equivalent (i.e. the sign of the zero
value may get lost in transmission).
Even though the above string, integer and float types are specified separately,
tuples are dynamically typed and conversion between the types is done depending
on what the application expects to receive.
Integer to float conversion should be obvious. Float to integer conversion may
be done either by rounding the floating point number to the nearest integer or
by throwing away the non-integer part (flooring), depending on the
implementation. What happens when the number is out of the range of the integer
type is also implementation-defined.
String to integer conversion should at least be supported when the string
matches the following regular expression: C<^-?([1-9][0-9]*|0)$>, in which case the
string should be interpreted as a decimal number. Other formats may be allowed
as well, but this is implementation-defined and should not be relied upon by
applications that attempt to be portable. Behaviour when the number is out of
range for the chosen integer type is again implementation-defined.
String to float conversion follows the same behaviour as string to integer
conversion. Strings matching the following regular expression must be supported
for conversion: C<-?([1-9][0-9]*|0)(\.[0-9]+)?([eE]?[+-]?[0-9]+)?>.
Float to string and integer to string conversions are implementation-defined,
as long they are reversible by the string to float and string to integer
conversions used in the same implementation.
Conversions to and from array and map types should not be allowed.
There is no special boolean type, but if a boolean value is required then the
following values should evaluate to I<false>: The integer or floating point
with a value equal to 0, the zero-length string and the one-length string
containing only the ASCII C<'0'> character. Any other value should be
Tuples are I<matched> using patterns. This is much like pattern matching in the
text processing world: a tuple represents some input string and a pattern is
similar to a (somewhat less powerful) regular expression or C<fnmatch(3)>-style
A tuple is said to I<match> a pattern when, for each element in the pattern,
the tuple has a matching element at the same location. Two elements match if
either of the following holds:
=item 1. Either element is a wildcard
If the element of either the pattern or the tuple is a wildcard, then other
element can be of any type and value (this includes arrays and maps).
=item 2. Both elements have the same integer value
This implies that both elements can be converted to an integer type, as
specified in the previous section. This also implies that, when matching on
floating point types, only the integer representation (either rounded or
floored) is considered. Since this is implementation-defined, matching against
a floating point number for which the floored number is not equivalent to the
rounded number is not portable.
=item 3. Both elements have the same string value
Two strings are equivalent if they have the same length and their byte
representations are equivalent. Strings are thus matched in a case-sensitive
Rule 2 and 3 never apply to array or map types, as those can be converted to
neither integers nor strings. Thus matching on these types is impossible except
in rule 1, using a wildcard.
The above rules also imply that the tuple must hold at least as many elements
as the pattern, but the number of elements does not have to be equal.
Note that matching on the previously mentioned notion of a boolean type is not
possible. That is, you can't specify that you wish to match on all elements
that are considered I<true> or I<false>. If this is required, it is recommended
to standardise on the integers C<1> and C<0> to represent true or false,
Also keep in mind that the above matching rules have a lot of
implementation-defined behaviour. For example, the integer C<1234> will match
on the string C<"02322"> if the implementation accepts octal numbers as a valid
candidate for integer conversion. This may lead to unexpected behaviour, but I
do not expect this to be a problem in practice.
Send and register are the two simplest form of communication. A session uses
the I<register> primitive to indicate that it is interested in receiving tuples
that match a certain pattern. A session can register as many patterns as it
wishes. If an incoming tuple matches multiple patterns registered by the same
session, the tuple will be received multiple times. (But note that
implementations may optimize away duplicate tuples for more efficient
transmission - the behaviour of duplication can still be achieved when a list
of registered patterns is kept locally).
The I<send> primitive is used to "send" a tuple to other sessions. It will be
received by any session that has registered for a matching pattern. This
primitive does not tell the sending session whether there were any recipients,
and it is not an error to send out tuples when no other sessions have
registered for it. Outgoing tuples are also matched against the patterns that
the sending session has registered for, so if a session sends out a tuple
matching one of its own pattern, then the tuple will be sent back as well.
(Again, these are purely semantics, an implementation can achieve this
behaviour without needing to communicate with any other session.)
Messages are always received by a session in the same order as the sending
session sent them. Besides that, there are no ordering restrictions: Messages
sent by two different sessions may be received by an other session in any
I<TODO:> Specify the return-path.