03.12.2012 Views

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

C++ for Scientists - Technische Universität Dresden

SHOW MORE
SHOW LESS

Create successful ePaper yourself

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

212 CHAPTER 7. EFFECTIVE PROGRAMMING: THE POLYMORPHIC WAY<br />

7.5 From Monomorphic to Polymorphic Behavior<br />

As presented in the last sections, each programming techique (or paradigm) offers different key<br />

benefits regarding effective programming. The imperative programming, the related procedural<br />

paradigm, and the object-related programming are simple and require that all calls to an object<br />

or function have exactly the same typing as the signature. So type checks and type constraints<br />

can be derived directly from the program text. But the effectivness (genericity and applicability)<br />

is greatly reduced <strong>for</strong> real world problems. This is in contrast to polymorphic code that freely<br />

operates only on abstract concept types. Polymorphic behavior enables the use of algorithms<br />

and data structures with several different types. The object-oriented, generic, and functional<br />

programming offer an additional mechanism which delays the actual type instantiation to a<br />

later evaluation point. Compared to the simple monomorphic way, the polymorphic mechanism<br />

is composed of a complex set of inference rules, because there is propagation of type in<strong>for</strong>mation<br />

between the object and function signature and the call signature in both directions.<br />

In object-oriented programming, libraries typically specify that the types supplied to the library<br />

must be derived from a common abstract base class, providing implementa- tions <strong>for</strong> a collection<br />

of pure virtual functions. The library knows only about the abstract base class interface,<br />

but can be extendedto work with new user types derived from the abstract interface. That is,<br />

variability is achieved through differing implementations of the virtual functions in the derived<br />

classes. This is how object-oriented programming supports modules that are closed <strong>for</strong> modification,<br />

yet remain open <strong>for</strong> extension. One strength of this paradigm is its support <strong>for</strong> varying<br />

the types supplied to a module at runtime. Composability of modules is limited, however,<br />

since independently produced modules generally do not agree on common abstract interfaces<br />

from which supplied types must inherit. The paradigm of generic programming, pioneered by<br />

Stepanov, Musser and their collaborators, is based on the principle of decomposing software into<br />

efficient components which make only minimal assumptions about other components, allowing<br />

maximum flexibility in composition. <strong>C++</strong> libraries developed following the generic programming<br />

paradigm typically rely on templates <strong>for</strong> the parametric and ad- hoc polymorphism they<br />

offer. Composability is enhanced as use of a library does not require inheriting from a particular<br />

abstract interface. Interfaces of library components are specified using concept collections of<br />

requirements analogous to, say, Haskell type classes. The key difference to abstract base classes<br />

and inheritance is that a type can be made to satisfy the constraints of a concept retroactively,<br />

independently of the definition of the type. Also, generic programming strives to make algorithms<br />

fully generic, while remaining as efficient as non-generic hand-written algorithms. Such<br />

an approach is not possible when the cost of any customization is a virtual function call.<br />

The strength of polymorphism is that the same piece of code can operate on different types,<br />

even types that are not known at the time the code was written. Such applicability is the<br />

cornerstone of polymorphism because it amplifies the usefulness and reusability of code. If<br />

the types of poymorphism are analysed in more detail, then two different main types can be<br />

observed:<br />

• Ad-hoc polymorphism<br />

• Universal polymorphism<br />

Only the second type, universal polymorphism, is actually important <strong>for</strong> effective programming,<br />

where the first type, ad-hoc polymorphism, is rather convenience.

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

Saved successfully!

Ooh no, something went wrong!