19.11.2014 Views

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

A function declaration may be separated from its definition. An abstract function declaration can be provided for<br />

overloaded function definitions. When the parameter type of an abstract function declaration includes a type that is<br />

declared with a comprises clause, it is a static error if the corresponding function definitions do not cover every<br />

immediate subtype of the type.<br />

Syntactically, an abstract function declaration is a function declaration without a body. Parameter names may be elided<br />

but parameter types cannot be omitted. Additionally, when a function’s type is not parameterized, <strong>Fortress</strong> provides<br />

an alternative mathematical notation for an abstract function declaration: function name followed by the token : ,<br />

followed by an arrow type.<br />

For example, after the following abstract function declaration:<br />

printMolecule(Molecule):()<br />

where trait Molecule is defined as follows:<br />

trait Molecule comprises {OrganicMolecule, InorganicMolecule} end<br />

the programmer could write:<br />

printMolecule(molecule:Molecule) = . . .<br />

or could write:<br />

printMolecule(molecule:OrganicMolecule) = . . .<br />

printMolecule(molecule:InorganicMolecule) = . . .<br />

For the latter, the programmer must provide a definition for every immediate subtype of Molecule, or it is a static<br />

error.<br />

12.4 Function Contracts<br />

Syntax:<br />

Contract ::= [Requires] [Ensures] [Invariant]<br />

Requires ::= requires Expr +<br />

Ensures ::= ensures (Expr + [provided Expr]) +<br />

Invariant ::= invariant Expr +<br />

Function contracts consist of three optional clauses: a requires clause, an ensures clause, and an invariant<br />

clause. All three clauses are evaluated in the scope of the function body.<br />

<strong>The</strong> requires clause consists of a sequence of expressions of type Boolean. <strong>The</strong> requires clause is evaluated<br />

during a function call before the body of the function. If any expression in a requires clause does not evaluate to<br />

true , a CallerViolation exception is thrown.<br />

<strong>The</strong> ensures clause consists of a sequence of ensures subclauses. Each such subclause consists of a sequence<br />

of expressions of type Boolean, optionally followed by a provided subclause. A provided subclause begins<br />

with the special reserved word provided followed by an expression of type Boolean. For each subclause in the<br />

ensures clause of a contract, the provided subclause is evaluated immediately after the requires clause during a<br />

function call (before the function body is evaluated). If a provided subclause evaluates to true , then the expressions<br />

preceding this provided subclause are evaluated after the function body is evaluated. If any expression evaluated<br />

after function evaluation does not evaluate to true , a CalleeViolation exception is thrown. <strong>The</strong> expressions preceding<br />

the provided subclause can refer to the return value of the function. A result variable is implicitly bound to a return<br />

value of the function and is in scope of the expressions preceding the provided subclause. <strong>The</strong> implicitly declared<br />

result shadows any other declaration with the same name in scope.<br />

89

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!