February 21, 2006
Fredrik Olsson wrote:
> Sean Kelly skrev:
> 
>> Fredrik Olsson wrote:
>>
>>> After some discussion on #d I though why not put my thoughts into more permanent writing.
>>>
>>> Keyword auto is used for two reasons; implicit type and making sure the object is destroyed when going out of scope. I suggest a new keyword for the latter: local.
>>>
>>> local auto foo = new Bar();
>>
>>
>>
>> If we're moving towards stack-based auto classes then I'd prefer the distinction be associated with the object and not the reference.  ie.
>>
>> auto foo = local Bar();
>>
> I see your point, especially with the object later being replaced. Maybe I am trying to shoot to far By arguing for not focusing on "stack-based" but rather on "destroyed when exiting scope".
> 
> 
>> I think the distinction is important because foo can be reassigned to a non-local object.  Alternately, simply omitting 'new' entirely might be feasible, though the meaning there is less obvious.  As I said in #d:
>>
>> Foo Bar() { return new Foo(); }
>>
>> auto foo = Bar();
>>
>> looks like a stack-based initialization even though it's not.  But perhaps it doesn't matter in this case, as nothing will break if a heap-based instance is used in place of a stack-based instance, it's replacing things the other direction that can cause problems.
>>
> But still I find it could be usefully, especially in a case like this when using a function as a to create the objects. But to solve this I think the distinction should be associated with the assignment, not the variable, nor the object.
> 
> Foo Bar() { return new Foo(); }
> auto foo = local Bar();
> auto baz = local new Baz();
> 
> My point still being; that we should not be so focused on how the technical bits like how and where the object is allocated (on stack or heap), but how it should be handled (local to scope or not). 

I think I agree (although not 100% certain yet)
Think it would be cool if local men't destruct at end of scope no mater is the actual instance created in this function or not.

Stack objects could still be created something like:
auto foo = Foo(); or maybe
auto baz = stack Foo(); or something else

I somehow feel these features might complicate the language a lot.
February 21, 2006
In article <dtf7gr$1sla$1@digitaldaemon.com>, Don Clugston says...
>
>You're saying, abolish finalisers from the language. Radical. But I agree. I have NEVER seen a single good use for a finaliser.

Woohoo! I'd almost given up.

(I have, several times, heard Java or .Net people enthuse about being able to 'resurrect' objects in their finalizers, but needless to say they never seem to supply a reason why you'd want to do something so braindead. One can only stare pityingly.)

>I bet removing finalisers would simplify the gc.

Yes... I was going to mention that, but I wasn't 100% sure and it's kind of tangential to my main motivation, which is to slap people around the face with a large halibut until they realize that GC is not the Second Coming for resource management.

>However, there's still the issue of manual memory management. It would I think be possible to allow RAII classes to be created on the heap with new, and have the destructor called manually with delete.

I'm not convinced that it's worth supporting. As soon as you get into manual destructor calls, you're separating the call from the object's lifetime, at which point I don't consider it a destructor in any useful sense. It's just a function that happens to do resource release, and I think that framing it in those terms would help prevent sloppy thinking. ("But it's a destructor, it can't possibly be called twice!")

>Of course, if RAII classes on the heap are forbidden, it's easy -- the GC then never has to worry about destructors or finalisers, it can just release memory.

That would be my preference in many ways - it's always easier to relax a restriction later than to impose a new one - but if a RAII ref is being assigned from the result of a function call, you don't know the actual type at compile time, which would make stack allocation tricky.

cheers,
Mike


February 21, 2006
Ivan Senji skrev:
> I think I agree (although not 100% certain yet)
> Think it would be cool if local men't destruct at end of scope no mater is the actual instance created in this function or not.
> 
> Stack objects could still be created something like:
> auto foo = Foo(); or maybe
> auto baz = stack Foo(); or something else
> 
> I somehow feel these features might complicate the language a lot.

I better write a summary :), with this my first proposal we really just have four cases:

// Object allways on heap, created from class, gc destroys whenever,
// Object can be passed out of scope
Foo foo = new Foo();

// Object allways on heap, created from another function,
// gc destroys whenever, object can be passed out of scope
Foo foo = Bar();

// Object could be on stack, created from class, scope exit destroys
// imidiately, can not be passed out of scope
Foo foo = local new Foo();

// Object allways on heap, created from another function, scope exit
// destroys imidiately, can not be passed out of scope.
Foo foo = local Bar();

And then auto could be used instead of Foo to declare the type, but that is beyond this discussion, and implied by auto _only_ meaning implicit type and nothing else.

Since objects that are potentially on the stack can not pass out of scope, and if sent as argument to other function they are just pointers anyway, there should be no requirements for changing any ABI.

Only addition is that local object on heap must be destroyed in the process of unwinding an exception. So any scope that uses local objects on heap must have an implicit try {} finally {} for releasing objects.

// Fredrik Olsson
February 21, 2006
++votes;


-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d-pu s+: a-->----- C+++$>++++ UL P+ L+ E--- W++ N++ o? K? w++ !O !M V? PS- PE- Y PGP t 5 X? R tv-- b DI- D+ G e>+++ h>++ !r !y
------END GEEK CODE BLOCK------

Tomasz Stachowiak  /+ a.k.a. h3r3tic +/
February 21, 2006
AgentOrange skrev:
> In article <ops5bhg5ol23k2f5@nrage.netwin.co.nz>, Regan Heath says...
> 
>>On Mon, 20 Feb 2006 21:23:26 +0100, Fredrik Olsson <peylow@gmail.com>  
>> <snip>
>>auto a = new A(); //heap alloc, 'a' is of type reference to 'A'
>>auto a = A();     //stack alloc, destruct at scope exit, 'a' is of type  reference to 'A'
>>
>>Regan
> 
> 
> are we going to lose static opCall? yikes!
> 
And the possibility of allowing non stack objects to automatically go out of scope in the future without changing the syntax? I do not say that it should be added now, all I say is that it would be good if the syntax allowed for it. Ones we go 1.0 much of the syntax will pretty much have to stay, so better be prepared :). A functionality restricted by the compiler is easier to fix and causes less harm than a feature restricted by the syntax.

Plus with: auto a = A();
It is absolutely no way to just at a glance make sure with 100% sertenty that a is not assigned the result of a function, instead of being instantiated on the stack.

// Fredrik
February 21, 2006
Fredrik Olsson wrote:
> Ivan Senji skrev:
> 
>> I think I agree (although not 100% certain yet)
>> Think it would be cool if local men't destruct at end of scope no mater is the actual instance created in this function or not.
>>
>> Stack objects could still be created something like:
>> auto foo = Foo(); or maybe
>> auto baz = stack Foo(); or something else
>>
>> I somehow feel these features might complicate the language a lot.
> 
> 
> I better write a summary :), with this my first proposal we really just have four cases:
> 
> // Object allways on heap, created from class, gc destroys whenever,
> // Object can be passed out of scope
> Foo foo = new Foo();
> 
> // Object allways on heap, created from another function,
> // gc destroys whenever, object can be passed out of scope
> Foo foo = Bar();
> 
> // Object could be on stack, created from class, scope exit destroys

Everything sounds cool, but that *could* part troubles me :)
It should either mean stack, or heap, or have a choise over that.

> // imidiately, can not be passed out of scope
> Foo foo = local new Foo();
> 
> // Object allways on heap, created from another function, scope exit
> // destroys imidiately, can not be passed out of scope.
> Foo foo = local Bar();
> 
> And then auto could be used instead of Foo to declare the type, but that is beyond this discussion, and implied by auto _only_ meaning implicit type and nothing else.
> 
> Since objects that are potentially on the stack can not pass out of scope, and if sent as argument to other function they are just pointers anyway, there should be no requirements for changing any ABI.
> 
> Only addition is that local object on heap must be destroyed in the process of unwinding an exception. So any scope that uses local objects on heap must have an implicit try {} finally {} for releasing objects.
> 
> // Fredrik Olsson
February 21, 2006
Ivan Senji skrev:
> Fredrik Olsson wrote:
> 
>> Ivan Senji skrev:
>> <snip>
>> // Object could be on stack, created from class, scope exit destroys
> 
> 
> Everything sounds cool, but that *could* part troubles me :)
> It should either mean stack, or heap, or have a choise over that.
> 
'Could' always sounds scary, but then again we can not decide if the compiler should inline functions, they *could* all be inlined if the compiler so chooses. The point here is that this case is the most likely for the compiler to be able to do fancy stuff too, so why restrict it? I am sure that 9 of 10 implementations of D would use the stack.

But what if another implementation for some reason or another do not want to go over the trouble to implement stack allocation? Or maybe even finds an even better way to do it, whatever that might be. The important point here is (if I have not completely misunderstood the intentions) to have an object that is destroyed when out of scope with as little overhead as possible. Using the stack for that purpose is good, but forcing, why?

// Fredrik
February 22, 2006
Could auto also be used in class definitions as well as stack finalisaton of objects e.g

class X {

// the object is destroyed automatically when the class X is destroyed.
auto A a = new A();
}

I like the additonal control.  If i've declared an object and i know that the
object is definitely NOT referenced by any other variable i want the semantics
and syntax to reflect that. And any performance gains is useful.
So auto would be used for
- stack scoped objects - either the scope co
- object that are 'children' of the class they are declared and should be
destroyed when the parent is destroyed.

Personally i would like the above use of auto and make gc explicit ie:
gc A a = new A();

And re implicit typing use var as c# 3 does:
var a = new A();


February 22, 2006
Fredrik Olsson wrote:
> AgentOrange skrev:
>> In article <ops5bhg5ol23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>>
>>> On Mon, 20 Feb 2006 21:23:26 +0100, Fredrik Olsson <peylow@gmail.com>  <snip>
>>> auto a = new A(); //heap alloc, 'a' is of type reference to 'A'
>>> auto a = A();     //stack alloc, destruct at scope exit, 'a' is of type  reference to 'A'
>>>
>>> Regan
>>
>>
>> are we going to lose static opCall? yikes!
>>
> And the possibility of allowing non stack objects to automatically go out of scope in the future without changing the syntax? I do not say that it should be added now, all I say is that it would be good if the syntax allowed for it. Ones we go 1.0 much of the syntax will pretty much have to stay, so better be prepared :). A functionality restricted by the compiler is easier to fix and causes less harm than a feature restricted by the syntax.
> 
> Plus with: auto a = A();
> It is absolutely no way to just at a glance make sure with 100% sertenty that a is not assigned the result of a function, instead of being instantiated on the stack.

Does that matter? After all, a constructor is just a function. Clearly a new variable 'a' is being declared, it's type will be the return value of A(), and then A() needs to be called to initialise it.
Or have I missed something?
February 22, 2006
Don Clugston skrev:
> Fredrik Olsson wrote:
>> AgentOrange skrev:
>>> In article <ops5bhg5ol23k2f5@nrage.netwin.co.nz>, Regan Heath says...
<snip>
>> Plus with: auto a = A();
>> It is absolutely no way to just at a glance make sure with 100% sertenty that a is not assigned the result of a function, instead of being instantiated on the stack.
> 
> Does that matter? After all, a constructor is just a function. Clearly a new variable 'a' is being declared, it's type will be the return value of A(), and then A() needs to be called to initialise it.
> Or have I missed something?

Not really. I just like to be able to see with a glance what my code does. I think it is good for productivity, code maintenance, and in general make the programming language look nice.

// Fredrik