I take this tile from the blog entry of the same name by Dominus.

He points out how, given two types C is a subtype of B, meaning that a C can be used anywhere a B was originally expected, then Collection[C] is not a subtype of Collection[B]. There are theoretical principles under which you might think it should be, but practical difficulties.

The problems arise, Mark points out, when aliasing is allowed, something that doesn't occur in pure functional languages or type theory. However, another "leg" is the fact that objects can be replaced with other objects. Again that doesn't happen in functional languages. Replacement of elements is a principle of "containers" which is why he noticed it there.

However, any r/w or lvalue access, when combined with aliasing, gives rise to this problem. In fact, Perl 6 literally explains "Item containers" as a collection of one. Perl 6 is supposed to provide for optional strong typing. In the vestigial typing of Perl 5 this type violation is not a big deal, since decorating the declaration doesn't promise much. But in Perl 6, a type is supposed to mean something.

Here is an example:
sub field_promotion (Soldier $x is rw) { $x = Private.new; # Private "isa" Soldier, allowed. } my General $y .= new; field_promotion ($y); # General "isa" Soldier, allowed. $y.order_attack();
So what would happen in C++, a mature language that demands accurate type information?
void field_promotion (Soldier& x) { x = Private(); // value assignment slices object (if allowed at a +ll) }
Well, we need reference semantics, not value semantics. That is the variables can refer to different polymorphic instances.
void field_promotion (Soldier* &x) { x= new Private(); // allowed, and updates caller's pointer variab +le } void caller() { General* y= new General(); field_promotion (y); // compile-time error }
Well, C++ rules have it that if C is a subtype of B, you can substitute C* for B* or C& for B& (giving normal use of polymorphism), but does not allow C** for B** etc.

So perhaps the "is rw" is the moral equivalent of another level of indirection, and similar rules should apply. Well, how about:
our Soldier $x; multi sub trythisone (General $y) { # $y is a read-only alias of the caller's variable, global $x in this + case. # This function chosen based on actual type of $x at the time the cal +l was made. $x = Private.new; # what just happened to $y? $y.order_attack(); } $x = General.new; trythisone ($x);
In C++, you can't get that to happen with a regular function because the choice of overloading and type matching is done with the declared compile-time type. If you make it a virtual function, you see that the this will refer directly to the object itself, and does not alias the caller's variable. Changing the original variable does not affect this.

The analogous thing in Perl 6 would be to make $y refer directly to the object that $x held at the time the call was made, so assigning to $x does not affect $y. Note that calling mutating methods on $x will affect the same object seen by $y. It's just the lvalueness of $x that is not captured. We are not aliasing the "collection of one" that can have cells replaced.

With that interpretation, the more bizzare cases involving closures to access local variables of the caller also go away.

So that's my meditation: that the "pillars of the problem" more fundamentally refer to lvalueness, not "Collection". And existing mature languages knew that all along.

—John


In reply to Subtypes and Polymorphism by John M. Dlugosz

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.