Aggregates & associations

Bruce Adams tortoise_74 at yeah.who.co.uk
Tue Dec 18 17:34:31 PST 2007


On Wed, 19 Dec 2007 00:53:43 -0000, Daniel Keep  
<daniel.keep.lists at gmail.com> wrote:

>
> You seem to be getting confused as to how D classes work.  In D, classes
> work like they do in Java: they are *always* references.  That is,
>
>   class Foo {}
>   Foo a;
>
> Here, a is *effectively* a pointer; it is a reference to an instance of
> Foo, just like in Java.
>
Right. I got that.

> If you want to control the layout of memory, you can use a struct.
>
>   struct Foo
>   {
>       int a, b;
>   }
>
>   struct Bar
>   {
>       Foo foo;
>       float x;
>   }
>
>   Bar b;
>
> Here, b is exactly 12 bytes long.  &b.foo.a == &b.foo == &b.  If b is
> declared as a function local, it takes up 12 bytes on the stack; if it's
> declared as part of an aggregate type (like a struct, class or union,)
> then it takes up 12 bytes within an instance of that type.
>
> So, to get back to your original question, you could probably represent
> aggregates as structs and associations with classes.  Note that the only
> one that can represent *both* would be a struct:
>
>   struct Baz
>   {
>       Foo aggregate;
>       Foo* association;
>   }
>
> Currently, this is all a bit of a mess.

Yes it is isn't it.
Why on Earth would any sensible refactoring of C++ include making the same
declaration "Foo aggregate" context dependent on whether its inside a  
struct or a class.
Why did Walter do this when his other refactorings were so sane?
  (Lose two guru points and make a sanity roll)

This is not want I would want as classes and structs are different things.  
An instance of
a class ISA object. A instance of a struct is not an object.

This is also no good because structs have value semantics and classes have  
reference
semantics. Is this why we I see a "ref" keyword popping up occasionally?  
Is it the main
way of making a struct behave like a class?

Is this all for the sake of eliminating -> and &? I'm not sure it was  
worth it.
I can see there is a trade off between:

Foo foo = new foo;

versus

Foo& foo = new Foo;  //this is not D but it could have been

The reference form is the most common usage so you don't want to type the  
extra &.
This makes sense with:

scope Foo foo;

being on (e.g.) the stack.
Though it doesn't obviously mean "I am a value type".


> However, I believe that Walter
> intends to (eventually) introduce scoped class members like so:
>
>   class Foo {}
>
>   class Bar
>   {
>       scope Foo aggregate;
>       Foo association;
>   }
>
> So that when an instance of Bar is destroyed, its 'aggregate' member is
> also destroyed (currently, this is impossible to guarantee if
> 'aggregate' is GC-allocated.)
>
> But that's not really useful at this point.
>
This is useful for defining ownership though it a stretch for the  
definition of scope.
I suppose its better than introducing a new keyword like 'owned' though.

> Hope that helps.
>
> 	-- Daniel

It does but it makes me want to run away from D.

What is really needed is a sensible way of saying "this is a value" versus
"this is a reference" as a qualifier on the type.
In c++ value was the norm and reference was &. So if reference is the norm  
we need
a qualifier that says I am a value.
Its not obvious what the best choice would be. Perhaps * because it is  
conventionally
understood to C/C++ emigrees to mean dereference. So.

class Bar
{
   *Foo aggregateValue;
   Foo association;
}

I think the above syntax is particularly vile and would go for something  
like "val" as the antinym of "ref".
i.e.

class Bar
{
   val Foo aggregateValue;
   Foo association;
}

The same keyword could solve the pass by value problem on functions too.
I like this it means that for every type there is always either a ref or  
val qualifier.  The ref qualifier
is just hidden because its the default.

Have I missed anything?



-- 
Using Opera's revolutionary [NOT!] e-mail client:  
http://www.opera.com/mail/



More information about the Digitalmars-d mailing list