From: Craig Chambers (chambers@cs.washington.edu)
Date: Thu Dec 05 2002 - 15:18:42 PST
Andrei Alexandrescu wrote:
>
> I kept the message below in my inbox for a while, to sleep on it.
>
> It would appear that it is benieficial to distinguish in the type system
> between two kinds of objects: those obtained via a static upcast (such as:
> Rectangle to Shape), and those obtained via a predicated upcast (such as
> Rectangle to Square). The former inheritance relationship is known
> statically to be always true, while the latter is transient and discovered
> only dynamically. (By the way, am I correct in interpreting Cecil predicates
> as a constrained form of dynamic inheritance?)
Square is a transitory *subclass* of Rectangle, so it's a downcast, not an
upcast.
>
> So imagine Cecil would add a type qualifier "transient" (qualifier that can
> be implemented as a parameterized type -- btw, what's the fundamental
> difference between qualifiers and parameterized types?). Any normal object
> "is-a" transient object. Then, predicated upcasts can only return transient
> objects. The point of doing all this is to limit what you can do to a
> transient object, i.e. an object returned by a predicated upcast.
I think this argument still applies to transient downcasts.
>
> So now, what can and what you cannot do with transient objects? An obvious
> thing to do is to disallow escape; a transient[Square] can not be stored nor
> converted to a Square. This is because the transient[Square] could actually
> originate from a Rectangle that is square-shaped. On the other hand, again,
> a Square happily morphs into a transient[Square].
>
> So you cannot store transient objects; the only thing you can do is to
> invoke on them other methods that accept transient objects.
>
> Not bad - but there is a major problem: aliasing. Consider this:
>
> method sneaky(rect:@Rectangle, sq: @transient[Square]);
> ...
> object rect isa Rectangle { ... };
> sneaky(rect, rect);
>
> Now inside sneaky a number of Bad Things(tm) are going to happen, caused by
> altering the Rectangle followed by altering what we think is a
> transient[Square]. This problem looks quite hard to solve...
>
> If anyone would like to comment, I'd be glad to hear from you!
>
> Andrei
In Cecil, an object can morph back from the transient predicate subclass to its
permanent superclass at essentially any time, so there's nothing you can really
do with the knowledge that at some instant in the past, the object had a special
state. So I think the problem is hopeless with Cecil-style implicit
classification. Approaches based on explicit reclassification have more hope
(and approaches in purely functional languages), but have similar aliasing
issues. See the papers on Fickle.
-- Craig
>
> ----- Original Message -----
> From: "Craig Chambers" <chambers@cs.washington.edu>
> To: <cecil@cs.washington.edu>
> Sent: Monday, October 21, 2002 9.49
> Subject: Re: Solving the Square/Rectangle problem in Cecil
>
> > I think you've hit on two limitations of Cecil's predicate classes, one
> > accidental, and one inherent.
> >
> > The accidental problem is that it turns out that two separate ideas have
> been
> > conflated with predicates: the superclass(es) that the original object is
> an
> > instance of (in this case Rectangle), and any additional superclass(es)
> that the
> > object should act like having when the predicate is true (in this case
> Square).
> > There's only one list of superclasses of a predicate class now, and
> they're all
> > treated as the first kind. I.e., preconditions, not postconditions. It
> > wouldn't be too hard to extend the language to allow the second kind of
> classes
> > to be specified also.
> >
> > The more inherent problem is that predicate subclasses can't be treated as
> > types. Say you wanted to have an array[Square]. You want to put in
> objects
> > that are subtypes of Square. BonaFideSquare is a subtype, so that works.
> But
> > the SquareRectangle predicate subclass of Rectangle *isn't* a subtype of
> Square,
> > even if it supports all the right square methods, because it is only
> > *temporarily* a square. It might at any point in the future stop being a
> > square, e.g. if its width but not its height were changed. If this
> > SquareRectangle were put into the array, then after the SquareRectangle
> reverted
> > to Rectangle, the array would contain an object that wasn't a Square, and
> type
> > safety would be violated.
> >
> > There are several alternative formulations of predicate class-like things
> that
> > are somewhat more amenable to static typechecking and partially resolve
> these
> > kinds of issues, but I don't know of anything that's completely
> satisfactory.
> >
> > -- Craig
> >
> >
> > Andrei Alexandrescu wrote:
> > >
> > > No waxing here, but Cecil is da bomb! Predicate-based inheritance is
> very
> > > powerful!
> > >
> > > There's a problem of which solution I believe can be devised with
> > > predicates, but I can't find it.
> > >
> > > Suppose I have the classic Shape hierarchy in a CAD program used for
> > > designing processors. There's a Rectangle class, a Line class and so on.
> > >
> > > Sometimes, I need to process all elements that are square. Now, there
> could
> > > be Rectangles that happen to have w = h, as well as some bona fide
> Square
> > > objects that are square by design (always). I want to iterate over both
> > > types in a shot and do something with them.
> > >
> > > The trick is to implement BonaFideSquare so as not to waste space;
> assume
> > > there are tons of such BonaFideSquare objects and you need to store the
> > > minimum information for each.
> > >
> > > So what's needed here is an object Square without data, an object
> > > BonaFideSquare that contains a point and an integer (origin and width),
> and
> > > another object Rectangle that contains a point and two integers (origin,
> > > width, height). When width = height, Rectangle should automagically
> inherit
> > > Square so it can be processed as such.
> > >
> > > What would be a solution in Cecil for that? I tried a number of
> approaches,
> > > but I couldn't find the space-saving one.
> > >
> > > Andrei
> > >
> > > _______________________________________________
> > > Cecil mailing list
> > > Cecil@cs.washington.edu
> > > http://majordomo.cs.washington.edu/mailman/listinfo/cecil
> > _______________________________________________
> > Cecil mailing list
> > Cecil@cs.washington.edu
> > http://majordomo.cs.washington.edu/mailman/listinfo/cecil
> >
>
> _______________________________________________
> Cecil mailing list
> Cecil@cs.washington.edu
> http://mailman.cs.washington.edu/mailman/listinfo/cecil
_______________________________________________
Cecil mailing list
Cecil@cs.washington.edu
http://mailman.cs.washington.edu/mailman/listinfo/cecil
This archive was generated by hypermail 2.1.5 : Thu Dec 05 2002 - 15:18:48 PST