digitalmars.D - Auto syntax revisited
- Fredrik Olsson <peylow gmail.com> Feb 20 2006
- "Derek Parnell" <derek psych.ward> Feb 20 2006
- Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> Feb 20 2006
- Sean Kelly <sean f4.ca> Feb 20 2006
- "Charles" <noone nowhere.com> Feb 20 2006
- Sean Kelly <sean f4.ca> Feb 20 2006
- Mike Capp <mike.capp gmail.com> Feb 20 2006
- Georg Wrede <georg.wrede nospam.org> Feb 20 2006
- Georg Wrede <georg.wrede nospam.org> Feb 21 2006
- Georg Wrede <georg.wrede nospam.org> Feb 21 2006
- Mike Capp <mike.capp gmail.com> Feb 21 2006
- Georg Wrede <georg.wrede nospam.org> Feb 21 2006
- Don Clugston <dac nospam.com.au> Feb 21 2006
- Mike Capp <mike.capp gmail.com> Feb 21 2006
- Georg Wrede <georg.wrede nospam.org> Feb 20 2006
- Fredrik Olsson <peylow gmail.com> Feb 20 2006
- Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> Feb 21 2006
- Fredrik Olsson <peylow gmail.com> Feb 21 2006
- Tom S <h3r3tic remove.mat.uni.torun.pl> Feb 21 2006
- Ivan Senji <ivan.senji_REMOVE_ _THIS__gmail.com> Feb 21 2006
- Fredrik Olsson <peylow gmail.com> Feb 21 2006
- Brad Roberts <braddr puremagic.com> Feb 20 2006
- S. Chancellor <dnewsgr mephit.kicks-ass.org> Feb 20 2006
- James <James_member pathlink.com> Feb 21 2006
- "Regan Heath" <regan netwin.co.nz> Feb 21 2006
- AgentOrange <AgentOrange_member pathlink.com> Feb 21 2006
- Fredrik Olsson <peylow gmail.com> Feb 21 2006
- Don Clugston <dac nospam.com.au> Feb 22 2006
- Fredrik Olsson <peylow treyst.se> Feb 22 2006
- Georg Wrede <georg.wrede nospam.org> Feb 22 2006
- james <james_member pathlink.com> Feb 21 2006
- Georg Wrede <georg.wrede nospam.org> Feb 22 2006
- james <james_member pathlink.com> Feb 22 2006
- Bruno Medeiros <daiphoenixNO SPAMlycos.com> Feb 24 2006
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();
Why? First of auto is only used for the implicit type, so no confusion.
The keyword local in itself describes pretty to the point what is
supposed to happen with the variable. And nothing is said about the
stack, so we are future proof if in the future we would like to also have:
local auto foo = Bar();
Where Bar(); is a function returning an Object, but we still want the
object to be destructed when going out of this scope. The implementation
is quite different as the Object would need to be on heap, but the
syntax is the same. So local would indicate what should be done (destroy
when out of scope), not how it should be done (allocate on stack or
whatever).
Even this could be possible, without syntax changes:
{
local Foo bar;
// some code
Baz(bar); // Jupp Baz have a inout parameter returning an object.
} // And bar is still destroyed if set to something here...
regards
// Fredrik Olsson
Feb 20 2006
On Tue, 21 Feb 2006 07:23:26 +1100, Fredrik Olsson <peylow gmail.com> 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.
Its got my vote. A much better idea that having 'auto' overloaded. -- Derek Parnell Melbourne, Australia
Feb 20 2006
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(); Why? First of auto is only used for the implicit type, so no confusion. The keyword local in itself describes pretty to the point what is supposed to happen with the variable. And nothing is said about the stack, so we are future proof if in the future we would like to also have: local auto foo = Bar(); Where Bar(); is a function returning an Object, but we still want the object to be destructed when going out of this scope. The implementation is quite different as the Object would need to be on heap, but the syntax is the same. So local would indicate what should be done (destroy when out of scope), not how it should be done (allocate on stack or whatever). Even this could be possible, without syntax changes: { local Foo bar; // some code Baz(bar); // Jupp Baz have a inout parameter returning an object. } // And bar is still destroyed if set to something here... regards // Fredrik Olsson
What ever the final syntax/semantics may be, a new keyword is a better solution.
Feb 20 2006
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 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. Sean
Feb 20 2006
auto foo = local Bar();
This gets my vote , but why is everyone using 'auto' ( deduction )keyword here, gets a little confusing since you're trying to replace the other auto with local. ( For people not in on the #d discussion ). MyClass foo = local MyClass("parameters"); yes ? So 'local' replaces 'new' for stack based allocations. "Sean Kelly" <sean f4.ca> wrote in message news:dtdb2e$2lsp$1 digitaldaemon.com...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 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. Sean
Feb 20 2006
Charles wrote:auto foo = local Bar();
This gets my vote , but why is everyone using 'auto' ( deduction )keyword here, gets a little confusing since you're trying to replace the other auto with local. ( For people not in on the #d discussion ).
Just to make things extra confusing :-)MyClass foo = local MyClass("parameters"); yes ? So 'local' replaces 'new' for stack based allocations.
Yes. Sean
Feb 20 2006
In article <dtdb2e$2lsp$1 digitaldaemon.com>, Sean Kelly says...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 think the distinction is important because foo can be reassigned to a non-local object.
Not currently, it can't. From http://www.digitalmars.com/d/attribute.html#auto : "Assignment to an auto, other than initialization, is not allowed." cheers, Mike
Feb 20 2006
Mike Capp wrote:In article <dtdb2e$2lsp$1 digitaldaemon.com>, Sean Kelly says...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 think the distinction is important because foo can be reassigned to a non-local object.
Not currently, it can't. From http://www.digitalmars.com/d/attribute.html#auto : "Assignment to an auto, other than initialization, is not allowed."
If 'local' were implemented, then it could, since then the meaning of 'auto' would only mean auto-typing and not RAII.
Feb 20 2006
Georg Wrede wrote:Mike Capp wrote:In article <dtdb2e$2lsp$1 digitaldaemon.com>, Sean Kelly says...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 think the distinction is important because foo can be reassigned to a non-local object.
Not currently, it can't. From http://www.digitalmars.com/d/attribute.html#auto : "Assignment to an auto, other than initialization, is not allowed."
If 'local' were implemented, then it could, since then the meaning of 'auto' would only mean auto-typing and not RAII.
On second thought, local Bla bla = new Bla(); // RR, heap storage auto bla = new Bla(); // autotyped, heap storage Bla bla = new Bla(); // heap storage local Bla bla = local Bla(); // RR, stack storage auto bla = local Bla(); // autotyped, stack storage, no RR Bla bla = local Bla(); // stack storage, no RR This brings up a few problems. First, the word 'local' is just about as smart as 'auto', i.e. it is misleading and ambiguous for what we're using it for. Second, do we really need this fine of a control over both storage and disposal? For the compiler writer, at first sight, keeping track of RR (RAII) here might look like a lot of work. But it actually is ok: "the variable knows" whether to invoke RR, so RR will be invoked irrespective of who happens to be referenced by it. This may actually open up new ways of using RR? One potential, hard problem is, this decouples RR-ness from the object instance, making it a property of the reference (the variable). This is obviously not in the spirit of why we have RR in the first place. ---- Unless we can sort out what we want here, I think the current state of RR is adequate -- _except_ that I want another word substituted for 'auto'! We can't have it mean "autotype and/or RAII", at the same time. That is just too much of a disgrace.
Feb 21 2006
Georg Wrede wrote:Georg Wrede wrote:Mike Capp wrote:Sean Kelly says...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 think the distinction is important because foo can be reassigned to a non-local object.
Not currently, it can't. From http://www.digitalmars.com/d/attribute.html#auto : "Assignment to an auto, other than initialization, is not allowed."
Currently (D.144) it _is_ allowed. (Obviously a bug.)If 'local' were implemented, then it could, since then the meaning of 'auto' would only mean auto-typing and not RAII.
On second thought, local Bla bla = new Bla(); // RR, heap storage auto bla = new Bla(); // autotyped, heap storage Bla bla = new Bla(); // heap storage local Bla bla = local Bla(); // RR, stack storage auto bla = local Bla(); // autotyped, stack storage, no RR Bla bla = local Bla(); // stack storage, no RR
Reordering the lines above might make it clearer: local Bla bla = new Bla(); // RR, heap storage local Bla bla = local Bla(); // RR, stack storage auto bla = new Bla(); // autotyped, heap storage auto bla = local Bla(); // autotyped, stack storage, no RR Bla bla = new Bla(); // heap storage Bla bla = local Bla(); // stack storage, no RR and consequently also: local auto bla = new Bla(); // RR, autotyped, heap storage local auto bla = local Bla(); // RR, autotyped, stack storageThis brings up a few problems. First, the word 'local' is just about as smart as 'auto', i.e. it is misleading and ambiguous for what we're using it for. Second, do we really need this fine of a control over both storage and disposal? For the compiler writer, at first sight, keeping track of RR (RAII) here might look like a lot of work. But it actually is ok: "the variable knows" whether to invoke RR, so RR will be invoked irrespective of who happens to be referenced by it. This may actually open up new ways of using RR?
Sigh, shouldn't try to think before noon:One potential, hard problem is, this decouples RR-ness from the object instance, making it a property of the reference (the variable). This is obviously not in the spirit of why we have RR in the first place.
Ok, RR-ness can be coupled with - the reference - the assignment - the instance - the class Of these, I'd see that instance and class should be made equivalent, since it would be clearer to have separate classes (one requiring RR and the other not) for purposes where _sometimes_ the instance absolutely needs to be RR only. (As opposed to storing knowledge of such a need in an instance variable.) Currently (D.144) couples RR-ness with the reference. Which is sort of ok, *except* for the fact that one now can assign (e.g.) a global instance to the reference, thus (probably inadvertently) marking it for impending destruction. One can also assign an instance created as RR to (e.g.) a global variable, and then get surprised at the later occurring access violation because the instance got destroyed, even if other references to it exist. Coupling RR-ness with the assignment is an intriguing alternative. This has the possibility of creating really robust code. Then the compiler could prevent other assignments to the reference, and it could prevent assignment of the instance to any variable with a longer scope than the original reference.---- Unless we can sort out what we want here, I think the current state of RR is adequate -- _except_ that I want another word substituted for 'auto'! We can't have it mean "autotype and/or RAII", at the same time. That is just too much of a disgrace.
To summarize: It would be handy to have a class that _requires_ RR instantiation. It would also be handy if RR is with the assignment. (That is, forcefully welding the reference and the instance together.)
Feb 21 2006
In article <43FAF3AC.2080609 nospam.org>, Georg Wrede says...I want another word substituted for 'auto'! We can't have it mean "autotype and/or RAII", at the same time. That is just too much of a disgrace.
Amen.To summarize: It would be handy to have a class that _requires_ RR instantiation.
And it's not that big a leap. Currently I believe you can declare a class "auto" to force all instances to be auto; you'd just have to beef up this rule to say that ONLY instances of auto classes can be declared auto. This is probably going to get me chased out of town with torches and pitchforks, but I'd actually like to go one step further and rule that ONLY auto classes can define destructors. The thinking being that if you care enough about a managed resource to write a destructor to release it, you almost certainly want that destructor called deterministically. Relying on the garbage collector to call it for you in a timely fashion is almost certainly setting you up for a nasty surprise. Far too many people still seem to think that GC is a panacea for resource management generally, not just memory management, and until they're jolted out of that I don't have much hope for D's RAII support improving. (Incidentally, what's with this "RR"??? I've never seen it before in 10 years of writing C++. If you mean RAII, it's probably less confusing to the reader to say RAII, however silly an acronym it might be.) cheers, Mike
Feb 21 2006
Mike Capp wrote:Georg Wrede says...I want another word substituted for 'auto'! We can't have it mean "autotype and/or RAII", at the same time. That is just too much of a disgrace.
Amen.To summarize: It would be handy to have a class that _requires_ RR instantiation.
And it's not that big a leap. Currently I believe you can declare a class "auto" to force all instances to be auto; you'd just have to beef up this rule to say that ONLY instances of auto classes can be declared auto.
How about file descriptors and the like? I think there's a lot of stuff that will sometimes be "auto" and sometimes not. It all depends on the local needs in code. Opening a socket in a function call, and passing its reference around while communicating, is an example of where auto would be cumbersome. Then again, another program that opens many sockets for a short while each, might really benefit from a guaranteed short lived socket.This is probably going to get me chased out of town with torches and pitchforks, but I'd actually like to go one step further and rule that ONLY auto classes can define destructors.
Hmm. This I find a lot more attractive.The thinking being that if you care enough about a managed resource to write a destructor to release it, you almost certainly want that destructor called deterministically. Relying on the garbage collector to call it for you in a timely fashion is almost certainly setting you up for a nasty surprise. Far too many people still seem to think that GC is a panacea for resource management generally, not just memory management, and until they're jolted out of that I don't have much hope for D's RAII support improving.
Maybe we should solicit for counter examples? If none are found, then we probably should implement this.(Incidentally, what's with this "RR"??? I've never seen it before in 10 years of writing C++. If you mean RAII, it's probably less confusing to the reader to say RAII, however silly an acronym it might be.)
Depends on the reader. ;-) Check out digitalmars.D:32289.
Feb 21 2006
Mike Capp wrote:In article <43FAF3AC.2080609 nospam.org>, Georg Wrede says...I want another word substituted for 'auto'! We can't have it mean "autotype and/or RAII", at the same time. That is just too much of a disgrace.
Amen.To summarize: It would be handy to have a class that _requires_ RR instantiation.
And it's not that big a leap. Currently I believe you can declare a class "auto" to force all instances to be auto; you'd just have to beef up this rule to say that ONLY instances of auto classes can be declared auto. This is probably going to get me chased out of town with torches and pitchforks, but I'd actually like to go one step further and rule that ONLY auto classes can define destructors. The thinking being that if you care enough about a managed resource to write a destructor to release it, you almost certainly want that destructor called deterministically.
You're saying, abolish finalisers from the language. Radical. But I agree. I have NEVER seen a single good use for a finaliser. I've only ever seen them used as "poor man's destructors". But I'll change my mind if anyone can show a use for them. Any takers? I bet removing finalisers would simplify the gc. 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. Whenever the gc runs, if it finds that it is able to collect an object which has a destructor, instead of calling it as a finaliser, it should assert -- a memory leak bug has been found. Alternatively, you could just use the C++ method and and perform the check only at the end of the program. (But it would be cool to have a function checkForMemoryLeaks() which could be run at any time, for anyone who still wants to use manual memory management. By using mark-and-sweep, you can detect a memory leak much earlier than in C/C++). 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. Relying on the garbage collector to call itfor you in a timely fashion is almost certainly setting you up for a nasty surprise. Far too many people still seem to think that GC is a panacea for resource management generally, not just memory management, and until they're jolted out of that I don't have much hope for D's RAII support improving.
Agreed. > (Incidentally, what's with this "RR"??? I've never seen it before in 10 years ofwriting C++. If you mean RAII, it's probably less confusing to the reader to say RAII, however silly an acronym it might be.)
You could think of RAII as "Release At Imminent Incineration" <g> Or come up with a better interpretation of the letters.cheers, Mike
Feb 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
Feb 21 2006
Sean Kelly wrote: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 think the distinction is important because foo can be reassigned to a non-local object.
Bull's eye! Funny that nobody thought of this before.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.
In general, it's much harder to spot something is missing than to spot the wrong thing. So, I definitely vote for the keyword 'local' for stack storage. Besides, that's what it means in other languages, too. Much cleaner: new allocates on heap, local on stack.
Feb 20 2006
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 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.
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). If the spec does not specify how things should be done, then the implementation is more free to choose what is best for every case, even if the cases may vary as even more new features are added later on (Hopefully without more syntax revisions). regards // Fredrik
Feb 20 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 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.
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.
Feb 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
Feb 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 +/
Feb 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
Feb 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.
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
Feb 21 2006
On Tue, 21 Feb 2006, Fredrik Olsson wrote: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). If the spec does not specify how things should be done, then the implementation is more free to choose what is best for every case, even if the cases may vary as even more new features are added later on (Hopefully without more syntax revisions). regards // Fredrik
I want to focus on the point. I have to strongly disagree, this sort of thing is what affects ABI's. If there's a desire to support more than one D compiler, this sort of thing can't be left ambiguous as it would make cross compiler compatibility a nightmare. A .o/.a/.so generated via dmd would have to successfully link with objects/archives/shared libraries created via other compilers. That means they'd have to behave the same with respect to anything that leaks out of a compilation unit. Aspects of this discussion might stay local enough to remain unspecified, if semantics leak outside of a single function, then it needs to be well defined. Later, Brad
Feb 20 2006
While I agree with your sentiment. However, I think local associated with the reference is confusing as it leads people to believe it is somehow different from "global." (See Python's usage of these keywords) This would make much more sense associated with the object, like Sean kelly mentioned. However, there is still problems with that. While we're coming to a consensus on these things, let us fix the reuse of static, and the !is keyword as well. -S. On 2006-02-20 12:23:26 -0800, Fredrik Olsson <peylow gmail.com> said: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(); Why? First of auto is only used for the implicit type, so no confusion. The keyword local in itself describes pretty to the point what is supposed to happen with the variable. And nothing is said about the stack, so we are future proof if in the future we would like to also have: local auto foo = Bar(); Where Bar(); is a function returning an Object, but we still want the object to be destructed when going out of this scope. The implementation is quite different as the Object would need to be on heap, but the syntax is the same. So local would indicate what should be done (destroy when out of scope), not how it should be done (allocate on stack or whatever). Even this could be possible, without syntax changes: { local Foo bar; // some code Baz(bar); // Jupp Baz have a inout parameter returning an object. } // And bar is still destroyed if set to something here... regards // Fredrik Olsson
Feb 20 2006
Re auto for implicit typing. I dont know if C# 3.0 seems to be going in the same direction - but with a different keyword. From Language Spec at http://msdn.microsoft.com/vcsharp/future/default.aspx Implicitly typed local variables In an implicitly typed local variable declaration, the type of the local variable being declared is inferred from the expression used to initialize the variable. When a local variable declaration specifies var as the type and no type named var is in scope, the declaration is an implicitly typed local variable declaration. For example: var i = 5; var s = "Hello"; var d = 1.0; var numbers = new int[] {1, 2, 3}; var orders = new Dictionary<int,Order>(); The implicitly typed local variable declarations above are precisely equivalent to the following explicitly typed declarations: int i = 5; string s = "Hello"; double d = 1.0; int[] numbers = new int[] {1, 2, 3}; Dictionary<int,Order> orders = new Dictionary<int,Order>(); A local variable declarator in an implicitly typed local variable declaration is subject to the following restrictions: The declarator must include an initializer. The initializer must be an expression. The initializer cannot be an object or collection initializer (§26.4) by itself, but it can be a new expression that includes an object or collection initializer. The compile-time type of the initializer expression cannot be the null type. If the local variable declaration includes multiple declarators, the initializers must all have the same compile-time type. The following are examples of incorrect implicitly typed local variable declarations: var x; // Error, no initializer to infer type from var y = {1, 2, 3}; // Error, collection initializer not permitted var z = null; // Error, null type not permitted ~~~~~~~~~~~ Sometimes i think it would be useful to take mono's c# front end and put it on gcc and make it a compiled language. With the additional of auto for stack based deterministic finalisation for objects.
Feb 21 2006
On Mon, 20 Feb 2006 21:23:26 +0100, Fredrik Olsson <peylow gmail.com> 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(); Why? First of auto is only used for the implicit type, so no confusion. The keyword local in itself describes pretty to the point what is supposed to happen with the variable. And nothing is said about the stack, so we are future proof if in the future we would like to also have: local auto foo = Bar(); Where Bar(); is a function returning an Object, but we still want the object to be destructed when going out of this scope. The implementation is quite different as the Object would need to be on heap, but the syntax is the same. So local would indicate what should be done (destroy when out of scope), not how it should be done (allocate on stack or whatever). Even this could be possible, without syntax changes: { local Foo bar; // some code Baz(bar); // Jupp Baz have a inout parameter returning an object. } // And bar is still destroyed if set to something here...
I thought the plan was to deprecate "auto" WRT declaring stack based auto destructed class instances, resulting in: class A {} A a = new A(); //heap alloc A a = A(); //stack alloc, destruct at scope exit So, "auto" would only mean "automatic type determination": 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
Feb 21 2006
In article <ops5bhg5ol23k2f5 nrage.netwin.co.nz>, Regan Heath says...On Mon, 20 Feb 2006 21:23:26 +0100, Fredrik Olsson <peylow gmail.com> 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(); Why? First of auto is only used for the implicit type, so no confusion. The keyword local in itself describes pretty to the point what is supposed to happen with the variable. And nothing is said about the stack, so we are future proof if in the future we would like to also have: local auto foo = Bar(); Where Bar(); is a function returning an Object, but we still want the object to be destructed when going out of this scope. The implementation is quite different as the Object would need to be on heap, but the syntax is the same. So local would indicate what should be done (destroy when out of scope), not how it should be done (allocate on stack or whatever). Even this could be possible, without syntax changes: { local Foo bar; // some code Baz(bar); // Jupp Baz have a inout parameter returning an object. } // And bar is still destroyed if set to something here...
I thought the plan was to deprecate "auto" WRT declaring stack based auto destructed class instances, resulting in: class A {} A a = new A(); //heap alloc A a = A(); //stack alloc, destruct at scope exit So, "auto" would only mean "automatic type determination": 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!
Feb 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!
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
Feb 21 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!
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?
Feb 22 2006
Don Clugston skrev:Fredrik Olsson wrote:AgentOrange skrev:In article <ops5bhg5ol23k2f5 nrage.netwin.co.nz>, Regan Heath says...
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
Feb 22 2006
Fredrik Olsson wrote:And the possibility of allowing non stack objects to automatically go out of scope in the future without changing the syntax?
This is important. For the destruction itself, it makes no difference whether an object is on the stack or on the heap. A programmer might have an opinion on where to initially store the object, but that has to do with issues like heap fragmentation, or whatever else except destruction details.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.
True!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.
Yes. And even more important, it should be obvious and stand out to the human reader -- or else debugging becomes a pain. That is, if the programmer has an opinion on where the object should be, then that opinion should stand out. If he doesn't care, then that should be the simplest syntax. Likewise, and /separately/ from that, it should be equally obvious if the programmer wanted it to be a scoped object. But if he didn't, then it does _not_ have to stand out (i.e. use normal syntax here), since the default has always been to not force immediate destruction.
Feb 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();
Feb 21 2006
james wrote: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(); }
(You mean _instance_ above, right? Classes don't get destroyed.)Personally i would like the above use of auto and make gc explicit ie: gc A a = new A();
GC has nothing to do with this. If a programmer wants an object destroyed immediately after going out of scope (by whatever mechanism it may eventually happen), then this applies to GC collected programs as well as non-GC-collected. (e.g. C++)
Feb 22 2006
In article <43FC743C.9090601 nospam.org>, Georg Wrede says...james wrote: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(); }
(You mean _instance_ above, right? Classes don't get destroyed.)
Personally i would like the above use of auto and make gc explicit ie: gc A a = new A();
GC has nothing to do with this. If a programmer wants an object destroyed immediately after going out of scope (by whatever mechanism it may eventually happen), then this applies to GC collected programs as well as non-GC-collected. (e.g. C++)
programmer has over object creation/destruction and memory management. Programmers who like auto are probably less keen on gc. And maybe would prefer it as optional rather than by default. Though technically auto and gc are not related.
Feb 22 2006
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.
Regardless of semantic changes (as a semantic change in auto-RAII might make it work without keyword), I wish for: auto for auto-RAII var for auto-type Why these names? Auto-RAII implies an action in run-time, whereas auto-type is a compile-time only action, with no run-time effects. The name 'auto' sounds more action-like than 'var', so it fits better being assigned to auto-RAII. Also, 'var' is shorter than 'auto', with only three letters, which is also nice, since auto-type is mainly a syntactic sugar feature, so with 'var' it is one less character to type. I wonder what Walter's plans for this are. It's been a while since this ambiguity was introduced and news on this have come. -- Bruno Medeiros - CS/E student "Certain aspects of D are a pathway to many abilities some consider to be... unnatural."
Feb 24 2006









"Derek Parnell" <derek psych.ward> 