19.11.2014 Views

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

The Fortress Language Specification - CiteSeerX

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

17.3 Coercion Invocations<br />

One may invoke a coercion explicitly with the syntax: Trait. coercion (expr) . Overloading resolution (described<br />

in Section 15.5) applies in the usual way if the specified trait has more than one coercion that applies to the actual<br />

argument.<br />

One way to think about coercion is that explicit calls to coercion declarations are automatically inserted into the<br />

arguments of functional calls and the right-hand sides of assignment expressions and variable definitions. If trait U<br />

has a coercion from type T , then whenever a functional, f , is declared with a parameter of type U , a call f(t) where<br />

t has type T can be rewritten to f(U. coercion (t)) making the declaration of f applicable to the call. However, this<br />

rewriting does not occur if there exists a declaration that is applicable to the call before the rewriting (see Section 17.5<br />

for further discussion).<br />

If coercion is possible for more than one element of a tuple argument, a cross-product effect is obtained. For example,<br />

in this code:<br />

object X<br />

coercion (kiki :Y ) = . . .<br />

coercion (tutu : Q) = . . .<br />

hack(other : X) = 1<br />

end<br />

object Y end<br />

object Q end<br />

foo(dodo : X) = 2<br />

bar(hyar : X,yon : X) = 3<br />

bar(hyar : Q,yon : Q) = 4<br />

the following method invocations are valid:<br />

X.hack(Y )<br />

X.hack(Q)<br />

Because there is no declaration of hack applicable to Y and Q , these invocations are rewritten to:<br />

X.hack(X. coercion (Y ))<br />

X.hack(X. coercion (Q))<br />

Similarly, the function calls in the left-hand side of the following are valid and rewritten to the right-hand side:<br />

foo(Y ) is rewritten to foo(X. coercion (Y ))<br />

foo(Q) is rewritten to foo(X. coercion (Q))<br />

bar(Y, X) is rewritten to bar(X. coercion (Y ), X)<br />

bar(Q, X) is rewritten to bar(X. coercion (Q), X)<br />

bar(X, Y ) is rewritten to bar(X, X. coercion (Y ))<br />

bar(X, Q) is rewritten to bar(X, X. coercion (Q))<br />

bar(Y, Y ) is rewritten to bar(X. coercion (Y ), X. coercion (Y ))<br />

bar(Q, Q) is rewritten to bar(Q, Q)<br />

bar(Q, Y ) is rewritten to bar(X. coercion (Q), X. coercion (Y ))<br />

bar(Y, Q) is rewritten to bar(X. coercion (Y ), X. coercion (Q))<br />

Note that the call bar(Q, Q) remains unchanged because there exists a declaration for bar that is applicable without<br />

coercion.<br />

To continue the example, let us illustrate a point about type parameters. If we add the following definitions:<br />

139

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

Saved successfully!

Ooh no, something went wrong!