3  Expressions

The syntax and meaning of the various expression forms is described in this section.

3.1  Names

Identifiers beginning with a lower case letter refer to pattern variables and named associations in let expressions.

Identifiers beginning with an upper case letter refer to data constructors.

3.1  Function Applications

A function application has the form:

<exprfun>  <exprarg>

Association is to the left, so the parentheses may be omited in (f x) y.

If a function has n arguments, then it said to have arity n. For a function of arity n (where n > 1) function application denotes a new function with arity n - 1. This is also known as currying and it allows for partial function applications.

Partial data constructor application is permitted.

3.2  Lambda Abstractions

A lambda abstraction has the form:

\ <patt1> ... <pattn> -> <expr>

It denotes a unnamed function of arity n. Currently, the only kind of permitted pattern is an optionally signed variable.

3.3  Operator Applications

The infix application of a binary operator <op> generally has the form:
<expression> <op> <expression>

There are two exceptions to this:

  1. The select operator . has two special forms:
    <expression>.<Name>
    or
    <expression>.<data constructor>

  2. The binding constructor:
    <Name>:<Expr>

The prefix notation is used for unary operators such as -, ¬:
<op> <expr>

There is an exception to this:

The select operator . has two special forms:
.<name>
or
.<data Constructor>

Semantically, operator applications are transformed to a standard function or type method application as specified in the following table:

Symbol Form Associativity Transformation Notes
. unary right (.) Root <name> or
(.) dataCon <expr> Root
Root select method or
Root object construction
¬ unary right (¬) <expr> Boolean negation
:: unary right (-) <type> Type constant
. binary left (.) <expr> <name> Select by name
- unary right (-) <expr> Numeric negation
^ binary left (^) <expr1> <expr2> Numeric exponentiation
* binary left (*) <expr1> <expr2> Numeric multiplication
/ binary left (/) <expr1> <expr2> Numeric division
mod binary left (modlt;expr1> <expr2> Numeric modulus
+ binary left (+) <expr1> <expr2> Numeric addition
- binary left (-) <expr1> <expr2> Numeric subtraction
< binary left (<) <expr1> <expr2> Less than
<= binary left (<=) <expr1> <expr2> Less than or equal to
= binary left (=) <expr1> <expr2> Equal to
¬= binary left (¬=) <expr1> <expr2> Not equal to
>= binary left (>=) <expr1> <expr2> Greater than or equal to
> binary left (>) <expr1> <expr2> Greater than
¬
not
binary right (¬) <expr> Logical NOT
&
and
binary left (&) <expr1> <expr2> Logical AND
|
or
binary left (|) <expr1> <expr2> Logical OR
unary right (#¬) <expr> Bitwise one's complement
<< binary left (<<) <expr1> <expr2> Bitwise left shift
>> binary left (>>) <expr1> <expr2> Bitwise right shift
#& binary left (#&) <expr1> <expr2> Bitwise AND
#^ binary left (#^) <expr1> <expr2> Bitwise Exclusive OR
#| binary left (#|) <expr1> <expr2> Bitwise Inclusive OR
: binary right Bind <name> <expr> Construct (Name, Exp *)
:= binary right See Assignment Assignment operator
-> binary right   Function type operator
:: binary left See Type Constraint Type constraint

3.3.1  Assignment

Property addition or destructive update is carried out by the assignment operator

Translation:

<expr1>.<name> := <expr2> => set <expr1> #<name> <expr2>

3.3.2  Type Constraint

Type constraints may be used to restrict values to sub-types of their primary type. Commonly used to constrain results of type * and object references (Ref), they take the form:

<expr> :: <type>

Any expression may be constrained, but it must be consistent with the type of its context. The compiler will either statically check that the constraint is valid or insert a run-time type check, which may result in FAIL.

Translation:

<expr> :: <type> => let !u = <expr> in let v::<type> = if typeOf u = ::<type> then u else FAIL in v
where u and v are new variables

3.4  Conditional Expressions

There are two forms of conditional expression:

if expr1 then expr2 else expr3

if expr1 then expr2

For both, expr1 is evaluated. If the result is True, the value of the conditional expression is expr2. Otherwise, the value is either expr2 or Void for the second form.

The type of e1 must be Bool; See case for more explanation about the type of a conditional expression.

Translations:

if <expr1> then <expr2> else expr3> => case <expr1> of {
 
True ->   <expr2>;
False ->   <expr3>}
if <expr1> then <expr2> => case <expr1> of {
 
True ->   <expr2>}

3.5  Case expressions

A case expression has the following form:

case <expr>
{
<alt1>;
<alt2>;
...
<altn>;
<default>;
}

where <alt1> has the form:

<pati> -> <exprj>
or
<pati>, <pati + i> ... <pati + m> -> <exprj>

and <default>

otherwise -> <exprdef>

Semantically, <expr> is evaluated, then matched against the sequence of alternatives: <alt1> ... <altn> as described in patterns.

The matches are tried sequentially, from top to bottom. The first successful match causes evaluation of the corresponding alternative body, in the environment of the case expression extended by the bindings created during the matching of that alternative and by the declarations associated with that alternative. If no match succeeds, the result is unspecified. The last alternative can start with the keyword otherwise, which will always be successful.

3.6  Blocks

A block expression has the following form:

{<sequence>}

where a sequence is

<expr1> ... ;<expr2> ... ;<exprn>

Translations:

{ <expr>} => <expr>
{ <expr1>; <expr2>; <exprn>} => seq <expr1> ({ <expr2>; <exprn>}))

seq x y is a standard function where the arguments are evaluated sequentially. The type of x is required to be either statically or dynamically determined to be Void. The evaluated type of seq x y is the evaluated type of y.

3.7  Let expressions

Let expressions have the form:

let {<decl1>; <decl2>; ... ;<decln>} in <expr>

The value is <expr> where the set of mutually recursive declarations has scope both in it and the right-hand side of the declarations.


home

Last update: 11 October, 2005