[Dynamite] another us trip...

Ian Holmes ihh@fruitfly.org
Mon, 10 Apr 2000 14:10:54 -0700 (PDT)


On Mon, 10 Apr 2000, Guy Slater wrote:

> > So I will take responsibility for doing the changes. If anyone really
> > can't stand the idea of using an IDL-to-C mapping that is changing under
> > their feet in this way, then speak up now.
> 
> I reckon this is going to be unavoidable,
> and I don't think it'll be too much of a problem,
> so long as we still have corresponding IDL at the end,

OK.

> > We *could* wait until I change
> > idlstubs, but again, it is an undesirable bottleneck.
> > Alternatively, we could just stick with the "has-a" model.
> > (If anyone needs a review of our inheritance-model discussion then
> > speak up; I'm assuming no-one does, cos I'm lazy and I hate typing.)
> 
> Hate typing ?  Nah.

Seriously, my knuckle joints are starting to form their own union.

> I was just coming round to has-a.
> Didn't you (ian) say is-a would barf with multiple inheritance ?

I came up with a trick to avoid this. Haven't tested it yet but it goes
like this:

Suppose you have IDL interface "Lemur", derived from IDL interface
"Mammal", i.e.

	interface Mammal { attribute float size; }
	interface Lemur : Mammal { attribute float furriness; }

Then the C goes like this:

	typedef struct tgMammal_str* tgMammal;
	typedef struct tgLemur_str* tgLemur;

	struct tgMammal_str {
		/* internal Euclid data members for Mammal go here */
		float size;
		/* private user data members for Mammal go here */
	};

	struct tgLemur_str {
		tgMammal_str mammal;
		/* internal Euclid data members for Lemur go here */
		float furriness;
		/* private user data members for Mammal go here */
	};

So then I think the offset of inherited_Mammal_str within Lemur_str is
zero, so you can cast a (Lemur_str*) to a (Mammal_str*) and use the same
methods on it.

> 
> What are the pros and cons ?

The original pro of "has-a", for me, was that it required *minimal* effort
on the part of the idlstubs compiler, because when the parser encountered
a derived interface, it didn't have to go and look up the base interface
to find out what methods it needed to provide for the derived interface.
Not a hugely difficult thing to add to the compiler, and I want to do it
anyway at some point.

With the "is-a" model I just described above, I don't think you need to
know anything about the base class either, so this may not be a pro OR a
con anymore.

Compare ways of accessing the base class for the two models - NB "is-a"
gives you two ways of doing it (the cast way is the GTK way):

(has-a)
	Lemur lemur;
	float my_size = lemur->mammal->size;  /* indirection */

(is-a)
	Lemur lemur;
	float my_size = ((tgMammal) lemur) -> size;   /* cast */
	float my_size_alternate = (*lemur).mammal.size;   /* indirection */

I think "is-a" is better.
NB "X is-a Y"  == "X_str contains Y_str as its first member"
   "X has-a Y" == "X_str contains a pointer to Y_str"

I don't know enough about ANSI struct padding to fully bless "is-a", but
it seems OK.

Ian

> --
> 
> 
> _______________________________________________
> Dynamite mailing list  -  Dynamite@bioperl.org
> http://www.bioperl.org/mailman/listinfo/dynamite
>