
Olaf van der Spek wrote:
On Fri, Oct 23, 2009 at 5:33 PM, Edward Diener <eldiener@tropicsoft.com> wrote:
You are not talking about the access syntax of properties, as I define it, so your "Unacceptable"s mean little to me. Of course if the syntax limitations of a property implementation vis-a-vis direct manipulation of a data value is unacceptable to you, then you just wouldn't use it.
Don't you agree that string& name = c.name; name.size() is kinda ugly/unusable compared to just c.name->size() (possible) or c.name.size() (not possible, but ideal)?
No I don't think it is unusable, and its ugliness is petty subjective. The c.name.size() is terser, I grant you, but my alternative of c.name.getReference().size(), with that extra "getReference()", does not seem to me so terrible. If I accede to "get" rather than "getReference" then it is even shorter as c.name.get().size() with that extra "get()". Of course I can program in some operator symbol, such as ->, with very little effort so it becomes c.name->size() but I am uncomfortable with an operator in this case because there is little precedence what operator would make easy mnemonic sense. I would love to be able to say c.name.size() but it can't be done in C++ AFAICS. BTW I very much like user-defined operators and have been a vociferous critic of Java's refusal to add them to that language, so I could probably be convinced to add a user-defined operator to my eventually published implemetation of property if I felt others would find one understandable. But it appears to me that the -> user-defined operator is too embedded with the notion of "pointer" to use in my case.
My main goals/reasons for properties are: 1) Syntactically treat a property as close as one can as a data member while providing the ability to control the accessing of the data and the setting of the data through callables ( functions, member functions, functors, boost::function ). 2) Have properties be a type. 3) Have all value properties of an underlying T type share an underlying base class and have all reference properties of an underlying T type share an underlying base class. 4) Provide means beyond just member functions for getting and setting values and getting references.
The main goal I guess is 1, as the others can be achieved with traditional get/set functions, right?
Traditional get/set functions are not to my mind always the clearest way of implementing properties, even if they are the most popular. Furthermore 2) and 3) were also done because I envision properties being types as important to future standard C++ RAD programming environments.
I have more than just these goals, but the above are the main ones.
Properties are in one way syntactic sugar for the plethora of get/retrieve/etc. and set/put/etc. member functions. I also acknowledge that it is syntactically impossible to manipulate properties as directly as one can manipulate data members as far as I can see. But properties are really not a substitute for data members but rather for get-like and set-like functions whose purpose is to access and manipulate a data value. After all, in my view of value properties, the data does not have to exist in memory at all, and I believe this is consistent with the implementation of properties in other languages.
That's right. And actually why I wanted to use a class reference property.
If there is a better way to do it than what I have imagined and implemented in my own version, I would consider it, but reference properties AFAICS means that the underlying data is returned by reference. I don't see any way to get around that. In my original implementation I did not have reference properties at all. The value properties I currently implement can be used with backing data which is actually a reference. The T type of the reference just needs to be copy constructible in that case, that's all. But then I thought about it longer and realized that if one did have a T & ( or T const & ) as backing data one should be able to implement a reference property which simply returned that reference. I further realized that if the reference property was returned as T & and T were not const, the property is read/write, otherwise it is just readable, which fits in well with he trsditional concept of properties in other languages being readable, writable, or read/write. In the case of a reference property as I have implemented it there is no such thing as just a writable reference property, but in the case of a value property there is. Finally I wanted reference properties because user-defined classes themselves could easily have their own properties and the theoretically best way of setting class objects is by setting the properties in the class and not by trying to set an object of that class as a whole.
Of course you can use "string & name()" and "void set_name(const string &)" if you like instead, or you can even just have a public variable of "string name" you directly access and manipulate. I can offer my criticism of the first choice or the second choice but I think it is already well known.
I know, and I agree.
My member function is actually currently called "getValue" for my reference property but I have decided that it is a confusing name since one is really getting a reference, and have changed it to "getReference". How about just get()? I rejected this because of a feeling that some implementations of C++ may macroize ( create a C++ preprocessor macro ) from such a common term as "get". The same goes for "set". I am aware that ideally macros should be all uppercase, but many implementations and header files which should know
Hmm, I'd consider such C++ implementations broken by design.
I do too and perhaps my reticence to use "get" ( and "set" ) is ill-founded. I would still defend it by saying that "getValue" and "getReference" are clearer mnemonically than just "get" even if I am forcing the end user to type some extra characters if they find it necessary to call the underlying function rather than use the operator T conversion operator.