• Aucun résultat trouvé

Ad hoc vs Parametric Polymorphism

Time Overhead in Type Computation

4.1 Issues in Overloading

4.1.4 Ad hoc vs Parametric Polymorphism

The essential idea behind overloading is that it is a syntactic sharing of names. It does not inter-fere with the semantics of the language. So, for languages that do not emphasize the concepts of polymorphism and code sharing, we do not even think of overloading as a means of poly-morphism. But a basic insight is that syntactic overloading can be traded o for semantically more polymorphic, higher-order, parametric polymorphism. Instead of attempting to replace syntactically overloaded programming constructs by their resolved instances in order to impart them a semantic meaning, we can choose to provide a parametric, semantic interpretation to the overloaded construct directly.

Consider the earlier example ofdouble. Instead of treating it as implicitly overloaded, we may interpret it to possess an extra parameter supplying the appropriate addition operation.

The intended interpretation is shown in gure 4.1, example (a), as a new transformed denition on the right. Now there is exactly one interpretation of double. It is now a parameterized function with an extra argument (+). An actual resolved instance of \+" is passed to it as shown in any particular application.

Parameterization also takes care of the exponentially large number of possible instances by constructing only one function which is passed suitable arguments in various situations to behave like dierent instances. Translation of doublepair in example (b) illustrates this.

Finally, it oers a clean solution to the recursive overloading problem as well (see example (c) for vadd). It converts the syntactic problem of choosing one of innitely many dierent resolution instances into that of composing the right application from the same parameterized instance recursively.

It may appear from the above discussion that we have already found a plausible scheme for implementing overloading of identiers. It is conceivable that a smart compiler will be able to generate the parameterized forms by looking at the type of the variables involved and the declaration of the various instances. Indeed, this is precisely the approach taken by Wadler and Blott in [63]. There the authors oer a general mechanism to systematically convert overloaded expressions into parameterized functions applying them to suitably resolved arguments.

It is possible to split this process into two parts. First, we may simply type-check the whole program and resolve all uses of overloaded identiers to their appropriate instances as far as possible. Then, in the second step, we may translate the program using our preferred strategy that suitably deals with resolved and unresolved contexts. Thus, we can make the following observations at this point,

1. Overloading relieves the user from having to deal with some complex parameterizations in a particular implementation.

2. It is possible for the compiler to automatically infer the parameterizations using local type context information.

3. Overloading only species certain analysis and translation requirements for the compiler.

A particular implementation may choose to satisfy them with more ecient compilation strategies than simple parameterization.

The last point needs some elaboration. Notice that the extra parameter(+) in vadd' is com-pletely arbitrary. It has no knowledge that it is to be used for the instances of the overloaded addition operation only. Even though the compiler has this information, it simply discards it and any subsequent application of vadd' is no dierent from a general procedure call. An optimizing compiler can do better. Keeping in mind that can only range over the useful

Source Code Transformed Code

Figure 4.1: Translation of Overloading into Parameterization.

compiler may choose to generate a specialized version ofvaddfor each such used instance. The specialized versions will have inline instructions to do the relevent operation, consequently be-ing far more ecient than parameter passbe-ing and general procedure calls. To take an example, in a matrix algebra library, it may suce to generate a version ofvaddfor vectors and matrices of integers and oats each. The specialized versions for vectors may have inline instructions to do integer and oating point addition of the components and may be called ivadd and fvadd respectively. These versions will be much more ecient than their parameterized counterparts

(vadd' iplus)and (vadd' fplus).

It may be noted that all possible instances need not be specialized (of course, there may be innitely many of them!). Obviously, it is non-trivial to decide which ones should be specialized.

A compiler can perform price/performance analysis to decide this. There are opportunities for making several trade-os here: compiling time vs execution time (eciency of compiled code), added compiler complexity (for extra specialization analysis) vs simplistic translation mechanism, space (keeping several special versions) vs time (overhead in parameter passing and general procedure call).

4.1.5 Discussion

We may note in passing that dierent languages take dierent approaches when it comes to overloading. While conventional languages like Fortran and C allow only xed, built-in interpre-tations of the overloaded symbols, Miranda does not allow overloading of arithmetic operators and treats equality to be fully polymorphic. Standard ML allows overloaded arithmetic op-erators in directly resolvable contexts such as (2*2) and (2.72*2.72) but cannot indirectly propagate it inside unresolved functions such as the function doubleabove. As for the equal-ity operator (==), ML treats it specially and overloads it with every type that admits equality.

This gives it a limited, but extensible polymorphic avor at the cost of some extra bookkeeping.

Finally, Haskell directly supports the complete proposal of Wadler and Blott with type classes and parametric translation.

Our approach in Id is to investigate both parameterization and specialization schemes. The parameterization scheme is attractive since it is universal and systematic. The specialization scheme is attractive because of sheer run-time eciency; the user need not pay any run-time price for the extra comfort of overloading. We describe our proposal below in two parts: rst

program and resolves the overloaded identiers, then in the second step it uses this information to generate either parameterized or specialized code.