December 19, 2007
Bruce Adams wrote:
> On Wed, 19 Dec 2007 15:11:46 -0000, Jason House <jason.james.house@gmail.com> wrote:
> 
>> Steven Schveighoffer Wrote:
>>
>>> "Sean Kelly" wrote
>>> >A long time ago Walter mentioned that the "scope" attribute may be 
>>> extended
>>> >to indicate aggregation:
>>> >
>>> >     class Foo
>>> >     {
>>> >         Bar valA;
>>> >         scope Baz val2;
>>> >     }
>>> >
>>> > With the above, the size of Foo would be expanded to contain an 
>>> instance
>>> > of Baz and val2 would be initialized to reference this memory, very 
>>> much
>>> > like "scope" works in functions now.  But I didn't see any mention 
>>> of this
>>> > in the D 2.0 writeup so the idea may have been either discarded or
>>> > forgotten.
>>>
>>> I believe this type of behavior is not necessary.  Whether a member is an
>>> aggregate or an association, it will be deleted when nothing references it
>>> anymore, which is when it should be deleted.  The only thing this proposed
>>> behavior can do is cause segfaults when something that still has a reference
>>> to a scoped member tries to use it.
>>
>> It has more value that that.  It's easy for me to imagine a scope class that includes one or more scope classes (such as a wrapper around an RAII object)
> 
> Also failing early can be a good thing. Attempting to use an associated object that
> is not valid is an error. Just because you have not released the memory for it
> does not make it valid. You program could give the illusion of working for a bit
> and then die mysteriously.
> The ability to delete deterministically as an optimisation could make programs more
> efficient too. You might even be able to simplify collection sweeps or switch them off
> temporarily without compromising performance.

Interestingly, if objects are constructed inside the memory reserved for other objects, then if one is collected by the GC it must be true that all other objects in the same block are free as well.  Also, since they share memory, all the objects can safely refer to one another in their dtors so long as they are careful to avoid using member data that may already have been released.  As you say, this promises to offer some interesting possibilities for composite objects.


Sean
December 19, 2007
Steven Schveighoffer wrote:
> "Sean Kelly" wrote
>> A long time ago Walter mentioned that the "scope" attribute may be extended to indicate aggregation:
>>
>>     class Foo
>>     {
>>         Bar valA;
>>         scope Baz val2;
>>     }
>>
>> With the above, the size of Foo would be expanded to contain an instance of Baz and val2 would be initialized to reference this memory, very much like "scope" works in functions now.  But I didn't see any mention of this in the D 2.0 writeup so the idea may have been either discarded or forgotten.
> 
> I believe this type of behavior is not necessary.  Whether a member is an aggregate or an association, it will be deleted when nothing references it anymore, which is when it should be deleted.  The only thing this proposed behavior can do is cause segfaults when something that still has a reference to a scoped member tries to use it.
> 
> -Steve 

I think the desired behavior is this:
1. Any object can have zero or one owners.
2. Any object that has an owner is collected and has its destructor called after its owner is collected and has its destructor called.
3. As an exception to (2), if an object's owner has no reference to it, the object can be collected.
December 20, 2007
On Wed, 19 Dec 2007 20:41:58 -0000, Sean Kelly <sean@f4.ca> wrote:

> Bruce Adams wrote:
>> On Wed, 19 Dec 2007 15:11:46 -0000, Jason House <jason.james.house@gmail.com> wrote:
>>
>>> Steven Schveighoffer Wrote:
>>>
>>>> "Sean Kelly" wrote
>>>> >A long time ago Walter mentioned that the "scope" attribute may be  
>>>> extended
>>>> >to indicate aggregation:
>>>> >
>>>> >     class Foo
>>>> >     {
>>>> >         Bar valA;
>>>> >         scope Baz val2;
>>>> >     }
>>>> >
>>>> > With the above, the size of Foo would be expanded to contain an  
>>>> instance
>>>> > of Baz and val2 would be initialized to reference this memory, very  
>>>> much
>>>> > like "scope" works in functions now.  But I didn't see any mention  
>>>> of this
>>>> > in the D 2.0 writeup so the idea may have been either discarded or
>>>> > forgotten.
>>>>
>>>> I believe this type of behavior is not necessary.  Whether a member is an
>>>> aggregate or an association, it will be deleted when nothing references it
>>>> anymore, which is when it should be deleted.  The only thing this proposed
>>>> behavior can do is cause segfaults when something that still has a reference
>>>> to a scoped member tries to use it.
>>>
>>> It has more value that that.  It's easy for me to imagine a scope class that includes one or more scope classes (such as a wrapper around an RAII object)
>>  Also failing early can be a good thing. Attempting to use an associated object that
>> is not valid is an error. Just because you have not released the memory for it
>> does not make it valid. You program could give the illusion of working for a bit
>> and then die mysteriously.
>> The ability to delete deterministically as an optimisation could make programs more
>> efficient too. You might even be able to simplify collection sweeps or switch them off
>> temporarily without compromising performance.
>
> Interestingly, if objects are constructed inside the memory reserved for other objects, then if one is collected by the GC it must be true that all other objects in the same block are free as well.  Also, since they share memory, all the objects can safely refer to one another in their dtors so long as they are careful to avoid using member data that may already have been released.  As you say, this promises to offer some interesting possibilities for composite objects.
>
>
> Sean

Except that at present there's no way to declare that an object is contained in
another object except as a struct and a struct is not an object. I don't think
scope would do this and if it did it would be ahem beyond its scope to do so.
December 20, 2007
Bruce Adams wrote:
> On Wed, 19 Dec 2007 20:41:58 -0000, Sean Kelly <sean@f4.ca> wrote:
>>
>> Interestingly, if objects are constructed inside the memory reserved for other objects, then if one is collected by the GC it must be true that all other objects in the same block are free as well.  Also, since they share memory, all the objects can safely refer to one another in their dtors so long as they are careful to avoid using member data that may already have been released.  As you say, this promises to offer some interesting possibilities for composite objects.
> 
> Except that at present there's no way to declare that an object is contained in
> another object except as a struct and a struct is not an object. I don't think
> scope would do this and if it did it would be ahem beyond its scope to do so.

Why?  It works this way for class variables declared elsewhere.  As a QOI feature, but still...


Sean
December 20, 2007
On Thu, 20 Dec 2007 00:49:05 -0000, Sean Kelly <sean@f4.ca> wrote:

> Bruce Adams wrote:
>> On Wed, 19 Dec 2007 20:41:58 -0000, Sean Kelly <sean@f4.ca> wrote:
>>>
>>> Interestingly, if objects are constructed inside the memory reserved for other objects, then if one is collected by the GC it must be true that all other objects in the same block are free as well.  Also, since they share memory, all the objects can safely refer to one another in their dtors so long as they are careful to avoid using member data that may already have been released.  As you say, this promises to offer some interesting possibilities for composite objects.
>>  Except that at present there's no way to declare that an object is contained in
>> another object except as a struct and a struct is not an object. I don't think
>> scope would do this and if it did it would be ahem beyond its scope to do so.
>
> Why?  It works this way for class variables declared elsewhere.  As a QOI feature, but still...
>
>
> Sean

Sorry I should have qualified that. Scope as I understand it, declares whether
a variable should be deleted or it. i.e. whether it is owned by the current scope,
which in the proposed extension would mean class scope. It does not say anything
about the memory layout. Whether the object is a value or reference is still up
for grabs. It doesn't usually matter in functions but in a class it does, at least
as an optimisation.
I think something like the "val" syntax would make this kind of optimisation possible
as well as solving the pass by value, pass by reference optimisation problem.

Bruce.
December 20, 2007
"Bruce Adams" <tortoise_74@yeah.who.co.uk> wrote in message news:op.t3mssesyxikks4@lionheart.cybernetics...

> Sorry I should have qualified that. Scope as I understand it, declares
> whether
> a variable should be deleted or it. i.e. whether it is owned by the
> current scope,
> which in the proposed extension would mean class scope. It does not say
> anything
> about the memory layout. Whether the object is a value or reference is
> still up
> for grabs. It doesn't usually matter in functions but in a class it does,
> at least
> as an optimisation.

See, it's an optimization.  Guess who should be doing optimizations?  Hint: it's not the programmer.  I'd place manual specification of whether a scope class is allocated inline the body of its owning class or function in the same category as "inline" and "register" -- ultimately meaningless hints to the compiler to do something that it can figure out better than you can. Chances are if we got scope class references in classes they _would_ be inlined into the owning class's body, if for no other reason than the principle of least surprise -- it already happens in functions -- and also because, well, it's a good optimization.

This is why C++ is complex.  It gives you all these possibilities and features, but leaves it up to you to make something useful out of them.  D tries to give you useful _semantic_ features whose semantics leave room for optimization, freeing you from dealing with the low-level crap that C++ makes you deal with.  I don't want D to go to the way C++ does it.


December 20, 2007
"Sean Kelly" wrote
> Steven Schveighoffer wrote:
>> "Sean Kelly" wrote
>>> A long time ago Walter mentioned that the "scope" attribute may be extended to indicate aggregation:
>>>
>>>     class Foo
>>>     {
>>>         Bar valA;
>>>         scope Baz val2;
>>>     }
>>>
>>> With the above, the size of Foo would be expanded to contain an instance of Baz and val2 would be initialized to reference this memory, very much like "scope" works in functions now.  But I didn't see any mention of this in the D 2.0 writeup so the idea may have been either discarded or forgotten.
>>
>> I believe this type of behavior is not necessary.  Whether a member is an aggregate or an association, it will be deleted when nothing references it anymore, which is when it should be deleted.  The only thing this proposed behavior can do is cause segfaults when something that still has a reference to a scoped member tries to use it.
>
> You're right that it's not necessary.  The GC is supposed to take care of this for you.  But constructing complex aggregates can be quite expensive in terms of GC use, as a separate allocation must be made for every object.  This can also reduce locality of the objects are of different sizes, which may affect performance by incurring cache misses. Now, it is possible in D 2.0 to get the size of an object and reserve space for it using a static array, but this requires the use of placement new, which requires yet more fancy template code to bolt onto existing classes, etc. So this is certainly possible, but far messier than in C++.  And it's really a fairly common design requirement.

I didn't quite understand your original post, thanks for explaining it further.

-Steve


December 21, 2007
On Thu, 20 Dec 2007 14:38:40 -0000, Jarrett Billingsley <kb3ctd2@yahoo.com> wrote:

> "Bruce Adams" <tortoise_74@yeah.who.co.uk> wrote in message
> news:op.t3mssesyxikks4@lionheart.cybernetics...
>
>> Sorry I should have qualified that. Scope as I understand it, declares
>> whether
>> a variable should be deleted or it. i.e. whether it is owned by the
>> current scope,
>> which in the proposed extension would mean class scope. It does not say
>> anything
>> about the memory layout. Whether the object is a value or reference is
>> still up
>> for grabs. It doesn't usually matter in functions but in a class it does,
>> at least
>> as an optimisation.
>
> See, it's an optimization.  Guess who should be doing optimizations?  Hint:
> it's not the programmer.  I'd place manual specification of whether a scope
> class is allocated inline the body of its owning class or function in the
> same category as "inline" and "register" -- ultimately meaningless hints to
> the compiler to do something that it can figure out better than you can.
> Chances are if we got scope class references in classes they _would_ be
> inlined into the owning class's body, if for no other reason than the
> principle of least surprise -- it already happens in functions -- and also
> because, well, it's a good optimization.
>
> This is why C++ is complex.  It gives you all these possibilities and
> features, but leaves it up to you to make something useful out of them.  D
> tries to give you useful _semantic_ features whose semantics leave room for
> optimization, freeing you from dealing with the low-level crap that C++
> makes you deal with.  I don't want D to go to the way C++ does it.
>
Its not quite as simple as that. What needs to be optimised depends on how the program is
used. The compiler cannot know that unless you add some pretty strong AI (or
at least a way to feedback profiling results to your compiler). This is why
inlining is still occasionally useful in C++, not because of bad language design.
December 23, 2007
On Tue, 18 Dec 2007, Jarrett Billingsley wrote:

> (side note: absolutely _everyone_ who uses Opera as their newsreader, their
> posts don't quote correctly in OE...)

And OE doesn't specify the message encoding. Well luckily there's rarely non-ASCII discussion here.
1 2
Next ›   Last »