Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I hope my post helps to get a language-agnostic view of the topic.</p> <p>For our internal trainings I have worked with the wonderful book "Smalltalk, Objects and Design (Chamond Liu)" and I rephrased following examples.</p> <p>What does “consistency” mean? The idea is to design type-safe type hierarchies with highly substitutable types. The key to get this consistency is sub type based conformance, if you work in a statically typed language. (We'll discuss the Liskov Substitution Principle (LSP) on a high level here.)</p> <p>Practical examples (pseudo code/invalid in C#): </p> <ul> <li><p>Covariance: Let's assume Birds that lay Eggs “consistently” with static typing: If the type Bird lays an Egg, wouldn't Bird's subtype lay a subtype of Egg? E.g. the type Duck lays a DuckEgg, then the consistency is given. Why is this consistent? Because in such an expression:<code>Egg anEgg = aBird.Lay();</code>the reference aBird could be legally substituted by a Bird or by a Duck instance. We say the return type is covariant to the type, in which Lay() is defined. A subtype's override may return a more specialized type. => “They deliver more.”</p></li> <li><p>Contravariance: Let's assume Pianos that Pianists can play “consistently” with static typing: If a Pianist plays Piano, would she be able to play a GrandPiano? Wouldn't rather a Virtuoso play a GrandPiano? (Be warned; there is a twist!) This is inconsistent! Because in such an expression: <code>aPiano.Play(aPianist);</code> aPiano couldn't be legally substituted by a Piano or by a GrandPiano instance! A GrandPiano can only be played by a Virtuoso, Pianists are too general! GrandPianos must be playable by more general types, then the play is consistent. We say the parameter type is contravariant to the type, in which Play() is defined. A subtype's override may accept a more generalized type. => “They require less.”</p></li> </ul> <p>Back to C#:<br> Because C# is basically a statically typed language, the "locations" of a type's interface that should be co- or contravariant (e.g. parameters and return types), must be marked explicitly to guarantee a consistent usage/development of that type, to make the LSP work fine. In dynamically typed languages LSP consistency is typically not a problem, in other words you could completely get rid of co- and contravariant "markup" on .Net interfaces and delegates, if you only used the type dynamic in your types. - But this is not the best solution in C# (you shouldn't use dynamic in public interfaces). </p> <p>Back to theory:<br> The described conformance (covariant return types/contravariant parameter types) is the theoretical ideal (supported by the languages Emerald and POOL-1). Some oop languages (e.g. Eiffel) decided to apply another type of consistency, esp. also covariant parameter types, because it better describes the reality than the theoretical ideal. In statically typed languages the desired consistency must often be achieved by application of design patterns like “double dispatching” and “visitor”. Other languages provide so-called “multiple dispatch” or multi methods (this is basically selecting function overloads at <em>run time</em>, e.g. with CLOS) or get the desired effect by using dynamic typing.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload