class properties: request for promotion and/or fast review.

Hi, I am using simple class properties facility for some time and found it quite useful. Actually it's nothing fancy - simple helper classes to eliminate repetitive setter/accessor methods (and no need for language extensions). Essentially if you need simple readwrite property with trivial access methods in you class you would instead of writing: T member; void set_member( T const& ) {...} T const& get_member() {...} would write: readwrite_property<T> member; Now any time you need to get a member value you would write T t = obj.member; while if you need to update the value: obj.member.value = t; It's not more nor less safe as usual get/set scheme. If you need readonly object property that get initialized in constructor and never updated you could use readonly_property template for example like this: class node { public: readonly<std::string> p_name; .... }; Now everywhere (almost) you could just use n.p_name. To get an access to name member functions you could use operator-> like this: n.p_name->size(); And nobody would be able to update readonly property value. Finally if you need to provide a write access for readonly property you could use another form of readonly_property template. Unfortunately during language limitations (inability to declare template parameter as friend) you would need to use macro, for example like this: class foo { public: BOOST_READONLY_PROPERTY( int, (foo)(Friend2) ) p_value; ... }; Now only class foo and Friend2 have a write access to the value of the property p_value; If boosters find this functionality worth reusing I am ready to prepare document page describing it's usage. If we don't find this header eligible for review I would like to ask then for permission to at least put these templates in boost namespace (currently boost::unit_test), for it inconvenience for me to keep it in deep namespace for rest of my current development. Header you could see here: http://tinyurl.com/38mcm Regards, Gennadiy.

Gennadiy Rozental wrote:
Hi,
I am using simple class properties facility for some time and found it quite useful. Actually it's nothing fancy - simple helper classes to eliminate repetitive setter/accessor methods (and no need for language extensions).
Essentially if you need simple readwrite property with trivial access methods in you class you would instead of writing:
T member;
void set_member( T const& ) {...} T const& get_member() {...}
would write:
readwrite_property<T> member;
Now any time you need to get a member value you would write
T t = obj.member;
while if you need to update the value:
obj.member.value = t;
It's not more nor less safe as usual get/set scheme.
If you need readonly object property that get initialized in constructor and never updated you could use readonly_property template for example like this:
class node { public: readonly<std::string> p_name; ....
};
Now everywhere (almost) you could just use n.p_name. To get an access to name member functions you could use operator-> like this:
n.p_name->size();
And nobody would be able to update readonly property value.
Some thoughts: 1) I would rather see a single templated type, call it property<T> which took other template policy parameters denoting "readonly" etc. 2) Why "obj.member.value = t" rather than "obj.member = t" ? Surely operator == can be overloaded for a write property. 3) Why "n.p_name -> size()" rather than n.p_name.size()" ? The variable p_name is not a property of type pointer to std::string but rather a property of type std::string.
Finally if you need to provide a write access for readonly property you could use another form of readonly_property template. Unfortunately during language limitations (inability to declare template parameter as friend) you would need to use macro, for example like this:
class foo { public: BOOST_READONLY_PROPERTY( int, (foo)(Friend2) ) p_value; ... };
Now only class foo and Friend2 have a write access to the value of the property p_value;
I personally would eliminate this last if the property were truly readonly. It's equivalent in my mind to declaring a const variable but letting only special objects change it. While such an idiom may have its use, I don't think it is the generally correct way to program. The idea of "const" means unchangeable after it has been set and the idea of a readonly property is the same. Of course I am being too inflexible, but if you wanted a property which could be changed only by select objects, I would have a property policy which would name it something different than readonly, maybe "onlychangeableby" or something more succinct but more understandable than "readonly" for this type of property policy.
If boosters find this functionality worth reusing I am ready to prepare document page describing it's usage. If we don't find this header eligible for review I would like to ask then for permission to at least put these templates in boost namespace (currently boost::unit_test), for it inconvenience for me to keep it in deep namespace for rest of my current development.
I have thought about properties, in the Borland and MS .NET terms, for awhile as being doable in pure C++. I am glad someone else has tackled it even on as simple a basis as you have done for your own use. I believe a slightly fuller treatment might be eventually beneficial. Here are some further ideas: 1) One could use boost::function to specify the read and write functors which get called whenever read or write access to a property's value was needed. 2) As in the Borland property implementation, a property doesn't necessarily need a read/write function but may "point to" a member variable, usually private, which holds the actual property value. 3) Since the range library has been reviewed, a property could have a template parameter which could be a range for the property. 4) A range may not be enough to specify all valid values for a property, so that when a user of the property attempts to set a value which is not valid, the code could throw an exception, assert, or silently ignore the attempted change, all of which actions should be choosable by the end user as a property policy. 4) Properties themselves do not necessarily have to be actual objects. Because of that, all attempts to get an address from a property should be short-circuited. Only its value matters. 5) If properties are a single type, with various policies, once the capabilities of reflection are added to C++ via the work Mr. Stroustrup is doing, it is possible for C++ properties to be used in RAD environments in much the same way that Borland has done with C++ Builder ( now a dead product unfortunately ) and MS is doing with Managed C++/.NET ( still a very alive product thank to Herb Sutter's and others efforts ). This is one of the main reasons I would like to see the pure C++ idea of property as a single templated type with different template policies determining its usage. Anyway, please don't let all these ideas stop you from offering what you have done for yourself to Boost. They are only thoughts about a more general property facility.

Some thoughts:
1) I would rather see a single templated type, call it property<T> which took other template policy parameters denoting "readonly" etc.
What is an advantage? Do you envision other types of properties?
2) Why "obj.member.value = t" rather than "obj.member = t" ? Surely operator == can be overloaded for a write property.
That's very important part of design to make sure that all write access to the property value goes through .value. This way I could textually see where my property get changed. In most cases I just search for property.value in sources.
3) Why "n.p_name -> size()" rather than n.p_name.size()" ? The variable p_name is not a property of type pointer to std::string but rather a property of type std::string.
Because you couldn't override operator. ;-)
Finally if you need to provide a write access for readonly property you could use another form of readonly_property template. Unfortunately during language limitations (inability to declare template parameter as friend) you would need to use macro, for example like this:
class foo { public: BOOST_READONLY_PROPERTY( int, (foo)(Friend2) ) p_value; ... };
Now only class foo and Friend2 have a write access to the value of the property p_value;
I personally would eliminate this last if the property were truly readonly. It's equivalent in my mind to declaring a const variable but letting only special objects change it. While such an idiom may have its use, I don't think it is the generally correct way to program. The idea of "const" means unchangeable after it has been set and the idea of a readonly property is the same.
Of course I am being too inflexible, but if you wanted a property which could be changed only by select objects, I would have a property policy which would name it something different than readonly, maybe "onlychangeableby" or something more succinct but more understandable than "readonly" for this type of property policy.
Unfortunately it's quite frequent to have a need for write access. First example is operator= for the owner class. To be able to implement it you need owner class to have write access to the property. And it does not make property "less readonly". That's why I frequently use BOOST_READONLY_PROPERTY( int, (foo) ) p_value; Another idiom that frequently require exclusive write access for some classes is Builder/Factory patterns. Let's say you read class MyClassBuilder that responsible for constructing objects of that class. In most cases you will be forces to make MyClassBuilder a friend for all properties to allow it to set the value. And again in most cases property is still readonly in it's nature. I am open for alternative design proposition, but usability is major player here. After all it simple facility for simple needs.
If boosters find this functionality worth reusing I am ready to prepare document page describing it's usage. If we don't find this header eligible for review I would like to ask then for permission to at least put these templates in boost namespace (currently boost::unit_test), for it inconvenience for me to keep it in deep namespace for rest of my current development.
I have thought about properties, in the Borland and MS .NET terms, for awhile as being doable in pure C++. I am glad someone else has tackled it even on as simple a basis as you have done for your own use. I believe a slightly fuller treatment might be eventually beneficial. Here are some further ideas:
1) One could use boost::function to specify the read and write functors which get called whenever read or write access to a property's value was needed.
It's actually is more complex idiom than one I am trying to model. But If you have a concrete proposition we may consider it.
2) As in the Borland property implementation, a property doesn't necessarily need a read/write function but may "point to" a member variable, usually private, which holds the actual property value.
One of the reason I use property templates is to eliminate need for separate definition of value and accessor.
3) Since the range library has been reviewed, a property could have a template parameter which could be a range for the property.
Range of what?
4) A range may not be enough to specify all valid values for a property, so that when a user of the property attempts to set a value which is not valid, the code could throw an exception, assert, or silently ignore the attempted change, all of which actions should be choosable by the end user as a property policy.
Again validators/interpretators may be useful, but it's more complex idiom and may require much more complex design.
4) Properties themselves do not necessarily have to be actual objects. Because of that, all attempts to get an address from a property should be short-circuited. Only its value matters.
You want be able to get a value of readonly property.
5) If properties are a single type, with various policies, once the capabilities of reflection are added to C++ via the work Mr. Stroustrup is doing, it is possible for C++ properties to be used in RAD environments in much the same way that Borland has done with C++ Builder ( now a dead product unfortunately ) and MS is doing with Managed C++/.NET ( still a very alive product thank to Herb Sutter's and others efforts ). This is one of the main reasons I would like to see the pure C++ idea of property as a single templated type with different template policies determining its usage.
RAD environment? I am not sure I follow what you are saying here. Could you elaborate.
Anyway, please don't let all these ideas stop you from offering what you have done for yourself to Boost. They are only thoughts about a more general property facility.
I proposed quite simple practical tool. It may coexist with more complex/powerful solution. But I would like to see more concrete propositions. Gennadiy.

Gennadiy Rozental wrote:
Some thoughts:
1) I would rather see a single templated type, call it property<T> which took other template policy parameters denoting "readonly" etc.
What is an advantage? Do you envision other types of properties?
Property is a single concept with different variations. It is clearer to me to make those different variations template parameters rather than introduce them as different class templates.
2) Why "obj.member.value = t" rather than "obj.member = t" ? Surely operator == can be overloaded for a write property.
That's very important part of design to make sure that all write access to the property value goes through .value. This way I could textually see where my property get changed. In most cases I just search for property.value in sources.
It is extra code to remember for your users. The expression x.y = somevalue is much easier to use/remember than x.y.value = somevalue. Why make your users pay for something which for you makes it only easier to find something in your code ?
3) Why "n.p_name -> size()" rather than n.p_name.size()" ? The variable p_name is not a property of type pointer to std::string but rather a property of type std::string.
Because you couldn't override operator. ;-)
The expression "n.p_name" should create a copy of the property, and applying the size() member function gives one the size of the copy. So n,p_name.size() is the correct syntax and not n.p_name -> size(). In my vision of properties, properties are not variables, but values ( ala Borland or MS ). If one wanted to change the size of the property n.p_name, one must write: std::string x(n.p_name); x.size(10); n.p_name = x; and not n.p_name.size(10); // This merely changes the size of a copy
Finally if you need to provide a write access for readonly property you could use another form of readonly_property template. Unfortunately during language limitations (inability to declare template parameter as friend) you would need to use macro, for example like this:
class foo { public: BOOST_READONLY_PROPERTY( int, (foo)(Friend2) ) p_value; ... };
Now only class foo and Friend2 have a write access to the value of the property p_value;
I personally would eliminate this last if the property were truly readonly. It's equivalent in my mind to declaring a const variable but letting only special objects change it. While such an idiom may have its use, I don't think it is the generally correct way to program. The idea of "const" means unchangeable after it has been set and the idea of a readonly property is the same.
Of course I am being too inflexible, but if you wanted a property which could be changed only by select objects, I would have a property policy which would name it something different than readonly, maybe "onlychangeableby" or something more succinct but more understandable than "readonly" for this type of property policy.
Unfortunately it's quite frequent to have a need for write access. First example is operator= for the owner class. To be able to implement it you need owner class to have write access to the property. And it does not make property "less readonly". That's why I frequently use BOOST_READONLY_PROPERTY( int, (foo) ) p_value; Another idiom that frequently require exclusive write access for some classes is Builder/Factory patterns. Let's say you read class MyClassBuilder that responsible for constructing objects of that class. In most cases you will be forces to make MyClassBuilder a friend for all properties to allow it to set the value. And again in most cases property is still readonly in it's nature. I am open for alternative design proposition, but usability is major player here. After all it simple facility for simple needs.
I understand the need, but I was really arguing semantics. I think "readonly" properties are truly readonly by everyone once they are created. Another name for properties which can be changed only by certain select objects/functions, rather than "readonly", should be used.
If boosters find this functionality worth reusing I am ready to prepare document page describing it's usage. If we don't find this header eligible for review I would like to ask then for permission to at least put these templates in boost namespace (currently boost::unit_test), for it inconvenience for me to keep it in deep namespace for rest of my current development.
I have thought about properties, in the Borland and MS .NET terms, for awhile as being doable in pure C++. I am glad someone else has tackled it even on as simple a basis as you have done for your own use. I believe a slightly fuller treatment might be eventually beneficial. Here are some further ideas:
1) One could use boost::function to specify the read and write functors which get called whenever read or write access to a property's value was needed.
It's actually is more complex idiom than one I am trying to model. But If you have a concrete proposition we may consider it.
Essentially the idea is that getters and setters could be passed as template parameters in the form of boost::function<etc.> type by the property creator. This would allow any function type of object to server as the property getter or setter by the class property creator. Boost::function is an overall solution to function callback. Why not use it with properties if it can be done ?
2) As in the Borland property implementation, a property doesn't necessarily need a read/write function but may "point to" a member variable, usually private, which holds the actual property value.
One of the reason I use property templates is to eliminate need for separate definition of value and accessor.
I was merely pointing out that getters and setters need not be used but an actual variable only need be specified for holding the value of a property. How this would be specified as a possibility along with a traditional getter/setter, such as a boost::function<>, I don't really know right now. Maybe as a union of choices somehow in a template parameter. If the actual implementation were too complicated, this could be dropped, although I can see a creator of a property<T,...> complaining that he/she doesn't need boost::function<> ( or a member finction ) to specify a getter/setter when a variable is good enough to hold the value of the property instead. This complaint may obviously be more true of a getter, which need not do any transformation before copying the value back to the user, than a setter, which often needs to do checking before setting a value.
3) Since the range library has been reviewed, a property could have a template parameter which could be a range for the property.
Range of what?
Range of the property value. Just like a SetAProperty(somevalue) function with non-properties, there may be a range of values for the property type which is acceptable and, outside of which an exception may be thrown etc.
4) A range may not be enough to specify all valid values for a property, so that when a user of the property attempts to set a value which is not valid, the code could throw an exception, assert, or silently ignore the attempted change, all of which actions should be choosable by the end user as a property policy.
Again validators/interpretators may be useful, but it's more complex idiom and may require much more complex design.
I agree. But it may be possible to shortcut the manual writing of validators by passing a templated validator function or class, as a template parameter to a policy-based property template class. Obviously the boost::range type could be such a class on the simple level of checking that the property value falls within a specific range when set.
4) Properties themselves do not necessarily have to be actual objects. Because of that, all attempts to get an address from a property should be short-circuited. Only its value matters.
You want be able to get a value of readonly property.
Of course, but that doesn't mean that properties have to be member variables themselves. The value of a property is returned as a copy of a value, but the actual value can be a something read from a file or a database on the fly. To me this is a central point of a property. Like getter functions, ie. x.getSomeProperty(), an actual value for SomeProperty() does not have to be a member variable in any form but can be manufactured as needed. That is why one can not take the address of a property.
5) If properties are a single type, with various policies, once the capabilities of reflection are added to C++ via the work Mr. Stroustrup is doing, it is possible for C++ properties to be used in RAD environments in much the same way that Borland has done with C++ Builder ( now a dead product unfortunately ) and MS is doing with Managed C++/.NET ( still a very alive product thank to Herb Sutter's and others efforts ). This is one of the main reasons I would like to see the pure C++ idea of property as a single templated type with different template policies determining its usage.
RAD environment? I am not sure I follow what you are saying here. Could you elaborate.
If a property were a single type, it would be easier for a pure C++ reflection method to simply find out all public properties of a class and present them as values which could be set by the end-user programmer at design time. Then when a certain object, represented by the design-time RAD creator, is actually created at run-time, all of the properties are automatically set to the values which had been specified by the end-user-programmer at design time. This is the way C++ Builder's Object Inspector and Microsoft's .NET equivalent, called the Component Designer, actually work. Of course both those implementations are using their own C++ extensions to "property" and "reflection", whereas if a property<T> template mechansim were created and reflection became part of the language in 2008, it could be done purely in C++ with no language extensions. Of course it is just as viable to look for a family of "property" types in a reflection mechanism as a single type, but I prefer the latter as a simplification mechanism.
Anyway, please don't let all these ideas stop you from offering what you have done for yourself to Boost. They are only thoughts about a more general property facility.
I proposed quite simple practical tool. It may coexist with more complex/powerful solution. But I would like to see more concrete propositions.
I think the most important thing regarding my concept of a "property" is that it is a value, not a member variable. As such the value can be read and/or written but attempting to take the address of a property, or access its theoretically underlying member variable, would be forbidden. I wasn't meaning to complicate matters for you but just to offer ideas which may make it into a better template based property mechanism. I think you should do what you feel is right for your view of property, while possibly listening to my view or other views, and it is up to me to present a different version if it can be done. I fully realize that talking about ideas, and actually implementing them are two different things, and the latter is quite a bit more work and much harder.

1) I would rather see a single templated type, call it property<T> which took other template policy parameters denoting "readonly" etc.
What is an advantage? Do you envision other types of properties?
Property is a single concept with different variations. It is clearer to me to make those different variations template parameters rather than introduce them as different class templates.
Clarity is the matter of taste. And IMO could not be driving force in selecting property<T,readonly> over readonly_property<T>. IMO first version present more complex design (and less convenient, for example in actual code it may look like boost::property<T,boost::readonly> ). For such simple facility primary driving force is usability. And you need more strong points to prefer more complex design.
2) Why "obj.member.value = t" rather than "obj.member = t" ? Surely operator == can be overloaded for a write property.
That's very important part of design to make sure that all write access to the property value goes through .value. This way I could textually see where my property get changed. In most cases I just search for property.value in sources.
It is extra code to remember for your users. The expression x.y = somevalue is much easier to use/remember than x.y.value = somevalue. Why make your users pay for something which for you makes it only easier to find something in your code ?
One of the primary reasons I use property instead of public member is an ability to see exactly where property value is get modified (Would I want x.y = ... syntax, I would just use public member). In multimillion code base (not necessarily written by you) an ability to find all places where property is modified is important. Also in my experience read access always prevail write access. So I don't believe it's such a burden.
3) Why "n.p_name -> size()" rather than n.p_name.size()" ? The variable p_name is not a property of type pointer to std::string but rather a property of type std::string.
Because you couldn't override operator. ;-)
The expression "n.p_name" should create a copy of the property, and applying the size() member function gives one the size of the copy. So n,p_name.size() is the correct syntax and not n.p_name -> size(). In my vision of properties, properties are not variables, but values ( ala Borland or MS ). If one wanted to change the size of the property n.p_name, one must write:
std::string x(n.p_name); x.size(10); n.p_name = x;
and not
n.p_name.size(10); // This merely changes the size of a copy
No. here I completely disagree. property layer should be thin and completely negligible at runtime. I would never agree to property design that require for me to create a string copy to be able to modify the property. Also you would never be able to make an expression n.p_name to create a copy of the property. p_name has type property<...>. You may have implicit cast to proxy that hold copy of the property. But whatever you do you will never be able to make m.p_name.size( 10 ) valid. If I have a permission to modify the property I should be able to call non-const property methods. If not I should be able to call const property methods. I do not know other way (other then operator->) to achieve this.
Unfortunately it's quite frequent to have a need for write access. First example is operator= for the owner class. To be able to implement it you need owner class to have write access to the property. And it does not make property "less readonly". That's why I frequently use BOOST_READONLY_PROPERTY( int, (foo) ) p_value; Another idiom that frequently require exclusive write access for some classes is Builder/Factory patterns. Let's say you read class MyClassBuilder that responsible for constructing objects of that class. In most cases you will be forces to make MyClassBuilder a friend for all properties to allow it to set the value. And again in most cases property is still readonly in it's nature. I am open for alternative design proposition, but usability is major player here. After all it simple facility for simple needs.
I understand the need, but I was really arguing semantics. I think "readonly" properties are truly readonly by everyone once they are created. Another name for properties which can be changed only by certain select objects/functions, rather than "readonly", should be used.
Why? p_name is in it's nature readonly property of class node, but deserializer should be able set a value to it when you read stored structure from file. It does not change readonly-ness of the property IMO.
It's actually is more complex idiom than one I am trying to model. But If you have a concrete proposition we may consider it.
Essentially the idea is that getters and setters could be passed as template parameters in the form of boost::function<etc.> type by the property creator. This would allow any function type of object to server as the property getter or setter by the class property creator. Boost::function is an overall solution to function callback. Why not use it with properties if it can be done ?
Because it clearly overkill for all my needs. And in my practice I almost never had a need for something like that. But it shouldn't stop you from working on policy based smart_property framework that would support validation, custom setter/getter, e.t.c. Be aware though that solution complexity should be justified by advantages over other conventional means. For example, why not just have property with custom type MyCustomType. MyCustomType definition may include all the features you mentioned. And I do not see right away how it may be worse than what you propose. Definitely simpler.
If a property were a single type, it would be easier for a pure C++ reflection method to simply find out all public properties of a class and present them as values which could be set by the end-user programmer at design time. Then when a certain object, represented by the design-time RAD creator, is actually created at run-time, all of the properties are automatically set to the values which had been specified by the end-user-programmer at design time. This is the way C++ Builder's Object Inspector and Microsoft's .NET equivalent, called the Component Designer, actually work. Of course both those implementations are using their own C++ extensions to "property" and "reflection", whereas if a property<T> template mechansim were created and reflection became part of the language in 2008, it could be done purely in C++ with no language extensions.
Of course it is just as viable to look for a family of "property" types in a reflection mechanism as a single type, but I prefer the latter as a simplification mechanism.
I wouldn't say it's simplification. And I do not see that much difference between one class or two.
I think the most important thing regarding my concept of a "property" is that it is a value, not a member variable. As such the value can be read and/or written but attempting to take the address of a property, or access its theoretically underlying member variable, would be forbidden.
I do not see anything wrong to allow get property address if you have a permission to do so. This is C++ not Java. And I remember I had a need to do so once somewhere. Gennadiy.

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
I am using simple class properties facility for some time and found it quite useful. Actually it's nothing fancy - simple helper classes to eliminate repetitive setter/accessor methods (and no need for language extensions).
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

I am using simple class properties facility for some time and found it quite useful. Actually it's nothing fancy - simple helper classes to eliminate repetitive setter/accessor methods (and no need for language extensions).
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't say they all over the place. But the need to something like this is quite widespread and perfectly valid IMO. For example in my project at work I have adaptation of old iterator_adaptor design to old compiler. Here I am using properties to model base and policies members of adaptor, while you had 4 access methods for them plus 2 definition lines. In general IMO properties better reflect class design, and contrast it with something like overridable behavior. Gennadiy.

David Abrahams wrote:
"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
I am using simple class properties facility for some time and found it quite useful. Actually it's nothing fancy - simple helper classes to eliminate repetitive setter/accessor methods (and no need for language extensions).
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't see what getters and setters have to do with levels of abstraction. Needless to say I see nothing wrong with the style that uses properties, but since you didn't say what bothers you about that style I can't answer for why you don't like it. Care to explain ?

"Edward Diener" <eddielee@tropicsoft.com> writes:
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't see what getters and setters have to do with levels of abstraction. Needless to say I see nothing wrong with the style that uses properties, but since you didn't say what bothers you about that style I can't answer for why you don't like it. Care to explain ?
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction. I haven't read through this to see if I agree with any of the points being made, but you can read an article on the subject here: http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html? and a pretty comprehensive discussion here: http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=70526 To the extent to which properties (which I *do* think have a place in good software) are just syntactic sugar for getters/setters, the same arguments apply. You can of course make up your own mind about this stuff ;-) -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't see what getters and setters have to do with levels of abstraction. Needless to say I see nothing wrong with the style that uses properties, but since you didn't say what bothers you about that style I can't answer for why you don't like it. Care to explain ?
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction.
Properties do not have to be data members at all but just values may be set anywhere, ie. a file on disk or a database, and a number of properties may refer to a single underlying object within the actual object having the property. As such I don't think that having many properties necessarily is any impediment to a level of abstraction. Furthermore properties of a derived class may actually affect some underlying functionality of a base class, which I don't see as any more an impediment to designing a good class hierarchy than calling a member function which uses base class functions to achieve its functionality. It could be equally as right to say that a class having many member functions does not represent a higher level of abstraction, but I think that this is an incorrect argument also. Cleary frameworks such as the VCL and .NET can present fairly high levels of abstraction for whatever concepts they are modeling for application development and each use properties very effectively to make it easier to program their respective frameworks. I do agree that an overuse of properties is a theoretical danger to programmers who may become so enamored of them that they substitute functionality for setting values and thus hide what should be functionality behind an obfuscated interface. But C++ has always been a language which has promoted best programming practices rather than protection of novices and I see no reason not to do this in the matter of properties also. My main interest in properties is to make it easier for future RAD functionality in C++ when reflection becomes a reality, rather than in syntactic sugar. With all that said about syntactic sugar, it is obviously safer to enable data member syntax with properties, whose underlying function can control whatever changes can be made, than to use raw data members. I do think that data member syntax better mirrors actually changing and access of values within a class than member functions with Set... and Get.. semantics.
I haven't read through this to see if I agree with any of the points being made, but you can read an article on the subject here:
http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html?
and a pretty comprehensive discussion here:
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=show&ixPost=70526
To the extent to which properties (which I *do* think have a place in good software) are just syntactic sugar for getters/setters, the same arguments apply.
You can of course make up your own mind about this stuff ;-)

"Edward Diener" <eddielee@tropicsoft.com> writes:
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction.
Properties do not have to be data members at all but just values may be set anywhere, ie. a file on disk or a database, and a number of properties may refer to a single underlying object within the actual object having the property.
I know all that. Please don't assume I have a naive view of properties. I am, after all, a Python programmer. I was talking specifically of "exposed properties that are just reflections of underlying data members". Does Gennadiy's library enable another kind of property? If so, so much the better. Anyway, I really suggest you follow the links I posted since I don't really have time to have this argument myself. I see both sides of the issue, and would be happy for people to make up their own minds when presented with all the information.
As such I don't think that having many properties necessarily is any impediment to a level of abstraction. Furthermore properties of a derived class may actually affect some underlying functionality of a base class, which I don't see as any more an impediment to designing a good class hierarchy than calling a member function which uses base class functions to achieve its functionality.
It could be equally as right to say that a class having many member functions does not represent a higher level of abstraction, but I think that this is an incorrect argument also. Cleary frameworks such as the VCL and .NET can present fairly high levels of abstraction for whatever concepts they are modeling for application development and each use properties very effectively to make it easier to program their respective frameworks.
That's a whole different ballgame from what's under discussion. The stuff that makes these properties work well in their frameworks has everything to do with introspectability and nothing to do with the syntactic sugar provided by properties.
I do agree that an overuse of properties is a theoretical danger to programmers who may become so enamored of them that they substitute functionality for setting values and thus hide what should be functionality behind an obfuscated interface. But C++ has always been a language which has promoted best programming practices rather than protection of novices and I see no reason not to do this in the matter of properties also.
I would like to have properties in the language, in part because they would increase expressivity and allow better DSELs to be written. The library substitutes are not good enough for me, though. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction.
Properties do not have to be data members at all but just values may be set anywhere, ie. a file on disk or a database, and a number of properties may refer to a single underlying object within the actual object having the property.
I know all that. Please don't assume I have a naive view of properties.
I didn't. I was making an argument for properties as values and not necessary variables. If they are merely a substitute for variables, they can be seen merely as syntactic sugar for getters and setters. As much as I like that because of my fondness for the data variable notation when accessing and setting properties, I see the concept as extending beyond that and being valuable as long as it is not overused.
I am, after all, a Python programmer.
I am also, although not as experienced with it as you are. Glad you like the language. I can see your boost python implementation also so I knew you know Python well.
I was talking specifically of "exposed properties that are just reflections of underlying data members". Does Gennadiy's library enable another kind of property? If so, so much the better.
I had assumed, without looking into it, that it attached getters and setters to property values so that there was at least some protection for setting them and possible transformations for getting them. I guess I made a naive assumption myself.
Anyway, I really suggest you follow the links I posted since I don't really have time to have this argument myself. I see both sides of the issue, and would be happy for people to make up their own minds when presented with all the information.
You can already guess no doubt that I found Allen Holub's arguments pretty weak.
As such I don't think that having many properties necessarily is any impediment to a level of abstraction. Furthermore properties of a derived class may actually affect some underlying functionality of a base class, which I don't see as any more an impediment to designing a good class hierarchy than calling a member function which uses base class functions to achieve its functionality.
It could be equally as right to say that a class having many member functions does not represent a higher level of abstraction, but I think that this is an incorrect argument also. Cleary frameworks such as the VCL and .NET can present fairly high levels of abstraction for whatever concepts they are modeling for application development and each use properties very effectively to make it easier to program their respective frameworks.
That's a whole different ballgame from what's under discussion. The stuff that makes these properties work well in their frameworks has everything to do with introspectability and nothing to do with the syntactic sugar provided by properties.
My point was merely that I don't believe having properties, as in those frameworks, is any impediment to abstraction. Even if they didn't use language/compiler extensions to do introspection, I would still feel that way although of course properties would be less useful for the lack of RAD capabilities associated with them in those environments. I understand the argument that the less reliance on particular types of data itself, the more easily a concept can be abstracted and changed without affecting the outside interface ( public or protected ), but almost all concepts must be modeled on some idea of data being manipulated and properties offer another possible alternative to safe data manipulation in the right situations. Associating properties with less abstraction is equivalent to saying that the less data a class entails the better off it automatically is in OO design terms.
I do agree that an overuse of properties is a theoretical danger to programmers who may become so enamored of them that they substitute functionality for setting values and thus hide what should be functionality behind an obfuscated interface. But C++ has always been a language which has promoted best programming practices rather than protection of novices and I see no reason not to do this in the matter of properties also.
I would like to have properties in the language, in part because they would increase expressivity and allow better DSELs to be written. The library substitutes are not good enough for me, though.
I would too, and I am glad we agree that they have their value. Perhaps a library flexible enough to do it hasn't been written yet, or perhaps it can not be written given C++ as it exists. Anyway it is a moot point unless I were willing to tackle it myself, and I agree that I haven't seen a library with enough flexibility to mimic the sort of properties in Borland and MS that is needed for C++ programmers. Having used C++ Builder properties and .NET properties in practical situations I can attest to their making certain tasks of programming and design easier for myself. Of course I can't speak for others.

From: "Edward Diener"
David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't see what getters and setters have to do with levels of abstraction. Needless to say I see nothing wrong with the style that uses properties, but since you didn't say what bothers you about that style I can't answer for why you don't like it. Care to explain ?
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction.
Properties do not have to be data members at all but just values may be set anywhere, ie. a file on disk or a database, and a number of properties may refer to a single underlying object within the actual object having the property.
It doesn't matter. Properties represent degrees of freedom. They don't describe dependent data well. As a relatively simple example, consider a pair of integers (x, y) that has an invariant of x*x + y*y = 25, and try to move from (3, 4) to (4, 3) by using the X and Y properties.

Peter Dimov wrote:
From: "Edward Diener"
David Abrahams wrote:
"Edward Diener" <eddielee@tropicsoft.com> writes:
If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't see what getters and setters have to do with levels of abstraction. Needless to say I see nothing wrong with the style that uses properties, but since you didn't say what bothers you about that style I can't answer for why you don't like it. Care to explain ?
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction.
Properties do not have to be data members at all but just values may be set anywhere, ie. a file on disk or a database, and a number of properties may refer to a single underlying object within the actual object having the property.
It doesn't matter. Properties represent degrees of freedom. They don't describe dependent data well.
As a relatively simple example, consider a pair of integers (x, y) that has an invariant of x*x + y*y = 25, and try to move from (3, 4) to (4, 3) by using the X and Y properties.
As an even simpler example, and I think more realistic example, consider a pair of integers ( xleft and xright ) which describe the coordinate boundaries of the x-axis of a rectangle, along with another property which is the width of the rectangle. Changing any of the integers will change the width while changing the width will change the xright integer. Even with all these interactions, the idea of being able to change the position and width by changing any of these properties is not that difficult to fathom. Of course as in your example, when two or more values have a more complex relationship they are not very good candidates for properties. Properties should be used assiduously, and certainly not every data value which a class contains should be a property. In your example I would hardly think that the designer of the class would want x or y to be directly manipulated in any way. My general argument to Mr. Abrahams is that I don't think that properties, or even data itself, has much to do with the ability to use abstraction to model concepts in OO areas. As such I don't see properties as an impediment to good OO design, while I do agree that like many concepts taken too literally, it is subject to abuse. Strangely enough I have found the greatest abuse of properties in JSP with JavaBeans, where the official mantra seems to be that changing and accessing properties is the way to program web applications. Ugh !!! An obvious case of the idea of properties carried to a bad extreme.

"Peter Dimov" <pdimov@mmltd.net> wrote in message news:018801c4417c$e59c1c60$0600a8c0@pdimov...
[...] It doesn't matter. Properties represent degrees of freedom. They don't describe dependent data well. [...]
As Dave A. likes to say (or, at least, I believe I've seen him say it before): "Doctor, doctor, my arm hurts when I move it this way!" "Then don't move it that way." Dave --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.683 / Virus Database: 445 - Release Date: 5/12/2004

If you are making designs that would normally have a lot of getters and setters, it suggests that they may have an insufficient level of abstraction. Of course, that isn't neccessarily the case -- but it does seem to be the rule in my code. I personally don't have a need for this facility and I don't think I want a library that would encourage that style.
I don't see what getters and setters have to do with levels of abstraction. Needless to say I see nothing wrong with the style that uses properties, but since you didn't say what bothers you about that style I can't answer for why you don't like it. Care to explain ?
When classes have a lot of getters and setters or, equivalently, exposed properties that are just reflections of underlying data members, they usually represent just a collection of exposed data values rather than a higher level of abstraction.
I agree. And in my expirience I from time to time need exactly something like this. I just need objects of class A have property (string p_type for example). I coud make it just public member std::string p_type. But this would allow anybody by mistake change it. So what I want is readonly property, that would be as close as possible to unsafe public member definition. class_property family of templates serve this purpose. It's not about should or should you not provide a direct access to the class members. It how to facilitate it. Wherther or not it's good design is a bit separate question. IMO it depends on situation and I found in many case good application for properties with very sound design. Gennadiy.

"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
It's not more nor less safe as usual get/set scheme.
Oh, one other point: the main reason for the "usual get/set scheme" isn't safety, per-se, but encapsulation. The interface can remain stable while the implementation changes so that there is no data member of the type being accessed. If your properties library doesn't have that property (I don't know whether it does or not), it isn't a substitute. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com

It's not more nor less safe as usual get/set scheme.
Oh, one other point: the main reason for the "usual get/set scheme" isn't safety, per-se, but encapsulation. The interface can remain stable while the implementation changes so that there is no data member of the type being accessed. If your properties library doesn't have that property (I don't know whether it does or not), it isn't a substitute.
I don't think single interface/many implementation is main reason. In most cases people just do not want public data members laying around. With this design property became part of class interface. Anyway it's completely different idiom and has nothing to do with this proposition. Gennadiy.

David Abrahams wrote:
"Gennadiy Rozental" <gennadiy.rozental@thomson.com> writes:
It's not more nor less safe as usual get/set scheme.
Oh, one other point: the main reason for the "usual get/set scheme" isn't safety, per-se, but encapsulation. The interface can remain stable while the implementation changes so that there is no data member of the type being accessed. If your properties library doesn't have that property (I don't know whether it does or not), it isn't a substitute.
I agree with you that encapsulation is a good reason, but getters and setters can offer the same encapsulation while hiding the implementation details. Some other reasons why I like properties: 1) I like the syntactic sugar of x.y = avalue as opposed to x.Sety(avalue). It also seems more natural to treat data values which have the backing of a function call in the former way rather than the latter way. The syntax is the same as manipulating a value, which is the way I think of properties anyway. 2) Is is Setx(avalue) ? Is is setx(avalue) ? Is it (pP)utx(avalue) ? etc. With properties it is just x = avalue. Much easier to remember. 3) Properties can serve as RAD types and make it easy for a RAD tool to do things with "properties". They can be actual types as opposed to using a naming convention, such as JavaBeans implements, and which is so easy to forget. Sometimes easy to program is best. RAD tools which work off of types, and not names, are more robust, easier to use, and easier to program originally.
participants (5)
-
David Abrahams
-
David B. Held
-
Edward Diener
-
Gennadiy Rozental
-
Peter Dimov