D - Null object semantics
- Les Baker (53/53) Feb 11 2004 I've been lurking for a while, and I wanted to suggest a feature that se...
- Ilya Minkov (36/68) Feb 12 2004 Do you come from Java background? It seems to me you have some sort of
I've been lurking for a while, and I wanted to suggest a feature that seems to partly be in the language already. That is automatically generated null objects for each class. Why I say this is that floating-point numbers have this already. Looking on the "Expression" and "Properties" pages of the D manual, floating point numbers have null semantics, because their "init" property is the special NaN value. The floating point numbers also have special comparison operators to specificially handle cases in which an operand is NaN. Why can't UDT's have that capability as well (note that although I'm mainly talking about classes, structs might apply to this as well)? What I'm thinking of is a static object field that is attached to each class. This object would get its static constructor run and member fields initialized, and any other fields initialized to their .init value (including contained objects). Then, when an object gets initialized without any new expression: Class obj; then it gets set to the .init static object. Methods would need some syntax to indicate what their "do nothing" return value is. class Person { char[] name; int id; int getID() = 0 { return id; } char[] getName() = "<null name>" { return name; } } (Well, I'll admit that was a bit contrived... couldn't think of anything better at the moment) The above syntax would be inadequate if something more needed to be done when a method was called on a null object... like make a log entry, bail out of the program, whatever. I want to emphasize I'm not making a hard and fast "proposal". I'm hoping discussion will generate from this, and an OO guru will shape something up and present something very compelling that Walter will like :-) One other nice benefit is that null object semantics would mesh very nicely with the foreach already in D. For example, if I were programming an Internet server with a fixed pool of connections, and the server was shutting down, then something like this could be coded Connection conn; foreach( conn; connectionPool ) conn.shutdown(); and the right thing would happen without worrying about if all the connections in the pool were actually live. Any thoughts? Thanks -- Les Baker PS. This post is also a "yes vote" for the opIn operator overload discussed a while back. :-)
Feb 11 2004
Les Baker wrote:I've been lurking for a while, and I wanted to suggest a feature that seems to partly be in the language already. That is automatically generated null objects for each class. Why I say this is that floating-point numbers have this already.Do you come from Java background? It seems to me you have some sort of weird understanding of the world of zeroes and ones. :>Looking on the "Expression" and "Properties" pages of the D manual, floating point numbers have null semantics, because their "init" property is the special NaN value. The floating point numbers also have special comparison operators to specificially handle cases in which an operand is NaN. Why can't UDT's have that capability as well (note that although I'm mainly talking about classes, structs might apply to this as well)?If you declare a class instance in your code, it gets automatically assigned "null", which is a pointer constant analogeous to C NULL. Which means invalid pointer, or in the case of an object a non-exisiting object.What I'm thinking of is a static object field that is attached to each class. This object would get its static constructor run and member fields initialized, and any other fields initialized to their .init value (including contained objects). Then, when an object gets initialized without any new expression:Object.init == nullClass obj; then it gets set to the .init static object. Methods would need some syntax to indicate what their "do nothing" return value is.The problem is, methods can only be called on exisiting objects. Making methods work "almost normally", that is, returning some rubbish values, on objects that don't exist would severely endanger language safety, besides killing performance. Especially, it would make it *very* hard to spot out that some object has not been created at some moment and why. Besides, it is not technically feasible, because method called depends on the object actually created, That is, it could be the object of the same actual as formal type, or an actual type can be subtype of a formal type. For that reason, objects contain a hidden pointer into an array which contains adress of actual implementation of each function. Now, if there is no object, you cannot decide what to do...I want to emphasize I'm not making a hard and fast "proposal". I'm hoping discussion will generate from this, and an OO guru will shape something up and present something very compelling that Walter will like :-)I hope your message gets ignored else you might get flamed. ;)One other nice benefit is that null object semantics would mesh very nicely with the foreach already in D. For example, if I were programming an Internet server with a fixed pool of connections, and the server was shutting down, then something like this could be codedThis could be the functionality of a pool not to iterate through non-exising objects - which is easy to determine by checking them for null. ;) BTW, to check manually there are 2 ways: - Object implicitly converts into boolean - true if it exists, false if it's a null so: if (myObject) //my object is alive { /* do something */ } if (!myObject) //whoops! forgot to create an object! { /* create an object now */ } - A reference comparison is done with === (or is) operator (phew!) if (myObject !== null) //my object is alive { /* do something */ } if (myObject is null) //whoops! forgot to create an object! { /* create an object now */ }and the right thing would happen without worrying about if all the connections in the pool were actually live.All means are just already there.PS. This post is also a "yes vote" for the opIn operator overload discussed a while back. :-)? I am apparently yet to find it. -eye
Feb 12 2004