November 25, 2001
"Pavel Minayev" <evilone@omen.ru> wrote in message news:9tptu2$22je$1@digitaldaemon.com...
>
> "Russell Borogove" <kaleja@estarcion.com> wrote in message
> news:3C0003D0.9070305@estarcion.com...
>     if (entity.class.extends(ClassThinkingEntity)) ...
>
> Or sumthing like that. Probably Walter will tell us if this works or not as he comes by this thread =)

No, I had missed that.

It's wierd how from time to time I discover interesting things in my own design <g>.


November 29, 2001
> IMHO, typechecking and typecasting should be _separate_ operations,
> not mixed. Because typecasting is usually performed on the generic
> pointer actually pointing to the child class when you know for sure
> that it does, and typechecking is used when you don't know what object
> your pointer references. These are two distinct things, let's not
> mix them.

I agree with this.  Dynamic typecasting can be almost zero overhead if the object is already known to be of such type or a descendant.

> > is-safe-to-cast? operation _must_ (as you noted) be provided by the language in a way that doesn't internally generate an exception, for performance reasons.
>
> BTW I've just thought that this operation is already supported by D due to its RTTI system:
>
>     if (entity.class == ClassThinkingEntity)
>         entity.Think();
>
> Personally, I like the "is" operator more, but even now D already has support for typechecking.

Nope, that won't catch the case where entity is actually a class derived from ClassThinkingEntity.  Maybe an 'is' operator here would be nice.  Only takes class types as arguments (an object being implicitly convertible to its class type)

Sean


November 29, 2001
This sounds like fine syntax to me.  I still think that once you've determined that an object is a subclass of some base class, you should be able to do the typecast without checking the same thing again.

if (entity.class.extends(ClassThinkingEntity))
   (static_cast(ClassThinkingEntity) entity).Think();

or

(dynamic_cast(ClassThinkingEntity) entity).Think(); // dynamic_cast must
throw an exception if it can't do it.

But I'd hate to pay the RTTI lookup overhead twice.

Sean

"Walter" <walter@digitalmars.com> wrote in message news:9trei7$euv$1@digitaldaemon.com...
>
> "Pavel Minayev" <evilone@omen.ru> wrote in message news:9tptu2$22je$1@digitaldaemon.com...
> >
> > "Russell Borogove" <kaleja@estarcion.com> wrote in message
> > news:3C0003D0.9070305@estarcion.com...
> >     if (entity.class.extends(ClassThinkingEntity)) ...
> >
> > Or sumthing like that. Probably Walter will tell us if this works or not as he comes by this thread =)
>
> No, I had missed that.
>
> It's wierd how from time to time I discover interesting things in my own design <g>.



November 30, 2001
	This post just gave me a thought.  It probably isn't appropriate for D
but I'll spit it out anyway.  Each type is going to have a property that
tells you the type right?  (Humor me.  Say yes.)  Likewise we could also
put such a property on the class identifier itself.  The property could
be the RTTI info.  I don't really care as long as it is a definite type
that the compiler can recognize.

	So you have:

		Class1;      // some class defined somewhere
		Class1 Obj1; // an instance of Class1
		Class2;	     // another class
		Class2 Obj2; // you know the drill

With the property I described above (I'll call it type) and some type comparison operators we could have:

		// true iff Obj1 & Obj2 are instances
		// of the same class
		Obj1.type == Obj2.type;

		// true iff Obj1 is a descendent of Obj2
		Obj1.type > Obj2.type;

		// true iff Obj1 is a parent of Obj2
		Obj1.type < Obj2.type;

Since classes have the property you could also say:

		// true iff Obj is an instance of Class
		Obj.type == Class.type;

You could also have all of the >=, <=, !=, <> type comparison too.  This could be done in the compiler but I imagine the detractors of operator overloading might also be offended by this.  It's clear (to me at least) concise, and does require new keywords or syntax.

Thought?
Dan

"Sean L. Palmer" wrote:
> 
> > IMHO, typechecking and typecasting should be _separate_ operations,
> > not mixed. Because typecasting is usually performed on the generic
> > pointer actually pointing to the child class when you know for sure
> > that it does, and typechecking is used when you don't know what object
> > your pointer references. These are two distinct things, let's not
> > mix them.
> 
> I agree with this.  Dynamic typecasting can be almost zero overhead if the object is already known to be of such type or a descendant.
> 
> > > is-safe-to-cast? operation _must_ (as you noted) be provided by the language in a way that doesn't internally generate an exception, for performance reasons.
> >
> > BTW I've just thought that this operation is already supported by D due to its RTTI system:
> >
> >     if (entity.class == ClassThinkingEntity)
> >         entity.Think();
> >
> > Personally, I like the "is" operator more, but even now D already has support for typechecking.
> 
> Nope, that won't catch the case where entity is actually a class derived from ClassThinkingEntity.  Maybe an 'is' operator here would be nice.  Only takes class types as arguments (an object being implicitly convertible to its class type)
> 
> Sean
November 30, 2001
a wrote:

> 	So you have:
> 
> 		Class1;      // some class defined somewhere
> 		Class1 Obj1; // an instance of Class1
> 		Class2;	     // another class
> 		Class2 Obj2; // you know the drill
> 
> With the property I described above (I'll call it type) and some type
> comparison operators we could have:
> 
> 		// true iff Obj1 & Obj2 are instances 		// of the same class
> 		Obj1.type == Obj2.type;
> 
> 		// true iff Obj1 is a descendent of Obj2
> 		Obj1.type > Obj2.type;
> 
> 		// true iff Obj1 is a parent of Obj2
> 		Obj1.type < Obj2.type;
> 
> Since classes have the property you could also say:
> 
> 		// true iff Obj is an instance of Class
> 		Obj.type == Class.type;
> 
> You could also have all of the >=, <=, !=, <> type comparison too.  This
> could be done in the compiler but I imagine the detractors of operator
> overloading might also be offended by this.  It's clear (to me at least)
> concise, and does require new keywords or syntax.


I like it, but I will be perpetually confused because I'll think of
parents as "greater than" children, or see the > as a directional
indicator of the direction of descendance instead of the direction
of inheritance.

Also, it's unclear what the right answers are when obj1 and obj2
are completely unrelated classes -- probably all relationals should
return false?

-RB



November 30, 2001
Russell Borogove wrote:
> 
> a wrote:
> 
> >       So you have:
> >
> >               Class1;      // some class defined somewhere
> >               Class1 Obj1; // an instance of Class1
> >               Class2;      // another class
> >               Class2 Obj2; // you know the drill
> >
> > With the property I described above (I'll call it type) and some type comparison operators we could have:
> >
> >               // true iff Obj1 & Obj2 are instances
> >               // of the same class
> >               Obj1.type == Obj2.type;
> >
> >               // true iff Obj1 is a descendent of Obj2
> >               Obj1.type > Obj2.type;
> >
> >               // true iff Obj1 is a parent of Obj2
> >               Obj1.type < Obj2.type;
> >
> > Since classes have the property you could also say:
> >
> >               // true iff Obj is an instance of Class
> >               Obj.type == Class.type;
> >
> > You could also have all of the >=, <=, !=, <> type comparison too.  This could be done in the compiler but I imagine the detractors of operator overloading might also be offended by this.  It's clear (to me at least) concise, and does require new keywords or syntax.
> 
> I like it, but I will be perpetually confused because I'll think of parents as "greater than" children, or see the > as a directional indicator of the direction of descendance instead of the direction of inheritance.

	I saw it as meaning the child class was everything the parent was and
more.  A superset of sorts.  However, swapping the operators probably
wouldn't hurt.  It would just have to have a good meaning that capture
the inheritance relation and how the parent is 'greater'.  (Age doesn't
count.)

> Also, it's unclear what the right answers are when obj1 and obj2 are completely unrelated classes -- probably all relationals should return false?

	I guess I was thinking of that as being treated like the NaN cases with
floats.  They aren't equal and neither one is greater than the other.
Isn't there a difference between != and <> for floats?

Dan
November 30, 2001
a wrote:

> I saw it as meaning the child class was everything the parent was and more.  A superset of sorts.  However, swapping the operators probably wouldn't hurt.  It would just have to have a good meaning that capture the inheritance relation and how the parent is 'greater'.  (Age doesn't count.)

If you think of a class as a set of objects, then the parent is the larger, since it encompasses a larger set and each child class encompasses a subset of the parent set.  That's how I've seen OOP theory taught.

However, from the view of a programmer, a class is a definition of a set of functionality, and so the child is a larger set.

I don't see any way to ensure clarity...other than just make a definition.  That's too bad, since I think that these operators are a very Good Idea.  Maybe it's worth the confusion...

> > Also, it's unclear what the right answers are when obj1 and obj2 are completely unrelated classes -- probably all relationals should return false?
>
>         I guess I was thinking of that as being treated like the NaN cases with
> floats.  They aren't equal and neither one is greater than the other.
> Isn't there a difference between != and <> for floats?

How about throw an exception if they're not comparable?

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


November 30, 2001
Another idea...it might be useful to include some sort of "greatest common class" function.

Object* ptr1,ptr2;
Class foo = greatestCommonClass(ptr1,ptr2);

It could be useful for generics:

Object* ptr1,ptr2;
Class base = greatestCommonClass(ptr1,ptr2);
if( !base.isChildOf(Comparable) )
   throw InvalidClassException("pointer cannot be compared");

if( (base*)ptr1.isLessThan((base*)ptr2) )
   etc...

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


November 30, 2001
Russ Lewis wrote:
> If you think of a class as a set of objects, then the parent is the larger, since it encompasses a larger set and each child class encompasses a subset of the parent set.  That's how I've seen OOP theory taught.
> 
> However, from the view of a programmer, a class is a definition of a set of functionality, and so the child is a larger set.
> 
> I don't see any way to ensure clarity...other than just make a definition.  That's too bad, since I think that these operators are a very Good Idea.  Maybe it's worth the confusion...

	It would have to be an arbitrary rule.  Just pick a semantic model.  I
can live with that.

> > > Also, it's unclear what the right answers are when obj1 and obj2 are completely unrelated classes -- probably all relationals should return false?
> >
> >         I guess I was thinking of that as being treated like the NaN cases with
> > floats.  They aren't equal and neither one is greater than the other.
> > Isn't there a difference between != and <> for floats?
> 
> How about throw an exception if they're not comparable?

	If the test to see if they are not at all related isn't any more
complicated than test for specific relation ships (i.e.. parent of,
child of, same) then I'd hate to burden the operation with an exception
throw.  Are we sure that there will never be a case where someone would
reasonably want to test if two objects are not related?
November 30, 2001
a wrote:

>         If the test to see if they are not at all related isn't any more
> complicated than test for specific relation ships (i.e.. parent of,
> child of, same) then I'd hate to burden the operation with an exception
> throw.  Are we sure that there will never be a case where someone would
> reasonably want to test if two objects are not related?

It's thinking about this that caused me to ponder the greatestCommonClass idea described in my subsequent post.  The test to see if two objects are related could be:

if( greatestCommonClass(ptr1,ptr2) != Object)

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]