On 8/25/06, Mark J. Reed <[EMAIL PROTECTED]> wrote:
Why not?  Is it any weirder than simply changing that functionality
beyond recognition?

You can always fake removing functionality even if the language
doesn't actually support it.

Yes, yes, of course.  That is not the issue.  We are trying to
determine whether Array is a subtype of Array::Const.  There are many
things you *can* do, but for core language features, it is probably
not a good idea to abandon OO foundations so quickly.

Larry says that a type that removes functionality is not a "subtype"
but a "subset".  But that is bogus.  Let's consider this class:

   class Accessor {
     has $:x;
     method set($x) { $.x = $x }
     method get()   { $:x }
   }

And let's define Accessors = the set of all objects on which you can
call set($x) and get().  That's not strictly the case, because there
may be other objects which are not Accessors which might have those
methods, but we can ignore that for the time being.

Now let's say there is another type, ConstAccessor, which removes the
set($x) ability, creating a "subset".  ConstAccessors is now the set
of things on which you can call get().

And now look at the sets:  Accessors = the set of all objects on which
you can call both set($x) and get().  ConstAccessors = the set of all
objects on which you can call get().  Clearly Accessors is a subset of
ConstAccessors, because anything you can call set($x) and get() on you
can call get() on.

Removing abilities, counterintuitive though it may seem on the
surface, makes the type *larger*.  It is not adding constraints, it is
removing them (you might not be able to call set($x) on this object
anymore).

There are many ways to think about this.  You can indeed take a
superclass which defines a method and override that method with one
that pretends the method doesn't exist, or throws some other kind of
error.  But that is a pure OO no-no; you were guaranteeing from the
superclass that you could safely call a method, and then the subclass
violated that guarantee.  Fortunately, Perl is not pure OO, so we are
allowed to do that in our code, but I don't think it's a good idea to
start following the faulty line of reasoning that a constant something
is a subtype of its nonconstant counterpart.

In order to resolve the linguistic conundrum of "when Array", we could
say that the Array role in fact implements a constant Array.  If you
would like to be a mutable array, you implement MutableArray or
something.  That would make code like this:

   given $x {
     when Array { $x[42] = 42; }
   }

broken from a pure point of view.  You may not be able to set element
42 of that array.  Perl would still allow the code to compile, of
course, because Perl is a laid-back language.

Constness is something that exists, so we have to solve it somehow.
My experience with C++ tells me that the best way to solve it is to
keep it out of the way most of the time (which C++ does not).  The
solution above is one way to do that, there may be others.  But
pretending that const arrays are arrays with the added capability that
they throw an error when you try to write to them is going to get us
to a broken type model.

Luke

Reply via email to