digitalmars.D - Proposal: 'auto' members and returning 'auto' instances
- Daniel Keep (176/176) May 22 2006 From the D docs (attribute.html#auto):
- Rémy Mouëza (7/7) May 23 2006 This seems to be like a kind of C++ "const" for memory à la D. Would the...
- Daniel Keep (15/23) May 23 2006 It doesn't change existing semantics for auto-destroyed objects EXCEPT
From the D docs (attribute.html#auto): "Auto cannot be applied to globals, statics, **data members**, inout or out parameters. Arrays of autos are not allowed, and **auto function return values** are not allowed. Assignment to an auto, other than initialization, is not allowed. Rationale: **These restrictions may get relaxed in the future if a compelling reason to appears**." Proposal ======== I'd like to propose the following additions to the abilities of the 'auto' attribute in D: 1. Allow 'auto' function return values, and 2. Allow 'auto' members. I will try to outline the specifics of these additions, and why I think they would be a valuable addition to D. I ask that you treat the two proposals as being separate, although related. Also, to try and disambiguate what I mean by 'auto', I will use the following terms: * auto keyword: the "auto" keyword itself * auto class: class with the auto keyword in its declaration * auto variable: a variable that was declared with the auto keyword * auto instance: an instance of an auto class, or an object instance that was assigned to an auto variable Details ======= Allow 'auto' function return values ----------------------------------- In the current edition of the D language, you may not return an auto instance from a function. I assume that the rationale behind this decision is simply that: if you can return an auto instance, then you cannot guarantee that the compiler can safely destroy all auto variables at the end of the scope. I assert that with four simple rules, this problem disappears, allowing you to have auto instance return values. The rules are: (1.) You may return an auto instance if it has been created using the 'new' keyword, and not yet assigned to any auto variable. eg: (2.) You may return an auto instance if it is the result of a function that returns an auto instance. eg: (3.) If a function returns an auto instance, this instance must either be stored in an auto variable, returned from the current function, or immediately destroyed. eg: Implicitly becomes: (Alternate 3.) If a function returns an auto instance, this instance must be explicitly stored in an auto variable so that it can be destroyed at scope exit. eg: to implement? (4.) All other forms involving auto instances and return statements are disallowed. eg: scope exit because the newly created object was never assigned to an auto variable: thus it won't be destroyed. same reason. A valid question that comes up is: wouldn't it be possible to violate this by passing an auto instance into a function and then returning it? In this case, no it wouldn't. Remember that AutoClass is, well, an auto class, and thus all instances of it are also auto. Not only that, but the return statement does not satisfy either rules 1 or 2. If you wanted to do something like this, you would need to use this idiom: Where dup is a function that creates a new, independent instance, allowing the original to be safely destroyed. You could also do this using *explicit* copy constructors, like so: Allow 'auto' members -------------------- From the definition of the auto keyword, it is not immediately apparent what applying the auto keyword to a member would mean. I propose that we define it to mean this: "An auto member is a member of an auto class that is declared with the auto keyword. An auto member may ONLY be assigned to from inside the class' constructor, and may only be assigned to once. When the owning object's instance is destroyed, all auto members are also automatically destroyed. It is an error to declare an auto member in a non-auto class." In other words, it would behave much like a 'const' member. It is worth noting that the previous proposal regarding return values does not allow these auto instances to 'escape' from the object: you still can't directly return the contents of an auto member: you need to dup it first. An alternate version is: "An auto member is a member of an auto class that is declared with the auto keyword. **When a non-null auto member is assigned to, the existing auto object is destroyed.** When the owning object's instance is destroyed, all auto members are also automatically destroyed. It is an error to declare an auto member in a non-auto class." In both cases, auto members would require the same assignment semantics as were used for return statements in the first proposal: that is, you may only assign to auto members if you can prove that the auto instance is not pointed to be anything else. I am not entirely sure which of the above would be most useful; the first is perhaps more consistent with the current auto keyword's semantics. Rationale ========= The cairo drawing API makes use of pointers to structs as "objects". These objects are reference counted. This is done not only to try to prevent memory leaks, but also because graphics objects can sometimes be very limited, or consume large amounts of memory: being able to deterministically destroy them is a good thing. When I originally started writing the object-oriented binding for cairo, I had envisaged using auto classes to implement a kind of reference counting system in D. That is, all variables would be auto, and you could get a "reference" to a cairo object by dup'ing the D object wrapping it. Of course, this fell through when I discovered that you can't return auto instances. This is not the only place where they would have been useful: there are many cases in Cairo where overloading the constructor is either not feasible, or would result in a massive number of "dummy" classes whose sole purpose is to provide a new constructor. In their place, static factory methods are often used; but since these can't return auto instances, you can't use auto classes at all. Also, as I hinted at above, this proposal would bring one of the few memory management techniques that D does not yet support into the fold: reference counting. As far as I know, there isn't another language in existence that supports explicit memory management, lazy management with a GC, RAII, scoped destruction AND reference counting. The proposal regarding auto members is mostly an offshoot of my thinking process: by adding them, we take auto instances from being solely one level-deep, to being arbitrarily deep trees of objects that will be destroyed the instant they are no longer needed, thus making them MUCH more useful. Summary ======= I realise it may be a bit late in the game to get this implemented for D 1.0, but I would be happy to simply have it flagged as being "in the next version". It's better to know it's coming eventually, then not to have it at all. Also, if I've made any silly mistakes in the above, please feel free to correct me :) -- Daniel Keep -- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 22 2006
This seems to be like a kind of C++ "const" for memory à la D. Would these auto variables complicate the type system, as in C++ ? Could it be done using some "scope ( exit ) { delete var1, var2, var... ; }" ? This extended use of auto may add some ambiguities with the "auto" type inference. This latter may use an other keyword like "let" to have things like: let sc = new SomeClass (); // type inference, with an Ocaml look. auto let sc = new SomeAutoClass (); // auto variable and type inference.
May 23 2006
Hooray! Someone replied! ^_^ Rï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ï ½ï¿½ï¿½ï¿½ï¿½ï¿½ï¿½ wrote:This seems to be like a kind of C++ "const" for memory � la D. Would these auto variables complicate the type system, as in C++ ? Could it be done using some "scope ( exit ) { delete var1, var2, var... ; }" ? This extended use of auto may add some ambiguities with the "auto" type inference. This latter may use an other keyword like "let" to have things like: let sc = new SomeClass (); // type inference, with an Ocaml look. auto let sc = new SomeAutoClass (); // auto variable and type inference.It doesn't change existing semantics for auto-destroyed objects EXCEPT to allow them to be a return type, and allow them as object members. Type inference will continue to work exactly as it did before. As for doing it manually, indeed you could! But then, 'auto' in it's current form can be done manually. 'auto' exists to help the programmer write safer, more predictable code. This is just extending where you can use it a little. -- Daniel Keep P.S. Thanks for commenting; I was beginning to wonder if anyone had even read it :P -- v1sw5+8Yhw5ln4+5pr6OFma8u6+7Lw4Tm6+7l6+7D a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP http://hackerkey.com/
May 23 2006