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 trait constraint consisting of the identifier of a naked type variable, followed by the special reserved word<br />

extends followed by a set of trait references which may include naked type variables,<br />

• a type alias (described in Section 8.9),<br />

• an arithmetic constraint,<br />

• a boolean constraint,<br />

• a unit equality constraint,<br />

• a coerces constraint (described in Section 17.2), or<br />

• a widens constraint (described in Section 17.2).<br />

A where clause may include mutually recursive constraints. All static variables in a trait, object, or functional<br />

declaration must occur either as a static parameter or as a where -clause variable. Appendix A.2 describes a <strong>Fortress</strong><br />

core calculus with where clauses.<br />

Trait declarations are allowed to extend other instantiations of themselves. For example, we can write:<br />

trait CS extends CT<br />

where {S extends T, T extends Object}<br />

end<br />

In this declaration, for every subtype S of T , CS is a subtype of CT . Effectively, we have expressed the fact<br />

that the static parameter S of C is covariant.<br />

Trait declarations need not have any static parameters in order to have a where clause. For example, the following<br />

trait declaration is legal:<br />

trait C extends DT<br />

where {T extends Object}<br />

end<br />

In this declaration, trait C is a subtrait of every instantiation of parametric trait D . Thus, trait C has all of the methods<br />

of every instantiation of D . By thinking of the declaration this way, we can see what restrictions we need to impose<br />

on the trait C in order for it to be sensible. If trait C inherits a method declaration that refers to T , it really contains<br />

infinitely many methods (one for each instantiation of T ). However, instantiations of the where -clause variables are<br />

not explicit from the program text as static parameters are. It must be possible to infer which method is referred to<br />

at the call site. If there is not enough information to infer which method is called, type checking rejects the program<br />

and requires more type information from the programmer. Programmers always can provide more type information<br />

by using type ascription as described in Section 13.30.<br />

Object or functional declarations may include where clauses. Here is an example declaration of an Empty list:<br />

object Empty extends ListT where {T extends Object}<br />

first() = throw Error<br />

rest() = throw Error<br />

cons(x) = Cons(x,self)<br />

append(xs) = xs<br />

end<br />

where Cons is declared in Section 10.1.<br />

84

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

Saved successfully!

Ooh no, something went wrong!