September 06, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Robert Atkinson | Robert Atkinson wrote:
> I believe that if we keep the auto/auto syntax, it will be a feature that everyone will love at first, but years from now it'll be the feature that we'll be cursing when we all have to maintain code. Scanning code quickly its hard to determine with the current auto/auto syntax if its RAII or auto typing.
Auto/auto will be ridiculed by those never aiming to switch to D. It will cause havoc when teaching the language. And it will embarrass each of us later when folks ask "weren't you in the D community? How come you didn't get rid of that thing already pre 1.0??"
Having things that look alike be different (and while I'm at it, also things that look different be the same), is something that belongs to wicked computer games, or stupid job admission tests.
Distinct concepts have to have distinct names. Clarity is the word.
| |||
September 06, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jeff | Agreed, this overload of the meaning of 'auto' has made me uncomfortable since it was introduced. It needlessly complicates things.
Jeff wrote:
> +1 :)
>
> I'm terrified of 'auto auto' making it into 1.0; it just -screams- "ugly and confusing" to me.
| |||
September 06, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | I wasn't aware of that, pretty cool! In this case, perhaps do away with the old local-scope meaning of 'auto' altogether.
Chris Nicholson-Sauls wrote:
>
> The following works right now, and does so just fine:
> Foo foo = SomeFactory.newFoo(...); scope(exit) delete foo;
> char[] a = read(filename); scope(exit) delete a;
>
> -- Chris Nicholson-Sauls
| |||
September 06, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | I'd like to note some problems that all of these approaches face.
Jarrett Billingsley wrote:
>
> Foo f = stack Foo();
Jarrett's proposed 'stack' allocation specifier is interesting in that it seems to indicate that the object currently referenced by f will be deleted even if a later line of code does something ugly like this:
f = stack Foo(); // assign a different Foo to f
Now both Foo objects will be *deallocated* as the stack unwinds, but it is not clear whether the destructor can be called on the unreferenced Foo, unless it is called during the reassignment process.
Alternatively, either of these current implementations happily leaves one Foo object dangling on the heap:
auto Foo g = new Foo();
g = new Foo(); // drops reference to original Foo
Foo g = new Foo(); scope(exit) delete g;
g = new Foo(); // drops reference to original Foo
How does the GC maintain these dropped references? This seems like an easy bug to insert, and potentially a difficult one to find.
It is unfortunate that true stack object instances do not exist in D. The 'stack' syntax defies D's current heap-only object allocation philosophy.
Another advantage of C++ style stack object instances is the ability to overload the assignment operator, which allows an object instance to be treated as a built-in type. You can't do this in D because it would alias your ability to reassign the object reference to another object. C++ has no problem implementing real and imaginary numbers as classes, they need not be built-in types since their instances can be treated as such syntactically.
I don't understand why modern high-level languages are so quick to discard (or bias against) the pointer. The distinction between object references/pointers and object instances is very valuable in C++. It can be nice to know that no other code is going to reassign another object to your variable.
Pissing in the wind,
Garett
| |||
September 07, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> BTW, I'm not wedded to 'local' but something, ... anything, that explicitly
> informs the reader that the object will be destroyed when it goes out of
> scope is needed. Leaving it out is not a good user interface.
Why? It's implicit in C style programming languages that things disappear when they go out of scope. It's the original meaning of 'auto' in C and C++, it's also the default behavior.
| |||
September 07, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Wed, 06 Sep 2006 21:07:15 -0700, Walter Bright wrote: > Derek Parnell wrote: >> BTW, I'm not wedded to 'local' but something, ... anything, that explicitly informs the reader that the object will be destroyed when it goes out of scope is needed. Leaving it out is not a good user interface. > > Why? It's implicit in C style programming languages that things disappear when they go out of scope. It's the original meaning of 'auto' in C and C++, it's also the default behavior. (N.B: I'm talking about the proposed situation where the D 'auto' keyword is *not* used to implement RAII.) Because D doesn't work that way. Sometimes, even when the object goes out of scope, the object is not destroyed - that is, the dtor is not guaranteed to be called. However, if you use a 'auto' object the dtor is called. import std.stdio; class Foo { static int s_cnt; int m_cnt; char[] m_id; this(char[] id) { m_id = id.dup; s_cnt++; m_cnt = s_cnt; writefln(m_id," CTOR", m_cnt); } ~this() { writefln(m_id, " DTOR", m_cnt);} } void func(char[] id) { Foo a = new Foo(id); auto Foo b = new Foo(id); // the dtor for 'a' is not necessarily called on func exit. // the dtor for 'b' is always called on func exit. } void main() { func("A"); func("B"); func("C"); func("D"); } The output from this is ... A CTOR1 A CTOR2 A DTOR2 B CTOR3 B CTOR4 B DTOR4 C CTOR5 C CTOR6 C DTOR6 D CTOR7 D CTOR8 D DTOR8 D DTOR7 C DTOR5 B DTOR3 A DTOR1 which clearly shows that the currently 'auto' objects are destroyed on scope exit but non-auto ones are not. My earlier discussion was focused on replacing the 'auto' keyword for RAII with a more meaningful keyword, such as 'local'. All I was saying was that I don't care so much which new keyword is used to replace 'auto' so long as it gives a better clue to the reader that a variable so decorated *WILL* be destroyed at scope end, as will its referenced object if any. -- Derek (skype: derek.j.parnell) Melbourne, Australia "Down with mediocrity!" 7/09/2006 2:38:38 PM | |||
September 07, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Garett Bass | No. The advantage of auto is that you can enforce this behaviour at the class declaration.
Example:
auto class Foo
{
int member;
this() {}
}
void main()
{
auto Foo foo = new Foo(); // ok
Foo bar = new Foo(); // error: reference to auto class must be auto
}
Of course, what Chris pointed out is cool from the standpoint that we could probably have the 'auto' keyword (or whatever may replace it) be in the allocator position without losing too much.
Garett Bass wrote:
> I wasn't aware of that, pretty cool! In this case, perhaps do away with the old local-scope meaning of 'auto' altogether.
>
> Chris Nicholson-Sauls wrote:
>
>>
>> The following works right now, and does so just fine:
>> Foo foo = SomeFactory.newFoo(...); scope(exit) delete foo;
>> char[] a = read(filename); scope(exit) delete a;
>>
>> -- Chris Nicholson-Sauls
| |||
September 07, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Chad J | Chad J wrote: > No. The advantage of auto is that you can enforce this behaviour at the class declaration. > Example: > > auto class Foo > { > int member; > this() {} > } > > void main() > { > auto Foo foo = new Foo(); // ok > Foo bar = new Foo(); // error: reference to auto class must be auto > } This is cool in theory but I have yet to actually use this feature. I simply don't see the point in re-using 'auto' in this way. > Of course, what Chris pointed out is cool from the standpoint that we could probably have the 'auto' keyword (or whatever may replace it) be in the allocator position without losing too much. If a keyword were retained to signify auto-destruction then I think it should be in place of 'new' and not attached to the variable itself. Reason being that it's the data that's going away, not whatever that variable happens to reference on scope end. Sean | |||
September 07, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Garett Bass | On Thu, 07 Sep 2006 02:44:43 +0300, Garett Bass <garettbass@studiotekne.com> wrote:
[snip]
> It is unfortunate that true stack object instances do not exist in D. The 'stack' syntax defies D's current heap-only object allocation philosophy.
>
> Another advantage of C++ style stack object instances is the ability to overload the assignment operator, which allows an object instance to be treated as a built-in type. You can't do this in D because it would alias your ability to reassign the object reference to another object. C++ has no problem implementing real and imaginary numbers as classes, they need not be built-in types since their instances can be treated as such syntactically.
>
> I don't understand why modern high-level languages are so quick to discard (or bias against) the pointer. The distinction between object references/pointers and object instances is very valuable in C++. It can be nice to know that no other code is going to reassign another object to your variable.
>
> Pissing in the wind,
> Garett
Now I know why D feels a bit strange at time to time. I wasn't fully aware of it until Garett pointed it out. And that's unability to create build-in types with classes. :|
I'm used to have my objects 'moduled', i.e. assigning X to Y and then changing Y won't change X. And there is no 'const' type... Time will tell how many errors I will make when handling my objects around... until I fully grab the concect of using references/pointers only.
Hmm, it's also 'interesting' to see how much dupping I will need. But dupping doesn't create deep copy, erh...
Should there be a 'physical' object instance class in D after all?
| |||
September 29, 2006 Re: Walter: Before you go and implement the new RAII syntax.. | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | I hate to dredge up an old post, but I was just thinking about this and thought I'd point out one thing to anyone listening: RAII stands for Resource Allocation Is Initialization. You can do RAII without automatically-deleted classes, it's just difficult. For this reason, a keyword 'raii' would be inappropriate - what's being described is NOT RAII, it's just an incidental change that makes RAII more useful. RDID (Resource Deallocation Is Destruction) is closer to what's being described, but still not spot-on: that has to do with the class definition, not the actual use of the class. What's being described is simply an object associated with a scope. In short: the changes described have nothing to do with RAII, they just make it more useful, so having a keyword 'raii' is nonsense. If I see a keyword 'raii' meaning anything like this at any point in the future, I'll be crying myself to sleep that night :P Just my 2ยข - Gregor Richards | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply