Reference Manual of LoI - Datatypes and Expressions

3.5 Datatypes and Expressions

Each expression results in a value and has a type. In the following, the different expressions are presented in clusters centering around the datatype they are connected to (for references to variables cf. 3.4 and roles cf. 3.6.3). All remaining forms of expressions, that do not fit in this scheme, will be described separatly.

3.5.1 Object

Object is an abstract type for data. It is usually used to pass data from one role to another without processing the data itself.

3.5.1.1 Type

The corresponding type is object

3.5.1.2 Objects

There is one constant which designates the empty object:

nil

3.5.1.3 Equality

Objects may be compared for equality or unequality.

<expression 1 of type object> = = <expression 2 of type object>
<expression 1 of type object> ! = <expression 2 of type object>

Objects are equal if they are identical, which means that they represent the same object. Unequality is the just the negation of equality.

3.5.2 Void

Values of type Void are actually used as dummy values (e.g.passing a value to a "function", which needs an argument).

3.5.2.1 Type

The corresponding type is void.

3.5.2.2 Constants

A constant (and the only value) is defined for Void:

( )

3.5.3 Integers

Integers are a continuous subset of the whole numbers (meaning that are no gaps in the subset). The minimum and maximum value of this subset depends on the implementation.

3.5.3.1 Type

The corresponding type is int.

3.5.3.2 Constants

Only the positive integers can be represented (cf. 3.2.4.1). Negative integers are created using the negation operator (cf.below).

3.5.3.3 Operators and Functions

The following binary and unary operators are possible for integers (consider also the increment operator in 3.4.2.2 or the decrement operator in 3.4.2.3)

<expression 1 of type integer> + <expression 2 of type integer>
<expression 1 of type integer> - <expression 2 of type integer>
<expression 1 of type integer> * <expression 2 of type integer>
<expression 1 of type integer> / <expression 2 of type integer>
<expression 1 of type integer> % <expression 2 of type integer>
- <expression of type integer>

The operators represent addition (+), subtraction ( -, binary), multiplication (*), division (/), remainder (%) and arithmetic negation ( -, unary).
Division and remainder are defined as a = b*(a / b) + a % b with 0 < a % b < b. The division and remainder are undefined if b = 0.
Remark: an underflow or an overflow may occur if the minimal or maximal value is passed.
The following two functions provide conversion from strings to integers and vice versa:

a2i <an expression of type string>
i2a <an expression of type int>

a2i converts a number given in a decimal representation to an integer. The result is undefined if non-decimal characters are used. i2a converts an integer to a number in a decimal representation.

3.5.3.4 Equality

Integers may be compared for equality or unequality.

<expression 1 of type integer> = = <expression 2 of type integer>
<expression 1 of type integer> ! = <expression 2 of type integer>

Expressions of type integer are equal if they result in the same value. Unequality is just the negation of equality.

3.5.3.5 Comparison Operators

Integers may be compared using the following operators

<expression 1 of type integer> < <expression 2 of type integer>
<expression 1 of type integer> > <expression 2 of type integer>
<expression 1 of type integer> <= <expression 2 of type integer>
<expression 1 of type integer> >= <expression 2 of type integer>

Each operator results in a value of type Boolean.

3.5.4 Floats

Floats are a subset of the rational numbers. The minimum and maximum value of this subset depends on the implementation. The same is true for the nearest (positive or negative) value to zero.

3.5.4.1 Type

The corresponding type is float

3.5.4.2 Constants

Only positive floats can be represented (cf. 3.2.4.1). Negative floats are created using the negation operator (cf.below).

3.5.4.3 Operators

The following binary and unary operators may be used in connection with floats:

<expression 1 of type float> + <expression 2 of type float>
<expression 1 of type float> - <expression 2 of type float>
<expression 1 of type float> * <expression 2 of type float>
<expression 1 of type float> / <expression 2 of type float>
 - <expression of type float>

The operators represent addition (+), subtraction ( -, binary), multiplication ( * ), division ( / ) and arithmetic negation ( -, unary).
Remark: an underflow or an overflow may occur if the minimal or maximal value is passed.

3.5.4.4 Equality

Floats may be compared for equality or unequality.

<expression 1 of type float> = = <expression 2 of type float>
<expression 1 of type float> ! = <expression 2 of type float>

Expressions of type float are equal if they result in the same value. Unequality is just the negation of equality.

3.5.4.5 Comparison Operators

Floats may be compared using the following operators

<expression 1 of type float> < <expression 2 of type float>
<expression 1 of type float> > <expression 2 of type float>
<expression 1 of type float> <= <expression 2 of type float>
<expression 1 of type float> >= <expression 2 of type float>

Each operator results in a value of type Boolean.

3.5.4.6 Functions

There are two conversion functions in relation to floats:

float2int <an expression of type int>
int2float <an expression of type float>

int2float converts the given float value into an integer value truncating the fractional part of the float. float2int is the opposite function: its result is the integer value of the given value.
Both functions may be partially defined - dependent on the implementation. float truncates the fractional part of the float value.

3.5.5 Boolean

The datatype Boolean is used in logical and relational expressions.

3.5.5.1 Type

The corresponding type is bool

3.5.5.2 Constants

Two constants are defined

true
false

3.5.5.3 Operators

The common Boolean operators are defined: and (&&), inclusive or ( | | ), and not ( ! ).

<expression 1 of type Boolean> && <expression 2 of type integer>
<expression 1 of type Boolean> || <expression 2 of type integer>
! <expression 1 of type Boolean>

The and- and or-operator have a special (partially non-strict) evaluation. Only the first argument is computed at the beginning, if the result equals true (for &&) or false (for | |) the second argument is not computed.

3.5.5.4 Equality

Boolean values may be compared for equality or unequality.

<expression 1 of type Boolean> = = <expression 2 of type Boolean>
<expression 1 of type Boolean> ! = <expression 2 of type Boolean>

Expressions of type Boolean are equal if they result in the same value. Unequality is just the negation of equality.

3.5.6 Char

Values of type Char are used to represent single symbols (like A).

3.5.6.1 Type

The corresponding type is char.

3.5.6.2 Constants

cf. 3.2.4.4

3.5.6.3 Functions

Two primitive functions are defined in relations to characters

ord <expression of type Char>
chr <expression of type Integer>

ord returns the code number of the given character; chr returns the character corresponding to the given code. chr is undefined for values for which there is no character defined in the underlying character set.

3.5.6.4 Equality

Characters may be compared for equality or unequality.

<expression 1 of type Char> = = <expression 2 of type Char>
<expression 1 of type Char> ! = <expression 2 of type Char>

Expressions of type Char are equal if they result in the same value. Unequality is just the negation of equality.

3.5.6.4 Comparison Operators

Characters may be compared using the following operators

<expression 1 of type char> < <expression 2 of type char>
<expression 1 of type char> > <expression 2 of type char>
<expression 1 of type char> <= <expression 2 of type char> 
<expression 1 of type char> >= <expression 2 of type char>

Each operator results in a value of type Boolean.

3.5.7 Mutex

Values of type Mutex are used for synchronization purposes (cf. 3.7.10). Essentially, a mutex is a simplified version of semaphores only allowing a locked and a unlocked state.

3.5.7.1 Type

The corresponding type is mutex.

3.5.7.2 Constants

There are no constants defined for data values of type Mutex.

3.5.7.3 Functions

There is a generator function for mutex values:

  make_mutex ()

This function returns a new mutex value.

3.5.7.4 Equality

Mutex values may be compared for equality or unequality.

<expression 1 of type Mutex> = = <expression 2 of type Mutex>
<expression 1 of type Mutex> ! = <expression 2 of type Mutex>

Expressions of type Mutex are equal if they result in the same mutex value. Unequality is just the negation of equality.

3.5.8 Agent

cf. 3.6.1

3.5.9 Aid

cf. 3.6.2

3.5.10 Modules

For the definition of a module cf. 3.3

3.5.10.1 Type

The corresponding type is module

3.5.10.2 Constants

cf. 3.3

3.5.10.3 Equality

It is not possible to compare modules.

3.5.11 Ports

Values of type Port can be interpreted as instances of roles. This means, that if two messages are passed to one and the same role, the messages might arrive at different agents if the port of the role was exchanged cf. 3.7.27). What makes them a bit special, is that a port can be connected to different roles at the same time. But it is not possible to connect several ports to one and the same role. Ports are especially useful for having different sessions with regards to interactions.

3.5.11.1 Type

The corresponding type is port.

3.5.11.2 Constants

There are no constants for ports.

3.5.11.3 Functions

One generator is defined:

make_port ()

This function generates new ports.
Cf. 3.7.27 for binding ports to roles.

3.5.11.4 Equality

Port values may be compared for equality or unequality.

<expression 1 of type Port> = = <expression 2 of type Port>
<expression 1 of type Port> ! = <expression 2 of type Port>

Expressions of type Port are equal if they result in the same port value.
Unequality is just the negation of equality.

3.5.12 Arrays

Arrays are values that cluster values of the same type. Each component of such an array is in a unique way addressable. The addresses range between 0 and the length of the array - 1.

3.5.12.1 Type

The corresponding type is {<component type>}

3.5.12.2 Constants

Array constants are enclosed in curly brackets and list the components of the array:

   { <an expression of type t>,
    <an expression of type t>,
    ...,
    <an expression of type t> }

There is also an abbreviation for components that have the same value and are ordered one after the other:

  <an expression of type t> # <an expression of type Integer>

The expression in front of the sharp character designates the component and the one after it the number of copies, that is

   {2+3#5} 
   {2+3, 2+3, 2+3, 2+3, 2+3}

result in both cases in an array with the same content.

3.5.12.3 Acces and Modification

The components of an array may be modified or accessed. A modification is only possible in modification statements (cf. 3.7.22), which have for arrays the following forms:

<a variable>[<an expression of type Integer>] := <an expression>
<a variable>[<an expression of type Integer>] ++
<a variable>[<an expression of type Integer>] - -

Note, that the variable has to be of type Array. With regards to the first form, the component type has to be equal with that of the expression. In the second and third form, the component type has to be equal to Integer. At first, the index is computed (the expression between the square brackets), then the component is accessed using the computed index and modified according to the given operation (assignment, increment or decrement).
An access expression is similar:

<an expression of type Array>[<an expression of type Integer>]

First the index is computed. Then the component is accessed and its value returned.
Remark: The operations, which have been described in the preceding paragraphs are only valid, if the computed index is within the bounds of the array.

3.5.12.4 Operators and Functions

The following operator generates a new array which is the concatenation of its arguments. The arrays given as arguments have to have the same component type.

<expression 1 of type Array> + <expression 2 of type Array>

The function returns the length of the given array as an integer.

length <an expression of type array>

3.5.12.5 Equality

Array values may be compared for equality or unequality.

<expression 1 of type Array> = = <expression 2 of type Array>
<expression 1 of type Array> ! = <expression 2 of type Array>

Expressions of type Array are equal if they result in the same array value, which means that the resulting array has to be identical. Unequality is just the negation of equality.

3.5.13 Strings

Strings are just arrays with the component type Char. Thus, all operations of arrays are also available to strings.

3.5.13.1Type

The corresponding type is string, which is equal to {char}.

3.5.13.2 Constants

There is special form which generates strings (cf. 3.2.4.5).

"<a sequence of characters>"

3.5.13.3 Comparison Operators

Strings may be compared using the following operators

<expression 1 of type string> < <expression 2 of type string>
<expression 1 of type string> > <expression 2 of type string>
<expression 1 of type string> <= <expression 2 of type string>
<expression 1 of type string> >= <expression 2 of type string>

Each operator results in a value of type Boolean.

3.5.14 Tuples

Tuples are used to cluster entities of different type. Components of a tuple may be labeled or unlabeled.
Remark: Two expressions of type Tuple may have different component types, but are equal with regards to their type.

3.5.14.1 Type

The corresponding type is

(<component type 1>, <component type 2>,....<component type n>).

3.5.14.2 Constants

Tuple constants are enclosed in parentheses and list the components of the tuple:

( <a tuple component>
  <a tuple component>
   ....,
  <a tuple component> )

Note, that a tuple must have two components at least. A component consist of an expression; optionally a label may be attached (cf.the second form):

<an expression>
<an identifier> = <an expression>

3.5.14.3 Modification and Access

The components of a tuple may be modified or accessed. A modification is only possible in modification statements (cf. 3.7.22), which have for tuples the following forms:

<a variable> . <a integer n> := <an expression>
<a variable> . <a integer n> ++
<a variable> . <a integer n> - -

Note, that the variable has to be of type Tuple. With regards to the first form, the component type (designated by the integer) has to be equal with that of the expression. In the second and third form, the component type has to be equal to Integer.
That component, which is denoted by the given integer, is modified according to the given operation (assignment, increment or decrement).
The access operation looks like

<an expression of type Tuple> . <a integer>

That component, which is denoted by the integer, is accessed and its value returned.
Remark: The operations, which have been described in the preceding paragraphs are only valid, if the integer (the index) is within the bounds of the tuple.
If a component has a label, it may also be modified as follows

<a variable> . <an identifier> := <an expression>
<a variable> . <an identifier> ++
<a variable> . <an identifier> - -

The access operation is then

<an expression of type Tuple> . <an identifier>

3.5.14.4 Equality

Tuple values may be compared for equality or unequality.

<expression 1 of type Tuple> = = <expression 2 of type Tuple>
<expression 1 of type Tuple> ! = <expression 2 of type Tuple>

Expressions of type Tuple are equal if they result in the same tuple value, which means that the resulting tuple has to be identical. Unequality is just the negation of equality.

3.5.15 Constructors

Constructors are the labels of concrete types (Cf. 3.4.9 for the definition of a constructor function). Typically, they are used to generate a value of that type:

<a constructor> <an expression>

The expression has to be of the same type as the parameters of the constructor.
Constructors can also be handled as separate values. This is necessary for the identification of the components of a constructed type.

3.5.15.1 Type

The corresponding type of a constructor is constructor The type of the result of the constructor function depends on the definition of the constructor.

3.5.15.2 Constants

cf. 3.4.9

3.5.15.3 Operators

arg <expression of type constructor> <expression of a constructed type>
constructor <expression of constructed type>

The arg operator returns the argument of the constructed type. The given constructor has to be defined for the constructed type; otherwise the result is undefined. constructor returns the constructor of the argument.
Examples:

   arg Cons Cons(1, Empty)
   constructor Cons(1, Empty)

The result of the first expression will be (1, Empty); the second expression will evaluate to Cons.

3.5.15.4 Equality

Constructors and concrete types can be compared for equality:

<expression 1 of type constructor> = = <expression 2 of type constructor>
<expression 1 of type constructor> ! = <expression 2 of type constructor>

expression 1 of a concrete type> = = <expression 2 of a concrete type>
expression 1 of a concrete type> ! = <expression 2 of a concrete type>

Expressions of type constructor are equal if they result in the same value. With regards to concrete types, both arguments have to have the same constructor and argument. Unequality is just the negation of equality.

3.5.16 Functions

Apart from the predefined functions it is possible to define new functions.

3.5.16.1 Type

The corresponding type is

<type of the parameters> => <result type>.

3.5.16.2 Constants

There are the predefined functions. New functions can be constructed using this forms

(<an identifier>, <an identifier>, ...., <an identifier>) =>
 { <a statement> }
 <an identifier> => {<a statement>}

This notation is best explained together with an application:

<an expression of type t1 => t2> <an expression of type t1>

If our function is defined in the first way, the second expression in the application has to be a tuple with the same number of components as the list of parameters in the definition - of cause the types of the argument and its corresponding parameter also have to be equal. If our function was defined in the second way, the parameter will be bound to the result of the second expresssion of the application.
Functions may return a result (cf. 3.7.17) or not. (In the second case they usually called procedures).
For recursive definitions it is possible to use a pseudo variable, this. This variable refers to the most actual function. Thus a definition of the factorial looks in LoI like that:

   fac = n => { if (n == 0)
                            return 1
                       else
                            return n * (this (n-1)) }

But, you can also use the name of the function itself:

   fac = n => { if (n == 0)
                            return 1
                        else
                           return n * (fac (n-1)) }

3.5.17 Additional Functions

Apart from functions already mentioned, we have

now <an expression of type void>
setseed <an expression of type int>
random<an expression of type void>

now returns the current time as an integer. (This might not correspond to wall time, but we expect that successive calls to now will never return a result that is less to a previous result.) setseed memorizes the given integer as a seed for pseudo-random number generation. random generates a pseudo-random number using a seed value.
For functions concerned with threads confer 3.8

3.5.18 Type Constraints

cf. 3.4.7

3.5.19 Function Calls or Module Activation

Like in 3.7.18, but the result of the function is the value of the expression. If a module (cf. 3.5.10) is activated, the result is void.

3.5.20 Subexpressions

Subexpressions are expressions that are enclosed in parentheses:

(<an expression>)

3.5.21 Precedence of Operators

The operators and forms, which may used in expressions, have the following increasing precedence (each line represents a precedence level):

+  -(binary) ||
* / % && &
! =  ==
> < >= <=
-(unary) ! # @ @@
Arrays; Function Call; Selection (Array/Tuple); Type Constraints
all other forms of expressions
Reference Manual of LoI - Datatypes and Expressions,
© 2000 by Gil Müller