Topic: Properties & RTTI
Author: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Wed, 26 Mar 2003 18:35:11 +0000 (UTC) Raw View
Lo=EFc Joly wrote:
> With properties, you could replace the data by a property that converts=
=20
> from and to the new representation, and no changes to client code would=
=20
> be required.
I agree with you, this situation recently happened to me, but I don't=20
think we can have fully-backward-compatible properties. For example:
struct A
{
int i;
};
A a;
void foo1(int);
void foo2(int&);
void foo3(const int&);
....
foo1(a.i); //ok
foo2(a.i); //ok
foo3(a.i); //ok
Now A become something like:
struct A
{
int property_get i() const;
void property_set i(int);
};
foo1(a.i); //ok
foo2(a.i); //error
foo3(a.i); //I guess it is ok, temporary created
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 22 Mar 2003 02:13:41 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote
> allan_w@my-dejanews.com (Allan W) wrote
> > belvis@pacbell.net (Bob Bell) wrote
> > > [Public member functions] are [equivalent to properties], according
> > > to the definition of properties we are discussing.
> > > As I've pointed out many times, the properties under discussion
> > > provide no functionality beyond that of accessors.
> >
> > That doesn't make them the same as properties!
>
> You should make up your mind. Later on, you say this:
>
> > Properties ARE accessor functions.
>
> Which way is it?
I stand by both statements, in their original context.
Properties don't provide any raw _functionality_ beyond accessor functions,
because they ARE accessor functions. But simply writing accessor functions
is not the same thing as creating a property. Properties have a name and
a syntax that accessor functions cannot provide.
> > > > In particular, there isn't any notification that the time has
> > > > elapsed, unless you poll get_seconds_to_go(). A real version
> > > > would need one or the other of the following:
[A property containing the "handle" of something to notify --
Window handle, pointer to object, or functor or similar object.]
> > > > or:
[An abstract function; use it by deriving your own class from timer.]
> > > or:
> > > * The timer holds a (client-settable) function pointer or functor,
> > > which it calls when the time reaches zero.
> > > or:
> > > * The timer holds a (list of) object(s) to be notified (via a
> > > "TimerFired" member function) when the time reaches zero.
> > > or:
> > > * An event object of some sort, held by the timer, is dispatched to
> > > a global list of objects that subscribe to that event when the
> > > time reaches zero.
> >
> > All three of these are examples of "handles."
>
> So you admit that properties are not needed for notification through
> "handles?" Your first alternative had properties and handles linked.
Properties are not the only way to use handles. It is possible to do the
same thing with raw accessor properties. In fact, it is possible to do
ANYTHING that properties do, through raw accessor properties. For that
matter, it is possible to create these particular handles through public
member data, global non-member functions, etc.
Of all these methods, I prefer properties because they are as easy
to use as public data members, but retain as much encapsulation and
control as accessor functions.
I think that last sentance would be true about ANY case where properties
are appropriate.
> > But suppose, 6 years after you wrote Point (and 50,000 lines of code
> > that depend on it), you discovered that whenever a Point changed
> > co-ordinates, you needed to be notified?
>
> This strikes me as unlikely in the extreme. So unlikely that it's a
> poor justification for adding a feature to the language.
>
> I have worked on several applications which use points (for more than
> 6 years), and not once have I seen a need like this.
It looks as if you're deliberately ignoring my point. You wouldn't do
that, though; this probably means I'm too close to the issue.
This class Point was a simple example, intended to demonstrate a class
where data would HAVE to be calculated at runtime, rather than stored
in data members.
Haven't you never needed to refactor the internals of a class? It DOES
happen. The whole concept of encapsulation is designed to minimize the
total impact of such refactoring. If you never need to modify any code
you've already written, you don't need encapsulation. The rest of us do.
> > Suppose your program has 200 functions that accept either a point, or
> > a vector of points. Half of these functions need Euclidian points, and
> > half of them need Polar points.
>
> Most likely, the need for a class which can simultaneously look like
> two different things is a sign of poor design. However, assuming that
> I convince myself that it isn't poor design, then I would look into
> finding or writing a single class that can behave as either a
> cartesian or polar point.
>
> But:
>
> -- What does this have to do with properties?
Properties allow you to create things that look like public data
members, but are really calculated and validated at runtime. Such
as the polar coordinates.
> -- A new need for a dual-nature point in no way invalidates the points
> I made above; it is still likely that most clients will need either
> cartesian or polar points.
Get past the "dual nature" concept. Class Point was my (perhaps poor)
attempt to demonstrate a class where data would HAVE to be calculated
at runtime, rather than stored in data members.
Think of any other class that does that -- perhaps an invoice has
a "totalamount" property. You don't need to construct your own loop
through all the line items plus shipping, tax, and whatever -- just
access the read-only property invoice.totalamount, and the accessor
function does all the work for you.
[YES! You could just add a function called calcTotal() to the class!
But the property might be more convenient to use!]
Or perhaps a machine has a "state" property (off, on, warmup, test,
running, shuttingdown, fault, maintenance). Reading the property would
tell what the machine is doing right now. Changing the property would
try to manipulate the machine.
[YES! You could just add functions getState() and setState() to the class!
But the property might be more convenient to use!]
Once you're used to the idea of properties, they can be used more
easily and intuitively than accessor functions. For you personally
(no offense intended), and some others of course, getting used to
the idea of properties will meet resistance, and thus it might take
a long time. I suspect that most people will get used to the idea
fairly quickly, and it will make them more productive.
Many other languages provide properties, lots of people have experience
using and creating them, and most of those people would consider the
idea generally useful. You can either conclude that we also ought to
include it in C++, so long as it fits in the overall design -- or
you can point out that just because some C# hacks like it, doesn't
mean it's a Good Thing(tm) for all of us. Both conclusions are correct.
I appreciate the effort you've gone through, to explain your point
of view. I think that you've made your points clearly, and I hope
that I've done the same. I don't think I want to argue this particular
issue anymore. I think it's like abortion or religion -- we're arguing
about preferences and beliefs, so there's no way that either of us
will ever sway the other.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 20 Mar 2003 18:14:53 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote
> allan_w@my-dejanews.com (Allan W) wrote
> > And the existing language supports public member functions, which you
> > seem to consider equivalent.
[to properties]
> >
> > But they aren't.
>
> They are, according to the definition of properties we are discussing.
> As I've pointed out many times, the properties under discussion
> provide no functionality beyond that of accessors.
That doesn't make them the same as properties!
> > > So what did you think of
> > > the Timer class? Does it satisfy your need?
> >
> > It's a toy example; it isn't designed for ANY real-world class.
>
> Not true; it is based on Niklas' description of his (real world) Timer
> class and is intended to be functionally equivalent. Yes, it is
> missing the notification machinery, but that is for illustrative
> purposes, which I thought would be clear.
>
> > In particular, there isn't any notification that the time has
> > elapsed, unless you poll get_seconds_to_go(). A real version
> > would need one or the other of the following:
> >
> > * A property, containing the "handle" of something to notify
> > when the time reaches 0. In a GUI this "handle" could be a
> > window ID; the Timer would send a message to that window. Or
> > it could be a pointer to an object derived from a class named
> > TimerReachedZero. Change Timer to be a template, and we could
> > instead use a functor, or perhaps any object that implements
> > function TimerReachedZero().
> > or:
> > * An abstract function TimerReachedZero(). To use the timer,
> > you would derive your own class from Timer and then implement
> > TimerReachedZero().
>
> or:
> * The timer holds a (client-settable) function pointer or functor,
> which it calls when the time reaches zero.
> or:
> * The timer holds a (list of) object(s) to be notified (via a
> "TimerFired" member function) when the time reaches zero.
> or:
> * An event object of some sort, held by the timer, is dispatched to
> a global list of objects that subscribe to that event when the
> time reaches zero.
All three of these are examples of "handles."
> I'm sure there are other possibilities. Properties are in no way
> necessary for this functionality. Just as properties and introspection
> are separate, so to are properties and notifications separate.
Yes that's true. In fact, you don't need a high-level language at
all -- you could do the whole thing in assembly language!
> > > Does it demonstrate a
> > > pattern of design/implementation that gives you what you want? Or is
> > > there a problem with it?
> > > Does it not scale well? Does it have
> > > different semantics than a property-based timer? Etc.
> >
> > This is the best that can be done without properties. Properties
> > wouldn't radically change this class -- perhaps not any class.
> > The differences are subtle.
> >
> > I think that another class might demonstrate the difference more
> > clearly. Let's modify the traditional class Point.
> >
> > struct Point {
> > double x, y;
> > Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
> > Point(const Point &p) : x(p.x), y(p.y) {}
> > };
> >
> > Point is too simple to make normal encapsulation worthwhile. If you
> > want to modify x and y, you just use the member variables.
> >
> > Point angle0 (0.0, 1.0); // 0 degrees, or 0*pi
> >
> > // Define 180 degrees as mirror-image of 0 degrees
> > Point angle180(angle0.x, -angle0.y);
> >
> > Here we peeked directly at angle0's y value. Conceptually identical
> > to angle0.getY() but easier to type, understand, use. We could also
> > modify x and y directly:
> > // Double the distance from the origin
> > #if false
> > angle0.setX(angle0.getX()*2.0);
> > angle0.setY(angle0.getY()*2.0);
> > #elif false
> > // If it's common to change the distance from origin:
> > angle0.multiplyDistanceFromOrigin(2.0);
> > #else
> > // If multiplying the distance from origin is rare,
> > // this is the easy way to do it:
> > angle0.x *= 2.0; angle0.y *= 2.0;
> > #endif
> > We all know that it "violates encapsulation" but this idiom is
> > nevertheless common, because encapsulation isn't needed for such
> > a simple concept.
>
> Direct access to x and y don't really violate encapsulation because
> there is nothing to encapsulate. A point _is_ an x and y coordinate.
Right.
But suppose, 6 years after you wrote Point (and 50,000 lines of code
that depend on it), you discovered that whenever a Point changed
co-ordinates, you needed to be notified?
Conceivably could happen in an application where all Points referred
to specific pixels on a display.
You could make x and y private, implement getX() and getY() functions
that return x and y, and implement setX() and setY() functions that
modify the value and also call the notification routine... and then
start modifying 50,000 lines of code to use getX() and getY()
instead of using x and y directly. Some of this work could be automated,
but you'd have to manually review all of the results.
OR
You could make x and y into properties, implement getX() and getY()
functions that return property x and property y, and implement
setX() and setY() functions that modify the value and also call the
notification routine... and then test.
> > But, what happens when we want to switch to polar notation?
> First, properties don't enable the "dual-nature" Point class; the same
> effect could have been achieved with accessor functions (although
> properties make it easier, due to the "syntax sugar is good" effect).
YES!
Properties ARE accessor functions. Unlike public data members, they
don't neccesarily have any "real" data members in the class. They
do the same thing as accessor functions, but they make it easier.
> Second, you seem to be saying that this:
>
> class Point {
> double xx, yy;
> public:
> Point() : xx(0.0), yy(0.0) {} // Default
> Point(const Point&p) : xx(p.xx), y(p.yy) {}
> // Use "Named constructor" idiom.
> static Point Euclidian(double x, double y);
> static Point Polar(double rho, double theta);
> // The notation used to declare properties is irrelevant.
> // The important thing is the notation used to use them.
> property double x { return xx; }
> property x(double newval) { xx = newval; }
> property double rho { return whatever(yy/xx); } // Note 1
> property rho(double newval) { /* Update xx and yy */ }
> property double theta { return sqrt(xx*xx+yy*yy); }
> property theta(double newval) { /* Update xx and yy */ }
> };
>
> is simpler/better than:
>
> struct Point {
> double x, y;
> Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
> Point(const Point &p) : x(p.x), y(p.y) {}
> };
>
> struct PolarPoint {
> double rho, theta;
> PolarPoint(r=0.0,t=0.0) : rho(r), theta(t) {}
> PolarPoint(const PolarPint &p) : rho(p.rho), theta(p.theta) {}
> void multiplyDistanceFromOrigin(double m) { theta *= m; }
> };
>
> PolarPoint EuclidToPolar(const Point &e);
> Point PolarToEuclid(const PolarPoint &p);
Yes, absolutely -- for many (not all) applications.
> I disagree. Given that Point, PolarPoint and the conversion functions
> can be packaged in separate headers, the client can include just the
> functionality that is necessary and no more. Clients that want
> cartesian points include Point.h. Clients that want polar points
> include PolarPoint.h. Clients that want to convert include both plus
> PointConvert.h. This is good because there is no reason to expect that
> every user of Point will also be a user of PolarPoint and vice-versa.
Makes sense, for programs that mostly need Polar or mostly need Euclidian.
> The property version, on the other hand, burdens the client with
> knowing about (and at the least including the functionality for) both
> cartesian and polar coordinates, even if he only needs one or the
> other. It's more complex, both in terms of functionality presented as
> well as in sheer function count.
Suppose your program has 200 functions that accept either a point, or
a vector of points. Half of these functions need Euclidian points, and
half of them need Polar points.
In this program, you're going to have to:
* Declare, in EVERY SINGLE ONE of those 200 functions, which type
is needed.
* Convert the points from one type to another, whenever the calling
function doesn't match the called function.
* For functions that sometimes need one type and sometimes or another
(i.e. a function that displays differently depending on display
mode), or functions that often need both types (i.e. a function
that displays both sets of numbers), you've got a real dilemma. You
can either:
-- Pick one type arbitrarily, then do the conversion inside the
function.
-- Pass BOTH types whenever you call the function (always
redundant, plus a potential source of errors if they don't
match to some degree of precision).
* Deal with operator==. Declaring four operator== functions instead
of one isn't a big deal -- but for the two versions that use both
types, what degree of precision do you require?
The property version doesn't have these problems. Also, the property
version allows you to create a vector of points, using any one of them
as either Polar or Euclidian -- to do the same thing with two classes,
you would do one of these:
* Choose one type (Euclidian or Polar) for the vector. Then if
you need to call a function that needs the opposite vector:
Create a new vector 'temp'
Copy the values from the permanent vector to temp,
translating as you go
Call the function
(If the function can modify the vector):
Copy the values from temp back to the permanent vector,
translating as you go
Imagine nesting this?
foo(vector<PointPolar>) could call
bar(vector<PointEuclid>) which calls
baz(vector<PointPolar>) -- ?
You'd probably end up creating bar(vector<PointPolar>) to help,
but take this too far and you duplicate quite a few of those
200 functions (half? 3/4?)
* Use an Abstract Base Class with virtual members
getX() setX()
getY() setY()
getRho() setRho()
getTheta() setTheta()
Now you've got Virtual Function Call overhead every time you use
an accessor function.
The property version allows you to create a vector of points and use
them as either a collection of Polar points or a collection of Euclidian
points (or both at the same time). To do the same thing with two
classes, you'd have to pick one in client code and constantly call the
conversion functions.
> The property version is simply an example of burdening a class with
> too many responsibilities. Another entry for the list of bad coding
> practices that properties make easier (although "just because a
> feature can be misued is not a reason not to add it to C++").
The property version is an example of hiding a design decision that
most client code will not care about. Surely code that displays the
value of a point cares if it's Polar or Euclidian, but most other
code (that does computations on the point) need not care. Hiding
this detail is good.
The encapsulation of this detail CAN be done without properties...
but properties make it easier.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 20 Mar 2003 18:15:01 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote in message news:<c87c1cfb.0303171117.546ebe03@posting.google.com>...
> dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v72k4t2rmhdq99@corp.supernews.com>...
> > Because one often wants public members that do not show up in
> > the published interface.
>
> You mean protected or private members? Can a property be private and
> published at the same time?
Sorry, I think I misread your statement as "because one often wants
PUBLISHED members that do not show up in the PUBLIC interface."
Sorry for the confusion.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Fri, 21 Mar 2003 05:05:37 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0303191718.3e2f531a@posting.google.com>...
> belvis@pacbell.net (Bob Bell) wrote
> > allan_w@my-dejanews.com (Allan W) wrote
> > > And the existing language supports public member functions, which you
> > > seem to consider equivalent.
> [to properties]
> > >
> > > But they aren't.
> >
> > They are, according to the definition of properties we are discussing.
> > As I've pointed out many times, the properties under discussion
> > provide no functionality beyond that of accessors.
>
> That doesn't make them the same as properties!
You should make up your mind. Later on, you say this:
> Properties ARE accessor functions.
Which way is it?
> > > In particular, there isn't any notification that the time has
> > > elapsed, unless you poll get_seconds_to_go(). A real version
> > > would need one or the other of the following:
> > >
> > > * A property, containing the "handle" of something to notify
> > > when the time reaches 0. In a GUI this "handle" could be a
> > > window ID; the Timer would send a message to that window. Or
> > > it could be a pointer to an object derived from a class named
> > > TimerReachedZero. Change Timer to be a template, and we could
> > > instead use a functor, or perhaps any object that implements
> > > function TimerReachedZero().
> > > or:
> > > * An abstract function TimerReachedZero(). To use the timer,
> > > you would derive your own class from Timer and then implement
> > > TimerReachedZero().
> >
> > or:
> > * The timer holds a (client-settable) function pointer or functor,
> > which it calls when the time reaches zero.
> > or:
> > * The timer holds a (list of) object(s) to be notified (via a
> > "TimerFired" member function) when the time reaches zero.
> > or:
> > * An event object of some sort, held by the timer, is dispatched to
> > a global list of objects that subscribe to that event when the
> > time reaches zero.
>
> All three of these are examples of "handles."
So you admit that properties are not needed for notification through
"handles?" Your first alternative had properties and handles linked.
> > Direct access to x and y don't really violate encapsulation because
> > there is nothing to encapsulate. A point _is_ an x and y coordinate.
>
> Right.
>
> But suppose, 6 years after you wrote Point (and 50,000 lines of code
> that depend on it), you discovered that whenever a Point changed
> co-ordinates, you needed to be notified?
This strikes me as unlikely in the extreme. So unlikely that it's a
poor justification for adding a feature to the language.
I have worked on several applications which use points (for more than
6 years), and not once have I seen a need like this.
> > Second, you seem to be saying that this:
> >
> > class Point {
> > double xx, yy;
> > public:
> > Point() : xx(0.0), yy(0.0) {} // Default
> > Point(const Point&p) : xx(p.xx), y(p.yy) {}
> > // Use "Named constructor" idiom.
> > static Point Euclidian(double x, double y);
> > static Point Polar(double rho, double theta);
> > // The notation used to declare properties is irrelevant.
> > // The important thing is the notation used to use them.
> > property double x { return xx; }
> > property x(double newval) { xx = newval; }
> > property double rho { return whatever(yy/xx); } // Note 1
> > property rho(double newval) { /* Update xx and yy */ }
> > property double theta { return sqrt(xx*xx+yy*yy); }
> > property theta(double newval) { /* Update xx and yy */ }
> > };
> >
> > is simpler/better than:
> >
> > struct Point {
> > double x, y;
> > Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
> > Point(const Point &p) : x(p.x), y(p.y) {}
> > };
> >
> > struct PolarPoint {
> > double rho, theta;
> > PolarPoint(r=0.0,t=0.0) : rho(r), theta(t) {}
> > PolarPoint(const PolarPint &p) : rho(p.rho), theta(p.theta) {}
> > void multiplyDistanceFromOrigin(double m) { theta *= m; }
> > };
> >
> > PolarPoint EuclidToPolar(const Point &e);
> > Point PolarToEuclid(const PolarPoint &p);
>
> Yes, absolutely -- for many (not all) applications.
Again, I've never seen a need for a point like this. That doesn't mean
such a need doesn't exist, but it makes me question your use of the
word "many" here.
> Suppose your program has 200 functions that accept either a point, or
> a vector of points. Half of these functions need Euclidian points, and
> half of them need Polar points.
Most likely, the need for a class which can simultaneously look like
two different things is a sign of poor design. However, assuming that
I convince myself that it isn't poor design, then I would look into
finding or writing a single class that can behave as either a
cartesian or polar point.
But:
-- What does this have to do with properties?
-- A new need for a dual-nature point in no way invalidates the points
I made above; it is still likely that most clients will need either
cartesian or polar points.
-- All of the problems you enumerate simply don't exist for a
dual-nature point class.
> > The property version is simply an example of burdening a class with
> > too many responsibilities. Another entry for the list of bad coding
> > practices that properties make easier (although "just because a
> > feature can be misued is not a reason not to add it to C++").
>
> The property version is an example of hiding a design decision that
> most client code will not care about.
They won't care about the _implementation_. They will care about the
_interface_. The _interface_ says that this point is both cartesian
and polar at the same time. Clients must be aware of that, whether
they use both variations or not. This is a bigger problem than whether
or not properties are used as the interface.
As I mentioned above, classes that must simultaneously look like two
different things is often a sign of a problematic design. See, for
example, http://www.gotw.ca/gotw/084.htm.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 19 Mar 2003 19:52:55 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v72k4t2rmhdq99@corp.supernews.com>...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0303131241.21ac5d59@posting.google.com...
> > [...]
> > And we used a GUI layout tool that didn't require any form of
> > introspection.
>
> May I ask which one?
It was an in-house gui builder written using our framework.
> > I'm starting to understand better where you're coming from.
> > Although your idea of "published" is a little weird, in the sense
> > that "published" means nothing in the C++ language other than
> > "public." I think that for a keyword like "published" to be
> > accepted, it should have some defined meaning within the scope
> > of C++.
>
> Like "register"? ;) In the same vein, "published" is a hint to the
> compilation environment...one which can be safely ignored by
> compilers which don't deem it relevant. ;)
Which compilers would deem it relevant? Since it has no language
definition, I don't know what a compiler would be compelled to do with
it.
> > Otherwise, you can do it yourself with
> >
> > #define published public
>
> True, this works, sorta (like macro "solutions" often do ;). What it
> also does is allow this nonsensical construction:
>
> class Derived : published Base
> {
> };
Ah, but one of the arguments used against my position is "just because
a feature can be misused is not a reason to prevent its use. ;-)
Anyway, given that "published" means "public" (as far as the compiler
is concerned), I'm not sure that your example is nonsense.
> > Why can't the RAD system look for public members (functions
> > or data)?
> > [...]
>
> Because one often wants public members that do not show up in
> the published interface.
You mean protected or private members? Can a property be private and
published at the same time?
> And remember that RAD IDEs typically
> do not expose objects in terms of functions and data. Properties
> reflect the concepts present in the RAD environment. That is
> why they are the most natural implementation for RAD-friendly
> source.
It strikes me that "properties are the most natural implementation" is
most likely a consequence of a particular design for RAD. It does not
suggest to me, for example, that a different RAD system could be
designed which does not use properties.
Another question (not really related to the foregoing): how are type
safety issues dealt with in RAD?
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 19 Mar 2003 19:54:25 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
> The problem is that properties are not required to be bound to a
> data member. They can also exist purely as an alternative interface
> to member functions. Let me illustrate:
>
> class timer
> {
> public:
> property bool running = {read = get_running, write = set_running };
> private:
> bool get_running(void) const
> { return time_remaining_ > 0; }
>
> void set_running(bool state)
> { if (state) time_remaining_ = 5; else time_remaining_ = 0; }
>
> int time_remaining_;
> };
>
> I'm not saying this is a good use of properties...just that it illustrates
> the non-data nature of properties. There is no actual bool data
> member associated with the running property.
We still don't need a language extension for that:
template <class Get, class Set>
struct property
{
...
};
or something. Working out the details so that it handles data
members, function objects, and pointers-to-member-functions is not
that hard; I did it in Boost.Python. On the other hand, the
non-state-carrying versions will take up a byte of storage, which you
might have a problem with.
So you could take an external approach:
template <>
struct properties<timer>
: mpl::vector<p1, p2, p3, ...> {};
>> I thought, "why not?"
>
> I agree, but I can't really imagine a use for it, either.
Serialization springs to mind. Also automatic generation of language
bindings.
>> > Let's fill it out a bit:
>> >
>> > template <class access, class T, T pm>
>> > struct member
>> > {
>> > typedef access access_type;
>> > typedef T member_type;
>> > T operator()(void) const { return pm; }
>> > };
>> >
>> > The trick is, would I be able to do this:
>> >
>> > typedef boost::mpl::at<1, members<foo> >::type prop_x;
>> >
>> > foo f;
>> > prop_x x;
>> >
>> > f.*(x()) = 5;
>> >
>> > If so, *should* I be able to do that?
>>
>> Again, "why not?"
>
> Namely, because foo originally looked like this:
>
> class foo
> {
> private:
> int x_;
> double y_;
> };
>
> So the introspection data would theoretically allow a non-friend
> to access private members of foo. Normally, this would be
> prevented when the compiler parses &foo::x_. However, since
> this is generated by the compiler, it's not clear how it would
> control access to it once the data is created. Does this violation
> of encapsulation bother you at all?
Oh, I don't have an opinion about this. Maybe it should be
disallowed, I don't know.
>> [...]
>> > Also, this is what I would call "full introspection", meaning that
>> > it offers much more data than what properties would provide,
>> > and it doesn't provide the design-time interface that properties
>> > *do* provide.
>>
>> I don't know; it seems as though you could build design-time info
>> with this.
>
> The problem is not what you could *extract*, but what *isn't*
> specified. Namely, what isn't specified is what parts of the class
> are relevant at design-time. Remember that the IDE already has full
> access to the class definition. It doesn't need compile-time or
> run-time introspection to do its job. In fact, using the compiler,
> *it is the one that generates such information*. The problem is
> that the program does not contain the information that *it*
> needs... namely, which parts of the class to publish in the
> design-time environment. No amount of compile-time or run-time
> introspection will provide that information, since that information
> is not implicit in the source itself. It must be specified
> explicitly as the intent of the programmer.
OK, so you use the property traits technique above.
> Going back to our class foo example: which members should be
> published, and how? Does your additional introspection data
> give us any more clues? That is, if you could view an instance of
> foo in a design-time object inspector (not a class inspector),
> would you expect to see x_ and y_ (the way you might expect to
> see a Caption property for a Window object)?
I understand the problem. I'm guessing it might be possible to
leverage the automatically generated introspection data along with
some user-specification of design-time relevance... but just how to
do it isn't obvious to me at the moment.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 19 Mar 2003 19:56:04 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0303121755.32e13dc5@posting.google.com>...
> belvis@pacbell.net (Bob Bell) wrote
> > OK:
> >
> > timer.set_seconds_to_go(60);
> >
> > This sets the time remaining and starts the timer. Here's the class:
> >
> > class Timer {
> >
> > public:
> >
> > void set_seconds_to_go(int);
> > int get_seconds_to_go(void) const;
> >
> > };
> >
>
> > That discussion must include, IMHO, a discussion of whether or not the
> > existing language supports the desired functionality. If your need (as
> > demonstrated by the timer example) can be satisfied by existing C++
> > constructs, new constructs aren't necessary.
>
> And the existing language supports public member functions, which you
> seem to consider equivalent.
>
> But they aren't.
They are, according to the definition of properties we are discussing.
As I've pointed out many times, the properties under discussion
provide no functionality beyond that of accessors. As I've also asked
many times, if you want to discuss a different notion of properties,
please define your terms and we can start a new discussion.
> > So what did you think of
> > the Timer class? Does it satisfy your need?
>
> It's a toy example; it isn't designed for ANY real-world class.
Not true; it is based on Niklas' description of his (real world) Timer
class and is intended to be functionally equivalent. Yes, it is
missing the notification machinery, but that is for illustrative
purposes, which I thought would be clear.
> In particular, there isn't any notification that the time has
> elapsed, unless you poll get_seconds_to_go(). A real version
> would need one or the other of the following:
>
> * A property, containing the "handle" of something to notify
> when the time reaches 0. In a GUI this "handle" could be a
> window ID; the Timer would send a message to that window. Or
> it could be a pointer to an object derived from a class named
> TimerReachedZero. Change Timer to be a template, and we could
> instead use a functor, or perhaps any object that implements
> function TimerReachedZero().
> or:
> * An abstract function TimerReachedZero(). To use the timer,
> you would derive your own class from Timer and then implement
> TimerReachedZero().
or:
* The timer holds a (client-settable) function pointer or functor,
which it calls when the time reaches zero.
or:
* The timer holds a (list of) object(s) to be notified (via a
"TimerFired" member function) when the time reaches zero.
or:
* An event object of some sort, held by the timer, is dispatched to
a global list of objects that subscribe to that event when the
time reaches zero.
I'm sure there are other possibilities. Properties are in no way
necessary for this functionality. Just as properties and introspection
are separate, so to are properties and notifications separate.
> > Does it demonstrate a
> > pattern of design/implementation that gives you what you want? Or is
> > there a problem with it?
> > Does it not scale well? Does it have
> > different semantics than a property-based timer? Etc.
>
> This is the best that can be done without properties. Properties
> wouldn't radically change this class -- perhaps not any class.
> The differences are subtle.
>
> I think that another class might demonstrate the difference more
> clearly. Let's modify the traditional class Point.
>
> struct Point {
> double x, y;
> Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
> Point(const Point &p) : x(p.x), y(p.y) {}
> };
>
> Point is too simple to make normal encapsulation worthwhile. If you
> want to modify x and y, you just use the member variables.
>
> Point angle0 (0.0, 1.0); // 0 degrees, or 0*pi
>
> // Define 180 degrees as mirror-image of 0 degrees
> Point angle180(angle0.x, -angle0.y);
>
> Here we peeked directly at angle0's y value. Conceptually identical
> to angle0.getY() but easier to type, understand, use. We could also
> modify x and y directly:
> // Double the distance from the origin
> #if false
> angle0.setX(angle0.getX()*2.0);
> angle0.setY(angle0.getY()*2.0);
> #elif false
> // If it's common to change the distance from origin:
> angle0.multiplyDistanceFromOrigin(2.0);
> #else
> // If multiplying the distance from origin is rare,
> // this is the easy way to do it:
> angle0.x *= 2.0; angle0.y *= 2.0;
> #endif
> We all know that it "violates encapsulation" but this idiom is
> nevertheless common, because encapsulation isn't needed for such
> a simple concept.
Direct access to x and y don't really violate encapsulation because
there is nothing to encapsulate. A point _is_ an x and y coordinate.
> But, what happens when we want to switch to polar notation?
> struct PolarPoint {
> double rho, theta;
> PolarPoint(r=0.0,t=0.0) : rho(r), theta(t) {}
> PolarPoint(const PolarPint &p) : rho(p.rho), theta(p.theta) {}
> void multiplyDistanceFromOrigin(double m) { theta *= m; }
> };
>
> And when we want to convert back and forth:
> PolarPoint EuclidToPolar(const Point &e);
> Point PolarToEuclid(const PolarPoint &p);
>
> It might make sense to introduce ONE type, which understands both
> Euclidian notation and polar notation. We have to pick one of these
> ways for the internal values, but we need not expose this decision
> to clients.
>
> class Point {
> double xx, yy;
> public:
> Point() : xx(0.0), yy(0.0) {} // Default
> Point(const Point&p) : xx(p.xx), y(p.yy) {}
> // Use "Named constructor" idiom.
> static Point Euclidian(double x, double y);
> static Point Polar(double rho, double theta);
> // The notation used to declare properties is irrelevant.
> // The important thing is the notation used to use them.
> property double x { return xx; }
> property x(double newval) { xx = newval; }
> property double rho { return whatever(yy/xx); } // Note 1
> property rho(double newval) { /* Update xx and yy */ }
> property double theta { return sqrt(xx*xx+yy*yy); }
> property theta(double newval) { /* Update xx and yy */ }
> };
>
> Now we can use either notation, without knowing which one(s) are
> used internally.
>
> Point p(Point::Euclidian(3.0, 4.0));
> std::cout << "p = (" << p.x << ", " << p.y << ")\n";
> std::cout << "p: rho=" << p.rho << ", theta=" << p.theta << std::endl;
>
> Despite the fact that rho and theta must do translating, you can call
> them as simply as if they were public data members. That's the value
> of properties.
First, properties don't enable the "dual-nature" Point class; the same
effect could have been achieved with accessor functions (although
properties make it easier, due to the "syntax sugar is good" effect).
Second, you seem to be saying that this:
class Point {
double xx, yy;
public:
Point() : xx(0.0), yy(0.0) {} // Default
Point(const Point&p) : xx(p.xx), y(p.yy) {}
// Use "Named constructor" idiom.
static Point Euclidian(double x, double y);
static Point Polar(double rho, double theta);
// The notation used to declare properties is irrelevant.
// The important thing is the notation used to use them.
property double x { return xx; }
property x(double newval) { xx = newval; }
property double rho { return whatever(yy/xx); } // Note 1
property rho(double newval) { /* Update xx and yy */ }
property double theta { return sqrt(xx*xx+yy*yy); }
property theta(double newval) { /* Update xx and yy */ }
};
is simpler/better than:
struct Point {
double x, y;
Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
Point(const Point &p) : x(p.x), y(p.y) {}
};
struct PolarPoint {
double rho, theta;
PolarPoint(r=0.0,t=0.0) : rho(r), theta(t) {}
PolarPoint(const PolarPint &p) : rho(p.rho), theta(p.theta) {}
void multiplyDistanceFromOrigin(double m) { theta *= m; }
};
PolarPoint EuclidToPolar(const Point &e);
Point PolarToEuclid(const PolarPoint &p);
I disagree. Given that Point, PolarPoint and the conversion functions
can be packaged in separate headers, the client can include just the
functionality that is necessary and no more. Clients that want
cartesian points include Point.h. Clients that want polar points
include PolarPoint.h. Clients that want to convert include both plus
PointConvert.h. This is good because there is no reason to expect that
every user of Point will also be a user of PolarPoint and vice-versa.
The property version, on the other hand, burdens the client with
knowing about (and at the least including the functionality for) both
cartesian and polar coordinates, even if he only needs one or the
other. It's more complex, both in terms of functionality presented as
well as in sheer function count.
The property version is simply an example of burdening a class with
too many responsibilities. Another entry for the list of bad coding
practices that properties make easier (although "just because a
feature can be misued is not a reason not to add it to C++").
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 20 Mar 2003 01:05:59 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote in message news:<c87c1cfb.0303171117.546ebe03@posting.google.com>...
> dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v72k4t2rmhdq99@corp.supernews.com>...
> > And remember that RAD IDEs typically
> > do not expose objects in terms of functions and data. Properties
> > reflect the concepts present in the RAD environment. That is
> > why they are the most natural implementation for RAD-friendly
> > source.
>
> It strikes me that "properties are the most natural implementation" is
> most likely a consequence of a particular design for RAD. It does not
> suggest to me, for example, that a different RAD system could be
> designed which does not use properties.
Man, I gotta read my stuff more carefully before posting.
The last sentence should read:
It does not suggest to me, for example, that a different RAD system
could NOT be designed which does't use properties.
Sorry for the confusion,
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 12 Mar 2003 18:46:47 +0000 (UTC) Raw View
eldiener@earthlink.net ("Edward Diener") wrote in message news:<aBFaa.10445$wJ1.993297@newsread2.prod.itd.earthlink.net>...
> Bob Bell wrote:
> > (Reposting -- it's been two days and this hasn't shown up yet.)
> >
> > eldiener@earthlink.net ("Edward Diener") wrote in message
> > news:<L3x9a.4322$wJ1.449104@newsread2.prod.itd.earthlink.net>...
> >> Bob Bell wrote:
> >>> But when asked what problems properties solve that couldn't be
> >>> solved
> >>> without them, we get examples like
> >>>
> >>> foo.x = bar.y + baz.z * (bar.w - baz.z);
> >>>
> >>> is much better than
> >>>
> >>> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() -
> >>> baz.get_z()));
> >>>
> >>> Even then, proponents of this argument don't claim that properties
> >>> enable new functionality, they just make existing functionality
> >>> easier
> >>> to type and read. However, it isn't a particularly convincing
> >>> argument, as the poor encapsulation is a bigger problem than how
> >>> much
> >>> typing is involved or how long it takes to read.
> >>
> >> Properties have nothing to do with "poor encapsulation". Care to
> >> explain why
> >> you injected such a statement in this discussion ?
> >
> > foo.x = bar.y + baz.z * (bar.w - baz.z);
> >
> > represents poor encapsulation because part of the state of foo is
> > being set in a particular, non-reusable way to some combination of
> > part of the states of bar and baz. The states of foo, bar, and baz are
> > not encapsulated.
>
> Your example has nothing to do with properties themselves. They are just an
> example of setting some value in an object based on the values of other
> objects, and then saying that this represents poor encapsulation. One can
> just as easily create your example by using member functions to get values
> from bar and baz and set a value in foo using a member function. Should we
> get rid of member functions then because they "represent poor encapsulation"?
The example I gave is similar to one from another discussion I had
with someone about properties. His point was that the more complicated
the expression gets, the more important it is to have properties --
with more complicated expressions all the "set_" and "get_" prefixes
and parentheses really make accessors significantly harder to read. I
countered by saying that the more complicated the expression, the more
you're simply avoiding encapsulation. He replied that of course the
example was contrived, he didn't actually write code like the example,
but I should get the idea.
In other words, for realistic code, one doesn't tend to write code
like the above contrived example. One tends to write simpler
expressions involving properties, or use member functions to wrap more
complicated expressions into reusable pieces. So for realistic code,
the readability advantage is kind of moot -- there's just not that
much different between something like
foo.x = 10;
and
foo.set_x(10);
Personally I prefer the latter -- it makes it obvious and explicit
that a function, which may have side effects, is being called.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 12 Mar 2003 18:46:50 +0000 (UTC) Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<uwujap6mk.fsf@boost-consulting.com>...
> There are two arguments, which as far as I can tell are completely
> separate issues (the proponents seem to fail to separate them):
>
> 1. Syntax. Properties allow full encapsulation (contrary to your
> assertion above) while retaining a lightweight syntax which nicely
> denotes "conceptual structural component". Syntactic sugar
> counts, or we'd all be programming in assembly language.
Sure, syntactic sugar matters, I just haven't been convinced that it
matters with properties vs. accessors. The benefits of syntactic sugar
should be more than it just saves a little typing. For example, as
others have pointed out, "for" and "while" and syntactic sugar for
"if" and "goto." But the benefit of structured loops is that ad-hoc
loops using "if" and "goto" involve a lot of repetition and bugs --
structured loops help me avoid that. I haven't seen the same level of
benefit with properties.
> 2. Introspectability. Standard C++ is a poor tool for jobs like
> serialization or the kind of dynamic configuration that goes on in
> a GUI builder, because you end up writing lots of redundant
> information (write down all the data members in the class
> declaration, then write down the code which serializes each one,
> then write down the code which deserializes each one). The notion
> of properties being suggested hook themselves into the RTTI
> mechanism so you can enumerate them for any class, and access them
> for any object.
>
> Clearly you could do either of these without the other one.
>
> Personally I think it would be a shame if we got #2 but it was only
> accessible at runtime and not a compile-time.
I've been avoiding the issue of introspection, because I agree that
properties and introspection are completely separate. For the record,
I believe that introspection is a useful feature that should be
seriously considered for C++0X, and I've read and agree with your
arguments about compile-time introspection as well as run-time
introspection.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bop2@telia.com ("Bo Persson")
Date: Wed, 12 Mar 2003 18:46:53 +0000 (UTC) Raw View
""Edward Diener"" <eldiener@earthlink.net> skrev i meddelandet
news:nB%aa.11951$wJ1.1150672@newsread2.prod.itd.earthlink.net...
> "Bo Persson" wrote:
> >
> > No, his point was that this use of properties represents poor
> > encapsualtion
> > *just* like use of get/set functions. The difference is that
> > properties are proposed to be added to the language, though some of
> > us cannot see any
> > *good* use for them. The example above was of *bad* use. In a good
> > object abstraction, you are generally not supposed to set values, you
> > are supposed to have the object perform things!
>
> This last sentence is your definition of "good object abstraction". It is
> far too limited for my own use, and I see no value to it. Not being able
to
> set characteristics which make up an object, other than at construction
> time, seems far too limiting to me. Your idea of an object is completely
> static such as that an object is created with certain characteristics and
> must then never be changed except through actions. I can't possibly
conceive
> of such a limited OOP model for myself.
Who said the objects are static?
My "perform things" of courses include actions that could affect the objects
state. The difference is in how you present the interface to the user
(programmer). I very much prefer
object.move_to(new_location);
over
object.x = 5; object.y = 7;
That is the difference!
> >
> > Look at the standard library classes, which might have a size() or
> > capacity() to ask about current state, but there are no set_size() or
> > set_capacity(). Different implementations might (and do!) choose
> > between storing size and capacity, or to compute them from pointers
> > when requested. IMO that is a sign of good abstractions.
>
> Containers are only one type of object. Other objects are not nearly as
> simple in representation as containers. If you want to build your own
> systems based on objects whose representation is completely defined at
> construction, that is your choice but you shouldn't think to impose such a
> severe restriction on others.
>
I don't understand how a complex representation would increase the need to
access the internal state of the object.
Bo Persson
bop2@telia.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 12 Mar 2003 18:46:57 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote
> > > The same argument ("if you don't use it then it won't impact you") can
> > > apply equally well to Prolog-style logic programming or symbolic
> > > programming as in Lisp. Do you think we should add those features to
> > > C++ as well?
> >
> > I don't know those features too well, but I suspect that they WOULD have
> > an impact, even if they weren't used.
>
> I claim that they could, at the least, be implemented in libraries
> today. Clearly if that's true, you could choose not to use the library
> and it would have no impact.
Well, then I might be interested in them.
> > It's not as if properties (or RAD, for that matter) are a new and novel
> > idea that's still experimental! Based on my knowledge from other
> > languages, I feel that both properties (as I understand them) and RAD
> > would be useful to a large percentage of C++ programmers. No, I don't
> > have statistics to back that up -- but have you been to a college lately?
>
> No, I haven't. What's going on at colleges lately?
They are teaching the concept of Object-Oriented programming.
Individual schools can teach anything they want, to some extent. But in
order to get and keep accreditation, a class on object-oriented
programming has to teach (among many other subjects) what a property is.
Teaching the concept "property" doesn't mean teaching any particular
language or any particular syntax. We could certainly use languages
other than C++. If we do use C++, we could certainly teach the existing
getXxx / setXxx notation. But the same could be said about objects in
general -- you can certainly write object-oriented programs in a
language that doesn't directly support it, such as C. We could even
teach it that way. "A structure can represent an object, if we obey
certain rules... A member variable can represent a property, if we still
other rules..."
I guess the point is, C++ is "object oriented" because it does more
than simply permit object-oriented techniques; it supports them.
Properties are an important part of object-oriented programming, and
so C++ ought to support that as well.
> > I submit that a large number of programmers want properties, at least
> > to the extent that if they were available, we would use them. I also
> > suggest that if a feature is in wide demand, and yet has no overhead
> > when not used, that this would be good for the C++ language.
>
> You're second point here is true, but it's a little more subtle than
> that. C++ isn't designed by democracy, it's designed by committee.
It's designed by a committee with specific goals.
> The
> majority of C++ programmers don't understand all of the intricate
> relationships between features that the committee must keep straight.
Maybe not. But I think that a some C++ programmers would understand
them all, and a large majority of C++ programmers would understand a
large majority of them.
> A feature being in wide demand is not enough motivation for it to be
> added -- it's fit into the big picture must be taken into
> consideration as well.
Such as: try to make sure that any language change
* is useful (more powerful, or prevents errors, or...)
* doesn't have to be used, by those who use a different programming paradigm
* fits cleanly into the existing language
* doesn't break too many existing programs
> It's when you look at the bigger picture that I
> see properties as falling down.
This, I think, is our fundamental difference. I believe that one of C++'s
most fundamental needs is to support object-oriented programming, and that
properties are part of that. You either aren't so much interested in OO,
or else you feel that OO isn't enhanced by adding language support for
properties. Either way, this difference is a matter of personal taste --
which means, I'm afraid, that we're not likely to resolve the difference
by enlightened debate. Neither one of us is ever likely to change the
mind of the other.
> I submit that a large number of programmers want "finally" added to
> the language, at least to the extent that if it were available, they
> would use it. But that doesn't mean that finally belongs in C++.
An excellent point.
> > Since you made an analogy, I will too. What sorts of problems are solved
> > with for() statements, that can't be solved without while() statements?
> > What does while() solve that can't be solved with if() and goto?
>
> This is a bit of an unfair comparison, since for and while were in C
> over 30 years ago.
Certainly it's not a comparison we're likely to do anything about directly.
But I don't think it was unfair -- I'm making a point here.
> C++ had no choice but to include it to maintain
> compatibility. C++ has also kept a lot of C warts, for the same
> reason.
>
> The concerns we have today when considering what features to add are
> very different from the concerns when C was invented.
That's true. But when I first read this, I thought your conclusion was:
if we didn't have for() today, we would have no need to add it.
Then I read this.
> Having said that, I will say that for and while statements fall into
> the category of keeping me from having to write repetitive code using
> if and goto which could lead to errors.
So you do believe that for() is useful, even though it's not strictly
neccesary.
And now to the point I was making. You've argued over and over again
that properties don't enable us to do anything we couldn't already do.
I agree, but feel it isn't relevant -- if for() isn't strictly neccesary,
than neither are properties, but if for() is useful, so are properties.
> > > [proponents of properties claim that]
> > > foo.x = bar.y + baz.z * (bar.w - baz.z);
> > > is much better than
> > > foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
> > > it isn't a particularly convincing argument, as the poor
> > > encapsulation is a bigger problem than how much typing is
> > > involved or how long it takes to read.
> >
> > When you use properties, the syntax is similar to the syntax used to
> > access public member data. Is that what you mean by poor encapsulation?
> > Because the whole point of properties is to permit that simpler notation
> > without breaking encapsulation!
>
> The states of the foo, bar, and baz objects above are not
> encapsulated, because the client programmer is allowed to change parts
> of their states in arbitrary, non-reusable ways.
NO!
The statement
foo.x = 1;
is not an attempt to "change the state in an arbitrary, non-reusable
way. It is a message that property x should now be updated. HOW the foo
object does this, is entirely up to the foo object. This does NOT need
to assign "1" to some internal variable. In fact, it's just as likely
that the "x" property is a write-only counter, and this statement ADDs
one to that value. This example is flawed in that "x" doesn't mean
anything, so there's no way to tell what it ought to accomplish.
In general, this statement is no different than
foo.X(1);
which also might do anything at all.
> Yes, I understand
> that when a property is accessed, it calls a function behind the
> scenes. But that doesn't change the fact that the foo, bar, and baz
> objects are represented as collections of unrelated data. (More below)
You don't know that. Nobody knows what these objects are, until they
get more meaningful names.
> This doesn't make the property very useful. The property "x" of an
> object promises an interface to the object -- that the x property can
> be changed. If this:
>
> foo.x = 10;
>
> can fail, it doesn't really sound like it's living up to its promise.
What promise does
foo.x = 10;
make that
foo.x(10);
doesn't make?
> > In that sense -- just as you've been saying (repetitively) all along,
> > a property-set function is exactly like a formally-named access
> > function (such as set_x above). If the former breaks encapsulation,
> > then so does the latter.
>
> Exactly. Accessors _do_, in general, break encapsulation. For a class
> like the standard list template, accessors to members would just allow
> clients to mess with the internal state.
>
> Another example: a date class, with year, month and day properties. If
> the date is currently Jan 31, 2003, and I want to change it to Feb 29,
> 2004, this sequence of code seems reasonable:
>
> dt.day = 29;
> dt.month = 2;
> dt.year = 2004;
>
> What happens when the month is assigned? Either
>
> -- the assignment happens, but I now (temporarily) have an invalid
> date: Feb 29, 2003
> -- the assignment fails, in which case I end up with Jan 29, 2004
> -- the assignment succeeds, but adjusts the date to be consistent, in
> which case I end up with Feb 28, 2004
>
> None of these options seem very good to me. Can you think of any
> better ones?
I'd probably either make day, month, and year read-only properties, or
document the fact that the month should be updated before the day. Better
yet, I'd create a function that initializes all 3 fields at once:
dt.set(29,2,2004);
Adding properties to the language doesn't prevent us from using functions!
> The problem is that a date class is not very well modeled as a
> collection of day, month and year properties. An intelligent date
> class is not simply three ints that can be changed independently, as
> the property interface suggests.
Absolutely correct. However, it would be VERY convenient to have
read-only properties for the day, month, and year.
> Note that this example wouldn't be any better if we were using
> set_date, set_month and set_year accessors.
Not a coincidence. When set_xxx DOES make sense, so does property xxx.
> There are very few classes for which pure accessors make sense:
> classes where the abstraction _is_ an aggregation of other data
> objects, and those objects are allowed to vary independently. An
> example is a 2D point. I also claim that these classes are exactly the
> set of classes for which properties make sense.
Agreed.
> I finally claim that
> there isn't any functionality added by properties that isn't available
> through accessors.
As you've been saying all along -- and I don't think anyone disagrees.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: r-smith@ihug.co.nz (Ross Smith)
Date: Wed, 12 Mar 2003 18:47:19 +0000 (UTC) Raw View
David Abrahams wrote:
>
> 2. Introspectability. Standard C++ is a poor tool for jobs like
> serialization or the kind of dynamic configuration that goes on in
> a GUI builder, because you end up writing lots of redundant
> information (write down all the data members in the class
> declaration, then write down the code which serializes each one,
> then write down the code which deserializes each one). The notion
> of properties being suggested hook themselves into the RTTI
> mechanism so you can enumerate them for any class, and access them
> for any object.
I don't understand this argument. What connection do you see between
properties and introspection?
--
Ross Smith ......... r-smith@ihug.co.nz ......... Auckland, New Zealand
Eagles may soar, but weasels never get sucked into a land war in Asia.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: comp.std.c++_2003-03-12@nmhq.net (Niklas Matthies)
Date: Wed, 12 Mar 2003 19:44:32 +0000 (UTC) Raw View
On 2003-03-12 00:14, David Abrahams <dave@boost-consulting.com> wrote:
[...]
> In general, I think properties should have "property-like" behavior.
> In other words, they should generally appear to be a
> reflection/transformation of some internal state, and side-effects
> should be limited to things like validation and notification.
> Otherwise, the communicative value of their syntax is completely
> undermined, and starts to work against the reader.
A mathematician is likely to say similar things about function calls
not having "function-like" behavior in C++. But it's all a question of
idioms. If you know the idiom, things stop to be surprising.
The idiom here is to think of property assignment as a request to the
object to perform the (obvious) behavior or state transition necessary
to make that property value a truth. The conceptually important aspect
here is that the client directly states the goal, instead of the
action, or sequence of actions, that happens to result in the desired
goal.
It's a different way to express things, one that can frequently be
considered to be more concise and to-the-point, once you've accepted
the basic premise.
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Wed, 12 Mar 2003 20:49:35 +0000 (UTC) Raw View
In article <uwujap6mk.fsf@boost-consulting.com>, David Abrahams
<dave@boost-consulting.com> writes
<snip>
>Standard C++ is a poor tool for jobs like
> serialization or the kind of dynamic configuration that goes on in
> a GUI builder, because you end up writing lots of redundant
> information (write down all the data members in the class
> declaration, then write down the code which serializes each one,
> then write down the code which deserializes each one).
Do what? Properties are not objects so they can't be serialized. It's
physically impossible to write a property to a disc.
Moreover, Borland use the __published keyword to trigger serialization.
This is best discussed in a separate thread. As are class loaders.
>The notion
> of properties being suggested hook themselves into the RTTI
> mechanism so you can enumerate them for any class, and access them
> for any object.
<snip>
Properties aren't types either. You need a different acronym. RTPI ?
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Wed, 12 Mar 2003 20:49:45 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303081047.719a1f1d@posting.google.com...
> [...]
> foo.x = bar.y + baz.z * (bar.w - baz.z);
>
> represents poor encapsulation because part of the state of foo
> is being set in a particular, non-reusable way to some
> combination of part of the states of bar and baz. The states of
> foo, bar, and baz are not encapsulated.
What if foo were a complex type, and x were the real component?
Don't you agree that having a struct-like interface that still allows
an accessor/mutator function to be called is syntactically superior?
After all, we could argue that infix notation is inferior to prefix
notation, and that symbolically named operators are completely
unnecessary. They don't solve any problems that alphanumerically
named operators already do. For instance, perhaps C++ ought
to require us to write your statement like this:
set(foo.x, add(bar.y, mult(baz.z, sub(bar.w, baz.z))));
Perhaps symbolic named operators are just unnecessary syntactic
sugar that weigh down the language and inflate compiler parser
tables.
> I repeat my question: what sorts of problems do properties solve
> that can't be solved without them?
What sorts of problems do symbolically named operators solve
that can't be solved without them?
> As I see it, the issue of whether or not to add properties to
> C++ comes down to this question.
Then at the same time, we should be arguing whether to remove
*all* syntactic sugar from the language.
Now, back to GUIs. ;) I argue that properties *increase*
encapsulation within the RAD context, because it enables a
RAD implementation to stream property values from a location
other than the source code. The source code ought to describe
the execution of a program. It ought not to be burdened with
the initial placement of windows and widgets. If you have a
bunch of c'tors that do nothing but place widgets in your window
manager, your program is cluttered with what should really be
*design time information*. This really has very little to do with
the behaviour of your program (most programs should not alter
their behaviour based on the arbitrary placement of a window
on the screen). By allowing the user to specify design time
information in a different file, the source can focus on
*behavior*. Design-time information encapsulated in a design-
time file, and behaviour information encapsulated in the source.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 12 Mar 2003 20:50:12 +0000 (UTC) Raw View
bop2@telia.com ("Bo Persson") wrote
> > Bob Bell wrote:
> > > foo.x = bar.y + baz.z * (bar.w - baz.z);
> > >
> > > represents poor encapsulation because part of the state of foo is
> > > being set in a particular, non-reusable way to some combination of
> > > part of the states of bar and baz. The states of foo, bar, and baz are
> > > not encapsulated.
> >
> ""Edward Diener"" <eldiener@earthlink.net> skrev
> > Your example has nothing to do with properties themselves. They
> > are just an example of setting some value in an object based on
> > the values of other objects, and then saying that this represents
> > poor encapsulation. One can just as easily create your example by
> > using member functions to get values from bar and baz and set a
> > value in foo using a member function. Should we get rid of member
> > functions then because they "represent poor encapsulation"
>
> No, his point was that this use of properties represents poor encapsualtion
> *just* like use of get/set functions. The difference is that properties are
> proposed to be added to the language, though some of us cannot see any
> *good* use for them. The example above was of *bad* use. In a good object
> abstraction, you are generally not supposed to set values, you are supposed
> to have the object perform things!
<sidetrack>
Hypothetical Person 1: I've just invented a way of putting radio receivers
in cars. People will be able to listen to The Lone Ranger while they drive!
Hypothetical Person 2: Oh yeah? Well, if you aimed the car directly at a
tree and pushed on the gas, what would happen?
HP1: They would crash, of course.
HP2: Exactly. The radio does nothing to prevent the crash. It's useless.
Crashing a car is an example of *bad* usage of cars. Crashing a
car-with-radio is also bad. That doesn't make the radio itself bad!
</sidetrack>
In good object abstraction, you are generally not suppsoed to set
values, you are supposed to have the object perform things! When do they
perform things -- whenever they feel like it? Whenever the click ticks?
The answer, of course, is that they are supposed to perform things whenever
they are asked to. The OO concept "passing a message" is implemented in C++
as "Calling a member function." When you call a member function, you are
asking the object to perform some action -- another way to say this is
that you are telling the object some relevant fact about the environment,
and allowing it to take whatever action is neccesary.
With properties, we have yet another way to "call a member function" in
order to "pass a message." The statement
customer.order = order.id;
could be a way to get the customer object to read the order object with
a certain ID, and update all internal balances and statistics accordingly.
Depending on the overall program design, this could be as natural (or even
more natural) than:
customer.ordercompleted(order.id);
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 12 Mar 2003 20:51:21 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
> "David Abrahams" <dave@boost-consulting.com> wrote in message
> news:ur89fooiw.fsf@boost-consulting.com...
>> dheld@codelogicconsulting.com ("David B. Held") writes:
>> > [...]
>> > Well, that would certainly give you more powerful introspection,
>> > but I don't think I've seen this be suggested before (the RTTI
>> > link).
>>
>> I don't see how you're going to easily build RAD systems which
>> allow you to tweak the fields of a class using a GUI otherwise.
>
> My understanding is that what properties do within a RAD system
> is merely provide a tag that tells the IDE "publish this data". The
> IDE can already see the class' structure. It doesn't need RTTI
> for that.
Well, we also don't need a language extension for that:
template <class T>
struct property
{
property() {};
template <class A1>
property(A1 a1) : value(unwrap_reference(a1)) {}
template <class A1, class A2>
property(A1 a1, A2 a2)
: value(unwrap_reference(a1), unwrap_reference(a2)) {}
...
T value;
};
Well, it would be really nice to have the forwarding proposal's && for
this, but I hope you get the idea.
>> > [...]
>> > class foo
>> > {
>> > private:
>> > int x_;
>> > double y_;
>> > };
>> >
>> > typeid(foo).member_count() == 2
>> > typeid(foo).member_at<0>::type == int
>> > typeid(foo).member_at<0>::value == foo::int*
>> > typeid(foo).member_at<1>::type == double
>> > typeid(foo).member_at<1>::value == foo::double*
>>
>> That won't work for dynamic polymorphism unless member_at<> is
>> a very odd type of member template. For the runtime interface you'd
>> need to do something which allows us to express that the Nth
>> member's type is different depending on the dynamic type of the
>> argument to typeid().
>
> Right. I was trying to get a discussion started on the compile-time
> interface first, but it probably doesn't make sense to ignore the
> run-time interface at the same time.
Oh, I guess I thought that *was* supposed to be the runtime interface.
>> I had something like this in mind for the compile-time interface.
>>
>> template <class access, class T, T pm>
>> struct member {};
>>
>> // generated by the compiler on demand:
>> template <>
>> struct members<foo>
>> : boost::mpl::vector<
>> member<public_tag, foo& (foo::*)(foo const&), &foo::operator=>
>> , member<private_tag, int foo::*, &foo::x_>
>> , member<private_tag, double foo::*, &foo::y_>
>> >
>> {
>> };
Probably add the member name as another template parameter.
> Ok, this is interesting. So you include the access information in the
> introspection data.
I thought, "why not?"
> Let's fill it out a bit:
>
> template <class access, class T, T pm>
> struct member
> {
> typedef access access_type;
> typedef T member_type;
> T operator()(void) const { return pm; }
> };
>
> The trick is, would I be able to do this:
>
> typedef boost::mpl::at<1, members<foo> >::type prop_x;
>
> foo f;
> prop_x x;
>
> f.*(x()) = 5;
>
> If so, *should* I be able to do that?
Again, "why not?" I'd like to see someone generate this kind of thing
with GCC_XML. I think it'd be relatively easy given the success of
the work that Bruno da Silva de Oliveira (Nicodemus) has been doing
with Pyste
(http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/*checkout*/boost/boost/libs/python/pyste/index.html).
> Also, this is what I would call "full introspection", meaning that
> it offers much more data than what properties would provide, and it
> doesn't provide the design-time interface that properties *do*
> provide.
I don't know; it seems as though you could build design-time info with
this.
> So I think this type of introspection is good and useful,
> but it's also beyond the scope of properties. Whether that is good
> or bad is open for debate.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 12 Mar 2003 20:51:37 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v6q4jarj2rs365@corp.supernews.com>...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0303092216.40820a9b@posting.google.com...
> > comp.std.c++ 2003-03-09@nmhq.net (Niklas Matthies) wrote in message
> news:<slrnb6m2na.1j6g.comp.std.c++_2003-03-09@nmhq.net>...
> > [...]
> > I would say it the other way around: that you are using properties
> > to simulate what is more natural with methods. If I see code that
> > sets a member variable (or _looks_ like it sets a member variable):
> >
> > timer.seconds_to_go = 60;
> >
> > I find it surprising that it has a side effect such as the one you
> > describe above.
>
> If you see code that sets a member variable, and the object looks
> non-POD, I hope you are shocked and suprised!!! Then, your
> second reaction should be: "Wait, this programmer surely knows
> about proper data hiding. What appears to be an assignment to
> a member is more likely an assignment to a property, which I
> expect to have side effects". Of course, if you don't work with RAD
> systems much, that is an unlikely second reaction, though it
> shouldn't be.
Except that when you see code like
timer.seconds_to_go = 60;
there is nothing in the code to tell me whether this is inappropriate
use of a public member or appropriate use of a property. I would have
to go look up the class definition or read documenation, if any, to
know for sure. Giving the class author the benefit of the doubt is not
a strategy that scales very well.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: comp.std.c++_2003-03-12@nmhq.net (Niklas Matthies)
Date: Wed, 12 Mar 2003 23:00:50 +0000 (UTC) Raw View
On 2003-03-12 18:46, Bob Bell <belvis@pacbell.net> wrote:
[...]
> OK:
>
> timer.set_seconds_to_go(60);
>
> This sets the time remaining and starts the timer. Here's the class:
>
> class Timer {
>
> public:
>
> void set_seconds_to_go(int);
> int get_seconds_to_go(void) const;
>
> };
>
> How is this more complex, conceptually, that the property version you
> describe?
Conceptually, here the client instructs the object to set its internal
seconds_to_go state to some value, or to kindly hand over its value,
instead of directly manipulating it. The state is only indirectly
manifest through the pair of methods. If you will, the object has the
two properties (in the literal sense) that you can instruct it to set
and get its internal state, and these two properties, taken together,
happen to provide the same functionality as if you could manipulate
the internal seconds_to_go state directly. But the functionality is
there only via this indirection of invoking methods. The distinction
is subtle, but it's definitely there.
> [...]
>
>> >> But the above behavior of setting seems less natural with a method
>> >> set seconds to go(...). Here, the client tells the object to set its
>> >> "seconds to go" to some value. It's less obvious that the object, in
>> >> addition to carrying out this request of setting a value of its
>> >> internal state, starts or stops to do something (i.e. counting down).
>> >
>> > This argument applies to
>> >
>> > timer.seconds_to_go = 60;
>> >
>> > It's not obvious that the object, in addition to carrying out this
>> > request of setting a value of its internal state, starts or stops to
>> > do something (i.e. counting down).
>>
>> The very purpose of the property here is to do away with the artificial
>> internal state / external state distinction, as far as the user of the
>> object is concerned. For the user, there's only one state, namely that
>> embodied by the property, and the object does nothing else than behaving
>> according to that state.
>
> That distinction isn't artificial: the state _is_ internal; an
> illusion that presents it as external doesn't change that.
No, the internal state should be an implementation detail that the
client need not be concerned about. Clearly the "seconds to go" value
virtually _is_ what defines the timer's state for the client, no
matter how the timer is implemented internally, hence it is most
natural to provide the (perfect) illusion to the client that this
is the state the client directly manipulates. Incidentally, my
implementation of the Timer class doesn't actually store a "seconds
to go" value anywhere internally. Nevertheless, this property (in the
literal sense) perfectly embodies the Timer object's state, and that's
why it's what is exposed externally.
Considering the other approach now, start()/stop() methods obviously
serve to toggle the running/not running aspect of the timer's state.
It necessitates the client's awareness of an abstract internal state
which is not directly manifest in the timer's interface. The client
has to perform more or less complex reasonings in the style of "okay,
if I invoke start(), this will cause the object to switch its internal
state to 'running', but only if the time value it has stored is not
zero". So, since the client _has_ to deal with this internal state
anyway to use the timer properly, why not simplify things by providing
it as a directly manipulatable, concrete entity?
>> > Not only that, but it is impossible to set the time remaining without
>> > simultaneously starting the timer.
>>
>> Why would you want to do that?
>> A timer's job is not to provide you with interim storage for values
>> that you only need sometime later.
>
> I suppose it depends on what you need.
>
> My point of view comes from the fact that if you need a timer that
> can be started and stopped, it cannot be built from the timer you
> describe.
Yes it can. You only have to save the remaining time away somewhere
immedietaly before stopping it. Think of the egg timer again. When you
want to "pause" it, you write down its current position, and then turn
it to zero. When you are ready to continue, you simply re-set it to
the position you have written down.
> However, the timer you describe can be built from one that can be
> started and stopped. I guess it's mostly a matter of taste and
> style, and I tend to favor more generic code.
So do I, but this is not the situation at hand.
>> >> The Timer object with its single property appears conceptually
>> >> simpler than its method-using counterpart(s), its state appears to
>> >> be external, concrete, not something hidden away inside that one
>> >> can only get at indirectly.
>> >
>> > None of these things seem like advantages -- why is it important that
>> > the state appear external and not hidden away?
>>
>> A client needs to know the state that an object it manipulates is in,
>> and needs to know how the actions applied to the object changes its
>> state. This is more straightforward when the state appears as an
>> directly accessible entity. Think of the mechanical egg timer, whose
>> state you manipulate directly, versus the electronic one, whose state
>> you manipulate indirectly by pushing buttons in sequence.
>
> I don't see a mechanical timer as allowing me to manipulate its state
> directly. It has an interface (usually a dial on the front with tick
> marks for minutes); the internal state is in the intersection of a
> gear, a little ratchet device and a spring.
>
> In this respect it's no different from an electronic timer, which has
> a separate interface and implementation.
The mechanical timer is much more direct, because you tighten or
untighten the spring by direct physical power transmission from your
hands. Of course there's always a certain amount of indirectness,
be it only from the brain to the muscles. Nevertheless, you can't tell
me that the mechanical and electronic timer are of equal conceptual
directness. The fact that it's markedly more difficult for a human
being to learn how to set the time on an electronic timer than on a
mechanical one should make this obvious.
[...]
>> The issues with simulating properties that way have already been
>> discussed in detail here, or over in comp.lang.c++.moderated, I
>> believe. This subthread was about whether properties have enough
>> merits as a concept to possibly justify dedicated language support.
>
> That discussion must include, IMHO, a discussion of whether or not
> the existing language supports the desired functionality. If your
> need (as demonstrated by the timer example) can be satisfied by
> existing C++ constructs, new constructs aren't necessary.
Define "same functionality". C++ and C both provide the same amount
of turing-completeness, and any C++ program can be rewritten to a C
program with identical semantics and same or very close space and time
complexity. But C++ makes it easier to express certain concepts than
C, and to do so in a more concise and less error-prone way. That is
the major strength that C++ has over C, despite the fact that there is
no C++ program that couldn't also be written in C.
Nobody disputes that properties don't add any computational
expressiveness. But they do add expressiveness at the conceptual
level. (I don't buy the "language-level properties are essential for
RAD" argument, by the way--a RAD standard could easily standardize
comments for the purpose of labelling to-be-published properties.)
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Wed, 12 Mar 2003 23:33:21 +0000 (UTC) Raw View
Bob Bell wrote:
> dave@boost-consulting.com (David Abrahams) wrote in message news:<uwuja=
p6mk.fsf@boost-consulting.com>...
>=20
>>There are two arguments, which as far as I can tell are completely
>>separate issues (the proponents seem to fail to separate them):
>>
>>1. Syntax. Properties allow full encapsulation (contrary to your
>> assertion above) while retaining a lightweight syntax which nicely
>> denotes "conceptual structural component". Syntactic sugar
>> counts, or we'd all be programming in assembly language.
>=20
>=20
> Sure, syntactic sugar matters, I just haven't been convinced that it
> matters with properties vs. accessors. The benefits of syntactic sugar
> should be more than it just saves a little typing. For example, as
> others have pointed out, "for" and "while" and syntactic sugar for
> "if" and "goto." But the benefit of structured loops is that ad-hoc
> loops using "if" and "goto" involve a lot of repetition and bugs --
> structured loops help me avoid that. I haven't seen the same level of
> benefit with properties.
I can propose one advantage, although I am not sure... It might=20
envourage a bad behaviour... Or it might be a reason to decide that this=20
behaviour is not bad anymore...
Suppose you a some badly written code that you have to maintain. This=20
code gives direct access to some class data. The clients of the class=20
make heavy use of this access.
You want to change the internal representation of this data, but doing=20
so is not possible because it breaks client code.
Currently, your solution is usually to parse all client code, and=20
manually replace direct access by function call (you cannot use the=20
find&replace of your text editor : even if the name did not appear=20
anywhere else, you coud not decide if it was to be replaced by the get=20
or the set accessor).
With properties, you could replace the data by a property that converts=20
from and to the new representation, and no changes to client code would=20
be required.
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Thu, 13 Mar 2003 03:11:05 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303111639.589ec513@posting.google.com...
> [...]
> Except that when you see code like
>
> timer.seconds_to_go = 60;
>
> there is nothing in the code to tell me whether this is inappropriate
> use of a public member or appropriate use of a property. I would
> have to go look up the class definition or read documenation, if any,
> to know for sure.
At the same time, there is nothing in the code to tell you whether this
is inappropriate use of operator overloading, or appropriate use of
copy assignment. You would have to go look up the class definition
or read the documentation, if any, to know for sure.
> Giving the class author the benefit of the doubt is not a strategy
> that scales very well.
Perhaps you would sympathize with those Java proponents who
argue that lack of operator overloading makes programs more
understandable? ;)
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Thu, 13 Mar 2003 07:10:27 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303111547.3ebc9a3a@posting.google.com...
> dheld@codelogicconsulting.com ("David B. Held") wrote in message
news:<v6n8fdtc7fnn9c@corp.supernews.com>...
> [...]
> For example, can you describe a project in which RAD eliminates
> or reduces a significant bottleneck in development?
Yes. Small-scale custom software that uses a lot of off-the-shelf
technology especially benefits from RAD. I don't even benefit from
the GUI building features perhaps as much as from the database
interface. Using a C API to access business databases is tedious,
to put it politely. In a program where the business logic is not
especially complicated, but is sufficiently client-specific that off-the-
shelf software does not exist, a good deal of the program can be
automated by RAD. I would go so far as to say that I've worked on
projects that would have taken 100% or more time to finish without
RAD. Furthermore, RAD encourages me to provide a richer
interface. I know that the details of the interface will be taken care
of for me, and I can concentrate on using more sophisticated
controls that really provide a superior interface.
> [...]
> Right now I'm working on small in-house tools for a visual effects
> company. In the past I've worked on a suite of 3D tools, including
> an animation system, a modeler and a renderer.
My guess is that the program logic dominated the development
time for these projects. In that case, RAD may not provide a
compelling benefit. Also, I would guess that you do not necessarily
use standard widgets for this application. Business applications
that tend to use standard widgets almost exclusively especially
benefit from RAD, in my opinion. Though now I can see why you
might not perceive any real benefit.
> [...]
> Properties don't give any introspection at all. Properties, as
> defined earlier in this thread, are nothing more or less than
> alternate syntax for accessor functions.
They don't give you run-time or compile-time introspection.
However, they do give you *design-time* introspection. That is,
they provide the design-time environment with the information
necessary to generate a RAD interface to the code.
> It seems you have a different idea of what properties are. One
> of the points I made early on is that many people have different
> definitions of properties, and that it's important to start from a
> common definition.
Strictly speaking, "design time" is outside the scope of C++. Nor
do I propose that it should be carefully defined by C++. In addition
to the property keyword, I think that "published" should be added
as an access specifier. The standard should then state that
"published" members have the same access as "public"
members. So as far as C++ is technically concerned, design-time
is irrelevant. However, these two features *enable* design-time
tools to interact with standard C++ source in a natural and
established way. Even though properties are not a C++ standard,
they are certainly a de facto standard for RAD.
Thus, properties, merely by showing up in the source, provide a
hook for the design-time environment. That is why they implicitly
provide design-time introspection.
> > It's not obvious that a general introspection system
> > would give enough information to do RAD. Unless it were
> > contrived to do so, I would guess that it wouldn't.
>
> Not sure what you mean here -- everything I know about RAD
> suggests that it's the introspection that's important, not
> properties.
By "general introspection", I really mean run-time/compile-time
introspection, which is what most people think of when they think
"C++" and "introspection" (I have also called it static/dynamic
introspection, as opposed to, say, RAD introspection).
> > > For example, RAD could be implemented by giving you a list
> > > of a class' functions to call without properties even coming
> > > into the picture.
> >
> > And more hand-waving from someone who probably hasn't
> > thought too hard about how RAD actually works.
>
> (Please, I haven't made any disparaging remarks about how
> hard you think.)
Fair enough. I apologize for making it personal.
> Have you seen how RAD is used in a language like Lisp or
> Smalltalk?
No, actually I wasn't aware that Lisp had any RAD capabilities
(nor are many people, I expect ;).
> They don't use properties, they use introspection, which they
> get due to the dynamic nature of the languages.
Right, and because C++ is statically typed, it cannot utilise the
same techniques. I suppose we should be comparing apples
to apples. Of course, properties are more appropriate for
statically typed languages. I argue that Lisp and Smalltalk still
have properties, but that they aren't called properties. ;) And
finding information on it is very difficult!
> Apple's Interface Builder also does RAD without properties,
> using the dynamic nature of Objective C.
I sense a pattern... ;)
> In other words, it's clear that RAD is possible without
> properties.
But you admit yourself that the RAD systems cited operate with
dynamically typed languages (well, Objective C is more
statically typed than the others, I think, but you can do some
pretty nasty stuff with it).
> > What good is a list of member functions to a RAD designer?
> > The most critical point where RAD intersects with the language
> > is this: there must be a way for the source to inform the RAD
> > system which parts of a class should be published. This is the
> > piece that generic introspection doesn't give you.
>
> On the contrary; this is exactly what introspection gives you.
But there are three different "time regimes" in which introspection
can operate: compile-time, run-time, and design-time. We need
to be careful about which one we speak.
> [...]
> Perhaps it would be useful to provide an introspection facility in
> C++ that can work in multiple contexts.
Yes, this is almost certainly desirable. At the least, I would expect
a run-time introspection facility to also work at compile-time. How
to integrate design-time introspection requires some thought. I
argue that all that is needed for design-time introspection, however,
is properties. ;) But whether properties can also be useful in the
compile-time and run-time domains should be considered.
> [...]
> Yes, you're right -- this is critical review. I'm probably just
> feeling a little lonely, being the only one coming out against
> properties. ;-)
Oh, I don't know. John Harris, Peter Dimov, and Bo Persson
seem none too fond of them either. ;) And others have spoken
up against them as well. I would guess that your position is that
of the majority, actually, which is why I have spent so much effort
trying to promote properties.
> The biggest example of "rush to judgment" is in the confusion
> that seems to exist among many that properties and introspection
> are tied together.
Can we agree that properties provide design-time introspection,
but not necessarily compile-time or run-time (as commonly
described)?
> [...]
> I have not suggested adding logic programming or symbolic
> programming to C++.
I understood you were being rhetorical to make a point.
> I think you misunderstood. My point was that because a feature
> can be implemented in a zero-overhead-if-not-used fashion is
> not enough of a reason to add the feature. There has to be more.
Ok, I thought you were suggesting that properties should be added
as a library extension. I don't think anyone is arguing that we should
add properties because they are "free". That is silly. All kinds of
features are "free" that should not be added. I think it is clear that
the proponents are identifying the "more" as "syntactic sugar" and
"RAD introspection".
> [...]
> Yes, operator overloading is syntactic sugar. However, operator
> overloading enables certain idioms that would be difficult or
> impossible to code otherwise. Example:
>
> template<typename It, typename Func>
> void for_each(It begin, It end, Func f)
> {
> for (; begin != end; ++begin)
> f(*begin);
> }
>
> Without operator overloading, I could not use for_each on user-
> defined iterators as well as pointers.
Nonsense. All you need is overloading. Period. Then instead of
requiring that iterators define operator++, you require that they
define increment(iterator). You also define increment() for pointer
types. Granted, the named solution is not as elegant as the
symbolic operator solution, nor as natural. I myself prefer the
symbolic operator solution, yet I must insist that it has 0 nutritional
value. It is 100% syntactic sugar.
> [...]
> First, I was speaking of writable properties which allow the write
> to fail, not read-only properties.
In that case, I would "write" it off as bad design, which can be done
with a named setter as easily as with a property (pardon the pun).
> [...]
> I use "accessor" to mean get and set functions. Whether you want
> to call the set function an accessor or a mutator doesn't address
> the essential argument.
Right. It's just a pet peeve of mine to see "setter" functions called
"accessors". ;)
> [...]
> Sorry, you lost me here. I don't see any problem at all with
>
> dt = date(29, 2, 2004);
>
> The assignment is atomic from the client's point of view -- there is
> no opportunity for the client to have access to an invalid date, so
> there's nothing to resolve.
Ok, I see that I was missing that the date would not be validated
piecewise in the c'tor, most likely.
> [...]
> > What would you do in the pure C++ case? My guess is this:
> >
> > * throw an exception
>
> How about a single member function that sets the whole date at
> once? This function can validate all the arguments at once and
> throw an exception if the resulting date would be invalid.
>
> dt.set(29, 2, 2004); // OK
> dt.set(30, 2, 2004); // Throws bad_date()
Yes, this is what I meant.
> [...]
> The point is, how many classes are there for which an
> "independent setting of members" kind of interface is
> appropriate? I've claimed that it's not very many, and for those,
> accessor functions work just fine.
Well, if you use a RAD system... ;)
> [...]
> So I suppose a feel a little less adamant about arguing against
> properties. I'm not sure I would ever use properties myself,
> though, because I see little need for them myself, and I still find
> they can still violate the principle of least surprise,
> [...]
So can macros, overloaded functions/operators, and typedefs. ;)
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 13 Mar 2003 16:40:17 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
>> In general, I think properties should have "property-like" behavior.
>> In other words, they should generally appear to be a
>> reflection/transformation of some internal state, and side-effects
>> should be limited to things like validation and notification.
>> Otherwise, the communicative value of their syntax is completely
>> undermined, and starts to work against the reader.
>
> I agree with this in principle. I think the realities of working with
> RAD might produce situations where the desired form is not
> always achieved, or somehow violated, but the spirit of the principle
> is definitely to be preferred.
Sorry, I can't make any sense of what you're saying here. Care to
rephrase?
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: francis.glassborow@ntlworld.com (Francis Glassborow)
Date: Thu, 13 Mar 2003 18:36:11 +0000 (UTC) Raw View
In article <v6vj8ilj039u98@corp.supernews.com>, David B. Held
<dheld@codelogicconsulting.com> writes
>Perhaps you would sympathize with those Java proponents who
>argue that lack of operator overloading makes programs more
>understandable? ;)
Only to the extent that it inhibits bad overloading, however it is very
clear the appropriate overloading makes code more understandable to
domain experts and hence less error prone.
One of the reasons that C continues to add new fundamental types is
exactly because that is the only way (within C) of providing the
legibility desired by domain specialists. Of course explicit function
calls could be used but in a world where most specialists are most
fluent with infix notation, function calls come a poor fourth to infix,
Polish and Reverse Polish. Function calls completely hide the structure
of an expression, almost always requiring mental reworking into one of
the other forms.
I would go even further an advocate that C++ investigate mechanisms to
allow extended operator syntax and the usage of domain specific symbols.
Unicode provides a substantial block of operator symbols, most are very
specialist but providing mechanisms to support them (as 'library'
operators) would make source code far more readable by the audience it
was intended for.
--
ACCU Spring Conference 2003 April 2-5
The Conference you cannot afford to miss
Check the details: http://www.accuconference.co.uk/
Francis Glassborow ACCU
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 13 Mar 2003 18:36:24 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) writes:
> dave@boost-consulting.com (David Abrahams) wrote in message news:<uwujap6mk.fsf@boost-consulting.com>...
>> There are two arguments, which as far as I can tell are completely
>> separate issues (the proponents seem to fail to separate them):
>>
>> 1. Syntax. Properties allow full encapsulation (contrary to your
>> assertion above) while retaining a lightweight syntax which nicely
>> denotes "conceptual structural component". Syntactic sugar
>> counts, or we'd all be programming in assembly language.
>
> Sure, syntactic sugar matters, I just haven't been convinced that it
> matters with properties vs. accessors. The benefits of syntactic sugar
> should be more than it just saves a little typing.
a. Saving a lot of typing can be a big advantage for development
time. You may be able safely expose a data member as public
without bothering to write accessors, without fear that it locks
you into an un-encapsulated interface.
b. There can be major syntactic advantages for defining
domain-specific sublanguages of C++. Bruno da Silva Oliveira has
just implemented a code-generating front-end in Python for
Boost.Python (Pyste). He used properties in a few places to reduce
syntactic clutter for the user. Doing the same in C++ using
function calls would've made usage noticeably more cumbersome.
There are only a few uses of properties in this case, but it's easy
to imagine how the principle might be extended.
Personally, I'm all for judicious hijacking of syntax for ulterior
purposes, c.f. Blitz++, Boost.uBlas, Boost.Spirit, Boost.Python, ...
I don't see any reason that the "a.b" syntax shouldn't be hijackable.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 13 Mar 2003 21:04:17 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v6viu32afbp695@corp.supernews.com>...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0303111547.3ebc9a3a@posting.google.com...
> > dheld@codelogicconsulting.com ("David B. Held") wrote in message
> news:<v6n8fdtc7fnn9c@corp.supernews.com>...
> > [...]
> > For example, can you describe a project in which RAD eliminates
> > or reduces a significant bottleneck in development?
>
> Yes. Small-scale custom software that uses a lot of off-the-shelf
> technology especially benefits from RAD.
I can see why you value RAD so highly. In such an environment, RAD
probably does shave significant time off of development.
As you correctly surmised below, I tend to think in terms of
larger-scale development, where the benefits of RAD are much smaller.
> > [...]
> > Right now I'm working on small in-house tools for a visual effects
> > company. In the past I've worked on a suite of 3D tools, including
> > an animation system, a modeler and a renderer.
>
> My guess is that the program logic dominated the development
> time for these projects. In that case, RAD may not provide a
> compelling benefit. Also, I would guess that you do not necessarily
> use standard widgets for this application.
You'd be surprised. These kinds of apps tend to have a large number of
dialog boxes and configuration windows, filled with standard widgets.
And we used a GUI layout tool that didn't require any form of
introspection. It made making those windows faster, but you're right
-- program logic dominated development time.
> > It seems you have a different idea of what properties are. One
> > of the points I made early on is that many people have different
> > definitions of properties, and that it's important to start from a
> > common definition.
>
> Strictly speaking, "design time" is outside the scope of C++. Nor
> do I propose that it should be carefully defined by C++. In addition
> to the property keyword, I think that "published" should be added
> as an access specifier. The standard should then state that
> "published" members have the same access as "public"
> members. So as far as C++ is technically concerned, design-time
> is irrelevant. However, these two features *enable* design-time
> tools to interact with standard C++ source in a natural and
> established way. Even though properties are not a C++ standard,
> they are certainly a de facto standard for RAD.
I'm starting to understand better where you're coming from. Although
your idea of "published" is a little weird, in the sense that
"published" means nothing in the C++ language other than "public." I
think that for a keyword like "published" to be accepted, it should
have some defined meaning within the scope of C++.
Otherwise, you can do it yourself with
#define published public
The other half of this question is why we need published at all? Why
isn't public enough? Why should a RAD system not have access to all
public members?
> > > It's not obvious that a general introspection system
> > > would give enough information to do RAD. Unless it were
> > > contrived to do so, I would guess that it wouldn't.
> >
> > Not sure what you mean here -- everything I know about RAD
> > suggests that it's the introspection that's important, not
> > properties.
>
> By "general introspection", I really mean run-time/compile-time
> introspection, which is what most people think of when they think
> "C++" and "introspection" (I have also called it static/dynamic
> introspection, as opposed to, say, RAD introspection).
As I understand it, what you're talking about isn't introspection at
all, because it sounds like you're saying that the RAD system must
parse a header file, looking for keywords like "property" and
"published." Is this a correct interpretation?
> > (Please, I haven't made any disparaging remarks about how
> > hard you think.)
>
> Fair enough. I apologize for making it personal.
No problem. I've been guilty of that myself from time to time. :-)
> > In other words, it's clear that RAD is possible without
> > properties.
>
> But you admit yourself that the RAD systems cited operate with
> dynamically typed languages (well, Objective C is more
> statically typed than the others, I think, but you can do some
> pretty nasty stuff with it).
The point is that it's the introspection ability (that in the case of
Lisp is a benefit of the dynamic nature of the language) that makes
RAD work. The reason it works in Objective C, a statically typed
language, is because it's "just dynamic enough" -- it allows a client
at run time to inquire about what methods can be called.
> > The biggest example of "rush to judgment" is in the confusion
> > that seems to exist among many that properties and introspection
> > are tied together.
>
> Can we agree that properties provide design-time introspection,
> but not necessarily compile-time or run-time (as commonly
> described)?
If it's true that design-time introspection is just a parsing phase
done by the RAD system, then it's still not clear to me that it is
properties that provide said introspection. The parsing process can be
made to look for any kind of syntactic construct, not just ones that
contain the key word "property."
Why can't the RAD system look for public members (functions or data)?
> > [...]
> > Yes, operator overloading is syntactic sugar. However, operator
> > overloading enables certain idioms that would be difficult or
> > impossible to code otherwise. Example:
> >
> > template<typename It, typename Func>
> > void for_each(It begin, It end, Func f)
> > {
> > for (; begin != end; ++begin)
> > f(*begin);
> > }
> >
> > Without operator overloading, I could not use for_each on user-
> > defined iterators as well as pointers.
>
> Nonsense. All you need is overloading. Period. Then instead of
> requiring that iterators define operator++, you require that they
> define increment(iterator). You also define increment() for pointer
> types. Granted, the named solution is not as elegant as the
> symbolic operator solution, nor as natural. I myself prefer the
> symbolic operator solution, yet I must insist that it has 0 nutritional
> value. It is 100% syntactic sugar.
Everything you say here is true, but as others have said, syntactic
sugar has value. I think this is an example of that.
> > [...]
> > So I suppose a feel a little less adamant about arguing against
> > properties. I'm not sure I would ever use properties myself,
> > though, because I see little need for them myself, and I still find
> > they can still violate the principle of least surprise,
> > [...]
>
> So can macros, overloaded functions/operators, and typedefs. ;)
For each of those (macros, overloaded functions/operators, and
typedefs), when violations of the principle of least surprise occurs,
we say that those features have been misused. I would avoid using
properties for the same reason I avoid macros that perform computation
and operator+ functions that perform multiplication. But that's just
me.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Fri, 14 Mar 2003 06:19:18 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uptov2x6i.fsf@boost-consulting.com...
> dheld@codelogicconsulting.com ("David B. Held") writes:
>
> >> In general, I think properties should have "property-like" behavior.
> >> In other words, they should generally appear to be a
> >> reflection/transformation of some internal state, and side-effects
> >> should be limited to things like validation and notification.
> >> Otherwise, the communicative value of their syntax is completely
> >> undermined, and starts to work against the reader.
> >
> > I agree with this in principle. I think the realities of working with
> > RAD might produce situations where the desired form is not
> > always achieved, or somehow violated, but the spirit of the
> > principle is definitely to be preferred.
>
> Sorry, I can't make any sense of what you're saying here. Care to
> rephrase?
Well, to give an example, the VCL (which is the RAD library shipped
with BCB) commonly uses an Active property to indicate whether a
design-time control automatically Open()s or Connect()s, or whatever
action is appropriate for activating it. Setting the Active property to
true or false calls this associated function (Open() or Close()). In
this case, the reason it is a property is so that the user can activate
the component at design time by setting the property.
The side-effect here is not a simple validation or notification, but
a major interface action. So it would seem to violate your rule.
In general, the VCL uses member functions to perform actions,
but for actions where the result should be streamable or activated
at design-time, they are also enabled as properties.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Fri, 14 Mar 2003 17:26:36 +0000 (UTC) Raw View
Bob Bell wrote:
> dheld@codelogicconsulting.com ("David B. Held") wrote in message
> news:<v6viu32afbp695@corp.supernews.com>...
>> "Bob Bell" <belvis@pacbell.net> wrote in message
>> news:c87c1cfb.0303111547.3ebc9a3a@posting.google.com...
>>> dheld@codelogicconsulting.com ("David B. Held") wrote in message
>> news:<v6n8fdtc7fnn9c@corp.supernews.com>...
>>> [...]
>>> For example, can you describe a project in which RAD eliminates
>>> or reduces a significant bottleneck in development?
>>
>> Yes. Small-scale custom software that uses a lot of off-the-shelf
>> technology especially benefits from RAD.
>
> I can see why you value RAD so highly. In such an environment, RAD
> probably does shave significant time off of development.
>
> As you correctly surmised below, I tend to think in terms of
> larger-scale development, where the benefits of RAD are much smaller.
>
>>> [...]
>>> Right now I'm working on small in-house tools for a visual effects
>>> company. In the past I've worked on a suite of 3D tools, including
>>> an animation system, a modeler and a renderer.
>>
>> My guess is that the program logic dominated the development
>> time for these projects. In that case, RAD may not provide a
>> compelling benefit. Also, I would guess that you do not necessarily
>> use standard widgets for this application.
>
> You'd be surprised. These kinds of apps tend to have a large number of
> dialog boxes and configuration windows, filled with standard widgets.
> And we used a GUI layout tool that didn't require any form of
> introspection. It made making those windows faster, but you're right
> -- program logic dominated development time.
RAD can also make using non-visual classes easier, not just visual widgets.
Being able to set some properties at design time in a RAD environment and
have event handlers created for you by the RAD environment to which you add
code in order to handle an object's events, makes it easier to program
whether the RAD component is a visual widget or a class which performs some
important task but which does not appear visually at run-time. One should
not think that the benefits of a property/method/event RAD environment just
extends to visual widgets.
>
>>> It seems you have a different idea of what properties are. One
>>> of the points I made early on is that many people have different
>>> definitions of properties, and that it's important to start from a
>>> common definition.
>>
>> Strictly speaking, "design time" is outside the scope of C++. Nor
>> do I propose that it should be carefully defined by C++. In addition
>> to the property keyword, I think that "published" should be added
>> as an access specifier. The standard should then state that
>> "published" members have the same access as "public"
>> members. So as far as C++ is technically concerned, design-time
>> is irrelevant. However, these two features *enable* design-time
>> tools to interact with standard C++ source in a natural and
>> established way. Even though properties are not a C++ standard,
>> they are certainly a de facto standard for RAD.
>
> I'm starting to understand better where you're coming from. Although
> your idea of "published" is a little weird, in the sense that
> "published" means nothing in the C++ language other than "public." I
> think that for a keyword like "published" to be accepted, it should
> have some defined meaning within the scope of C++.
The __published section in a C++ Builder class is used to specify which
properties and events ( events are actually another kind of property in C++
Builder ) show up in something called an Object Inspector, an IDE tool that
allows one to set property values and event handlers at design time ( one
can also set these at run-time through code if one likes just as one can do
for public properties and events ). The reason for distinguishing between
__published and public in C++ Builder is that Borland did not want to force
all public properties and events into the design-time interface, especially
given that there are programmers who may not want to use the RAD
capabilities of C++ Builder. This was a very good decision as programmers
who want to use traditional, non-RAD programming but who do want to use
properties and events as a run-time mechanism, shouldn't unknowingly have
all their property and event designations showing up visually at design-time
in the Object Inspector.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Fri, 14 Mar 2003 17:27:16 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303131241.21ac5d59@posting.google.com...
> [...]
> And we used a GUI layout tool that didn't require any form of
> introspection.
May I ask which one?
> [...]
> I'm starting to understand better where you're coming from.
> Although your idea of "published" is a little weird, in the sense
> that "published" means nothing in the C++ language other than
> "public." I think that for a keyword like "published" to be
> accepted, it should have some defined meaning within the scope
> of C++.
Like "register"? ;) In the same vein, "published" is a hint to the
compilation environment...one which can be safely ignored by
compilers which don't deem it relevant. ;)
> Otherwise, you can do it yourself with
>
> #define published public
True, this works, sorta (like macro "solutions" often do ;). What it
also does is allow this nonsensical construction:
class Derived : published Base
{
};
> The other half of this question is why we need published at all?
> Why isn't public enough? Why should a RAD system not have
> access to all public members?
Often times, there are properties which don't make sense to use
at design time. But for the purpose of consistency, they are made
properties. You don't want to clutter up the design-time interface
with these properties.
> [...]
> As I understand it, what you're talking about isn't introspection
> at all, because it sounds like you're saying that the RAD system
> must parse a header file, looking for keywords like "property"
> and "published." Is this a correct interpretation?
That's probably the way it works, but I haven't implemented it
myself, so I can't say anything authoritative. ;) It's certainly not
like compile-time or run-time introspection. Whether it's really
proper to call it introspection at all is probably something I need
to think about some more (I was never totally comfortable with
the idea to begin with).
> [...]
> The point is that it's the introspection ability (that in the case
> of Lisp is a benefit of the dynamic nature of the language) that
> makes RAD work.
I'd have to see an implementation to assess this claim, and it was
very difficult to find information on the web about Lisp RAD
tools (without having to actually download and use one, which
is a bit more work than I care to do at the moment).
> [...]
> If it's true that design-time introspection is just a parsing phase
> done by the RAD system, then it's still not clear to me that it is
> properties that provide said introspection. The parsing process
> can be made to look for any kind of syntactic construct, not just
> ones that contain the key word "property."
This is true. However, it is desirable to have a consistent interface
both at design time and run time. But the design-time interface of
most RAD systems does not involve data and functions. It
involves properties and events. And a property can be a datum
or a function, or both. You could design a system that requires
this type of property declaration:
class foo
{
public:
void SetCaption(string const&);
private:
string Caption_;
};
RegisterProperty(foo, Caption, string, Caption_, &foo::SetCaption);
But then, there is no Caption property in the source. It is purely
a design-time artifact. So setting the caption in the source is
different from setting it in the design-time environment. This
tends to take the "Rapid" out of "RAD", as the programmer has
to translate between design-time and run-time interfaces. It also
breaks encapsulation, relative to property-enabled code, because
properties unify accessor and mutator functions. Without
properties, the programmer has to remember these independently.
As an analogy, consider Boost.MPL. It contains an algorithm
called copy<>, which is a compile-time analog of
std::copy(), which operates on "meta-iterators" instead of
iterators (technically, it operates on sequences, but that is a
design artifact, not an intended feature). While the syntax is
different, the "flavor" of the invokation was made as similar to
the run-time analog as possible. I think most people agree that
a more direct similarity to the run-time version would be even
more desirable, if it were possible.
> Why can't the RAD system look for public members (functions
> or data)?
> [...]
Because one often wants public members that do not show up in
the published interface. And remember that RAD IDEs typically
do not expose objects in terms of functions and data. Properties
reflect the concepts present in the RAD environment. That is
why they are the most natural implementation for RAD-friendly
source.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 14 Mar 2003 18:54:09 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
> Well, to give an example, the VCL (which is the RAD library shipped
> with BCB) commonly uses an Active property to indicate whether a
> design-time control automatically Open()s or Connect()s, or whatever
> action is appropriate for activating it. Setting the Active property to
> true or false calls this associated function (Open() or Close()). In
> this case, the reason it is a property is so that the user can activate
> the component at design time by setting the property.
>
> The side-effect here is not a simple validation or notification, but
> a major interface action. So it would seem to violate your rule.
> In general, the VCL uses member functions to perform actions,
> but for actions where the result should be streamable or activated
> at design-time, they are also enabled as properties.
If the "design" interface lets users set properties, why not also let
them call functions? Then you could preserve some semantic
correspondence with the syntax.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Mon, 17 Mar 2003 21:27:15 +0000 (UTC) Raw View
dave@boost-consulting.com (David Abrahams) wrote
> In general, I think properties should have "property-like" behavior.
> In other words, they should generally appear to be a
> reflection/transformation of some internal state, and side-effects
> should be limited to things like validation and notification.
> Otherwise, the communicative value of their syntax is completely
> undermined, and starts to work against the reader.
Well, sure.
In the same sense, overloaded operators ought to have "operator-like"
behavior. Operator+ ought to add something, operator- ought to
subtract something, operator++ ought to increment something, etc.
Naturally, the compiler does not (and cannot) judge your code based
on this rule. If you define operator+ so that adding 1 actually
sends an e-mail message, adding 2 actually starts an elevator moving
up, and adding 3 actually pages somebody -- well, you can't expect
any compiler to say, "that's not a good design for operator+."
Similarly, if properties become part of the language, a programmer
hell-bent on abusing the feature can do so. It would be easy to create
a property which -- if you set it to 1, it actually sends an e-mail
message, if you set it to 2 it actually starts an elevator moving up,
and so on.
Just like operators, anyone who learns how to use properties will first
learn the warning: "This feature exists for a purpose. Learn what
properties are supposed to do, before writing your own!" Just like
operators, there will be "hot-shot" programmers who never heed warnings,
and abuse them anyway. Just like operators, most of the hot-shot
programmers will get shot down in code reviews, and the rest will have
to live with their code (the "school of hard knocks" is yet another way
to learn the lesson).
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 17 Mar 2003 21:28:02 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:usmtta28t.fsf@boost-consulting.com...
> [...]
> Well, we also don't need a language extension for that:
>
> template <class T>
> struct property
> {
> ...
>
> T value;
> };
The problem is that properties are not required to be bound to a
data member. They can also exist purely as an alternative interface
to member functions. Let me illustrate:
class timer
{
public:
property bool running = {read = get_running, write = set_running };
private:
bool get_running(void) const
{ return time_remaining_ > 0; }
void set_running(bool state)
{ if (state) time_remaining_ = 5; else time_remaining_ = 0; }
int time_remaining_;
};
I'm not saying this is a good use of properties...just that it illustrates
the non-data nature of properties. There is no actual bool data
member associated with the running property.
> [...]
> Probably add the member name as another template parameter.
Yes, that's probably a good idea.
> > Ok, this is interesting. So you include the access information in
> > the introspection data.
>
> I thought, "why not?"
I agree, but I can't really imagine a use for it, either.
> > Let's fill it out a bit:
> >
> > template <class access, class T, T pm>
> > struct member
> > {
> > typedef access access_type;
> > typedef T member_type;
> > T operator()(void) const { return pm; }
> > };
> >
> > The trick is, would I be able to do this:
> >
> > typedef boost::mpl::at<1, members<foo> >::type prop_x;
> >
> > foo f;
> > prop_x x;
> >
> > f.*(x()) = 5;
> >
> > If so, *should* I be able to do that?
>
> Again, "why not?"
Namely, because foo originally looked like this:
class foo
{
private:
int x_;
double y_;
};
So the introspection data would theoretically allow a non-friend
to access private members of foo. Normally, this would be
prevented when the compiler parses &foo::x_. However, since
this is generated by the compiler, it's not clear how it would
control access to it once the data is created. Does this violation
of encapsulation bother you at all?
> I'd like to see someone generate this kind of thing with
> GCC_XML.
Yes, I'd like to see that as well.
> [...]
> > Also, this is what I would call "full introspection", meaning that
> > it offers much more data than what properties would provide,
> > and it doesn't provide the design-time interface that properties
> > *do* provide.
>
> I don't know; it seems as though you could build design-time info
> with this.
The problem is not what you could *extract*, but what *isn't*
specified. Namely, what isn't specified is what parts of the class
are relevant at design-time. Remember that the IDE already
has full access to the class definition. It doesn't need compile-time
or run-time introspection to do its job. In fact, using the compiler,
*it is the one that generates such information*. The problem is
that the program does not contain the information that *it* needs...
namely, which parts of the class to publish in the design-time
environment. No amount of compile-time or run-time introspection
will provide that information, since that information is not implicit
in the source itself. It must be specified explicitly as the intent of
the programmer.
Going back to our class foo example: which members should be
published, and how? Does your additional introspection data
give us any more clues? That is, if you could view an instance of
foo in a design-time object inspector (not a class inspector),
would you expect to see x_ and y_ (the way you might expect to
see a Caption property for a Window object)?
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Mon, 17 Mar 2003 21:28:23 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote
> OK:
>
> timer.set_seconds_to_go(60);
>
> This sets the time remaining and starts the timer. Here's the class:
>
> class Timer {
>
> public:
>
> void set_seconds_to_go(int);
> int get_seconds_to_go(void) const;
>
> };
>
> That discussion must include, IMHO, a discussion of whether or not the
> existing language supports the desired functionality. If your need (as
> demonstrated by the timer example) can be satisfied by existing C++
> constructs, new constructs aren't necessary.
And the existing language supports public member functions, which you
seem to consider equivalent.
But they aren't.
> So what did you think of
> the Timer class? Does it satisfy your need?
It's a toy example; it isn't designed for ANY real-world class.
In particular, there isn't any notification that the time has
elapsed, unless you poll get_seconds_to_go(). A real version
would need one or the other of the following:
* A property, containing the "handle" of something to notify
when the time reaches 0. In a GUI this "handle" could be a
window ID; the Timer would send a message to that window. Or
it could be a pointer to an object derived from a class named
TimerReachedZero. Change Timer to be a template, and we could
instead use a functor, or perhaps any object that implements
function TimerReachedZero().
or:
* An abstract function TimerReachedZero(). To use the timer,
you would derive your own class from Timer and then implement
TimerReachedZero().
> Does it demonstrate a
> pattern of design/implementation that gives you what you want? Or is
> there a problem with it?
> Does it not scale well? Does it have
> different semantics than a property-based timer? Etc.
This is the best that can be done without properties. Properties
wouldn't radically change this class -- perhaps not any class.
The differences are subtle.
I think that another class might demonstrate the difference more
clearly. Let's modify the traditional class Point.
struct Point {
double x, y;
Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
Point(const Point &p) : x(p.x), y(p.y) {}
};
Point is too simple to make normal encapsulation worthwhile. If you
want to modify x and y, you just use the member variables.
Point angle0 (0.0, 1.0); // 0 degrees, or 0*pi
// Define 180 degrees as mirror-image of 0 degrees
Point angle180(angle0.x, -angle0.y);
Here we peeked directly at angle0's y value. Conceptually identical
to angle0.getY() but easier to type, understand, use. We could also
modify x and y directly:
// Double the distance from the origin
#if false
angle0.setX(angle0.getX()*2.0);
angle0.setY(angle0.getY()*2.0);
#elif false
// If it's common to change the distance from origin:
angle0.multiplyDistanceFromOrigin(2.0);
#else
// If multiplying the distance from origin is rare,
// this is the easy way to do it:
angle0.x *= 2.0; angle0.y *= 2.0;
#endif
We all know that it "violates encapsulation" but this idiom is
nevertheless common, because encapsulation isn't needed for such
a simple concept.
But, what happens when we want to switch to polar notation?
struct PolarPoint {
double rho, theta;
PolarPoint(r=0.0,t=0.0) : rho(r), theta(t) {}
PolarPoint(const PolarPint &p) : rho(p.rho), theta(p.theta) {}
void multiplyDistanceFromOrigin(double m) { theta *= m; }
};
And when we want to convert back and forth:
PolarPoint EuclidToPolar(const Point &e);
Point PolarToEuclid(const PolarPoint &p);
It might make sense to introduce ONE type, which understands both
Euclidian notation and polar notation. We have to pick one of these
ways for the internal values, but we need not expose this decision
to clients.
class Point {
double xx, yy;
public:
Point() : xx(0.0), yy(0.0) {} // Default
Point(const Point&p) : xx(p.xx), y(p.yy) {}
// Use "Named constructor" idiom.
static Point Euclidian(double x, double y);
static Point Polar(double rho, double theta);
// The notation used to declare properties is irrelevant.
// The important thing is the notation used to use them.
property double x { return xx; }
property x(double newval) { xx = newval; }
property double rho { return whatever(yy/xx); } // Note 1
property rho(double newval) { /* Update xx and yy */ }
property double theta { return sqrt(xx*xx+yy*yy); }
property theta(double newval) { /* Update xx and yy */ }
};
Now we can use either notation, without knowing which one(s) are
used internally.
Point p(Point::Euclidian(3.0, 4.0));
std::cout << "p = (" << p.x << ", " << p.y << ")\n";
std::cout << "p: rho=" << p.rho << ", theta=" << p.theta << std::endl;
Despite the fact that rho and theta must do translating, you can call
them as simply as if they were public data members. That's the value
of properties.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 17 Mar 2003 21:28:48 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
> Perhaps you would sympathize with those Java proponents who
> argue that lack of operator overloading makes programs more
> understandable? ;)
They lost, eventually. Java now has some limited operator
overloading support.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 17 Mar 2003 21:29:05 +0000 (UTC) Raw View
john@nospam.demon.co.uk (John G Harris) writes:
> In article <uwujap6mk.fsf@boost-consulting.com>, David Abrahams
> <dave@boost-consulting.com> writes
> <snip>
>>Standard C++ is a poor tool for jobs like
>> serialization or the kind of dynamic configuration that goes on in
>> a GUI builder, because you end up writing lots of redundant
>> information (write down all the data members in the class
>> declaration, then write down the code which serializes each one,
>> then write down the code which deserializes each one).
>
> Do what? Properties are not objects so they can't be serialized. It's
> physically impossible to write a property to a disc.
>
> Moreover, Borland use the __published keyword to trigger serialization.
> This is best discussed in a separate thread. As are class loaders.
I don't really know anything about Borland's properties, but I infer
from this statement by Dave Held, that you get some kind of
(de)serialization from them:
Now, back to GUIs. ;) I argue that properties *increase*
encapsulation within the RAD context, because it enables a
RAD implementation to stream property values from a location
other than the source code.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Mon, 17 Mar 2003 21:29:43 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v6n6hcqn537u04@corp.supernews.com>...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0303081047.719a1f1d@posting.google.com...
> > [...]
> > foo.x = bar.y + baz.z * (bar.w - baz.z);
> >
> > represents poor encapsulation because part of the state of foo
> > is being set in a particular, non-reusable way to some
> > combination of part of the states of bar and baz. The states of
> > foo, bar, and baz are not encapsulated.
>
> What if foo were a complex type, and x were the real component?
> Don't you agree that having a struct-like interface that still allows
> an accessor/mutator function to be called is syntactically superior?
It depends on the complexity of the types and operations involved. I
think that this
foo.ComplexFunction(bar, baz);
is better then the "foo.x = bar.y + ..." example above. The operation
is encapsulated in a function and is reusable.
If foo were complex and x is the real component, then you're back to a
situation where the abstraction _is_ the contained data. A complex
value _is_ a real and an imaginary part. In fact, it might make sense
to just expose the real and imaginary parts as public data members.
> > I repeat my question: what sorts of problems do properties solve
> > that can't be solved without them?
>
> What sorts of problems do symbolically named operators solve
> that can't be solved without them?
>
> > As I see it, the issue of whether or not to add properties to
> > C++ comes down to this question.
>
> Then at the same time, we should be arguing whether to remove
> *all* syntactic sugar from the language.
Although I still think the question "what do properties do that can't
be done without them?" is worth asking, I am starting to be swayed by
the "syntax sugar is good" arguments.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 17 Mar 2003 21:30:18 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uwuj2dx5q.fsf@boost-consulting.com...
> [...]
> If the "design" interface lets users set properties, why not also
> let them call functions? Then you could preserve some semantic
> correspondence with the syntax.
Probably because it's not clear how you would allow the user to
call arbitrary functions at design-time. The property system forces
users to write functions with a specific signature as a design-time
interface (meaning those functions can call other functions with
any signature you like, but they must also provide the appropriate
context for the call). I could see how it would be useful to be able
to call certain functions at design-time, and maybe this is a direction
in which RAD could evolve. But I'm not aware of any RAD
systems that let you do this (though I suspect some of the more
dynamic languages which have RAD systems probably support
this).
Is is a bit curious that RAD uses the PME model, but only
properties can actually be manipulated at design-time. It would
be interesting to consider the impliciations of allowing users to
call methods and fire events manually at design-time, but I
suspect that the complications of providing an appropriate
execution environment would make this a challenging topic.
This would effectively give C++ a middle ground between
compiled and interpreted languages.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Tue, 18 Mar 2003 01:04:04 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uu1e7yvhf.fsf@boost-consulting.com...
> john@nospam.demon.co.uk (John G Harris) writes:
> > [...]
> > Do what? Properties are not objects so they can't be serialized.
> > It's physically impossible to write a property to a disc.
This isn't correct. Just because properties are not C++ objects
does not mean they can't (or aren't!) serialized. In fact, property
states are regularly stored in .dfm files in BCB projects (and have
been for years).
> > Moreover, Borland use the __published keyword to trigger
> > serialization.
This isn't correct either. All that __published does is expose part
of the interface to the design-time system. It does so
independently of serialization.
> > This is best discussed in a separate thread. As are class
> > loaders.
>
> I don't really know anything about Borland's properties, but I infer
> from this statement by Dave Held, that you get some kind of
> (de)serialization from them:
>
> Now, back to GUIs. ;) I argue that properties *increase*
> encapsulation within the RAD context, because it enables a
> RAD implementation to stream property values from a
> location other than the source code.
Well, technically, Borland uses Delphi to perform the serialization,
but it mostly involves registering the classes, which should be
possible in C++ (but Borland isn't motivated to try it in C++, since
the VCL is already written in Delphi, and tweaked to work in
BCB). I'll be honest and admit that I don't know exactly how
the serialization is performed in BCB/Delphi, but that it's probably
not pure C++ (or C++ at all, for that matter). However, I don't
see why properties couldn't or shouldn't aid serialization.
However, for the type of automatic serialization that some people
would like, I don't think properties would necessarily give an
extra advantage unless they also included some type of run-time
introspection support (which might not be a bad idea either).
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Tue, 18 Mar 2003 05:21:19 +0000 (UTC) Raw View
David Abrahams wrote:
> john@nospam.demon.co.uk (John G Harris) writes:
>
>> In article <uwujap6mk.fsf@boost-consulting.com>, David Abrahams
>> <dave@boost-consulting.com> writes
>> <snip>
>>> Standard C++ is a poor tool for jobs like
>>> serialization or the kind of dynamic configuration that goes on in
>>> a GUI builder, because you end up writing lots of redundant
>>> information (write down all the data members in the class
>>> declaration, then write down the code which serializes each one,
>>> then write down the code which deserializes each one).
>>
>> Do what? Properties are not objects so they can't be serialized. It's
>> physically impossible to write a property to a disc.
>>
>> Moreover, Borland use the __published keyword to trigger
>> serialization. This is best discussed in a separate thread. As are
>> class loaders.
>
> I don't really know anything about Borland's properties, but I infer
> from this statement by Dave Held, that you get some kind of
> (de)serialization from them:
You do get serialization and deserialization of properties but there is no
knowledge by the serialization/deserialization code of whether an actual
variable exists for the property, which is why a property is not to be
though as an l-value. Rather the serialization says: get me the property
value, I am going to stream it out somewhere, and the deserialization says:
here is the property value from the input stream; you can set your property
with it. Because of this, serialization/deserialization is not at all
coupled to the idea that an actual data member, or variable of any kind,
must actually exist for the Borland __property. And that is a good design
and very clever. It also points out why a property is only be passed by
value and not by either pointer or reference. In general I believe property
was one of the things which Borland got almost completely right.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: amir@iae.nsk.su (Amir Yantimirov)
Date: Tue, 18 Mar 2003 07:17:22 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0303121755.32e13dc5@posting.google.com>...
> I think that another class might demonstrate the difference more
> clearly. Let's modify the traditional class Point.
>
> struct Point {
> double x, y;
> Point(double xx=0.0, double yy=0.0) : x(xx), y(yy) {}
> Point(const Point &p) : x(p.x), y(p.y) {}
> };
>
> Point is too simple to make normal encapsulation worthwhile. If you
> want to modify x and y, you just use the member variables.
>
> Point angle0 (0.0, 1.0); // 0 degrees, or 0*pi
>
> // Define 180 degrees as mirror-image of 0 degrees
> Point angle180(angle0.x, -angle0.y);
>
> Here we peeked directly at angle0's y value. Conceptually identical
> to angle0.getY() but easier to type, understand, use. We could also
> modify x and y directly:
> // Double the distance from the origin
> #if false
> angle0.setX(angle0.getX()*2.0);
> angle0.setY(angle0.getY()*2.0);
> #elif false
> // If it's common to change the distance from origin:
> angle0.multiplyDistanceFromOrigin(2.0);
> #else
> // If multiplying the distance from origin is rare,
> // this is the easy way to do it:
> angle0.x *= 2.0; angle0.y *= 2.0;
> #endif
> We all know that it "violates encapsulation" but this idiom is
> nevertheless common, because encapsulation isn't needed for such
> a simple concept.
>
> But, what happens when we want to switch to polar notation?
> struct PolarPoint {
> double rho, theta;
> PolarPoint(r=0.0,t=0.0) : rho(r), theta(t) {}
> PolarPoint(const PolarPint &p) : rho(p.rho), theta(p.theta) {}
> void multiplyDistanceFromOrigin(double m) { theta *= m; }
> };
>
> And when we want to convert back and forth:
> PolarPoint EuclidToPolar(const Point &e);
> Point PolarToEuclid(const PolarPoint &p);
>
> It might make sense to introduce ONE type, which understands both
> Euclidian notation and polar notation. We have to pick one of these
> ways for the internal values, but we need not expose this decision
> to clients.
>
> class Point {
> double xx, yy;
> public:
> Point() : xx(0.0), yy(0.0) {} // Default
> Point(const Point&p) : xx(p.xx), y(p.yy) {}
> // Use "Named constructor" idiom.
> static Point Euclidian(double x, double y);
> static Point Polar(double rho, double theta);
> // The notation used to declare properties is irrelevant.
> // The important thing is the notation used to use them.
> property double x { return xx; }
> property x(double newval) { xx = newval; }
> property double rho { return whatever(yy/xx); } // Note 1
> property rho(double newval) { /* Update xx and yy */ }
> property double theta { return sqrt(xx*xx+yy*yy); }
> property theta(double newval) { /* Update xx and yy */ }
> };
>
> Now we can use either notation, without knowing which one(s) are
> used internally.
>
> Point p(Point::Euclidian(3.0, 4.0));
> std::cout << "p = (" << p.x << ", " << p.y << ")\n";
> std::cout << "p: rho=" << p.rho << ", theta=" << p.theta << std::endl;
>
> Despite the fact that rho and theta must do translating, you can call
> them as simply as if they were public data members. That's the value
> of properties.
Exactly! Lets me add something along:
http://www174.pair.com/yamir/programming/interfaces.htm
Actually, I think, properties shouldn't be part of further version of
C++. Not because they aren't good but because I see them as fragments
of new powerful programming paradigm what cannot be fully supported in
C++ and so they will remain merely a syntax sugar.
Amir Yantimirov
http://www174.pair.com/yamir/programming/
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 18 Mar 2003 17:42:31 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) writes:
> dave@boost-consulting.com (David Abrahams) wrote
>> In general, I think properties should have "property-like" behavior.
>> In other words, they should generally appear to be a
>> reflection/transformation of some internal state, and side-effects
>> should be limited to things like validation and notification.
>> Otherwise, the communicative value of their syntax is completely
>> undermined, and starts to work against the reader.
>
> Well, sure.
>
> In the same sense, overloaded operators ought to have "operator-like"
> behavior. Operator+ ought to add something, operator- ought to
> subtract something, operator++ ought to increment something, etc.
I don't agree with that; for example that would rule out expression
templates and especially libraries like spirit (http://spirit.sf.net)
This is a subtle distinction: the syntax should communicate something
"appropriate" about what's happening, but what's appropriate may
depend on the problem domain.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Wed, 19 Mar 2003 01:19:25 +0000 (UTC) Raw View
In article <c87c1cfb.0303131242.6737e50c@posting.google.com>, Bob Bell
<belvis@pacbell.net> writes
<snip>
>Although I still think the question "what do properties do that can't
>be done without them?" is worth asking, I am starting to be swayed by
>the "syntax sugar is good" arguments.
>
>Bob Bell
I still think we need some discussion of what properties can't do.
For instance : internationalisation (i18n) has been neglected. A RAD
system needs to display a Unicode string appropriate to the RAD user,
not the C++ identifier. Where does it come from ?
For instance : A RAD system will have severe problems if the property's
get/set type is any of the std:: types. They don't have serialisation
facilities.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 7 Mar 2003 00:26:41 +0000 (UTC) Raw View
Restoring deleted context: "Bob Bell" <belvis@pacbell.net> once wrote
> > > Also, on a slightly off-topic note, I've never been convinced
> > > that RAD is all that necessary. ...
> > > Tying this back to the topic at hand, this further reduces the
> > > case for properties in my book; since RAD isn't really that
> > > necessary,
> allan_w@my-dejanews.com (Allan W) replied
> > One of the best things about C++ is that it supports multiple
> > paradigms. It supports both structured programming and OO programming,
> > but you don't have to use either one of them to use C++. If you think
> > that "goto" is evil, just put up a shop rule not to use it. And so on.
> >
> > If C++ supports properties (or RAD, for that matter) and you choose
> > not to use it, the impact on you will be zero.
belvis@pacbell.net (Bob Bell) wrote
> This is not the same thing as saying that C++ should have properties.
You're right, it isn't. I didn't mean to imply that any feature which
has no impact when not used, should be accepted.
You said that you didn't feel RAD was neccesary! Which is a bit like
saying that you don't believe in gravity -- it's going to happen anyway.
If C++ has facilities to support RAD, or if it doesn't, it's still
going to be used.
Having decided that RAD wasn't neccesary, you went on to conclude that
properties had no value either. I'm not quite sure that I see the
connection; it's like saying that if you don't watch television, you
don't need electric outlets (ignoring lamps).
Frankly, I don't buy the assumption that RAD needs properties, but I
strenuously object to the idea that properties are useless without
RAD.
> The same argument ("if you don't use it then it won't impact you") can
> apply equally well to Prolog-style logic programming or symbolic
> programming as in Lisp. Do you think we should add those features to
> C++ as well?
I don't know those features too well, but I suspect that they WOULD have
an impact, even if they weren't used.
It's not as if properties (or RAD, for that matter) are a new and novel
idea that's still experimental! Based on my knowledge from other
languages, I feel that both properties (as I understand them) and RAD
would be useful to a large percentage of C++ programmers. No, I don't
have statistics to back that up -- but have you been to a college lately?
I submit that a large number of programmers want properties, at least
to the extent that if they were available, we would use them. I also
suggest that if a feature is in wide demand, and yet has no overhead
when not used, that this would be good for the C++ language.
> It comes down to this, hand-waving about RAD and GUIs aside: what
> sorts of problems do properties solve that can't be solved without
> them?
Since you made an analogy, I will too. What sorts of problems are solved
with for() statements, that can't be solved without while() statements?
What does while() solve that can't be solved with if() and goto?
Properties will enhance the expressiveness of the language. It makes
programs easier to write and understand.
> when asked what problems properties solve that couldn't be solved
> without [templates], we get examples like
>
> foo.x = bar.y + baz.z * (bar.w - baz.z);
>
> is much better than
>
> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
I'd have to agree with that!
> Even then, proponents of this argument don't claim that properties
> enable new functionality, they just make existing functionality easier
> to type and read. However, it isn't a particularly convincing
> argument, as the poor encapsulation is a bigger problem than how much
> typing is involved or how long it takes to read.
Would you please explain that last remark?
When you use properties, the syntax is similar to the syntax used to
access public member data. Is that what you mean by poor encapsulation?
Because the whole point of properties is to permit that simpler notation
without breaking encapsulation!
Perhaps, after all this, the real problem is that you don't understand
what properties are trying to accomplish?
Bob, one of us is missing the point. I hope it's not me!
Unlike public member data, assignments to (or reads of) properties
would always execute code defined privately in the class. That code
could be set up to validate the data, record it's change, or simply
deny the update. It could return having made no change, or it could
throw an exception, or display a debugging message, or simply
terminate the program.
In that sense -- just as you've been saying (repetitively) all along,
a property-set function is exactly like a formally-named access
function (such as set_x above). If the former breaks encapsulation,
then so does the latter.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sun, 9 Mar 2003 04:16:13 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) writes:
> But when asked what problems properties solve that couldn't be solved
> without them, we get examples like
>
> foo.x = bar.y + baz.z * (bar.w - baz.z);
>
> is much better than
>
> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
>
> Even then, proponents of this argument don't claim that properties
> enable new functionality, they just make existing functionality easier
> to type and read. However, it isn't a particularly convincing
> argument, as the poor encapsulation is a bigger problem than how much
> typing is involved or how long it takes to read.
>
> What have I missed? Why should C++ have properties?
There are two arguments, which as far as I can tell are completely
separate issues (the proponents seem to fail to separate them):
1. Syntax. Properties allow full encapsulation (contrary to your
assertion above) while retaining a lightweight syntax which nicely
denotes "conceptual structural component". Syntactic sugar
counts, or we'd all be programming in assembly language.
2. Introspectability. Standard C++ is a poor tool for jobs like
serialization or the kind of dynamic configuration that goes on in
a GUI builder, because you end up writing lots of redundant
information (write down all the data members in the class
declaration, then write down the code which serializes each one,
then write down the code which deserializes each one). The notion
of properties being suggested hook themselves into the RTTI
mechanism so you can enumerate them for any class, and access them
for any object.
Clearly you could do either of these without the other one.
Personally I think it would be a shame if we got #2 but it was only
accessible at runtime and not a compile-time.
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Sun, 9 Mar 2003 05:27:16 +0000 (UTC) Raw View
(Reposting -- it's been two days and this hasn't shown up yet.)
eldiener@earthlink.net ("Edward Diener") wrote in message news:<L3x9a.4322$wJ1.449104@newsread2.prod.itd.earthlink.net>...
> Bob Bell wrote:
> > allan_w@my-dejanews.com (Allan W) wrote in message
> > news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
> >> One of the best things about C++ is that it supports multiple
> >> paradigms. It supports both structured programming and OO
> >> programming,
> >> but you don't have to use either one of them to use C++. If you think
> >> that "goto" is evil, just put up a shop rule not to use it. And so
> >> on.
> >>
> >> If C++ supports properties (or RAD, for that matter) and you choose
> >> not to use it, the impact on you will be zero.
> >
> > But when asked what problems properties solve that couldn't be solved
> > without them, we get examples like
> >
> > foo.x = bar.y + baz.z * (bar.w - baz.z);
> >
> > is much better than
> >
> > foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
> >
> > Even then, proponents of this argument don't claim that properties
> > enable new functionality, they just make existing functionality easier
> > to type and read. However, it isn't a particularly convincing
> > argument, as the poor encapsulation is a bigger problem than how much
> > typing is involved or how long it takes to read.
>
> Properties have nothing to do with "poor encapsulation". Care to explain why
> you injected such a statement in this discussion ?
foo.x = bar.y + baz.z * (bar.w - baz.z);
represents poor encapsulation because part of the state of foo is
being set in a particular, non-reusable way to some combination of
part of the states of bar and baz. The states of foo, bar, and baz are
not encapsulated.
I repeat my question: what sorts of problems do properties solve that
can't be solved without them? As I see it, the issue of whether or not
to add properties to C++ comes down to this question.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Sun, 9 Mar 2003 05:28:00 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0303061545.2a5390e7@posting.google.com>...
> > > If C++ supports properties (or RAD, for that matter) and you choose
> > > not to use it, the impact on you will be zero.
>
> belvis@pacbell.net (Bob Bell) wrote
> > This is not the same thing as saying that C++ should have properties.
>
> You're right, it isn't. I didn't mean to imply that any feature which
> has no impact when not used, should be accepted.
>
> You said that you didn't feel RAD was neccesary! Which is a bit like
> saying that you don't believe in gravity -- it's going to happen anyway.
All I said was that there's no hard evidence that I'm aware of that
shows that RAD makes a significant difference in development time. All
the evidence I've heard is anecdotal. I have used GUI building tools,
and they don't seem to shave much off the total development time,
because GUI building is not a bottleneck.
In addition, it isn't even clear that properties are necessary for
RAD. What you need is some kind of introspection facility, and it's
not clear that introspection and properties are married together. For
example, RAD could be implemented by giving you a list of a class'
functions to call without properties even coming into the picture.
Perhaps you're right that it is going to happen anyway. But it seems
like there's a rush to judgment without any real critical review.
> If C++ has facilities to support RAD, or if it doesn't, it's still
> going to be used.
>
> Having decided that RAD wasn't neccesary, you went on to conclude that
> properties had no value either. I'm not quite sure that I see the
> connection; it's like saying that if you don't watch television, you
> don't need electric outlets (ignoring lamps).
>
> Frankly, I don't buy the assumption that RAD needs properties, but I
> strenuously object to the idea that properties are useless without
> RAD.
David Held claimed that RAD was the motivation for properties; I
refuted that. If you don't buy David's argument, then my refutation is
moot. However, it isn't the only refutation I've got. :-)
> > The same argument ("if you don't use it then it won't impact you") can
> > apply equally well to Prolog-style logic programming or symbolic
> > programming as in Lisp. Do you think we should add those features to
> > C++ as well?
>
> I don't know those features too well, but I suspect that they WOULD have
> an impact, even if they weren't used.
I claim that they could, at the least, be implemented in libraries
today. Clearly if that's true, you could choose not to use the library
and it would have no impact.
> It's not as if properties (or RAD, for that matter) are a new and novel
> idea that's still experimental! Based on my knowledge from other
> languages, I feel that both properties (as I understand them) and RAD
> would be useful to a large percentage of C++ programmers. No, I don't
> have statistics to back that up -- but have you been to a college lately?
No, I haven't. What's going on at colleges lately?
> I submit that a large number of programmers want properties, at least
> to the extent that if they were available, we would use them. I also
> suggest that if a feature is in wide demand, and yet has no overhead
> when not used, that this would be good for the C++ language.
You're second point here is true, but it's a little more subtle than
that. C++ isn't designed by democracy, it's designed by committee. The
majority of C++ programmers don't understand all of the intricate
relationships between features that the committee must keep straight.
A feature being in wide demand is not enough motivation for it to be
added -- it's fit into the big picture must be taken into
consideration as well. It's when you look at the bigger picture that I
see properties as falling down.
I submit that a large number of programmers want "finally" added to
the language, at least to the extent that if it were available, they
would use it. But that doesn't mean that finally belongs in C++.
> > It comes down to this, hand-waving about RAD and GUIs aside: what
> > sorts of problems do properties solve that can't be solved without
> > them?
>
> Since you made an analogy, I will too. What sorts of problems are solved
> with for() statements, that can't be solved without while() statements?
> What does while() solve that can't be solved with if() and goto?
This is a bit of an unfair comparison, since for and while were in C
over 30 years ago. C++ had no choice but to include it to maintain
compatibility. C++ has also kept a lot of C warts, for the same
reason.
The concerns we have today when considering what features to add are
very different from the concerns when C was invented.
Having said that, I will say that for and while statements fall into
the category of keeping me from having to write repetitive code using
if and goto which could lead to errors.
> Properties will enhance the expressiveness of the language. It makes
> programs easier to write and understand.
>
> > when asked what problems properties solve that couldn't be solved
> > without [templates], we get examples like
> >
> > foo.x = bar.y + baz.z * (bar.w - baz.z);
> >
> > is much better than
> >
> > foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
>
> I'd have to agree with that!
>
> > Even then, proponents of this argument don't claim that properties
> > enable new functionality, they just make existing functionality easier
> > to type and read. However, it isn't a particularly convincing
> > argument, as the poor encapsulation is a bigger problem than how much
> > typing is involved or how long it takes to read.
>
> Would you please explain that last remark?
Certainly.
> When you use properties, the syntax is similar to the syntax used to
> access public member data. Is that what you mean by poor encapsulation?
> Because the whole point of properties is to permit that simpler notation
> without breaking encapsulation!
The states of the foo, bar, and baz objects above are not
encapsulated, because the client programmer is allowed to change parts
of their states in arbitrary, non-reusable ways. Yes, I understand
that when a property is accessed, it calls a function behind the
scenes. But that doesn't change the fact that the foo, bar, and baz
objects are represented as collections of unrelated data. (More below)
> Perhaps, after all this, the real problem is that you don't understand
> what properties are trying to accomplish?
>
> Bob, one of us is missing the point. I hope it's not me!
>
> Unlike public member data, assignments to (or reads of) properties
> would always execute code defined privately in the class. That code
> could be set up to validate the data, record it's change, or simply
> deny the update. It could return having made no change, or it could
> throw an exception, or display a debugging message, or simply
> terminate the program.
This doesn't make the property very useful. The property "x" of an
object promises an interface to the object -- that the x property can
be changed. If this:
foo.x = 10;
can fail, it doesn't really sound like it's living up to its promise.
> In that sense -- just as you've been saying (repetitively) all along,
> a property-set function is exactly like a formally-named access
> function (such as set_x above). If the former breaks encapsulation,
> then so does the latter.
Exactly. Accessors _do_, in general, break encapsulation. For a class
like the standard list template, accessors to members would just allow
clients to mess with the internal state.
Another example: a date class, with year, month and day properties. If
the date is currently Jan 31, 2003, and I want to change it to Feb 29,
2004, this sequence of code seems reasonable:
dt.day = 29;
dt.month = 2;
dt.year = 2004;
What happens when the month is assigned? Either
-- the assignment happens, but I now (temporarily) have an invalid
date: Feb 29, 2003
-- the assignment fails, in which case I end up with Jan 29, 2004
-- the assignment succeeds, but adjusts the date to be consistent, in
which case I end up with Feb 28, 2004
None of these options seem very good to me. Can you think of any
better ones?
The problem is that a date class is not very well modeled as a
collection of day, month and year properties. An intelligent date
class is not simply three ints that can be changed independently, as
the property interface suggests.
Note that this example wouldn't be any better if we were using
set_date, set_month and set_year accessors.
There are very few classes for which pure accessors make sense:
classes where the abstraction _is_ an aggregation of other data
objects, and those objects are allowed to vary independently. An
example is a 2D point. I also claim that these classes are exactly the
set of classes for which properties make sense. I finally claim that
there isn't any functionality added by properties that isn't available
through accessors.
Given that:
-- the functionality enabled by properties is already available
through accessors
-- the number of classes which need this functionality is small
I just don't see any justification for adding properties to C++.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: comp.std.c++_2003-03-09@nmhq.net (Niklas Matthies)
Date: Sun, 9 Mar 2003 20:07:47 +0000 (UTC) Raw View
On 2003-03-09 04:16, David Abrahams <dave@boost-consulting.com> wrote:
> belvis@pacbell.net (Bob Bell) writes:
[...]
>> What have I missed? Why should C++ have properties?
>=20
> There are two arguments, which as far as I can tell are completely
> separate issues (the proponents seem to fail to separate them):
>=20
> 1. Syntax. Properties allow full encapsulation (contrary to your
> assertion above) while retaining a lightweight syntax which nicely
> denotes "conceptual structural component". Syntactic sugar
> counts, or we'd all be programming in assembly language.
Very well said. To give an example, in Visual Basic, which supports
properties, I've written a Timer class that has a property
'seconds_to_go'. (The class' raison d'=EAtre is that, unlike VB's
standard timer control, it is not bound to a form.) Setting it to a
non-zero value (re)starts the timer with the given number of seconds.
Setting it to zero stops the timer, if it was running. Reading it
yields the number of seconds to go until the timer elapses, of course,
or zero if it already has elapsed/was stopped. The Timer class has no
other methods, only this property. (When the timer reaches zero, the
object raises an event.)
Of course one can always simulate the same functionality with methods.
But the above behavior of setting seems less natural with a method
set_seconds_to_go(...). Here, the client tells the object to set its
"seconds to go" to some value. It's less obvious that the object, in
addition to carrying out this request of setting a value of its
internal state, starts or stops to do something (i.e. counting down).
In fact, I would expect that, for this reason, most C++ programmers
would design the class in a different way than with a pair of get/set
methods, either like
void start(int seconds); // undefined when running?
void stop();
int get_seconds_to_go() const; // undefined when stopped?
or even
void set_seconds(int seconds); // no effect when running?
// maybe on next start?
void start(); // undefined when running?
void stop();
int get_seconds() const; // initial count, or seconds to go?
With the property, on the other hand, conceptually the client does the
setting himself, and the object's activity merely consists of adjusting
its behavior to the new setting. This is, in a way, also similar to a
hardware-register-like volatile variable, where setting it has a
certain side effect.
What's important here is that using properties that way _feels_
significantly different than doing the same with a set of methods.
It changes how you think about the object. It removes one level of
indirection in how the client conceptually sees the object, and the
object's state. The Timer object with its single property appears
conceptually simpler than its method-using counterpart(s), its state
appears to be external, concrete, not something hidden away inside
that one can only get at indirectly.
As should have become clear by now, I happen to think that properties
are a valuable conceptual tool, and that C++ would be richer in having
them. To repeat what David Abarahams said above: syntactic sugar counts.
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Sun, 9 Mar 2003 20:07:47 +0000 (UTC) Raw View
Bob Bell wrote:
> (Reposting -- it's been two days and this hasn't shown up yet.)
>
> eldiener@earthlink.net ("Edward Diener") wrote in message
> news:<L3x9a.4322$wJ1.449104@newsread2.prod.itd.earthlink.net>...
>> Bob Bell wrote:
>>> allan_w@my-dejanews.com (Allan W) wrote in message
>>> news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
>>>> One of the best things about C++ is that it supports multiple
>>>> paradigms. It supports both structured programming and OO
>>>> programming,
>>>> but you don't have to use either one of them to use C++. If you
>>>> think
>>>> that "goto" is evil, just put up a shop rule not to use it. And so
>>>> on.
>>>>
>>>> If C++ supports properties (or RAD, for that matter) and you choose
>>>> not to use it, the impact on you will be zero.
>>>
>>> But when asked what problems properties solve that couldn't be
>>> solved
>>> without them, we get examples like
>>>
>>> foo.x = bar.y + baz.z * (bar.w - baz.z);
>>>
>>> is much better than
>>>
>>> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() -
>>> baz.get_z()));
>>>
>>> Even then, proponents of this argument don't claim that properties
>>> enable new functionality, they just make existing functionality
>>> easier
>>> to type and read. However, it isn't a particularly convincing
>>> argument, as the poor encapsulation is a bigger problem than how
>>> much
>>> typing is involved or how long it takes to read.
>>
>> Properties have nothing to do with "poor encapsulation". Care to
>> explain why
>> you injected such a statement in this discussion ?
>
> foo.x = bar.y + baz.z * (bar.w - baz.z);
>
> represents poor encapsulation because part of the state of foo is
> being set in a particular, non-reusable way to some combination of
> part of the states of bar and baz. The states of foo, bar, and baz are
> not encapsulated.
Your example has nothing to do with properties themselves. They are just an
example of setting some value in an object based on the values of other
objects, and then saying that this represents poor encapsulation. One can
just as easily create your example by using member functions to get values
from bar and baz and set a value in foo using a member function. Should we
get rid of member functions then because they "represent poor encapsulation"
?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bop2@telia.com ("Bo Persson")
Date: Mon, 10 Mar 2003 00:51:03 +0000 (UTC) Raw View
""Edward Diener"" <eldiener@earthlink.net> skrev i meddelandet
news:aBFaa.10445$wJ1.993297@newsread2.prod.itd.earthlink.net...
> Bob Bell wrote:
> > (Reposting -- it's been two days and this hasn't shown up yet.)
> >
> > eldiener@earthlink.net ("Edward Diener") wrote in message
> > news:<L3x9a.4322$wJ1.449104@newsread2.prod.itd.earthlink.net>...
> >> Bob Bell wrote:
> >>> allan_w@my-dejanews.com (Allan W) wrote in message
> >>> news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
> >>>> One of the best things about C++ is that it supports multiple
> >>>> paradigms. It supports both structured programming and OO
> >>>> programming,
> >>>> but you don't have to use either one of them to use C++. If you
> >>>> think
> >>>> that "goto" is evil, just put up a shop rule not to use it. And so
> >>>> on.
> >>>>
> >>>> If C++ supports properties (or RAD, for that matter) and you choose
> >>>> not to use it, the impact on you will be zero.
> >>>
> >>> But when asked what problems properties solve that couldn't be
> >>> solved
> >>> without them, we get examples like
> >>>
> >>> foo.x = bar.y + baz.z * (bar.w - baz.z);
> >>>
> >>> is much better than
> >>>
> >>> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() -
> >>> baz.get_z()));
> >>>
> >>> Even then, proponents of this argument don't claim that properties
> >>> enable new functionality, they just make existing functionality
> >>> easier
> >>> to type and read. However, it isn't a particularly convincing
> >>> argument, as the poor encapsulation is a bigger problem than how
> >>> much
> >>> typing is involved or how long it takes to read.
> >>
> >> Properties have nothing to do with "poor encapsulation". Care to
> >> explain why
> >> you injected such a statement in this discussion ?
> >
> > foo.x = bar.y + baz.z * (bar.w - baz.z);
> >
> > represents poor encapsulation because part of the state of foo is
> > being set in a particular, non-reusable way to some combination of
> > part of the states of bar and baz. The states of foo, bar, and baz are
> > not encapsulated.
>
> Your example has nothing to do with properties themselves. They are just
an
> example of setting some value in an object based on the values of other
> objects, and then saying that this represents poor encapsulation. One can
> just as easily create your example by using member functions to get values
> from bar and baz and set a value in foo using a member function. Should we
> get rid of member functions then because they "represent poor
encapsulation"
> ?
>
No, his point was that this use of properties represents poor encapsualtion
*just* like use of get/set functions. The difference is that properties are
proposed to be added to the language, though some of us cannot see any
*good* use for them. The example above was of *bad* use. In a good object
abstraction, you are generally not supposed to set values, you are supposed
to have the object perform things!
Look at the standard library classes, which might have a size() or
capacity() to ask about current state, but there are no set_size() or
set_capacity(). Different implementations might (and do!) choose between
storing size and capacity, or to compute them from pointers when requested.
IMO that is a sign of good abstractions.
Bo Persson
bop2@telia.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 10 Mar 2003 03:22:05 +0000 (UTC) Raw View
""Bo Persson"" <bop2@telia.com> wrote in message
news:rmPaa.3647$ID6.7672@newsc.telia.net...
> [...]
> No, his point was that this use of properties represents poor
> encapsualtion *just* like use of get/set functions. The difference
> is that properties are proposed to be added to the language,
> though some of us cannot see any *good* use for them. The
> example above was of *bad* use. In a good object abstraction,
> you are generally not supposed to set values, you are supposed
> to have the object perform things!
Perhaps a more appropriate example would be something like the
VCL's TDataSet class. It exposes a property called Active. You
can check the property to see if the associated dataset (table or
query result) is open or not. You can open the associated dataset
by setting Active to true. You can close it by setting Active to
false. Whether or not there is an actual boolean data variable in
the TDataSet definition representing the Active property is totally
irrelevant. What the Active member does is provide a design-time
interface for opening and closing the dataset. If you save the
component with Active set to true, then the dataset is
automatically opened for you when the component is created.
This is an example of what I call "design-time encapsulation":
design-time information (whether a dataset is open or not) gets
stored in the .dfm rather than the source file. There are named
functions Open() and Close() in the public interface of TDataSet
which provide the member function interface for Active. But the
way you inform the RAD environment that you want to open the
dataset is by setting the Active property to true in the object
inspector. This lets you open a dataset at *design time*, and
view live data to ensure that your controls have been configured
as expected (without having to go through a compile-link-execute
cycle).
If this sounds like it doesn't save time, consider the case when
the dataset is a query. You can force the dataset to auto-
generate field objects for the result set based on the SQL string
you provide. For simple queries, this is just a nice convenience,
saving some time and typing, and helping you by generating
synchronized source that could otherwise be a source of typing
errors if you had to do it yourself. For complex queries with
lots of fields and joins, this saves a *lot* of time, as being able
to validate the SQL string at design-time helps you catch errors
right away, rather than after an iteration of the compile-link-
execute cycle. Indeed, it allows you to validate your SQL
before you've even written program logic that would otherwise
do so.
Now, does the Active property of TDataSet violate
encapsulation? Without looking at the source code, we can't
even say! Why? Because we don't even know if there is an
actual data member associated with Active! It would be
perfectly legal for there to be a read function associated with
Active that simply always returned true (in fact, some
properties are implemented just this way in base classes where
the functionality is not yet defined), and the write function to
merely call Open() or Close() as appropriate. The property
interface only violates encapsulation if you make it violate
encapsulation. And even if there is an actual data variable
representing the Active property, it is obvious that the write
function for the property is not a naive setter function. It
simply gives the programmer an alternative way to spell
Open() and Close() (that happens to be RAD-friendly).
> Look at the standard library classes, which might have a
> size() or capacity() to ask about current state, but there are
> no set_size() or set_capacity(). Different implementations
> might (and do!) choose between storing size and capacity,
> or to compute them from pointers when requested.
> IMO that is a sign of good abstractions.
Look at the VCL TDataSet class, which I mentioned before.
It contains an ActiveRecord property which returns the index
of the active record. Is there a way to set this value? Even
though such a thing might be a sensible synonym for
GotoRecord(), this property is, in fact, a read-only property.
Of the 44 properties exposed by TDataSet, all but 18 of
them are read-only properties. This means that 26 of the
properties are no different than simple accessor functions
(note that I do not include mutator functions in the class of
"accessors"). Given that TDataSet is considerably more
feature-rich than the standard library classes (which must
be generic, not feature-laden), it is appropriate that there
are many switches and features which can be turned on
or off. These "feature switches" are generally controlled
by properties, and are almost surely linked to appropriate
functions on the write side of the property.
Consider the Bookmark property of TDataSet. If the
property interface were not available, the most appropriate
interface would be something like: GetBookmarkStr(),
SetBookmarkStr(AnsiString) (which is the actual functions
called by the property itself). Does the setter in this case
really violate encapsulation? The bookmark is an
independent feature of the dataset which does not need to
coordinate with any other features to enforce class
invariants. And if the named setter function does not violate
encapsulation, then why should it through the extra layer of
indirection that is the property?
It is possible to design bad interfaces without properties,
but properties themselves do not force you to write bad
interfaces. If you think the examples I have provided
represent poor encapsulation, then feel free to explain
why.
Dave
P.S. If there is an actual data member behind the Active
property, you wouldn't know it by reading the docs, since
they specify the property to call a GetActive and SetActive
member for reading and writing, respectively. Although
GetActive or SetActive could theoretically be the names
of data members, I think it's pretty obvious that they are
most likely function names.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 10 Mar 2003 03:22:34 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uwujap6mk.fsf@boost-consulting.com...
> [...]
> There are two arguments, which as far as I can tell are
> completely separate issues (the proponents seem to fail to
> separate them):
Actually, if you look carefully, you'll see that I avoid arguing for
the syntax benefit of properties, while Allan W generally avoids
arguing for the RAD benefit. Only Ed Diener appears comfortable
with both sides.
> 1. Syntax. Properties allow full encapsulation (contrary to your
> assertion above) while retaining a lightweight syntax which
> nicely denotes "conceptual structural component". Syntactic
> sugar counts, or we'd all be programming in assembly language.
Yes, there are several language features which offer little or nothing
more than syntactic sugar. Symbolic operator overloading, switch,
operator[], and operator-> come to mind.
> 2. Introspectability. Standard C++ is a poor tool for jobs like
> serialization or the kind of dynamic configuration that goes on
> in a GUI builder, because you end up writing lots of redundant
> information (write down all the data members in the class
> declaration, then write down the code which serializes each
> one, then write down the code which deserializes each one).
> The notion of properties being suggested hook themselves into
> the RTTI mechanism so you can enumerate them for any class,
> and access them for any object.
Well, that would certainly give you more powerful introspection,
but I don't think I've seen this be suggested before (the RTTI
link).
> Clearly you could do either of these without the other one.
Yes, I think we've all said about as much.
> Personally I think it would be a shame if we got #2 but it was
> only accessible at runtime and not a compile-time.
Compile-time introspection would certainly be nice, but isn't
that a much larger scope than what properties would cover, even
with your RTTI angle? And would a static/dynamic introspection
system still provide the design-time capability that properties
provide? I argue that the answer is "not necessarily". As I see
it, using properties to provide introspection gives what you might
call "limited" or "controlled" introspection. This might be an
efficient way to prevent the compiler from generating a lot of
introspection data that does not get used, but it is not generically
powerful. For instance, it would not allow introspection of
classes which cannot be modified. Perhaps we should debate
whether introspection should be cooperative or not.
Providing what I call "full introspection" would involve operators
that would simply give access to data and/or function members
in a uniform way. Perhaps something like this:
class foo
{
private:
int x_;
double y_;
};
typeid(foo).member_count() == 2
typeid(foo).member_at<0>::type == int
typeid(foo).member_at<0>::value == foo::int*
typeid(foo).member_at<1>::type == double
typeid(foo).member_at<1>::value == foo::double*
Maybe you could do something like this:
foo f;
f.*(typeid(foo).member_at<0>::value) = 5;
This is non-intrusive and gives full introspection data, rather than
just prescribed data. On the other hand, it violates access rules.
And one probably does not want to make the data members
public just to get introspection.
So on second thought, perhaps properties are a good way to
providing introspection while maintaining access permissions.
To satisfy your compile-time introspection, perhaps we could
have something like this:
class foo
{
public:
property int x = {read = x_;};
property double y = {read = y_;};
private:
int x_;
double y_;
};
typeid(foo).property_at<0>::type == int
typeid(foo).property_at<0>::value == foo::int*
typeid(foo).property_at<1>::type == double
typeid(foo).property_at<1>::value == foo::double*
And require that property_at<n>::type is a typedef for a type,
so it is available at compile-time.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 10 Mar 2003 04:05:03 +0000 (UTC) Raw View
bop2@telia.com ("Bo Persson") writes:
>> Your example has nothing to do with properties themselves. They are
>> just an example of setting some value in an object based on the
>> values of other objects, and then saying that this represents poor
>> encapsulation. One can just as easily create your example by using
>> member functions to get values from bar and baz and set a value in
>> foo using a member function. Should we get rid of member functions
>> then because they "represent poor encapsulation" ?
>
> No, his point was that this use of properties represents poor encapsualtion
> *just* like use of get/set functions. The difference is that properties are
> proposed to be added to the language, though some of us cannot see any
> *good* use for them. The example above was of *bad* use. In a good object
> abstraction, you are generally not supposed to set values, you are supposed
> to have the object perform things!
This is one of those rules that's very good for critical reasoning
about your code, but which shouldn't be taken as gospel. Some
abstractions *are* conceptually composed of others.
> Look at the standard library classes, which might have a size() or
> capacity() to ask about current state, but there are no set_size() or
> set_capacity(). Different implementations might (and do!) choose between
> storing size and capacity, or to compute them from pointers when requested.
> IMO that is a sign of good abstractions.
The standard library containers are a perfect example! They
directly expose the elements they contain (are composed of). Other
examples of abstractions like this include graphs, which are composed
of vertices and edges, and "fields" in certain physical simulations,
which are composed of multiple collections of particles.
Trying to stuff all of the algorithms which might possibly operate on
graphs or fields into the graph or field objects themselves would be
disastrous for program structure (see std::basic_string for a mild
example), not to mention that it doesn't support algorithms which
operate on multiple objects as equal participants. Somehow you need
to get access to the edges, vertices, electrons, holons, spinons, and
bogons. In cases like this it might be better to access them via
f.bogons than via f.bogons(). Either of those is better than
f.begin_holons(), f.end_holons() pairs.
However, though I buy the syntax argument, I don't think it's nearly
as important as the introspection argument (which most people are
ignoring because it's not as easy to grok ;-)).
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Mon, 10 Mar 2003 14:32:40 +0000 (UTC) Raw View
comp.std.c++ 2003-03-09@nmhq.net (Niklas Matthies) wrote in message news:<slrnb6m2na.1j6g.comp.std.c++_2003-03-09@nmhq.net>...
> On 2003-03-09 04:16, David Abrahams <dave@boost-consulting.com> wrote:
> > belvis@pacbell.net (Bob Bell) writes:
> [...]
> >> What have I missed? Why should C++ have properties?
> >
> > There are two arguments, which as far as I can tell are completely
> > separate issues (the proponents seem to fail to separate them):
> >
> > 1. Syntax. Properties allow full encapsulation (contrary to your
> > assertion above) while retaining a lightweight syntax which nicely
> > denotes "conceptual structural component". Syntactic sugar
> > counts, or we'd all be programming in assembly language.
>
> Very well said. To give an example, in Visual Basic, which supports
> properties, I've written a Timer class that has a property
> 'seconds to go'. (The class' raison d' tre is that, unlike VB's
> standard timer control, it is not bound to a form.) Setting it to a
> non-zero value (re)starts the timer with the given number of seconds.
> Setting it to zero stops the timer, if it was running. Reading it
> yields the number of seconds to go until the timer elapses, of course,
> or zero if it already has elapsed/was stopped. The Timer class has no
> other methods, only this property. (When the timer reaches zero, the
> object raises an event.)
>
> Of course one can always simulate the same functionality with methods.
I would say it the other way around: that you are using properties to
simulate what is more natural with methods. If I see code that sets a
member variable (or _looks_ like it sets a member variable):
timer.seconds_to_go = 60;
I find it surprising that it has a side effect such as the one you
describe above. But code like this:
timer.set_seconds_to_go(60);
timer.start();
makes it explicit exactly what's happening.
> But the above behavior of setting seems less natural with a method
> set seconds to go(...). Here, the client tells the object to set its
> "seconds to go" to some value. It's less obvious that the object, in
> addition to carrying out this request of setting a value of its
> internal state, starts or stops to do something (i.e. counting down).
This argument applies to
timer.seconds_to_go = 60;
It's not obvious that the object, in addition to carrying out this
request of setting a value of its internal state, starts or stops to
do something (i.e. counting down).
Not only that, but it is impossible to set the time remaining without
simultaneously starting the timer. One must therefore be more careful
with this version of the timer.
> In fact, I would expect that, for this reason, most C++ programmers
> would design the class in a different way than with a pair of get/set
> methods, either like
>
> void start(int seconds); // undefined when running?
> void stop();
> int get seconds to go() const; // undefined when stopped?
>
> or even
>
> void set seconds(int seconds); // no effect when running?
> // maybe on next start?
> void start(); // undefined when running?
> void stop();
> int get seconds() const; // initial count, or seconds to go?
>
> With the property, on the other hand, conceptually the client does the
> setting himself, and the object's activity merely consists of adjusting
> its behavior to the new setting. This is, in a way, also similar to a
> hardware-register-like volatile variable, where setting it has a
> certain side effect.
>
> What's important here is that using properties that way feels
> significantly different than doing the same with a set of methods.
> It changes how you think about the object. It removes one level of
> indirection in how the client conceptually sees the object, and the
> object's state.
I don't see this -- using either properties or member functions,
you're changing the object's state and causing side effects. How do
you think differently about the property version?
> The Timer object with its single property appears
> conceptually simpler than its method-using counterpart(s), its state
> appears to be external, concrete, not something hidden away inside
> that one can only get at indirectly.
None of these things seem like advantages -- why is it important that
the state appear external and not hidden away?
> As should have become clear by now, I happen to think that properties
> are a valuable conceptual tool, and that C++ would be richer in having
> them. To repeat what David Abarahams said above: syntactic sugar counts.
To be frank, more than anything else this example seems like it
violates the principle of least surprise. If today (without
properties) I show you this line of code
timer.seconds_to_go = 60;
you would think that it assigns 60 to the seconds_to_go member. And
unless seconds_to_go is a type with a user-defined copy assignment
operator with extra side effects, you'd be right. Copy assignment
operators with side effects are frowned upon for good reason --
because they violate the principle of least surprise.
But even after that, if you really want this kind of class, you don't
need properties to create it in today's C++:
class Timer {
public:
class TimerInternal {
public:
// Return the time remaining:
operator int(void) const;
// Set the time remaining and start the timer.
// When the timer goes off, fire an event (whatever
// that is):
TimerInternal& operator=(int iSeconds);
private:
// Allow the enclosing class to create a TimerInternal
friend class Timer;
// Prevent the rest of the world from using TimerInternal.
// Of course, these functions need to be implemented.
// Note that copying doesn't need to be implemented if
// Timer isn't copyable.
TimerInternal(void);
TimerInternal(const TimerInternal&);
~TimerInternal(void);
TimerInternal& operator=(const TimerInternal&);
// Timer members here
};
TimerInternal seconds_to_go;
private:
};
This will do today, without properties, what you describe. I have no
idea how much more verbose this is than the property version, but it
doesn't seem all that verbose to me.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Mon, 10 Mar 2003 14:32:59 +0000 (UTC) Raw View
"Bo Persson" wrote:
> ""Edward Diener"" <eldiener@earthlink.net> skrev i meddelandet
> news:aBFaa.10445$wJ1.993297@newsread2.prod.itd.earthlink.net...
>> Bob Bell wrote:
>>> (Reposting -- it's been two days and this hasn't shown up yet.)
>>>
>>> eldiener@earthlink.net ("Edward Diener") wrote in message
>>> news:<L3x9a.4322$wJ1.449104@newsread2.prod.itd.earthlink.net>...
>>>> Bob Bell wrote:
>>>>> allan_w@my-dejanews.com (Allan W) wrote in message
>>>>> news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
>>>>>> One of the best things about C++ is that it supports multiple
>>>>>> paradigms. It supports both structured programming and OO
>>>>>> programming,
>>>>>> but you don't have to use either one of them to use C++. If you
>>>>>> think
>>>>>> that "goto" is evil, just put up a shop rule not to use it. And
>>>>>> so on.
>>>>>>
>>>>>> If C++ supports properties (or RAD, for that matter) and you
>>>>>> choose not to use it, the impact on you will be zero.
>>>>>
>>>>> But when asked what problems properties solve that couldn't be
>>>>> solved
>>>>> without them, we get examples like
>>>>>
>>>>> foo.x = bar.y + baz.z * (bar.w - baz.z);
>>>>>
>>>>> is much better than
>>>>>
>>>>> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() -
>>>>> baz.get_z()));
>>>>>
>>>>> Even then, proponents of this argument don't claim that properties
>>>>> enable new functionality, they just make existing functionality
>>>>> easier
>>>>> to type and read. However, it isn't a particularly convincing
>>>>> argument, as the poor encapsulation is a bigger problem than how
>>>>> much
>>>>> typing is involved or how long it takes to read.
>>>>
>>>> Properties have nothing to do with "poor encapsulation". Care to
>>>> explain why
>>>> you injected such a statement in this discussion ?
>>>
>>> foo.x = bar.y + baz.z * (bar.w - baz.z);
>>>
>>> represents poor encapsulation because part of the state of foo is
>>> being set in a particular, non-reusable way to some combination of
>>> part of the states of bar and baz. The states of foo, bar, and baz
>>> are not encapsulated.
>>
>> Your example has nothing to do with properties themselves. They are
>> just an example of setting some value in an object based on the
>> values of other objects, and then saying that this represents poor
>> encapsulation. One can just as easily create your example by using
>> member functions to get values from bar and baz and set a value in
>> foo using a member function. Should we get rid of member functions
>> then because they "represent poor encapsulation" ?
>>
>
> No, his point was that this use of properties represents poor
> encapsualtion
> *just* like use of get/set functions. The difference is that
> properties are proposed to be added to the language, though some of
> us cannot see any
> *good* use for them. The example above was of *bad* use. In a good
> object abstraction, you are generally not supposed to set values, you
> are supposed to have the object perform things!
This last sentence is your definition of "good object abstraction". It is
far too limited for my own use, and I see no value to it. Not being able to
set characteristics which make up an object, other than at construction
time, seems far too limiting to me. Your idea of an object is completely
static such as that an object is created with certain characteristics and
must then never be changed except through actions. I can't possibly conceive
of such a limited OOP model for myself.
>
> Look at the standard library classes, which might have a size() or
> capacity() to ask about current state, but there are no set_size() or
> set_capacity(). Different implementations might (and do!) choose
> between storing size and capacity, or to compute them from pointers
> when requested. IMO that is a sign of good abstractions.
Containers are only one type of object. Other objects are not nearly as
simple in representation as containers. If you want to build your own
systems based on objects whose representation is completely defined at
construction, that is your choice but you shouldn't think to impose such a
severe restriction on others.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 10 Mar 2003 18:21:05 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
> "David Abrahams" <dave@boost-consulting.com> wrote in message
> news:uwujap6mk.fsf@boost-consulting.com...
>> 2. Introspectability. Standard C++ is a poor tool for jobs like
>> serialization or the kind of dynamic configuration that goes on
>> in a GUI builder, because you end up writing lots of redundant
>> information (write down all the data members in the class
>> declaration, then write down the code which serializes each
>> one, then write down the code which deserializes each one).
>> The notion of properties being suggested hook themselves into
>> the RTTI mechanism so you can enumerate them for any class,
>> and access them for any object.
>
> Well, that would certainly give you more powerful introspection,
> but I don't think I've seen this be suggested before (the RTTI
> link).
I don't see how you're going to easily build RAD systems which allow
you to tweak the fields of a class using a GUI otherwise.
>> Personally I think it would be a shame if we got #2 but it was
>> only accessible at runtime and not a compile-time.
>
> Compile-time introspection would certainly be nice, but isn't
> that a much larger scope than what properties would cover, even
> with your RTTI angle?
I'm not sure it is.
> And would a static/dynamic introspection system still provide the
> design-time capability that properties provide? I argue that the
> answer is "not necessarily". As I see it, using properties to
> provide introspection gives what you might call "limited" or
> "controlled" introspection. This might be an efficient way to
> prevent the compiler from generating a lot of introspection data
> that does not get used, but it is not generically powerful. For
> instance, it would not allow introspection of classes which cannot
> be modified. Perhaps we should debate whether introspection should
> be cooperative or not.
>
> Providing what I call "full introspection" would involve operators
> that would simply give access to data and/or function members
> in a uniform way. Perhaps something like this:
>
> class foo
> {
> private:
> int x_;
> double y_;
> };
>
> typeid(foo).member_count() == 2
> typeid(foo).member_at<0>::type == int
> typeid(foo).member_at<0>::value == foo::int*
> typeid(foo).member_at<1>::type == double
> typeid(foo).member_at<1>::value == foo::double*
That won't work for dynamic polymorphism unless member_at<> is a very
odd type of member template. For the runtime interface you'd need to
do something which allows us to express that the Nth member's type is
different depending on the dynamic type of the argument to typeid().
I had something like this in mind for the compile-time interface.
template <class access, class T, T pm>
struct member {};
// generated by the compiler on demand:
template <>
struct members<foo>
: boost::mpl::vector<
member<public_tag, foo& (foo::*)(foo const&), &foo::operator=>
, member<private_tag, int foo::*, &foo::x_>
, member<private_tag, double foo::*, &foo::y_>
>
{
};
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 10 Mar 2003 18:24:32 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303081046.67af31b8@posting.google.com...
> allan_w@my-dejanews.com (Allan W) wrote in message
news:<7f2735a5.0303061545.2a5390e7@posting.google.com>...
> [...]
> All I said was that there's no hard evidence that I'm aware of
> that shows that RAD makes a significant difference in development
> time.
It depends on the size and nature of the project.
> All the evidence I've heard is anecdotal.
I could relate personal experience, but then you would just say that
it's not your experience, and ignore it.
> I have used GUI building tools, and they don't seem to shave much
> off the total development time, because GUI building is not a
> bottleneck.
What types of applications do you write?
> In addition, it isn't even clear that properties are necessary for
> RAD.
They may not be strictly necessary, but thus far, I have not seen
any alternative offered.
> What you need is some kind of introspection facility, and it's
> not clear that introspection and properties are married together.
I agree with this. But properties give you enough introspection
to do RAD. It's not obvious that a general introspection system
would give enough information to do RAD. Unless it were
contrived to do so, I would guess that it wouldn't.
> For example, RAD could be implemented by giving you a list
> of a class' functions to call without properties even coming into
> the picture.
And more hand-waving from someone who probably hasn't
thought too hard about how RAD actually works. What good is
a list of member functions to a RAD designer? The most critical
point where RAD intersects with the language is this: there must
be a way for the source to inform the RAD system which parts
of a class should be published. This is the piece that generic
introspection doesn't give you. Introspection gives you
information about the class without telling you what part of that
information is relevant to RAD. *That* is abandoning
encapsulation. What properties do, plain and simple, is inform
the RAD system of the relevant portions of classes. That it
also happens to provide some introspection capability is useful
and necessary, but not the primary benefit to RAD. And note
that the type of introspection that properties provide is not really
useful in other contexts, like generic programming. For instance,
it still wouldn't be possible to write a function that assigns a value
to all the members of a class using properties. The type of
introspection that properties provide is mostly useful above the
language level (at the design-time level). And the type of
information that general introspection provides is mostly useful
at the language level, but below the design-time level.
> Perhaps you're right that it is going to happen anyway. But it
> seems like there's a rush to judgment without any real critical
> review.
I think we've been having a critical review for weeks now. ;)
And I don't see any "rush to judgement". Perhaps you could
specify how you think that is happening?
> [...]
> David Held claimed that RAD was the motivation for
> properties; I refuted that.
You refuted that RAD is the motivation for properties? No you
didn't. Or you refuted that RAD is useful? Didn't do that either.
Besides, didn't anyone ever tell you that it's impossible to prove
a negative? ;)
> [...]
> > > The same argument ("if you don't use it then it won't impact
> > > you") can apply equally well to Prolog-style logic
> > > programming or symbolic programming as in Lisp. Do you
> > > think we should add those features to C++ as well?
> >
> > I don't know those features too well, but I suspect that they
> > WOULD have an impact, even if they weren't used.
>
> I claim that they could, at the least, be implemented in libraries
> today. Clearly if that's true, you could choose not to use the
> library and it would have no impact.
And if it *could* be implemented in a library, then why would you
suggest to add it to the language? Only because it is compellingly
useful, which you have not demonstrated. Zero-overhead
properties *cannot* be implemented in a library, or we wouldn't
be having this discussion. Which is why your point about Lisp is
irrelevant.
> [...]
> The concerns we have today when considering what features to
> add are very different from the concerns when C was invented.
But you seem to be completely ignoring the fact that operator
overloading is no less syntactic sugar than properties (even more
so, since that's *all* it provides over named function overloading,
whereas properties also provide limited introspection), and it is
a distinctly C++ feature that was added using "C++ criteria".
> [...]
> This doesn't make the property very useful. The property "x" of
> an object promises an interface to the object -- that the x
> property can be changed.
Patently false.
> If this:
>
> foo.x = 10;
>
> can fail, it doesn't really sound like it's living up to its promise.
You must not have used RAD designers for very long, because
read-only properties are both common and useful. They are as
common and useful as accessor functions (which do not break
encapsulation, because functions which change state are not
*accessors*...they are *mutators*).
> [...]
> Exactly. Accessors _do_, in general, break encapsulation. For
> a class like the standard list template, accessors to members
> would just allow clients to mess with the internal state.
But list.size() is essentially an accessor function. A function
which allows for the direct setting of internal state is not an
"accessor".
> Another example: a date class, with year, month and day
> properties. If the date is currently Jan 31, 2003, and I want
> to change it to Feb 29, 2004, this sequence of code seems
> reasonable:
>
> dt.day = 29;
> dt.month = 2;
> dt.year = 2004;
>
> What happens when the month is assigned? Either
>
> -- the assignment happens, but I now (temporarily) have an
> invalid date: Feb 29, 2003
> -- the assignment fails, in which case I end up with Jan 29, 2004
> -- the assignment succeeds, but adjusts the date to be consistent,
> in which case I end up with Feb 28, 2004
>
> None of these options seem very good to me. Can you think of
> any better ones?
Yes, but first, let's consider the problem without properties. If
we have a date object currently set to Jan 31, 2003, and I want
to change it to Feb 29, 2004, this code seems reasonable:
dt = date(29, 2, 2004);
What happens when the month is assigned?
* the assignment happens, but I now have an invalid date
* the assignment fails, in which case I might end up with Jan 29,
2004
* the assignment succeeds, but adjusts the date to be consistent,
in which case I end up with Feb 28, 2004
If none of those options seem very good to you, I submit that
one of two conditions holds: 1) C++ is hopelessy broken, and
can never deal sensibly with dates, or 2) your imagination has
limited the possible options.
What would you do in the pure C++ case? My guess is this:
* throw an exception
Guess what? You can do that from a property assignment
function as well. You might still get an inconsistent date, but
at least you are informed that there was a problem, and can
clean it up. But any sensible programmer is only going to allow
independent setting of members if it makes sense to do so.
In the date case, this is is probably not a good idea. So
properties allow naive programmers to construct such classes
anyway, right? Well, C++ allows naive programmers to write
set_day(), set_moth() and set_year() as well. Are properties
really any more dangerous?
> The problem is that a date class is not very well modeled as
> a collection of day, month and year properties. An intelligent
> date class is not simply three ints that can be changed
> independently, as the property interface suggests.
Right, which is not a problem with properties, but rather of
interface design. You can design a poor interface with any
language or set of language features. You don't need
properties to do that.
> [...]
> Given that:
>
> -- the functionality enabled by properties is already available
> through accessors
I must insist that properties provide design-time introspection,
which accessors do not.
> -- the number of classes which need this functionality is small
The VCL contains hundreds, if not thousands of such classes.
Easily thousands or tens of thousands if you include third-party
components.
> I just don't see any justification for adding properties to C++.
That's because you've never built a database-driven app in an
hour by dragging and dropping components onto a design-time
form.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: comp.std.c++_2003-03-11@nmhq.net (Niklas Matthies)
Date: Tue, 11 Mar 2003 19:54:47 +0000 (UTC) Raw View
On 2003-03-10 14:32, Bob Bell <belvis@pacbell.net> wrote:
> comp.std.c++ 2003-03-09@nmhq.net (Niklas Matthies) wrote in message news:<slrnb6m2na.1j6g.comp.std.c++_2003-03-09@nmhq.net>...
[...]
>> To give an example, in Visual Basic, which supports
>> properties, I've written a Timer class that has a property
>> 'seconds to go'. (The class' raison d' tre is that, unlike VB's
>> standard timer control, it is not bound to a form.) Setting it to a
>> non-zero value (re)starts the timer with the given number of seconds.
>> Setting it to zero stops the timer, if it was running. Reading it
>> yields the number of seconds to go until the timer elapses, of course,
>> or zero if it already has elapsed/was stopped. The Timer class has no
>> other methods, only this property. (When the timer reaches zero, the
>> object raises an event.)
>>
>> Of course one can always simulate the same functionality with methods.
>
> I would say it the other way around: that you are using properties to
> simulate what is more natural with methods. If I see code that sets a
> member variable (or _looks_ like it sets a member variable):
>
> timer.seconds_to_go = 60;
>
> I find it surprising that it has a side effect such as the one you
> describe above.
>
> But code like this:
>
> timer.set_seconds_to_go(60);
> timer.start();
>
> makes it explicit exactly what's happening.
This implies that the timer needs to maintain a "seconds to go" count
that is independent of the actual seconds to go. Or, put differently,
it needs a enabled/disabled flag. This makes the client-side view of
the timer's state more complex.
Think of a simple, mechanical spring-driven egg timer. Setting its
time and starting it is the same. The time "displayed" inherently
_is_ the egg timer's state. Then compare with an electronic timer
that behaves more as you seem to prefer: You can set the time, start
and stop it using a couple of buttons. Everyone who only needs the
functionality of an egg timer finds the simple egg timer easier and
more intuitive to handle. You have less state to worry about, and
changing it is more straightforward.
To apply your example to string objects, it's a bit like as if
instead of
string.resize(new_size);
one had to write
string.set_new_size_to_be_applied(new_size);
string.apply_new_size();
With properties, we could simply have
string.size = new_size;
and not need seperate size()/resize() methods.
I agree that, in C++ context, the side effect of
timer.seconds_to_go = 60;
will currently appear to be confusing to the average C++ programmer.
Likely, I'd write:
timer.seconds_to_go = 60; // activates timer
to make things crystal clear.
But it's really a natural way to behave for a timer.
When you think about it, having seconds_to_go = 60 and not being
running is about as unnatural as things can get for a timer.
>> But the above behavior of setting seems less natural with a method
>> set seconds to go(...). Here, the client tells the object to set its
>> "seconds to go" to some value. It's less obvious that the object, in
>> addition to carrying out this request of setting a value of its
>> internal state, starts or stops to do something (i.e. counting down).
>
> This argument applies to
>
> timer.seconds_to_go = 60;
>
> It's not obvious that the object, in addition to carrying out this
> request of setting a value of its internal state, starts or stops to
> do something (i.e. counting down).
The very purpose of the property here is to do away with the artificial
internal state / external state distinction, as far as the user of the
object is concerned. For the user, there's only one state, namely that
embodied by the property, and the object does nothing else than behaving
according to that state.
> Not only that, but it is impossible to set the time remaining without
> simultaneously starting the timer.
Why would you want to do that?
A timer's job is not to provide you with interim storage for values
that you only need sometime later.
> One must therefore be more careful with this version of the timer.
Only if one is conditioned to the type of timer you propose.
>> In fact, I would expect that, for this reason, most C++ programmers
>> would design the class in a different way than with a pair of get/set
>> methods, either like
>>
>> void start(int seconds); // undefined when running?
>> void stop();
>> int get seconds to go() const; // undefined when stopped?
>>
>> or even
>>
>> void set seconds(int seconds); // no effect when running?
>> // maybe on next start?
>> void start(); // undefined when running?
>> void stop();
>> int get seconds() const; // initial count, or seconds to go?
>>
>> With the property, on the other hand, conceptually the client does the
>> setting himself, and the object's activity merely consists of adjusting
>> its behavior to the new setting. This is, in a way, also similar to a
>> hardware-register-like volatile variable, where setting it has a
>> certain side effect.
>>
>> What's important here is that using properties that way feels
>> significantly different than doing the same with a set of methods.
>> It changes how you think about the object. It removes one level of
>> indirection in how the client conceptually sees the object, and the
>> object's state.
>
> I don't see this -- using either properties or member functions,
> you're changing the object's state and causing side effects. How do
> you think differently about the property version?
With the method version, a client needs to take care of setting a
state (which, in the second version above, the object is even
blissfully unaware of initially), and then, in addition, tell the
object to now do something with its state. So you have a two-layered
state, for one some sort of internal state more or less directly
manipulated by the client, and then a superimposed behavioral state of
the object that needs to be triggered seperately. This is unnecessarily
complex.
>> The Timer object with its single property appears conceptually
>> simpler than its method-using counterpart(s), its state appears to
>> be external, concrete, not something hidden away inside that one
>> can only get at indirectly.
>
> None of these things seem like advantages -- why is it important that
> the state appear external and not hidden away?
A client needs to know the state that an object it manipulates is in,
and needs to know how the actions applied to the object changes its
state. This is more straightforward when the state appears as an
directly accessible entity. Think of the mechanical egg timer, whose
state you manipulate directly, versus the electronic one, whose state
you manipulate indirectly by pushing buttons in sequence.
[...]
> But even after that, if you really want this kind of class, you don't
> need properties to create it in today's C++:
[...]
> This will do today, without properties, what you describe. I have no
> idea how much more verbose this is than the property version, but it
> doesn't seem all that verbose to me.
The issues with simulating properties that way have already been
discussed in detail here, or over in comp.lang.c++.moderated, I
believe. This subthread was about whether properties have enough
merits as a concept to possibly justify dedicated language support.
-- Niklas Matthies
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Tue, 11 Mar 2003 19:55:18 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303092216.40820a9b@posting.google.com...
> comp.std.c++ 2003-03-09@nmhq.net (Niklas Matthies) wrote in message
news:<slrnb6m2na.1j6g.comp.std.c++_2003-03-09@nmhq.net>...
> [...]
> I would say it the other way around: that you are using properties
> to simulate what is more natural with methods. If I see code that
> sets a member variable (or _looks_ like it sets a member variable):
>
> timer.seconds_to_go = 60;
>
> I find it surprising that it has a side effect such as the one you
> describe above.
If you see code that sets a member variable, and the object looks
non-POD, I hope you are shocked and suprised!!! Then, your
second reaction should be: "Wait, this programmer surely knows
about proper data hiding. What appears to be an assignment to
a member is more likely an assignment to a property, which I
expect to have side effects". Of course, if you don't work with RAD
systems much, that is an unlikely second reaction, though it
shouldn't be.
> But code like this:
>
> timer.set_seconds_to_go(60);
> timer.start();
>
> makes it explicit exactly what's happening.
If you don't need this to interact with the RAD system.
> [...]
> timer.seconds_to_go = 60;
>
> It's not obvious that the object, in addition to carrying out this
> request of setting a value of its internal state, starts or stops to
> do something (i.e. counting down).
It does if you assume that the programmer has not simply exposed
a public data member like a fool.
> Not only that, but it is impossible to set the time remaining
> without simultaneously starting the timer. One must therefore
> be more careful with this version of the timer.
Or read the documentation. And the fact that the timer starts is not
a requirement of the property implementation. It's just an illustrative
design decision (that I probably would not have made).
> [...]
> To be frank, more than anything else this example seems like it
> violates the principle of least surprise. If today (without
> properties) I show you this line of code
>
> timer.seconds_to_go = 60;
>
> you would think that it assigns 60 to the seconds_to_go member.
And that's exactly the point. You should automatically assume that
this is a poor design or a strange design. If you're not suprised by
it already, then something is wrong. Which is why properties fit
into the language. They utilize an idiom which should not be seen
in non-property code anyway. So in a property-enabled environment,
when you see assignment to a data member, you should
immediately think "property...side effects".
> [...]
> But even after that, if you really want this kind of class, you don't
> need properties to create it in today's C++:
> [...]
> This will do today, without properties, what you describe. I have no
> idea how much more verbose this is than the property version, but
> it doesn't seem all that verbose to me.
There's one thing that it won't do...it won't present a design-time
environment to a RAD system. ;)
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Tue, 11 Mar 2003 19:55:31 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:ur89fooiw.fsf@boost-consulting.com...
> dheld@codelogicconsulting.com ("David B. Held") writes:
> > [...]
> > Well, that would certainly give you more powerful introspection,
> > but I don't think I've seen this be suggested before (the RTTI
> > link).
>
> I don't see how you're going to easily build RAD systems which
> allow you to tweak the fields of a class using a GUI otherwise.
My understanding is that what properties do within a RAD system
is merely provide a tag that tells the IDE "publish this data". The
IDE can already see the class' structure. It doesn't need RTTI
for that. It just needs to know which part of the structure is relevant
in the design-time environment. You know this is case, because
BCB inserts member declarations and functions directly into the
source code. So it "understands" the class structure even before
the RTTI data is generated.
> > [...]
> > class foo
> > {
> > private:
> > int x_;
> > double y_;
> > };
> >
> > typeid(foo).member_count() == 2
> > typeid(foo).member_at<0>::type == int
> > typeid(foo).member_at<0>::value == foo::int*
> > typeid(foo).member_at<1>::type == double
> > typeid(foo).member_at<1>::value == foo::double*
>
> That won't work for dynamic polymorphism unless member_at<> is
> a very odd type of member template. For the runtime interface you'd
> need to do something which allows us to express that the Nth
> member's type is different depending on the dynamic type of the
> argument to typeid().
Right. I was trying to get a discussion started on the compile-time
interface first, but it probably doesn't make sense to ignore the
run-time interface at the same time.
> I had something like this in mind for the compile-time interface.
>
> template <class access, class T, T pm>
> struct member {};
>
> // generated by the compiler on demand:
> template <>
> struct members<foo>
> : boost::mpl::vector<
> member<public_tag, foo& (foo::*)(foo const&), &foo::operator=>
> , member<private_tag, int foo::*, &foo::x_>
> , member<private_tag, double foo::*, &foo::y_>
> >
> {
> };
Ok, this is interesting. So you include the access information in the
introspection data. Let's fill it out a bit:
template <class access, class T, T pm>
struct member
{
typedef access access_type;
typedef T member_type;
T operator()(void) const { return pm; }
};
The trick is, would I be able to do this:
typedef boost::mpl::at<1, members<foo> >::type prop_x;
foo f;
prop_x x;
f.*(x()) = 5;
If so, *should* I be able to do that?
Also, this is what I would call "full introspection", meaning that it
offers much more data than what properties would provide, and it
doesn't provide the design-time interface that properties *do*
provide. So I think this type of introspection is good and useful,
but it's also beyond the scope of properties. Whether that is
good or bad is open for debate.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 12 Mar 2003 00:14:47 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
>> I would say it the other way around: that you are using properties
>> to simulate what is more natural with methods. If I see code that
>> sets a member variable (or _looks_ like it sets a member variable):
>>
>> timer.seconds_to_go = 60;
>>
>> I find it surprising that it has a side effect such as the one you
>> describe above.
>
> If you see code that sets a member variable, and the object looks
> non-POD, I hope you are shocked and suprised!!! Then, your
> second reaction should be: "Wait, this programmer surely knows
> about proper data hiding. What appears to be an assignment to
> a member is more likely an assignment to a property, which I
> expect to have side effects". Of course, if you don't work with RAD
> systems much, that is an unlikely second reaction, though it
> shouldn't be.
This looks like a bad use of properties to me. The method should be
called "start" if it starts the timer.
timer.start(60)
if you don't like the fact that 60 doesn't have units, we need
timer.start(60 * second)
or with a new language feature:
timer.start(seconds: 60)
In general, I think properties should have "property-like" behavior.
In other words, they should generally appear to be a
reflection/transformation of some internal state, and side-effects
should be limited to things like validation and notification.
Otherwise, the communicative value of their syntax is completely
undermined, and starts to work against the reader.
-Dave
--
Dave Abrahams
Boost Consulting
www.boost-consulting.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Wed, 12 Mar 2003 18:46:11 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uwuj5a2ux.fsf@boost-consulting.com...
> [...]
> This looks like a bad use of properties to me. The method should
> be called "start" if it starts the timer.
I agree that this gratuitous use of properties is probably ill-advised.
The only way that properties could be justfied in this context, maybe
is if there were a "running" property, which you turned on and off,
like so:
timer.running = true; // synonym for timer.start()
timer.running = false; // synonym for timer.stop()
However, this isn't any more obvious than "timer.start()", and so I
would not cite this as an advantageous use of properties. However,
in the context of a RAD environment, this might be appropriate
(but only for RAD purposes).
> [...]
> In general, I think properties should have "property-like" behavior.
> In other words, they should generally appear to be a
> reflection/transformation of some internal state, and side-effects
> should be limited to things like validation and notification.
> Otherwise, the communicative value of their syntax is completely
> undermined, and starts to work against the reader.
I agree with this in principle. I think the realities of working with
RAD might produce situations where the desired form is not
always achieved, or somehow violated, but the spirit of the principle
is definitely to be preferred.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 12 Mar 2003 18:46:15 +0000 (UTC) Raw View
comp.std.c++_2003-03-11@nmhq.net (Niklas Matthies) wrote in message news:<slrnb6qjbg.1f4g.comp.std.c++_2003-03-11@nmhq.net>...
> On 2003-03-10 14:32, Bob Bell <belvis@pacbell.net> wrote:
> > I would say it the other way around: that you are using properties to
> > simulate what is more natural with methods. If I see code that sets a
> > member variable (or _looks_ like it sets a member variable):
> >
> > timer.seconds_to_go = 60;
> >
> > I find it surprising that it has a side effect such as the one you
> > describe above.
> >
> > But code like this:
> >
> > timer.set_seconds_to_go(60);
> > timer.start();
> >
> > makes it explicit exactly what's happening.
>
> This implies that the timer needs to maintain a "seconds to go" count
> that is independent of the actual seconds to go. Or, put differently,
> it needs a enabled/disabled flag. This makes the client-side view of
> the timer's state more complex.
OK:
timer.set_seconds_to_go(60);
This sets the time remaining and starts the timer. Here's the class:
class Timer {
public:
void set_seconds_to_go(int);
int get_seconds_to_go(void) const;
};
How is this more complex, conceptually, that the property version you
describe?
[...]
> >> But the above behavior of setting seems less natural with a method
> >> set seconds to go(...). Here, the client tells the object to set its
> >> "seconds to go" to some value. It's less obvious that the object, in
> >> addition to carrying out this request of setting a value of its
> >> internal state, starts or stops to do something (i.e. counting down).
> >
> > This argument applies to
> >
> > timer.seconds_to_go = 60;
> >
> > It's not obvious that the object, in addition to carrying out this
> > request of setting a value of its internal state, starts or stops to
> > do something (i.e. counting down).
>
> The very purpose of the property here is to do away with the artificial
> internal state / external state distinction, as far as the user of the
> object is concerned. For the user, there's only one state, namely that
> embodied by the property, and the object does nothing else than behaving
> according to that state.
That distinction isn't artificial: the state _is_ internal; an
illusion that presents it as external doesn't change that.
> > Not only that, but it is impossible to set the time remaining without
> > simultaneously starting the timer.
>
> Why would you want to do that?
> A timer's job is not to provide you with interim storage for values
> that you only need sometime later.
I suppose it depends on what you need.
My point of view comes from the fact that if you need a timer that can
be started and stopped, it cannot be built from the timer you
describe. However, the timer you describe can be built from one that
can be started and stopped. I guess it's mostly a matter of taste and
style, and I tend to favor more generic code.
> >> The Timer object with its single property appears conceptually
> >> simpler than its method-using counterpart(s), its state appears to
> >> be external, concrete, not something hidden away inside that one
> >> can only get at indirectly.
> >
> > None of these things seem like advantages -- why is it important that
> > the state appear external and not hidden away?
>
> A client needs to know the state that an object it manipulates is in,
> and needs to know how the actions applied to the object changes its
> state. This is more straightforward when the state appears as an
> directly accessible entity. Think of the mechanical egg timer, whose
> state you manipulate directly, versus the electronic one, whose state
> you manipulate indirectly by pushing buttons in sequence.
I don't see a mechanical timer as allowing me to manipulate its state
directly. It has an interface (usually a dial on the front with tick
marks for minutes); the internal state is in the intersection of a
gear, a little ratchet device and a spring.
In this respect it's no different from an electronic timer, which has
a separate interface and implementation.
> [...]
> > But even after that, if you really want this kind of class, you don't
> > need properties to create it in today's C++:
> [...]
> > This will do today, without properties, what you describe. I have no
> > idea how much more verbose this is than the property version, but it
> > doesn't seem all that verbose to me.
>
> The issues with simulating properties that way have already been
> discussed in detail here, or over in comp.lang.c++.moderated, I
> believe. This subthread was about whether properties have enough
> merits as a concept to possibly justify dedicated language support.
That discussion must include, IMHO, a discussion of whether or not the
existing language supports the desired functionality. If your need (as
demonstrated by the timer example) can be satisfied by existing C++
constructs, new constructs aren't necessary. So what did you think of
the Timer class? Does it satisfy your need? Does it demonstrate a
pattern of design/implementation that gives you what you want? Or is
there a problem with it? Does it not scale well? Does it have
different semantics than a property-based timer? Etc.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Wed, 12 Mar 2003 18:46:16 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v6n8fdtc7fnn9c@corp.supernews.com>...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0303081046.67af31b8@posting.google.com...
> > allan_w@my-dejanews.com (Allan W) wrote in message
> news:<7f2735a5.0303061545.2a5390e7@posting.google.com>...
> > [...]
> > All I said was that there's no hard evidence that I'm aware of
> > that shows that RAD makes a significant difference in development
> > time.
>
> It depends on the size and nature of the project.
I should clarify: what I mean is that *I'm not aware* of any hard
evidence that shows that RAD makes a significant difference in
development time. That doesn't mean that no evidence exists; if you
know of any evidence I'd be happy to see it.
For example, can you describe a project in which RAD eliminates or
reduces a significant bottleneck in development?
> > All the evidence I've heard is anecdotal.
>
> I could relate personal experience, but then you would just say that
> it's not your experience, and ignore it.
Perhaps I'm coming off too harsh. I am in this discussion to be
convinced.
By "anecdotal", I mean things like "I used RAD on my last project and
it only took 6 months start to finish." That doesn't really say
anything about how much time was saved.
However, this would: "A couple years ago we developed a GUI app
without RAD and it took 12 months. Last year we wrote a comparable app
using RAD and it only took 6 months."
> > I have used GUI building tools, and they don't seem to shave much
> > off the total development time, because GUI building is not a
> > bottleneck.
>
> What types of applications do you write?
Right now I'm working on small in-house tools for a visual effects
company. In the past I've worked on a suite of 3D tools, including an
animation system, a modeler and a renderer.
> > In addition, it isn't even clear that properties are necessary for
> > RAD.
>
> They may not be strictly necessary, but thus far, I have not seen
> any alternative offered.
>
> > What you need is some kind of introspection facility, and it's
> > not clear that introspection and properties are married together.
>
> I agree with this. But properties give you enough introspection
> to do RAD.
Properties don't give any introspection at all. Properties, as defined
earlier in this thread, are nothing more or less than alternate syntax
for accessor functions.
It seems you have a different idea of what properties are. One of the
points I made early on is that many people have different definitions
of properties, and that it's important to start from a common
definition.
> It's not obvious that a general introspection system
> would give enough information to do RAD. Unless it were
> contrived to do so, I would guess that it wouldn't.
Not sure what you mean here -- everything I know about RAD suggests
that it's the introspection that's important, not properties.
> > For example, RAD could be implemented by giving you a list
> > of a class' functions to call without properties even coming into
> > the picture.
>
> And more hand-waving from someone who probably hasn't
> thought too hard about how RAD actually works.
(Please, I haven't made any disparaging remarks about how hard you
think.)
Have you seen how RAD is used in a language like Lisp or Smalltalk?
They don't use properties, they use introspection, which they get due
to the dynamic nature of the languages. Apple's Interface Builder also
does RAD without properties, using the dynamic nature of Objective C.
In other words, it's clear that RAD is possible without properties.
> What good is
> a list of member functions to a RAD designer? The most critical
> point where RAD intersects with the language is this: there must
> be a way for the source to inform the RAD system which parts
> of a class should be published. This is the piece that generic
> introspection doesn't give you.
On the contrary; this is exactly what introspection gives you.
> Introspection gives you
> information about the class without telling you what part of that
> information is relevant to RAD. *That* is abandoning
> encapsulation. What properties do, plain and simple, is inform
> the RAD system of the relevant portions of classes.
Again, we seem to have a difference of opinion about what properties
are.
> That it
> also happens to provide some introspection capability is useful
> and necessary, but not the primary benefit to RAD. And note
> that the type of introspection that properties provide is not really
> useful in other contexts, like generic programming.
Perhaps it would be useful to provide an introspection facility in C++
that can work in multiple contexts.
> For instance,
> it still wouldn't be possible to write a function that assigns a value
> to all the members of a class using properties. The type of
> introspection that properties provide is mostly useful above the
> language level (at the design-time level). And the type of
> information that general introspection provides is mostly useful
> at the language level, but below the design-time level.
>
> > Perhaps you're right that it is going to happen anyway. But it
> > seems like there's a rush to judgment without any real critical
> > review.
>
> I think we've been having a critical review for weeks now. ;)
> And I don't see any "rush to judgement". Perhaps you could
> specify how you think that is happening?
Yes, you're right -- this is critical review. I'm probably just
feeling a little lonely, being the only one coming out against
properties. ;-)
The biggest example of "rush to judgment" is in the confusion that
seems to exist among many that properties and introspection are tied
together.
> > [...]
> > David Held claimed that RAD was the motivation for
> > properties; I refuted that.
>
> You refuted that RAD is the motivation for properties? No you
> didn't. Or you refuted that RAD is useful? Didn't do that either.
> Besides, didn't anyone ever tell you that it's impossible to prove
> a negative? ;)
Another example of me being unclear. It would be more accurate to say
"David Held claimed that RAD was the motivation for properties. I said
that if that's true, and if RAD is unnecessary, then that removes
support for properties. Then I asked for evidence that RAD is
necessary."
> > > > The same argument ("if you don't use it then it won't impact
> > > > you") can apply equally well to Prolog-style logic
> > > > programming or symbolic programming as in Lisp. Do you
> > > > think we should add those features to C++ as well?
> > >
> > > I don't know those features too well, but I suspect that they
> > > WOULD have an impact, even if they weren't used.
> >
> > I claim that they could, at the least, be implemented in libraries
> > today. Clearly if that's true, you could choose not to use the
> > library and it would have no impact.
>
> And if it *could* be implemented in a library, then why would you
> suggest to add it to the language? Only because it is compellingly
> useful, which you have not demonstrated.
I have not suggested adding logic programming or symbolic programming
to C++. I think you misunderstood. My point was that because a feature
can be implemented in a zero-overhead-if-not-used fashion is not
enough of a reason to add the feature. There has to be more.
> > The concerns we have today when considering what features to
> > add are very different from the concerns when C was invented.
>
> But you seem to be completely ignoring the fact that operator
> overloading is no less syntactic sugar than properties (even more
> so, since that's *all* it provides over named function overloading,
> whereas properties also provide limited introspection), and it is
> a distinctly C++ feature that was added using "C++ criteria".
Yes, operator overloading is syntactic sugar. However, operator
overloading enables certain idioms that would be difficult or
impossible to code otherwise. Example:
template<typename It, typename Func>
void for_each(It begin, It end, Func f)
{
for (; begin != end; ++begin)
f(*begin);
}
Without operator overloading, I could not use for_each on user-defined
iterators as well as pointers.
> > If this:
> >
> > foo.x = 10;
> >
> > can fail, it doesn't really sound like it's living up to its promise.
>
> You must not have used RAD designers for very long, because
> read-only properties are both common and useful. They are as
> common and useful as accessor functions (which do not break
> encapsulation, because functions which change state are not
> *accessors*...they are *mutators*).
First, I was speaking of writable properties which allow the write to
fail, not read-only properties. If x were a read-only property, I
would expect
foo.x = 10;
to fail with a compiler error.
Second, I have thought about this a little more and agree that
property assignments that can fail really aren't a problem, in the
same way that ordinary member functions that can fail aren't a
problem.
> > [...]
> > Exactly. Accessors _do_, in general, break encapsulation. For
> > a class like the standard list template, accessors to members
> > would just allow clients to mess with the internal state.
>
> But list.size() is essentially an accessor function. A function
> which allows for the direct setting of internal state is not an
> "accessor".
I use "accessor" to mean get and set functions. Whether you want to
call the set function an accessor or a mutator doesn't address the
essential argument.
list.size() is an accessor. For that matter, vector.size() and
vector.resize() are accessors as well, and as pointed out by David
Abrahams, could be modeled reasonably as properties.
> Yes, but first, let's consider the problem without properties. If
> we have a date object currently set to Jan 31, 2003, and I want
> to change it to Feb 29, 2004, this code seems reasonable:
>
> dt = date(29, 2, 2004);
>
> What happens when the month is assigned?
>
> * the assignment happens, but I now have an invalid date
> * the assignment fails, in which case I might end up with Jan 29,
> 2004
> * the assignment succeeds, but adjusts the date to be consistent,
> in which case I end up with Feb 28, 2004
>
> If none of those options seem very good to you, I submit that
> one of two conditions holds: 1) C++ is hopelessy broken, and
> can never deal sensibly with dates, or 2) your imagination has
> limited the possible options.
Sorry, you lost me here. I don't see any problem at all with
dt = date(29, 2, 2004);
The assignment is atomic from the client's point of view -- there is
no opportunity for the client to have access to an invalid date, so
there's nothing to resolve.
Further, with an assignment of the form
dt = date(29, 2, 2004);
properties don't come into it at all. Which illustrates my point:
properties are the wrong interface for a date class that maintains an
invariant that the date always be valid (and I understand that you
agree with this point).
> What would you do in the pure C++ case? My guess is this:
>
> * throw an exception
How about a single member function that sets the whole date at once?
This function can validate all the arguments at once and throw an
exception if the resulting date would be invalid.
dt.set(29, 2, 2004); // OK
dt.set(30, 2, 2004); // Throws bad_date()
This gives the user a way to change the date without having to worry
about going through invalid intermediate states.
> Guess what? You can do that from a property assignment
> function as well. You might still get an inconsistent date, but
> at least you are informed that there was a problem, and can
> clean it up. But any sensible programmer is only going to allow
> independent setting of members if it makes sense to do so.
> In the date case, this is is probably not a good idea. So
> properties allow naive programmers to construct such classes
> anyway, right? Well, C++ allows naive programmers to write
> set_day(), set_moth() and set_year() as well. Are properties
> really any more dangerous?
The point is, how many classes are there for which an "independent
setting of members" kind of interface is appropriate? I've claimed
that it's not very many, and for those, accessor functions work just
fine.
However, others have offered the argument that syntax sugar is
important in and of itself, and some of the examples have been
compelling. Also, properties do enable some lousy interfaces, but as
you point out, lousy interfaces are not a consequence of properties --
they can be written with any feature. C++ has never avoided useful
features because they could be misused, so it's clear that "properties
enable lousy interfaces" is not a good reason to deny properties. For
the same reason, it's clear that "properties allow poor encapsulation"
is not a good reason to deny properties either.
So I suppose a feel a little less adamant about arguing against
properties. I'm not sure I would ever use properties myself, though,
because I see little need for them myself, and I still find they can
still violate the principle of least surprise, but if it works for
you, go for it.
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 6 Mar 2003 00:34:46 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
> One of the best things about C++ is that it supports multiple
> paradigms. It supports both structured programming and OO programming,
> but you don't have to use either one of them to use C++. If you think
> that "goto" is evil, just put up a shop rule not to use it. And so on.
>
> If C++ supports properties (or RAD, for that matter) and you choose
> not to use it, the impact on you will be zero.
This is not the same thing as saying that C++ should have properties.
The same argument ("if you don't use it then it won't impact you") can
apply equally well to Prolog-style logic programming or symbolic
programming as in Lisp. Do you think we should add those features to
C++ as well?
It comes down to this, hand-waving about RAD and GUIs aside: what
sorts of problems do properties solve that can't be solved without
them?
Consider templates. Without templates, whole classes of problems
couldn't be solved in C++ without large amounts of error-prone
repetition of code or error-prone preprocessor hacks.
But when asked what problems properties solve that couldn't be solved
without them, we get examples like
foo.x = bar.y + baz.z * (bar.w - baz.z);
is much better than
foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
Even then, proponents of this argument don't claim that properties
enable new functionality, they just make existing functionality easier
to type and read. However, it isn't a particularly convincing
argument, as the poor encapsulation is a bigger problem than how much
typing is involved or how long it takes to read.
What have I missed? Why should C++ have properties?
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Thu, 6 Mar 2003 05:11:29 +0000 (UTC) Raw View
Bob Bell wrote:
> allan_w@my-dejanews.com (Allan W) wrote in message
> news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
>> One of the best things about C++ is that it supports multiple
>> paradigms. It supports both structured programming and OO
>> programming,
>> but you don't have to use either one of them to use C++. If you think
>> that "goto" is evil, just put up a shop rule not to use it. And so
>> on.
>>
>> If C++ supports properties (or RAD, for that matter) and you choose
>> not to use it, the impact on you will be zero.
>
> But when asked what problems properties solve that couldn't be solved
> without them, we get examples like
>
> foo.x = bar.y + baz.z * (bar.w - baz.z);
>
> is much better than
>
> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
>
> Even then, proponents of this argument don't claim that properties
> enable new functionality, they just make existing functionality easier
> to type and read. However, it isn't a particularly convincing
> argument, as the poor encapsulation is a bigger problem than how much
> typing is involved or how long it takes to read.
Properties have nothing to do with "poor encapsulation". Care to explain why
you injected such a statement in this discussion ?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Thu, 6 Mar 2003 21:17:37 +0000 (UTC) Raw View
In article <c87c1cfb.0303051147.4d5ecc6e@posting.google.com>, Bob Bell
<belvis@pacbell.net> writes
<snip>
>What have I missed? Why should C++ have properties?
Another important question is : What are properties?
So far, I've only seen some examples and a mention that certain actions
aren't possible. We haven't seen enough of a description to vote on. For
instance, I still can't tell if properties are just a rather privileged
kind of macro.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Thu, 6 Mar 2003 23:32:49 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:2O4G1eM9K7Z+Ew$e@jgharris.demon.co.uk...
> [...]
> Another important question is : What are properties?
This is actually a very good question. It would be nice if the folks
who have implemented them in a compiler would make some
comments on that, and try to specify them more formally. I'm
afraid that I personally couldn't give a very detailed description.
> So far, I've only seen some examples and a mention that certain
> actions aren't possible. We haven't seen enough of a description
> to vote on. For instance, I still can't tell if properties are just a
> rather privileged kind of macro.
In the sense that member functions are a rather priviledged kind of
macro, perhaps.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Thu, 6 Mar 2003 23:33:02 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0303051147.4d5ecc6e@posting.google.com...
> allan_w@my-dejanews.com (Allan W) wrote in message
news:<7f2735a5.0303041452.1ec2261c@posting.google.com>...
> > One of the best things about C++ is that it supports multiple
> > paradigms. It supports both structured programming and OO
> > programming, but you don't have to use either one of them to
> > use C++. If you think that "goto" is evil, just put up a shop rule
> > not to use it. And so on.
> >
> > If C++ supports properties (or RAD, for that matter) and you
> > choose not to use it, the impact on you will be zero.
>
> This is not the same thing as saying that C++ should have
> properties. The same argument ("if you don't use it then it won't
> impact you") can apply equally well to Prolog-style logic
> programming or symbolic programming as in Lisp.
Can it? What is required to implement those styles? I know that
Lisp relies heavily on GC, and I can't imagine that Lisp syntax
wouldn't affect the C++ grammar in a dramatic way. I don't think
it's the same argument at all.
> Do you think we should add those features to C++ as well?
No, because they are too expensive to justify. Native properties
are relatively cheap. Sure, they increase the complexity of the
compiler, but not in a radical way.
> It comes down to this, hand-waving about RAD and GUIs
> aside: what sorts of problems do properties solve that can't be
> solved without them?
I know other people disagree with me, but I must insist that RAD
and GUIs is what it's all about. The problem properties solve is
informing the design-time system which class members can be
accessed, called, or persisted during design time. There is no
way to make such a specification in C++ currently.
> Consider templates. Without templates, whole classes of
> problems couldn't be solved in C++ without large amounts
> of error-prone repetition of code or error-prone preprocessor
> hacks.
When was the last time someone proposed a change to the
language of the magnitude of templates? It isn't fair to compare
properties to templates. A better comparison is properties vs.
any of the other more common feature requests on this list,
like more liberal forward references, final, standard numeric
constants (like pi), etc. Or to more realistic proposals, like
move semantics, definition namespaces, or typeof().
> But when asked what problems properties solve that couldn't
> be solved without them, we get examples like
>
> foo.x = bar.y + baz.z * (bar.w - baz.z);
>
> is much better than
>
> foo.set_x(bar.get_y() + baz.get_z() * (bar.get_w() - baz.get_z()));
>
> Even then, proponents of this argument don't claim that
> properties enable new functionality, they just make existing
> functionality easier to type and read.
And there is value to this. Macros do not enable any functionality
which could not be performed manually either, yet I don't hear
anyone lobbying for the removal of the preprocessor.
> However, it isn't a particularly convincing argument, as the poor
> encapsulation is a bigger problem than how much typing is
> involved or how long it takes to read.
What do you think about the definition namespace idea? That is
absolutely nothing more than pure syntactic sugar, yet I didn't see
anyone strongly objecting to it. So on the basis of that alone, it
seems that properties aren't so unreasonable. However, you still
have the RAD factor, even though you like to dimiss it with some
hand-waving of your own.
What do move semantics give us that can't be done in C++?
Optimizations. That's it. But that's enough. I don't know anyone
who insists that we really don't need move semantics. What
about references to references? That can be solved with a type
trait. Changing the language rules as proposed gives us nothing
but syntactic sugar for the type traits solution. But that sugar is
deemed important by most people who have thought about it.
What about typeof()? You can do just about everything typeof()
does with a good set of type traits. It's big, fat and messy, but
I'm pretty sure it's doable. Typeof just makes things easier.
And that's the point. Programming is hard enough without us
trying to keep it that way.
> What have I missed? Why should C++ have properties?
Write yourself a GUI app with BCB or Kylix, and it will all
become clear. To get all that with the addition of just one
concept is a good value, if you ask me. I will be so bold as to
say that RAD is to UI design as templates are to library design.
It is a fundamental tool that provides so much power that the
utility is manifest to those who use it. But unlike templates,
you do not need to be a guru to appreciate the power of RAD.
There really isn't a way to describe the usefulness of RAD to
someone who does not have to design UIs and has not
experienced RAD first-hand, just as there really isn't a way to
describe Beethoven's 5th to a deaf person. It must be
experienced to be comprehended.
While templates are powerful, they are not directly useful to
everybody. There are thousands, perhaps even hundreds
of thousands of programmers who have not written any
template code themselves. There are probably quite a few
that have not even *used* template code. One disadvantage
of properties is that they are really only compellingly useful
to people who must design UIs. This is unlike templates,
which are useful to people who don't know how to write them.
On the other hand, there are much more obscure areas of
the language that are not directly used by a large number of
programmers as well, such as bit fields, operator delete,
function try blocks, etc. Yet we "pay" for those features to
exist in our compilers anyway.
And just as application programmers benefit from the work
of library designers, all programmers benefit from the work
of UI designers indirectly, because commercial applications
by and large require a user interface, and having good ones
advances the state of the art in software design (and
compels customers to continue purchasing new software,
which funds the entire industry). Imagine how much software
would get sold if everything were still operated from a
command line.
Investing in GUIs and RAD is a good move for C++. It's
not even a risky, forward-thinking move. It's playing
catch-up to established industry practice. If anything, only
adding properties is conservative, and not adding them at
all is downright stubborn.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Wed, 5 Mar 2003 02:59:59 +0000 (UTC) Raw View
> "Bob Bell" <belvis@pacbell.net> wrote
> > [...]
> > If the major motivation for properties is RAD,
I don't buy that it is. Properties are just a robust feature that
I would like to have.
> > then I'm still
> > skeptical. C++ runs in environments where RAD and GUIs
> > don't make sense.
dheld@codelogicconsulting.com ("David B. Held") wrote
> And it runs in environments where exception handling is too
> expensive.
Right.
Furthermore, if you choose not to use RAD you don't pay for it;
in order to "not pay for" exceptions, you have to have it disabled
in every single compilation unit (including the standard library).
> > One of the nice things about C++ is its universality: it runs
> > in many environments and doesn't have features that skew
> > towards any one in particular. Adding properties as a way to
> > support RAD would change that somewhat.
I disagree. When properties aren't used, (RAD or otherwise),
they would have absolutely no impact. You won't pay for it unless
you use it.
> > Also, on a slightly off-topic note, I've never been convinced
> > that RAD is all that necessary.
...
> > Tying this back to the topic at hand, this further reduces the
> > case for properties in my book; since RAD isn't really that
> > necessary,
One of the best things about C++ is that it supports multiple
paradigms. It supports both structured programming and OO programming,
but you don't have to use either one of them to use C++. If you think
that "goto" is evil, just put up a shop rule not to use it. And so on.
If C++ supports properties (or RAD, for that matter) and you choose
not to use it, the impact on you will be zero.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Sat, 22 Feb 2003 21:41:18 +0000 (UTC) Raw View
"Peter Dimov" <pdimov@mmltd.net> wrote in message
news:7dc3b1ea.0302220948.3793d718@posting.google.com...
> eldiener@earthlink.net ("Edward Diener") wrote in message
news:<nqy5a.878$4n4.73427@newsread2.prod.itd.earthlink.net>...
> > "Bob Bell" <belvis@pacbell.net> wrote in message
> > news:c87c1cfb.0302210850.13d9a02a@posting.google.com...
> > > If the major motivation for properties is RAD, then I'm still
> > > skeptical. C++ runs in environments where RAD and GUIs don't make
> > > sense. One of the nice things about C++ is its universality: it runs
> > > in many environments and doesn't have features that skew towards any
> > > one in particular. Adding properties as a way to support RAD would
> > > change that somewhat.
> >
> > I don't understand why it would impact the above at all. However I also
> > don't see why properties must only be tied to RAD development in the
first
> > place and why properties can not be considered a syntactical convenience
for
> > non-RAD classes/objects.
>
> Properties model public data members, and C++ programmers
> traditionally don't view public data members as an adequate tool for
> expressing interfaces. Public data members, or properties, can only
> express the concept of independent attributes.
>
> Consider the illustrative case of
>
> struct X
> {
> /* property */ int a;
> /* property */ int b;
> };
>
> where X has an invariant of a == b. Now try to go from the (1, 1)
> state to (2, 2), without violating the invariant.
struct X
{
/* property */ int a = { read = readA, write = writeA };
/* property */ int b = { read = readB, write = writeB };
int readA() { return a;}
int readB() { return b;}
void writeA(int val) { a = val; b = val; } // invariant of a == b
void writeB(int val) { b = val; a = val; } // invariant of a == b
};
This above shows that a "property" need not be only a public data member and
that a property can indeed express an idea that is more than an independent
attribute and more like an interface. In fact without the ability to attach
read and write functionality to a "property" ( or getters and setters if you
like ), there is no reason to consider properties as anything more than a
public data member with a fancier name unless the only point of "properties"
is to designate a data member as special for RAD design-time programming. I
have repeatedly argued against that limited view of properties.
Of course when one documents property a or property b above, one specifies
the invariant so that users will know that changing property a or property b
also changes the other property to the same value. This of course is no
different from documenting member functions correctly.
One of the reasons for the C++ model for making data members private is that
one does not want end-users changing those data members to fallacious
values. Having "properties" as a sort of smart data member allows the ease
and clarity of data member access while controlling the value to which that
data member, and possibly other data members, are changed. A "property"
setter can silently reject the new value, throw an exception, use an assert,
or even pop-up a message box telling the end-user the reasons why the new
value is inappropriate at design-time.
Now one can always of course argue that a setter member function can control
the value and take the same actions also, and one would be right. Because of
that I view "properties" as a syntactical improvement in that respect, while
in the case of RAD programming a "property" acts as a convenient tag for "a
more important type data member". Taken together I view the addition of
properties as worthwhile. I think there is a place for "syntactical sugar"
to make the use of a computer language more closely model one's thinking
about programming constructs, and having used a C++ implementation which
promotes RAD programming, C++ Builder, I think there is a place for a
language to consider supporting ideas which promote a design-time model of
construction of objects.
>
> For comparison, the idiomatic C++ way to express the same concept is:
>
> struct X
> {
> X(int a, int b);
> };
>
> X x(1, 1);
> x = X(2, 2);
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Mon, 24 Feb 2003 19:56:32 +0000 (UTC) Raw View
In article <Ahy5a.868$4n4.71955@newsread2.prod.itd.earthlink.net>,
Edward Diener <eldiener@earthlink.net> writes
<snip>
>I think all of your concerns are valid. I will give answers according to the
>way that properties currently work in C++ Builder and to the way I think
>they should work if I disagree with a C++ Builder limitation.
>
>>
>> Can properties have global or namespace scope ?
>
>No, properties are entities of objects and are declared/defined as members
>of classes.
Why? Wouldn't some C programmers like this kind of access to global
variables?
>> Can properties be function parameters ?
>
>Not in C++ Builder but I see no reason why they shouildn't be allowed in
>function parameters since each property has a value of a particular type. In
>this sense properties are only pass-by-value entities.
>> Can properties be in-out arguments in function calls ?
>
>Meaning that one passes a reference or pointer to a property ? No, because
>properties are pass-by-value entities.
If they can be parameters then you can do this :
void f(int property x)
{ x = 3; }
so these two questions have to be answered very carefully.
<snip>
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 24 Feb 2003 20:10:24 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:$9o05CNPUoV+EwtU@jgharris.demon.co.uk...
> [...]
> A modern integrated development environment can reach into the
> compiler and get all the type information it needs.
But can it reach into your brain and get the intent of your code as
well? If so, please demonstrate with a working IDE.
> That's how the editor can give you a list of function parameters or
> members as soon as you type a name.
Function parameters and members are a part of C++. That's
exactly why I'm arguing for properties. If you don't have a way of
saying: "This is a property", how does the editor get that information?
Divination?
> Obviously, the IDE could also get this information and package it
> as needed for any reusable components it makes available for
> RAD use.
If it's so obvious, please demonstrate. There's a lot of IDE
developers that would like to see this magic.
> [...]
> Goodness gracious me, this is the age of point and click. The
> programmer points at a member declaration, clicks, and says
> "that's the one" to the IDE, which then remembers all that needs
> to be remembered. It might even highlight the declaration in
> bright red.
So now you're suggesting that we use color to indicate syntax?
Why stop at properties? Why don't we reduce all numeric types
to "number" and the precision is indicated by the color: gray for
integers, red for floats, orange for doubles, green for shorts...
Furthermore, your little scheme merely betrays an ignorance of
how properties work. There are typically two types of properties,
and your solution seems non-sensical for both types. One type
is where a property is associated with a data member. Since there
is no way to say "property" in C++, you suggest that we merely
change the color of the data member to indicate a property?
Well, properties have names. So where does the name of the
property go? Do you have to open a menu to see it? Perhaps
we need to add sound as well, and when you click on a data
member that is a property, the IDE must play an audio file that
speaks the name of the property in your native language? What
if you want more than one property to refer to a single member?
Do you add the colors together? How do color-blind
programmers read your code? Do we really want "rainbow
source"? How do you print it out on paper on a B&W laser
printer? How do you *use* the property? Do you say:
class X
{
int <red>Size_</red>;
};
void foo(X const& x)
{
int i = x.<red>Size_</red>;
}
Properties also obey access rules, so how do you distinguish
between public and private properties? More colors? Will
we need a spectrometer to tell us all the attributes of a given
class? Maybe a physicist will look at some code and decide
that it happens to match the spectra of stellar carbon. ;>
The other type of property is an accessor-based one, where
no data member need be involved. Of course, all the same
questions apply to this type of property (and those which
combine the two). How do you call it? How do you use one
function in multiple properties? How do you discover the
name? Etc., etc. Please spend some time thinking about how
such a system would work, and fill in some of the details,
because the whole thing seems rather silly to me.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Mon, 24 Feb 2003 20:10:26 +0000 (UTC) Raw View
In article <VAy5a.891$4n4.75111@newsread2.prod.itd.earthlink.net>,
Edward Diener <eldiener@earthlink.net> writes
>"John G Harris" <john@nospam.demon.co.uk> wrote in message
>news:$9o05CNPUoV+EwtU@jgharris.demon.co.uk...
<snip>
>> A modern integrated development environment can reach into the compiler
>> and get all the type information it needs. That's how the editor can
>> give you a list of function parameters or members as soon as you type a
>> name. Obviously, the IDE could also get this information and package it
>> as needed for any reusable components it makes available for RAD use.
>
>The argument previously made is that a modern IDE must use non-standard ways
>to do this, such as for instance parsing the source files when compiling and
>extracting the information it wants and making assumptions about what is
>valid data such as "properties" and "events' and how they are defined.
>Whereas if introspection were standardized, each environment could use the
>standardized mechanism and concepts such as properties and events would be
>well-defined between environments.
>
>In much the same Java has standardized the way properties, methods, and
>events are defined for Java Beans and a system of introspection for
>discovering these things at run-time if necessary, so that any Java Beans
>hosting environment can discover the properties, events, and methods of a
>Java Bean without parsing any Java source code for that bean.
<snip>
I think you'll find there's more to it than published properties, in
both BCB and in JavaBeans. For instance, property editors can be
provided and registered. The result in both systems is a peculiar
mixture of language features and well-known function/class names. It
always looks rather messy to me.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: usenet@phatbasset.com ("Hillel Y. Sims")
Date: Mon, 24 Feb 2003 20:10:28 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0302210850.13d9a02a@posting.google.com...
>
> Also, on a slightly off-topic note, I've never been convinced
that RAD
> is all that necessary. Every RAD system I've seen makes it
easy to do
> things like lay out widgets in a window, and RAD does make
this quick
> and easy. However, without RAD, how much time on a project is
spent
> doing this? Less than 10% of the total time? Less than 1%? RAD
has
> always struck me as being like premature optimization, in that
RAD
> makes something that isn't a bottleneck much faster.
>
It may not be strictly necessary in the same sense that water is
necessary for human survival, but it sure can be much higher
than 10% of the total time in a lot of cases (speaking from 5+
years personal experience doing a lot of GUI development in a
non-RAD/visual environment) -- Imagine if you are trying to
create a slick dialog box with a whole bunch of graphic elements
in *just* the right layout.. With a RAD "visual" system, you
drag-n-drop everything exactly how you want it, then you code up
the "business logic" behind it all and you're all set. Without
that, you can spend nearly 50% of your development time guessing
at a bunch of coordinates, compiling/linking/executing, oh nuts
it's not quite right, adjust all the numbers slightly by hand
and repeat (x 5 until you get it right, and then the product
developer decides she wants to move this button over *there* and
you start all over again.. with drag-n-drop, it is fairly
trivial to readjust everything). Sometimes almost makes me want
to do Windows programming ...*shudder*
(I'm not particularly weighing in on whether 'properties' are
important for enabling RAD development or not, just responding
to Bob's point.)
hys
--
(c) 2003 Hillel Y. Sims
hsims AT factset.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 24 Feb 2003 20:10:32 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0302210850.13d9a02a@posting.google.com...
> [...]
> If the major motivation for properties is RAD, then I'm still
> skeptical. C++ runs in environments where RAD and GUIs
> don't make sense.
And it runs in environments where exception handling is too
expensive.
> One of the nice things about C++ is its universality: it runs
> in many environments and doesn't have features that skew
> towards any one in particular. Adding properties as a way to
> support RAD would change that somewhat.
Not any more than exceptions and RTTI "skew" C++ towards
environments that can afford it.
> Also, on a slightly off-topic note, I've never been convinced
> that RAD is all that necessary. Every RAD system I've seen
> makes it easy to do things like lay out widgets in a window,
> and RAD does make this quick and easy.
It does more than that. Non-visual components allow you to
easily add features to an application without trying to figure out
which headers need to be included and which libraries need to
be linked in. They also simplify the interface by leveraging the
PME model to make it easy to interact with the component's
functionality. This leads me to conclude that you have not had
the pleasure of working in a RAD environment on any serious
projects.
> However, without RAD, how much time on a project is
> spent doing this? Less than 10% of the total time? Less than
> 1%? RAD has always struck me as being like premature
> optimization, in that RAD makes something that isn't a
> bottleneck much faster.
I wonder what the motivation for Visual Basic was, then? And
why have so many companies chosen what is arguably a fat,
slow language to implement client-side applications. For thin
clients, the interface can easily take up a significant portion of
the total time. And I argue that RAD allows for better interfaces,
because it gives the programmer the freedom to experiment and
try different layout designs at much lower expense. Unlike other
aspects of programming, interface design is a lot less rigid and a
lot more artistic. It's not always so easy and obvious what the
best way to lay out an interface should be. Having the freedom
to quickly prototype a few different potential layouts improves
the quality of the interface over a design that is set in stone
before the first widget is placed. And it seems rather arrogant
to me that you would have such an insightful view of RAD
compared to the companies that have invested a considerable
amount of time and resources creating and using it. There's no
shortage of RAD environments *or* users, so either you're
smarter than all the folks out there using it, or maybe they've
learned something you don't know. Your opinion seems to
be typical of people who generally don't have to spend a lot of
time writing UIs (because of the nature of their application
domain). I don't think I've met anyone who has to spend any
serious amount of time designing UIs that thinks RAD is a
waste of time or resources.
> Tying this back to the topic at hand, this further reduces the
> case for properties in my book; since RAD isn't really that
> necessary,
This has not been convincingly established.
> and properties make RAD easier, properties aren't really that
> necessary.
Tell that to the Java, Delphi, VB, C# and BCB folks.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 24 Feb 2003 21:40:34 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:laHCAxEwS9V+Ew97@jgharris.demon.co.uk...
> [...]
> I think you'll find there's more to it than published properties, in
> both BCB and in JavaBeans. For instance, property editors can
> be provided and registered. The result in both systems is a peculiar
> mixture of language features and well-known function/class names.
> It always looks rather messy to me.
Property editors do not require any other C++ language extensions
than the 'property' concept itself. I don't think anyone is arguing for
a standard RAD C++ environment. That would be extreme, and
would certainly violate the spirit of C++. Once we have properties,
all the product- and vendor-specific RAD features can build on top of
that. But because properties appear in and interact with source and
the language at a fairly fundamental level, they are necessary to
establish any kind of standard RAD environment. Property editors
and other nifty RAD features don't generally interact with the language
in any depth.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: loic.actarus.joly@wanadoo.fr (=?ISO-8859-1?Q?Lo=EFc_Joly?=)
Date: Mon, 24 Feb 2003 22:43:50 +0000 (UTC) Raw View
John G Harris wrote:
> In article <Ahy5a.868$4n4.71955@newsread2.prod.itd.earthlink.net>,
> Edward Diener <eldiener@earthlink.net> writes
>>> Can properties have global or namespace scope ?
>>
>>No, properties are entities of objects and are declared/defined as memb=
ers
>>of classes.
>=20
>=20
> Why? Wouldn't some C programmers like this kind of access to global
> variables?
That looks fun, I never thought of this use... In fact, it would enable=20
to create singletons that look exactly like a global.
I do not know if I really like it... In one way, that is fine, because=20
singletons are already like a global variable, but in another way, it=20
might impy that the overused singleton has become something approved by=20
the standard...
>>> Can properties be in-out arguments in function calls ?
>>
>>Meaning that one passes a reference or pointer to a property ? No, beca=
use
>>properties are pass-by-value entities.
>=20
>=20
> If they can be parameters then you can do this :
>=20
> void f(int property x)
> { x =3D 3; }
I am not sure I understand what you mean... I beleive one question could=20
be :
struct Foo
{
int property x =3D {read =3D readX, write =3D writeX};
// ...
};
int f(int &i) { /*...*/ }
Foo foo;
f(foo.x); // 1
What should happen :
1 - Compilation error ?
2 - The line 1 evaluates to :
int a =3D foo.readX();
f(a);
foo.writeX(a);
3 - Each time i is read inside of f, readX is called, and each time it=20
is written to, writeX is called ?
4 - Something else I failed to see ?
--=20
Lo=EFc
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Tue, 25 Feb 2003 03:37:17 +0000 (UTC) Raw View
Lo c Joly wrote:
> John G Harris wrote:
>> In article <Ahy5a.868$4n4.71955@newsread2.prod.itd.earthlink.net>,
>> Edward Diener <eldiener@earthlink.net> writes
>>>> Can properties be in-out arguments in function calls ?
>>>
>>> Meaning that one passes a reference or pointer to a property ? No,
>>> because properties are pass-by-value entities.
>>
>>
>> If they can be parameters then you can do this :
>>
>> void f(int property x)
>> { x = 3; }
>
> I am not sure I understand what you mean... I beleive one question
> could
> be :
> struct Foo
> {
> int property x = {read = readX, write = writeX};
> // ...
> };
>
> int f(int &i) { /*...*/ }
>
> Foo foo;
> f(foo.x); // 1
>
> What should happen :
> 1 - Compilation error ?
> 2 - The line 1 evaluates to :
>
> int a = foo.readX();
> f(a);
> foo.writeX(a);
>
> 3 - Each time i is read inside of f, readX is called, and each time it
> is written to, writeX is called ?
> 4 - Something else I failed to see ?
What should happen is exactly the same that should happen if you had:
struct Foo
{
int readX();
// ...
};
int f(int &i) { /*...*/
Foo foo;
f(foo.readX());
which I believe fails because the temporary can only be dealt with as a
const int &. Why make a special case for the property read= function and
complicate things unnecessarily ?
The idea with "property" is to keep it simple and use it in a clear manner.
I believe Borland's BCB implementation of __property does this.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Tue, 25 Feb 2003 20:15:40 +0000 (UTC) Raw View
In article <v5fgueadidlg0c@corp.supernews.com>, David B. Held
<dheld@codelogicconsulting.com> writes
>"John G Harris" <john@nospam.demon.co.uk> wrote in message
>news:$9o05CNPUoV+EwtU@jgharris.demon.co.uk...
<snip>
>> Obviously, the IDE could also get this information and package it
>> as needed for any reusable components it makes available for
>> RAD use.
>
>If it's so obvious, please demonstrate. There's a lot of IDE
>developers that would like to see this magic.
I was responding to your request for more introspection. I don't think
IDE designers need me to tell them how to do syntax highlighting and
class inspectors.
<snip>
>Please spend some time thinking about how
>such a system would work, and fill in some of the details,
>because the whole thing seems rather silly to me.
The job of a C++ program is to describe the executable program.
Describing the design-time environment really belongs to another
language, one that needs more than just properties. I'm not convinced
that it would be a good idea to graft this language onto C++.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Edward Diener" <eldiener@earthlink.net>
Date: Tue, 25 Feb 2003 16:16:30 CST Raw View
John G Harris wrote:
> In article <v5fgueadidlg0c@corp.supernews.com>, David B. Held
> <dheld@codelogicconsulting.com> writes
>> "John G Harris" <john@nospam.demon.co.uk> wrote in message
>> news:$9o05CNPUoV+EwtU@jgharris.demon.co.uk...
>
> <snip>
>>> Obviously, the IDE could also get this information and package it
>>> as needed for any reusable components it makes available for
>>> RAD use.
>>
>> If it's so obvious, please demonstrate. There's a lot of IDE
>> developers that would like to see this magic.
>
> I was responding to your request for more introspection. I don't think
> IDE designers need me to tell them how to do syntax highlighting and
> class inspectors.
>
> <snip>
>> Please spend some time thinking about how
>> such a system would work, and fill in some of the details,
>> because the whole thing seems rather silly to me.
>
> The job of a C++ program is to describe the executable program.
> Describing the design-time environment really belongs to another
> language, one that needs more than just properties. I'm not convinced
> that it would be a good idea to graft this language onto C++.
The idea of introspection, whether one approves of the properties notion or
not, is to give a design time environment the ability to find out what it
needs at run-time to do what it likes. I don't think C++ should try to
determine how design time IDEs should work, but I don't see why C++ can not
create introspection primitives as part of the language which would enable a
design time environment to find out what it needs in a standardized way.
Other languages have done this successfully ( Java, C# ) and I see no shame
for C++ to follow the lead of other languages in adapting a good idea if it
is deemed so.
While I believe that properties would aid introspection by a form of tagging
important "data members" to be used by a RAD IDE, I don't think that the
concept of properties should be tied only to introspecton. As a "syntactic
sugar" ease of use and expression, over getXXX and setXXX member functions,
they justify themselves IMHO.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "David B. Held" <dheld@codelogicconsulting.com>
Date: Tue, 25 Feb 2003 16:24:41 CST Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:r+jBJ8Cu$4W+EwXy@jgharris.demon.co.uk...
> In article <v5fgueadidlg0c@corp.supernews.com>, David B. Held
> <dheld@codelogicconsulting.com> writes
> >"John G Harris" <john@nospam.demon.co.uk> wrote in message
> >news:$9o05CNPUoV+EwtU@jgharris.demon.co.uk...
>
> <snip>
> >> Obviously, the IDE could also get this information and package
> >> it as needed for any reusable components it makes available for
> >> RAD use.
> >
> >If it's so obvious, please demonstrate. There's a lot of IDE
> >developers that would like to see this magic.
>
> I was responding to your request for more introspection. I don't think
> IDE designers need me to tell them how to do syntax highlighting
> and class inspectors.
I think you missed the point entirely. Syntax highlighting does not
require language support because the compiler already knows
everything it needs to recognize keywords, etc. Class inspectors do
not involve new features of the language either. You don't have to
write any special source code for either of those features to function.
However, properties are not an attribute of *existing C++ programs*.
There is no way to say: "Let there be a property called X in my
program". Therefore, an IDE *cannot* simply "get [the] information
and package it as needed", because *the information does not exist
until the programmer puts it there*.
There are basically two obvious ways I can think of to make properties
"automatic", not requiring any user intervention. One is to simply make
everything a property. I think we all agree that this degenerate solution
is pretty worthless. The other is to create a mapping between special
member functions and properties. That is, create a rule that function
names matching a certain regex are properties. I think it is trivially
argued that this is bad as well. The only sensible way to implement
properties is *to let the user specify them*. Now, if you are suggesting
that it is easy for IDE designers to automatically decide what properties
should exist for any given C++ program, *that* is magic that we would
all like to see.
> >Please spend some time thinking about how such a system would
> >work, and fill in some of the details, because the whole thing seems
> >rather silly to me.
>
> The job of a C++ program is to describe the executable program.
> Describing the design-time environment really belongs to another
> language, one that needs more than just properties. I'm not
> convinced that it would be a good idea to graft this language onto
> C++.
Right now, C++Builder compiles that language, and it's essentially
"C++ with Properties". Yes, I said it that way intentionally. There are
certain vagarities of BCB that are related to its incestuous relationship
with Delphi, but those are not relevant to the properties discussion.
Essentially the only thing needed to turn BCB programs into well-
formed C++ programs (without extensions) is the property concept.
This is hardly "another language".
As far as "the job of a C++ program" goes, I would note that design-
time is merely a special instance of run-time. In fact, property
methods can get called during design-time, just as they would during
run-time (only you don't have the entire program context). To that
extent, design-time isn't any stranger a concept to C++ than threading
is, and most people agree that threading is a needed addition to
the language. They both involve non-traditional execution contexts.
And, like threading, design-time has a well-defined, but vendor
specific behaviour that would benefit from the standardization that
would come from having native property support.
So I could argue that threading really belongs to another language,
one that needs more than just threads, and that we shouldn't graft
this language onto C++. But if special execution environments
like threading *are*, in fact, relevant to C++, then it seems
reasonable to me that the special execution environment of design-
time also ought to be relevant (and is).
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Sun, 16 Feb 2003 21:46:37 +0000 (UTC) Raw View
In article <v4sqgqncm4qaf1@corp.supernews.com>, David B. Held
<dheld@codelogicconsulting.com> writes
>"John G Harris" <john@nospam.demon.co.uk> wrote in message
>news:drCccEB83NT+EwpX@jgharris.demon.co.uk...
>> [...]
>> Unfortunately, some property enthusiasts seem to believe that
>> properties are the *only* way to give that information to the
>> IDE. I don't see why an IDE implementation should be labelled
>> non-standard if it uses a different way.
>
>Well, technically, *every* property implementation is "non-
>standard", so such an argument is without merit either way. But
>it seems to me that adding properties is better than having a
>custom pre-processor. What do you think?
I think you've misunderstood me. I'm saying that a visual design system
can be implemented without changing the C++ syntax. Therefore, anyone
wanting to introduce some kind of new property syntax has to convince us
that properties are so superior that we can't do without them.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Mon, 17 Feb 2003 05:10:47 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:Dhn7OhBrg3T+EwrR@jgharris.demon.co.uk...
> In article <v4sqgqncm4qaf1@corp.supernews.com>, David B. Held
> <dheld@codelogicconsulting.com> writes
> >"John G Harris" <john@nospam.demon.co.uk> wrote in message
> >news:drCccEB83NT+EwpX@jgharris.demon.co.uk...
> >> [...]
> >> Unfortunately, some property enthusiasts seem to believe that
> >> properties are the *only* way to give that information to the
> >> IDE. I don't see why an IDE implementation should be labelled
> >> non-standard if it uses a different way.
> >
> >Well, technically, *every* property implementation is "non-
> >standard", so such an argument is without merit either way. But
> >it seems to me that adding properties is better than having a
> >custom pre-processor. What do you think?
>
> I think you've misunderstood me. I'm saying that a visual design system
> can be implemented without changing the C++ syntax. Therefore, anyone
> wanting to introduce some kind of new property syntax has to convince us
> that properties are so superior that we can't do without them.
The idea of properties does not exist solely for the purpose of a visual
design system, although it has made one implementation which uses a visual
design system, Borland's C++ Builder, easier to create and use.
Regarding your last sentence, do you believe that every change to a computer
language must entail something "so superior that we can't do without" it ? I
take the viewpoint that computer languages can be changed if the change
makes the language easier and more intuitive to use, without having to be
"so superior that we can't do without" it. Of course each case of deciding
whether a change which makes the language easier and more intuitive to use,
must be considered on its own right and weighed against the ramifications of
the change to the language. In the case of properties, the change would IMHO
make it easier to access an object's "data" using a natural syntax which
hides the underlying fact that getter and setter functions might be called.
I view that clarity of syntax enough to justify the consideration of adding
properties to C++.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 17 Feb 2003 06:19:11 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:Dhn7OhBrg3T+EwrR@jgharris.demon.co.uk...
> [...]
> I think you've misunderstood me. I'm saying that a visual design
> system can be implemented without changing the C++ syntax.
> Therefore, anyone wanting to introduce some kind of new property
> syntax has to convince us that properties are so superior that we
> can't do without them.
Sure it's *possible*. But the point is that without a special syntax,
a RAD designer would have to give special meaning to certain
identifiers, in the absence of any real introspection. It seems to me
that this is simply a bad way to proceed. What RAD exposes is
a limitation of C++...namely the lack of introspection. Simply saying
that it's theoretically possible to RAD without introspection is not,
in my opinion, a good argument against it. I mean, it's possible to
do OOP without virtual functions too.
The way I see it, the debate is not over whether we need
properties, but whether we need introspection. I think most people
would agree that generalized introspection would be a nice and
useful addition to C++, but nobody really wants to design such a
thing. If you agree that RAD is useful, then you agree that C++
needs introspection.
Saying that we can do RAD without properties is like telling people
to do OOP with jump tables instead of virtual functions. Yes, it
can be done, but I think we agree that virtual functions are better.
The RAD analogue to jump tables is what you might call "contrived
introspection". That's associating certain named functions with
various data members, or deciding that certain named functions are
properties, even without being associated with a data member.
It's "contrived" because there is no obvious logical such mapping,
so compiler vendors would simply have to make one up arbitrarily.
And whatever naming scheme is decided might change the meaning
of existing programs.
Suppose that a vendor decided that all member functions starting
with 'get' and ending with the name of a data variable constitute
properties. Well, that means that functions named "getCount()"
become properties whether that is intended or not. So even
though the runtime behaviour of the program doesn't change, the
design-time behaviour of the code is unexpected.
With native properties, the programmer explicitly tells the compiler
which members are properties, so design-time behaviour is
controlled and predictable. The problem is that with RAD, design-
time becomes as important as compile-time and run-time. If you
simply ignore this fact, and tell compiler vendors to make up
whatever clever tricks to get desired design-time behaviour,
then there will be no uniformity, and you will end up with
incompatible extensions, exactly as you have now. The only way
to make C++ RAD-friendly is to let C++ explicitly define
design-time behaviour. There are multiple ways to achieve this,
but we already have implementations and experience using
properties, so why not leverage existing practice?
Right now, design-time behaviour of C++ programs is completely
implementation-defined. By mandating design-time semantics for
certain syntactical constructs, we can make C++ RAD-friendly.
If you wish to propose a contrived introspection scheme, be my
guest. But I think such a thing would violate the spirit of C++.
Design-time is a new realm for C++. Let's do it right by following
industry practice and adopting properties.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Fri, 21 Feb 2003 20:15:59 +0000 (UTC) Raw View
In article <CgW3a.5558$_c6.535119@newsread2.prod.itd.earthlink.net>,
Edward Diener <eldiener@earthlink.net> writes
<retransmission>
<snip>
>Regarding your last sentence, do you believe that every change to a computer
>language must entail something "so superior that we can't do without" it ? I
>take the viewpoint that computer languages can be changed if the change
>makes the language easier and more intuitive to use, without having to be
>"so superior that we can't do without" it. Of course each case of deciding
>whether a change which makes the language easier and more intuitive to use,
>must be considered on its own right and weighed against the ramifications of
>the change to the language. In the case of properties, the change would IMHO
>make it easier to access an object's "data" using a natural syntax which
>hides the underlying fact that getter and setter functions might be called.
>I view that clarity of syntax enough to justify the consideration of adding
>properties to C++.
My attitude to properties is biased by what hasn't been said. I don't
recall any discussion of the following questions :
Can properties have global or namespace scope ?
Can properties be function parameters ?
Can properties be in-out arguments in function calls ?
Can properties be returned ?
Are properties lvalues ? Presumably not, so what effect do properties
have on the definitions of expressions ?
Can properties be pointed to ? Referenced ?
Do properties belong to the current type system ? Or do they belong
to a separate type hierarchy ?
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Fri, 21 Feb 2003 20:34:08 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") wrote in message news:<v50kbasvt2j5ed@corp.supernews.com>...
> Right now, design-time behaviour of C++ programs is completely
> implementation-defined. By mandating design-time semantics for
> certain syntactical constructs, we can make C++ RAD-friendly.
> If you wish to propose a contrived introspection scheme, be my
> guest. But I think such a thing would violate the spirit of C++.
> Design-time is a new realm for C++. Let's do it right by following
> industry practice and adopting properties.
If the major motivation for properties is RAD, then I'm still
skeptical. C++ runs in environments where RAD and GUIs don't make
sense. One of the nice things about C++ is its universality: it runs
in many environments and doesn't have features that skew towards any
one in particular. Adding properties as a way to support RAD would
change that somewhat.
Also, on a slightly off-topic note, I've never been convinced that RAD
is all that necessary. Every RAD system I've seen makes it easy to do
things like lay out widgets in a window, and RAD does make this quick
and easy. However, without RAD, how much time on a project is spent
doing this? Less than 10% of the total time? Less than 1%? RAD has
always struck me as being like premature optimization, in that RAD
makes something that isn't a bottleneck much faster.
Tying this back to the topic at hand, this further reduces the case
for properties in my book; since RAD isn't really that necessary, and
properties make RAD easier, properties aren't really that necessary.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Fri, 21 Feb 2003 22:12:52 +0000 (UTC) Raw View
In article <v50kbasvt2j5ed@corp.supernews.com>, David B. Held
<dheld@codelogicconsulting.com> writes
<retransmission>
<snip>
>The way I see it, the debate is not over whether we need
>properties, but whether we need introspection. I think most people
>would agree that generalized introspection would be a nice and
>useful addition to C++, but nobody really wants to design such a
>thing. If you agree that RAD is useful, then you agree that C++
>needs introspection.
<snip>
A modern integrated development environment can reach into the compiler
and get all the type information it needs. That's how the editor can
give you a list of function parameters or members as soon as you type a
name. Obviously, the IDE could also get this information and package it
as needed for any reusable components it makes available for RAD use.
>With native properties, the programmer explicitly tells the compiler
>which members are properties, so design-time behaviour is
>controlled and predictable.
<snip>
Goodness gracious me, this is the age of point and click. The programmer
points at a member declaration, clicks, and says "that's the one" to the
IDE, which then remembers all that needs to be remembered. It might even
highlight the declaration in bright red.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Fri, 21 Feb 2003 23:27:07 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:gdezRjMVToV+EwN7@jgharris.demon.co.uk...
> In article <CgW3a.5558$_c6.535119@newsread2.prod.itd.earthlink.net>,
> Edward Diener <eldiener@earthlink.net> writes
>
> <retransmission>
>
> <snip>
> >Regarding your last sentence, do you believe that every change to a
computer
> >language must entail something "so superior that we can't do without" it
? I
> >take the viewpoint that computer languages can be changed if the change
> >makes the language easier and more intuitive to use, without having to be
> >"so superior that we can't do without" it. Of course each case of
deciding
> >whether a change which makes the language easier and more intuitive to
use,
> >must be considered on its own right and weighed against the ramifications
of
> >the change to the language. In the case of properties, the change would
IMHO
> >make it easier to access an object's "data" using a natural syntax which
> >hides the underlying fact that getter and setter functions might be
called.
> >I view that clarity of syntax enough to justify the consideration of
adding
> >properties to C++.
>
> My attitude to properties is biased by what hasn't been said. I don't
> recall any discussion of the following questions :
I think all of your concerns are valid. I will give answers according to the
way that properties currently work in C++ Builder and to the way I think
they should work if I disagree with a C++ Builder limitation.
>
> Can properties have global or namespace scope ?
No, properties are entities of objects and are declared/defined as members
of classes.
>
> Can properties be function parameters ?
Not in C++ Builder but I see no reason why they shouildn't be allowed in
function parameters since each property has a value of a particular type. In
this sense properties are only pass-by-value entities.
>
> Can properties be in-out arguments in function calls ?
Meaning that one passes a reference or pointer to a property ? No, because
properties are pass-by-value entities.
>
> Can properties be returned ?
Not in C++ Builder but I see no reason why properties shouldn't be returned
by value.
>
> Are properties lvalues ? Presumably not, so what effect do properties
> have on the definitions of expressions ?
Properties do not have to be lvalues. You can set the value of a property
via SomeProperty = somevalue in which case the property setter function gets
called. In expressions, if a property is used as an lvalue, its setter
function gets called, if used as an rvalue its getter function gets called.
>
> Can properties be pointed to ? Referenced ?
No, because properties do not have to be lvalues.
>
> Do properties belong to the current type system ? Or do they belong
> to a separate type hierarchy ?
Current type system. Properties have a type just like any other data member.
A final note about current usage of properties in C++ Builder. You can set
the value of a property as if you were setting the value of an object's data
member but a property does not have to be an actual data variable, in other
words a property does not have to be an lvalue. When you set the value of a
property, the property's setter function is called. When you access the
value of a property, the properties getter function is called to get the
value. Because of this properties can be passed by value in functions but
not by reference or pointer.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Sat, 22 Feb 2003 00:00:30 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0302210850.13d9a02a@posting.google.com...
> dheld@codelogicconsulting.com ("David B. Held") wrote in message
news:<v50kbasvt2j5ed@corp.supernews.com>...
> > Right now, design-time behaviour of C++ programs is completely
> > implementation-defined. By mandating design-time semantics for
> > certain syntactical constructs, we can make C++ RAD-friendly.
> > If you wish to propose a contrived introspection scheme, be my
> > guest. But I think such a thing would violate the spirit of C++.
> > Design-time is a new realm for C++. Let's do it right by following
> > industry practice and adopting properties.
>
> If the major motivation for properties is RAD, then I'm still
> skeptical. C++ runs in environments where RAD and GUIs don't make
> sense. One of the nice things about C++ is its universality: it runs
> in many environments and doesn't have features that skew towards any
> one in particular. Adding properties as a way to support RAD would
> change that somewhat.
I don't understand why it would impact the above at all. However I also
don't see why properties must only be tied to RAD development in the first
place and why properties can not be considered a syntactical convenience for
non-RAD classes/objects.
>
> Also, on a slightly off-topic note, I've never been convinced that RAD
> is all that necessary. Every RAD system I've seen makes it easy to do
> things like lay out widgets in a window, and RAD does make this quick
> and easy. However, without RAD, how much time on a project is spent
> doing this? Less than 10% of the total time? Less than 1%? RAD has
> always struck me as being like premature optimization, in that RAD
> makes something that isn't a bottleneck much faster.
It doesn't have to be a bottleneck in the run-time speed sense to make
things easier. RAD can speed up the physical layout of widgets and operating
system controls on a window as well as provide the ability to set properties
and events for those things at design time. Finally RAD can provide the same
design time properties and events for non-visual components also. Thw whole
process generally makes using both visual components ( classes with
properties, methods, and events ) and non-visual components much easier to
use.
>
> Tying this back to the topic at hand, this further reduces the case
> for properties in my book; since RAD isn't really that necessary, and
> properties make RAD easier, properties aren't really that necessary.
The last paragraph would IMHO unfortunately fail any course in logic in any
university in the world.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Sat, 22 Feb 2003 00:00:56 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:$9o05CNPUoV+EwtU@jgharris.demon.co.uk...
> In article <v50kbasvt2j5ed@corp.supernews.com>, David B. Held
> <dheld@codelogicconsulting.com> writes
>
> <retransmission>
>
> <snip>
> >The way I see it, the debate is not over whether we need
> >properties, but whether we need introspection. I think most people
> >would agree that generalized introspection would be a nice and
> >useful addition to C++, but nobody really wants to design such a
> >thing. If you agree that RAD is useful, then you agree that C++
> >needs introspection.
> <snip>
>
> A modern integrated development environment can reach into the compiler
> and get all the type information it needs. That's how the editor can
> give you a list of function parameters or members as soon as you type a
> name. Obviously, the IDE could also get this information and package it
> as needed for any reusable components it makes available for RAD use.
The argument previously made is that a modern IDE must use non-standard ways
to do this, such as for instance parsing the source files when compiling and
extracting the information it wants and making assumptions about what is
valid data such as "properties" and "events' and how they are defined.
Whereas if introspection were standardized, each environment could use the
standardized mechanism and concepts such as properties and events would be
well-defined between environments.
In much the same Java has standardized the way properties, methods, and
events are defined for Java Beans and a system of introspection for
discovering these things at run-time if necessary, so that any Java Beans
hosting environment can discover the properties, events, and methods of a
Java Bean without parsing any Java source code for that bean.
>
> >With native properties, the programmer explicitly tells the compiler
> >which members are properties, so design-time behaviour is
> >controlled and predictable.
> <snip>
>
> Goodness gracious me, this is the age of point and click. The programmer
> points at a member declaration, clicks, and says "that's the one" to the
> IDE, which then remembers all that needs to be remembered. It might even
> highlight the declaration in bright red.
But it has to compile the code, and create its own system of discovery. It
would be much more advantage if it could discover such things at run-time,
without the need for the source, from a standardized system of
introspection.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: pdimov@mmltd.net (Peter Dimov)
Date: Sat, 22 Feb 2003 20:25:28 +0000 (UTC) Raw View
eldiener@earthlink.net ("Edward Diener") wrote in message news:<nqy5a.878$4n4.73427@newsread2.prod.itd.earthlink.net>...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0302210850.13d9a02a@posting.google.com...
> > If the major motivation for properties is RAD, then I'm still
> > skeptical. C++ runs in environments where RAD and GUIs don't make
> > sense. One of the nice things about C++ is its universality: it runs
> > in many environments and doesn't have features that skew towards any
> > one in particular. Adding properties as a way to support RAD would
> > change that somewhat.
>
> I don't understand why it would impact the above at all. However I also
> don't see why properties must only be tied to RAD development in the first
> place and why properties can not be considered a syntactical convenience for
> non-RAD classes/objects.
Properties model public data members, and C++ programmers
traditionally don't view public data members as an adequate tool for
expressing interfaces. Public data members, or properties, can only
express the concept of independent attributes.
Consider the illustrative case of
struct X
{
/* property */ int a;
/* property */ int b;
};
where X has an invariant of a == b. Now try to go from the (1, 1)
state to (2, 2), without violating the invariant.
For comparison, the idiomatic C++ way to express the same concept is:
struct X
{
X(int a, int b);
};
X x(1, 1);
x = X(2, 2);
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Wed, 12 Feb 2003 21:52:05 +0000 (UTC) Raw View
amkanad@yahoo.co.uk (kanad) wrote in message news:<Xns931FD3F5F9CB4kanad@207.217.77.23>...
> My team is
> using C++ on a qnx paltform with 16MB RAM in C++. Why bloat my code with
> all the excess baggage I do not require.
One of the most important aspects of this feature is that you do not
have to pay any penalty if you do not use it. I would never argue for
a feature that benefits its users and hurts the developers who don't
use it. Likewise I would argue against a feature that exacts a
penalty on me for not using it. Your code would not be automatically
bloated. If that were the case then I wouldn't even be posting any of
this because I would be content with the Boost libraries.
> Moreover high quality GUI (MS
> office , mozilla etc) is all possible without your features which proves
> that your proposed features have no value.
I never stated that it could not be done. Anything that Visual BASIC,
Delphi, C#, and Java developers can do can also be done in C++. The
real issue here is can it be done as easy and elegantly. I believe
these are important factors in software engineering because I believe
they affect productivity and maintenance.
My proposed features have no value? According to that logic then why
did developers move from assembly language to the C programming
language? C cleary offers no value. Any system level application,
and console user interface application, can be developed in assembly
language. Does C++ have any value? C is very capable of allowing an
object oriented software solution. It isn't pretty, but it can be
done.
> I think one of the basic purpose of C++ is that is supported by the
> widest possible paltform, many of them even do not have a GUI.
I save this for last. I used to believe this argument. Technology is
changing though and soon what becomes the lowest common denominator
also changes. In the past one could rightly say that C++ was an
excellent cross-platform development tool for console applications.
After all, just about every device supported some kind of text I/O
that is wrapped by the C++ I/O system and text system. But let's get
practical now. Graphical user interfaces are starting to become
ubiquitous. I know it is not there yet, but just give it a little
more time. Everyone thought that cell phones with text provided
information was cool stuff. That wasn't too long ago and now that is
starting to be laughed at. By whom you ask? How about the people who
play graphical games on their cell phones! Graphical web browsing,
graphical games, and office software in the embedded environment is
already here. Just wait, soon the notion of standard widgets that
provide rudimentary graphical I/O and display capabilities will be the
norm.
Nicholas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Thu, 13 Feb 2003 00:26:24 +0000 (UTC) Raw View
"kanad" <amkanad@yahoo.co.uk> wrote in message
news:Xns931FD3F5F9CB4kanad@207.217.77.23...
> [...]
> 1. You cannot write GUI using standard c++
No, that's not the argument at all. Essentially every GUI library
is implemented at some low level that C++ can call directly. The
advantage of properties is not just GUI development, but RAD
development. I still see people bragging about using gcc + emacs.
I admit that for console-based *nix apps, I use that combination
myself. But unfortunately, the world does not run on console-
based *nix apps. And I'd like to see those folks writing thousands
of lines of WinAPI calls and bragging about what emacs can do.
In particular, I want to see them drawing control layouts and
computing pixel offsets to put into their API calls. That's no way
to write apps for a GUI OS.
> I think one of the basic purpose of C++ is that is supported by
> the widest possible paltform, many of them even do not have a
> GUI. My team is using C++ on a qnx paltform with 16MB RAM
> in C++. Why bloat my code with all the excess baggage I do not
> require.
I think just about everyone involved have said that properties
should have no overhead for people who don't use them. In that
case, what "bloat" do you speak of?
> Moreover high quality GUI (MS office , mozilla etc) is all possible
> without your features which proves that your proposed features
> have no value.
All "high quality" software is possible without C++, which proves
that C++ has no value.
> [...]
> These kinds of proposals are worthless as it bloats up the language
> and promotes lazy programmers.
I don't think you understand what properties do. I also suspect
you've never tried to write a non-trivial GUI app. Or perhaps
you've simply never had the pleasure of using a RAD tool.
> 2. Your compiler doesn't support the already existing methods.
>
> Fine either wait or change your compiler. The standard should not
> be changed for that purpose.
Compilers don't have to support non-standard extensions, which is
what properties currently are. If you want to talk about bloat, let's
talk about full run-time introspection. I guarantee you that will bring
along some bloat. But properties introduce a very limited scope
compile-time introspection that allows the programmer to tell the
compiler some essential information about certain class types so as
to aid RAD designs. Because the programmer is telling the
compiler what information is important, this extra info is not
generated for any types that don't use properties. It's not like
RTTI, where you turn it on, and it exists across your entire
application. So properties are actually a very economical tool that
are very much in the spirit of C++ insofar as "don't pay for what
you don't use" goes.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: john@nospam.demon.co.uk (John G Harris)
Date: Fri, 14 Feb 2003 18:13:52 +0000 (UTC) Raw View
In article <v4kve8a7aetjed@corp.supernews.com>, David B. Held
<dheld@codelogicconsulting.com> writes
<snip>
>But properties introduce a very limited scope
>compile-time introspection that allows the programmer to tell the
>compiler some essential information about certain class types so as
>to aid RAD designs.
<snip>
Unfortunately, some property enthusiasts seem to believe that properties
are the *only* way to give that information to the IDE. I don't see why
an IDE implementation should be labelled non-standard if it uses a
different way.
John
--
John Harris
mailto:john@jgharris.demon.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sat, 15 Feb 2003 20:32:05 +0000 (UTC) Raw View
"John G Harris" <john@nospam.demon.co.uk> wrote in message
news:drCccEB83NT+EwpX@jgharris.demon.co.uk...
> [...]
> Unfortunately, some property enthusiasts seem to believe that
> properties are the *only* way to give that information to the
> IDE. I don't see why an IDE implementation should be labelled
> non-standard if it uses a different way.
Well, technically, *every* property implementation is "non-
standard", so such an argument is without merit either way. But
it seems to me that adding properties is better than having a
custom pre-processor. What do you think?
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 7 Feb 2003 20:04:45 +0000 (UTC) Raw View
pkl@mailme.dk ("Peter Koch Larsen") wrote
> One problem you cant resolve with properties in general is when you pass the
> property as a reference. This can not be done with properties and is one
> case, where Allan W's "switch from base members to properties when
> necesarry" principle would fail.
Yes, I agree. I hadn't thought of that before.
As a result,
std::cin >> foo.prop
might have problems, too.
> So far as I know this would fail with
> Borland properties as well - at least this is the desired behaviour if
> meaning should not change.
The way I understand properties to work, just because the property is
seen as type A doesn't mean there's actually a type A object anywhere
within the class. Therefore there's nothing for a reference to bind to.
This would be true no matter how the property is implemented.
(Including Bob Bell's template-driven version -- here "PropX" exists
as a public member, but it isn't the type we're advertising.)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: amkanad@yahoo.co.uk (kanad)
Date: Wed, 12 Feb 2003 07:16:56 +0000 (UTC) Raw View
ndsalerno@yahoo.com (Nicholas Salerno) wrote in
news:b9da50a9.0301221607.3405a901@posting.google.com:
> witless@attbi.com (Witless) wrote in message
> news:<3E2D51F4.DE67FD6C@attbi.com>...
>>
>> Much of that was driven by their resistance to OOD. They admitted
>> that MFC was not OO and that they designed it that way on purpose.
>> They also claimed to have "dumbed down" the design in order to
>> address their perception of their customers needs.
>>
>> So MFC is not a good example of the use of C++.
>>
>
> In the case of MFC how does one design and develop a GUI framework
> with (to an extent) ANSI C++? I claim that it is very difficult.
> Despite what mistakes Microsoft made with MFC, it is not entirely
> their fault and not because they have an aversion towards OOD. I
> think both Microsoft's MFC, Troll Tech's Qt, Borland's products
> clearly show that current ANSI C++ lacks some needed programming
> constructs that are important in the world of graphical user
> interfaces. MFC is cumbersome with their message maps, dialog
> templates, and DDX code (and Class Wizard does not always take care of
> everthing for you). Qt is a lot nicer than MFC, however, to implement
> an elegant object communication mechanism that is nicer than MFC
> message maps, Troll Tech has introduced a whole new compilation phase
> known as the Meta-Object Compiler. Borland, in my opinion, has the
> best C++ IDE. Unfortunately I cannot count them as a ANSI C++
> solution because they extended the language. Are they trying to tell
> us something?
>
>> >
>> > Sophisticated GUI tools that rely on object properties are going to
>> > demand a certain level of RTTI that is beyond the current C++ RTTI
>> > capabilities.
>>
>> Like what?
>>
>
> Delphi. C++ Builder. Visual BASIC (via the COM/ActiveX technology).
> As much as I like Qt it does not compare to the elegance of graphical
> application development that the above tools can provide.
>
> Nicholas
So basically your argument is
1. You cannot write GUI using standard c++
I think one of the basic purpose of C++ is that is supported by the
widest possible paltform, many of them even do not have a GUI. My team is
using C++ on a qnx paltform with 16MB RAM in C++. Why bloat my code with
all the excess baggage I do not require. Moreover high quality GUI (MS
office , mozilla etc) is all possible without your features which proves
that your proposed features have no value.
Beleive me I am learning java (after 4 years in C++) and people in java
groups are complaining about the enormous mess created by a large amount
of library etc that most of them never use. Most of the wishes or
proposals nowadays here are
i. change the syntax , its too tough for me ?
ii. change the sytax , I dont want to see type so much , or go back to
the header file to see how the parameters are declared etc etc.
These kinds of proposals are worthless as it bloats up the language and
promotes lazy programmers.
2. Your compiler doesn't support the already existing methods.
Fine either wait or change your compiler. The standard should not be
changed for that purpose.
kanad.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Fri, 7 Feb 2003 19:27:22 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote
> allan_w@my-dejanews.com (Allan W) wrote
> > There is a lot of parallel there. The same thing applies to any
> > other operator. operator[]() is syntactic sugar for index(), and
> > operator+() is syntactic sugar for add(), and so on.
> >
> > There is something to be said for inline notation, however. If users
> > can use a property "as if" it was a data member, they no longer need
> > to be concerned about the distinction unless they plan to alter the
> > implementation.
>
> I see allowing/encouraging programmers to use classes "as if" they
> were unencapsulated collections of data as a step backwards,
> personally.
That's not really fair, for several reasons.
First of all, and (IMHO) most important, C++ is designed for multiple
programming styles. Not everyone wants to use encapsulation, at least
not rigorously. As a matter of fact, I've never yet been on a project
that used any one programming paradigm rigorously -- they have all
been hybrids. Some have fairly rigorous use of objects, except for
some legacy code that hadn't yet been rewritten. Others had one or
two objects around which the application centered, but otherwise had
very few user-defined classes. And so on.
Second, properties DO offer encapsulation -- they just do it in a form
you're not yet prepared to recognize. What does encapsulation really
mean? According to dictionary.com, it is:
The ability to provide users with a well-defined interface to a
set of functions in a way which hides their internal workings.
In _object-oriented programming_, the technique of keeping together
data structures and the methods (procedures) which act on them.
Properties do in fact accomplish this. When you declare a
property, you are actually declaring the accessor functions that
read and write that property. The only difference between this and
the normal spelled-out "accessor" functions is the syntax used to
call them.
std::cout foo.name; // calls foo's function to read the name property
foo.balance = 0; // calls foo's function to set the balance property
foo.balance += invoice_total; // Calls them both
There is no exposure to private variables. In fact, there doesn't even
have to be a private variable that (directly) holds the balance.
> > std::cout << "Changing customer " << cust.id << "'s name from \""
> > << cust.name;
> > std::cout << "\" to \"" << (cust.name=newname); << "\"!\n";
> >
> > Much easier to read, write, and understand than
> >
> > std::cout << "Changing customer " << cust.getID() << "'s name from \""
> > << cust.getName();
> > cust.setName(newname);
> > std::cout << "\" to \"" << cust.getName(); << "\"!\n";
> >
> > I'll respect your right to disagree, if you choose to ... but then please
> > tell me if you dislike operator overloading as well.
>
> It's irrelevant, since operator overloading is already part of the
> language. We're talking about a proposal to add to the language.
And your dislike of that proposal. Previously you objected that this
is "syntactic sugar," because using different syntax you could
accomplish the same thing (by defining accessor functions). I'll
concede that this is a valid point.
>>> [So] if there's no need to use properities at all, this huge
>>> advantage [of syntax] is moot. So when would you need to? Why
>>> is that need so strong as to justify such a large language
>>> change?
Because syntax IS the language. We want to express our intents in
a way that's as natural as possible. We would much rather write
area = pi * r * r;
than
load pi
mul r
mul r
store area
Both code snippets do the same thing, but C++ uses the "Syntactic
sugar" of expressions to make the code easier to write and understand.
Similarly, we could write
// Contrived code to make a point.
// Returns TRUE if the customers are sorted by sales rep name
bool isSortedBySalesRepName(
const std::vector<Customer> &cust, // Vector of customers
const std::vector<SalesRep> &rep) { // Vector of sales reps
for (int i=1; i<cust.getSize(); ++i)
if (rep.getElement(cust.getElement(i).getRepNumber()).getName() <
rep.getElement(cust.getElement(i-1).getRepNumber()).getName())
return false;
return true;
}
But we might (at least slightly) prefer:
// Contrived code to make a point.
// Returns TRUE if the customers are sorted by sales rep name
bool isSortedBySalesRepName(
const std::vector<Customer> &cust, // Vector of customers
const std::vector<SalesRep> &rep) { // Vector of sales reps
for (int i=1; i<cust.getSize(); ++i)
if (rep[cust[i].RepNumber].getName() <
rep[cust[i-1].RepNumber].getName())
return false;
return true;
}
This might(!) not be the best coding style. My point is, the only
difference between the two is the syntax.
> > > In addition, the syntactic changes required for references were
> > > extremely minor compared to the syntactic changes required for
> > > properties. So with references we had a small change in syntax with a
> > > change in semantics, as compared to pointers. With properties (as
> > > discussed in this post) we have a big change in syntax and no change
> > > in semnatics, as compared to accessors.
> >
> > How so?
>
> There is a change to class declaration syntax.
Not at all, unless you use the new feature. Even then, I imagine that
the change to the class declaration syntax would be relatively mild
and intuitive. It would certainly be less startling than the shock C
programmers get when they see functions declared in the middle of a
struct.
> > > But if there's no need to use properities at all, this huge advantage
> > > is moot. So when would you need to? Why is that need so strong as to
> > > justify such a large language change?
> >
> > I don't see it as a large change.
>
> The point is that, whether you see it as large or small, the change is
> there; what justifies it? What problems do properties solve? What is
> it that can't be done with today's C++ that properties would enable?
It's a more natural way to use accessor functions. Again I draw your
attention to the same advantages in expression notation, operator
overloading, and so on. Each one of these must have looked, initially,
like "nice-to-have" features that weren't really needed -- but they
improve the expressive power of the language, making complicated code
look much simpler.
> The "syntax sugar for accessors" properties we are discussing here
> solve no problems of this type, since they don't provide any
> additional semantics beyond accessors. In fact, this kind of property
> can be implemented today, with no language change:
Okay, deciphering what you wrote. This half is the library code that
you'd only write once:
> template<typename T, typename Owner>
> class Property {
> public:
> typedef void (Owner::* Setter)(T);
> typedef T (Owner::* Getter)(void) const;
>
> Property(Owner* iOwner,
> Setter iSetter,
> Getter iGetter);
>
> operator T(void) const;
> Property& operator=(const T& iArg);
> private:
> Owner* mOwner;
> Setter mSetter;
> Getter mGetter;
> };
>
> template<typename T, typename Owner>
> Property<T, Owner>::Property(Owner* iOwner, Setter iSetter,Getter iGetter)
> : mOwner(iOwner), mSetter(iSetter), mGetter(iGetter) { }
>
> template<typename T, typename Owner>
> Property<T, Owner>::operator T(void) const
> { return (mOwner->*mGetter)(); }
>
> template<typename T, typename Owner>
> Property<T, Owner>& Property<T, Owner>::operator=(const T& iArg)
> { (mOwner->*mSetter)(iArg); }
Then here comes a class that actually uses properties:
> class Foo {
> public:
> Foo(void);
// propX is the property, which is public:
> Property<int, Foo> propX;
> private:
// Pointers to these private functions will be passed to the property.
// Then the property will call them to implement get and set.
// The signatures (other than the name) must be exactly as used here:
// "void something(T)" for set, and "T something() const" for get.
void SetX(int iX) { mX = iX; }
int GetX(void) const { return mX; }
// And here's the private data used by SetX and GetX.
> int mX;
> };
The constructor initializes the property with member-function pointers:
> Foo::Foo(void)
: mX(0)
, propX( // The property needs to have:
this, // the address of the object it's instantiated for
&Foo::SetX, // Pointer to void SetFunction(T)
&Foo::GetX), // Pointer to T GetFunction()
{ }
> // Usage:
> void F(void)
> {
> Foo f;
> f.propX = 10;
> std::cout << f.propX << "\n";
> f.propX = 20;
> std::cout << f.propX << "\n";
> }
>
> I don't think there's anything you can do with the "syntax sugar"
> properties that this template doesn't do.
Wow.
That's certainly the "usage" we were going for.
Essentially, what you've done is to stuff half of the "proxy" pattern
into a template. Very ingenious. I've been coding proxies manually;
this could make it a lot more convenient.
Having said that, may I add that the usage certainly isn't intuitive,
at least not without the comments I added above.
Plus, I've read David B. Held's comments about the extra space
needed for each Property and I think he's exactly right about that.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: pkl@mailme.dk ("Peter Koch Larsen")
Date: Wed, 5 Feb 2003 17:55:57 +0000 (UTC) Raw View
""David B. Held"" <dheld@codelogicconsulting.com> skrev i en meddelelse
news:v3m8lqaaoh3qc5@corp.supernews.com...
> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0301311245.3db27b2d@posting.google.com...
> > [...]
> > I don't think there's anything you can do with the "syntax sugar"
> > properties that this template doesn't do.
> > [...]
> > Owner* mOwner;
> > Setter mSetter;
> > Getter mGetter;
>
> Except save sizeof(Owner*) + sizeof(Setter) + sizeof(Getter)
> bytes for each property. Typical classes in the VCL have
> upwards of 20 properties. On BCB, sizeof(void (T::*)()) == 12.
> That gives an overhead of 28 bytes per property, or 560 bytes
> per VCL class, on average. You think that over half a KB of
> memory *per object* is an acceptable price to pay?
>
I believe you could implement properties without any overhead in the base
class - using some rather simple template functions. I do agree that this is
a tedious process.
> On VC++, sizeof(void (T::*)()) is only 4, but that still means you
> have 12 bytes of overhead for each property. Considering a
> typical property is an int or a pointer, that's 300% overhead!!
>
> You can save a lot of memory by making the Setter and Getter
> template parameters, but native properties would presumably
> have 0 memory overhead (just like class members don't need
> a pointer to their enclosing class to work properly). The best
> you can do to eliminate memory overhead for properties
> today is some highly non-portable and questionable pointer
> arithmetic to get a pointer to the enclosing class. Odds are,
> there's no legal way to do this for all scenarios.
I believe there are. The idea is to have a property template class which
contains a reference to the owner, the getter and the setter functions.
This class has a proptype operator, which returns the result of the getter
function and an assignment operator which calls the setter-function.
One problem you cant resolve with properties in general is when you pass the
property as a reference. This can not be done with properties and is one
case, where Allan W's "switch from base members to properties when
necesarry" principle would fail. So far as I know this would fail with
Borland properties as well - at least this is the desired behaviour if
meaning should not change.
>
> Dave
Kind regards
Peter
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Thu, 6 Feb 2003 00:56:04 +0000 (UTC) Raw View
""Peter Koch Larsen"" <pkl@mailme.dk> wrote in message
news:3e40d882$0$219$edfadb0f@dread16.news.tele.dk...
> [...]
> I believe you could implement properties without any overhead
> in the base class - using some rather simple template functions. I
> do agree that this is a tedious process.
> [...]
Please illustrate this with compilable code. And I hope you're
talking about a generic solution, and not an intrusive one. I am
only skeptical because I've seen this discussed before, and some
of the most clever people couldn't come up with a decent generic
solution that had 0 overhead.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 30 Jan 2003 22:46:19 +0000 (UTC) Raw View
> > belvis@pacbell.net (Bob Bell) wrote
> > > OK, I read the proposal. Unless I missed something, the section on
> > > properties didn't describe anything that can't be done today with
> > > get/set functions. In fact, properties were described as nothing more
> > > than syntactic sugar for accessors. There was some mention of
> > > introspection, but it was defined very loosely, so it's not clear what
> > > it means.
> allan_w@my-dejanews.com (Allan W) wrote
> > Syntactic Sugar. An interesting phrase. The same thing was said about
> > references -- and sure enough, everything that can be done with
> > references can also be done with pointers, if you don't mind completely
> > rewriting the code to use a different syntax.
belvis@pacbell.net (Bob Bell) wrote
> Yet references are not syntactic sugar for pointers, regardless of
> what was "said". Pointers can be reseated while references can't,
> failed dynamic_cast of pointers returns NULL while failed dynamic_cast
> of references throws std::bad_cast, and there is no equivalent for
> pointer arithmetic with references. A reference is permanently tied to
> the object it's bound to, while no such restriction exists for
> pointers. References have very different semantics from pointers.
Back to properties, as I understand them. (Since they don't really
exist in C++ yet, we may be talking about two or more different
concepts -- I'll stick to what I know.) You call them "syntactic
sugar" (with negative connotations) for get/set accessor functions.
There is a lot of parallel there. The same thing applies to any
other operator. operator[]() is syntactic sugar for index(), and
operator+() is syntactic sugar for add(), and so on.
There is something to be said for inline notation, however. If users
can use a property "as if" it was a data member, they no longer need
to be concerned about the distinction unless they plan to alter the
implementation.
std::cout << "Changing customer " << cust.id << "'s name from \""
<< cust.name;
std::cout << "\" to \"" << (cust.name=newname); << "\"!\n";
Much easier to read, write, and understand than
std::cout << "Changing customer " << cust.getID() << "'s name from \""
<< cust.getName();
cust.setName(newname);
std::cout << "\" to \"" << cust.getName(); << "\"!\n";
I'll respect your right to disagree, if you choose to ... but then please
tell me if you dislike operator overloading as well.
> In addition, the syntactic changes required for references were
> extremely minor compared to the syntactic changes required for
> properties. So with references we had a small change in syntax with a
> change in semantics, as compared to pointers. With properties (as
> discussed in this post) we have a big change in syntax and no change
> in semnatics, as compared to accessors.
How so?
The syntax required to use a property would match the syntax used to
access member data: the -> or . operator, followed by the property name.
The syntax required to declare a property in a class would no doubt
startle you by being in some way "new." Perhaps we might even (gasp)
use a new keyword. This is by far the most radical part of the idea.
On the other hand we might use some new syntax just for properties,
if we can find anything intuitive enough. Since one way to implement
this requires us to name one or two member functions, maybe the
notation to specify that would be enough to mark it as a property
in the first place:
class foo {
int mypropget() { return 1; }
void mypropset(int i); // Defined elsewhere
int getROprop() { return 2; }
void setWOprop(int x); // Defined elsewhere
public:
int myproperty = { mypropget, mypropset };
int myROproperty = { getROprop };
int myWOproperty = { 0, setWOprop };
};
> > The Borland proposal for properties is very useful. You're right,
> > it doesn't explicitly state the syntax for accessing properties, but
> > I assume it would be absolutely identical to public data members.
> > One huge advantage of this approach is that you wouldn't have to
> > use properties until there's some motivating need to.
>
> But if there's no need to use properities at all, this huge advantage
> is moot. So when would you need to? Why is that need so strong as to
> justify such a large language change?
I don't see it as a large change.
You're right -- most of the time, when I have read/write properties
that don't trigger an action on read or write, I would start by
implementing them as simple data. But I would do this without any
accessor functions, secure in the knowledge that I could change it
to be a property later, and none of my client source code would need
to be changed.
You quoted an example of this idea.
> > class Foo {
> > // ...
> > public:
> > std::string FooName; // The foo name
> > };
Note that FooName is a data member, not a property.
> > // Display the current FooName
> > std::cout << foo.FooName;
> >
> > // Read a new FooName
> > std::cin >> foo.FooName;
> >
> > Tomorrow we decide to use an enhanced string class, to replace the
> > standard one.
> >
> > class Foo {
> > // ...
> > // These convert EnhancedString to/from std::string
> > std::string getFooName() { return FooName2.getStdString(); }
> > void setFooName(std::string ss) { FooName2 = ss; }
> > public:
> > SomeVendor::enhancedstring FooName2; // The enhanced foo name
> > property<std::string> FooName = {
> > read = getFooName,
> > write = setFooName
> > }
> > };
> > New code can use FooName2 instead, and get all the enhancements.
> > Old code doesn't have to change at all; the data is still available
> > as promised.
>
> Your example could just have easily been satisfied using accessor
> functions directly, with the same advantages of old code not having to
> change at all. So why do we need to add properties to the language?
Writing accessor functions is tedious. Using them is even more tedious.
> I got the impression that the OP thought properties were more than
> that. Which, if true, demonstrates my other point that properties mean
> different things to different people. I'm not even sure we're all
> talking about the same thing.
I share this concern.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sat, 1 Feb 2003 00:35:04 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0301251136.5be433c2@posting.google.com...
> [...]
> In addition, the syntactic changes required for references were
> extremely minor compared to the syntactic changes required for
> properties. So with references we had a small change in syntax
> with a change in semantics, as compared to pointers. With
> properties (as discussed in this post) we have a big change in
> syntax and no change in semnatics, as compared to accessors.
> [...]
I personally believe there is one very good reason why Borland
uses properties in BCB instead of accessors: __published. In
order to provide a nice design-time interface, it is necessary to
distinguish "important" members from implementation details.
Simply putting data members in a __published section gives you
no access control. You would have to come up with some kind
of special naming scheme whereby the compiler/IDE could
recognize which accessors matched which data members.
Giving special meaning to certain user-defined names other than
the c'tor and d'tor goes against the grain of C++. If you simply
provide a way for a compiler/IDE to quickly and easily identify
the "true interface" for a class, including all the different levels
of access you wish to provide, you can leave the user to choose
whatever names she wishes for her accessors. If we want C++
to forever be a language oblivious to everything but a command
line and line editor, then keeping out properties is fine. But if
we want to support C++ in the competitive GUI marketplace, we
need to seriously consider features like properties. Let's not
beat around the bush: BCB exists because of it's RAD interface.
properties support RAD, plain and simple. They don't give us
special new computational abilities. They don't allow us to
express algorithms in clever new ways. They give us
fundamental GUI/RAD support, and that should be reason
enough for their serious consideration.
Anyone who has used BCB for 10 minutes to build a Windows
app knows how powerful it is. M$ knows how powerful it is,
because we now have C#. Let's stop pretending graphical
OSes don't exist. They do. You're using one right now. If we
want C++ to continue to be relevant, we must help it become
aware of the world, and that world includes GUIs. Support
properties. The fate of C++ just might depend on it. ;>
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Sat, 1 Feb 2003 00:35:24 +0000 (UTC) Raw View
"Allan W" <allan_w@my-dejanews.com> wrote in message
news:7f2735a5.0301301435.5434b017@posting.google.com...
> > > belvis@pacbell.net (Bob Bell) wrote
> > In addition, the syntactic changes required for references were
> > extremely minor compared to the syntactic changes required for
> > properties. So with references we had a small change in syntax with a
> > change in semantics, as compared to pointers. With properties (as
> > discussed in this post) we have a big change in syntax and no change
> > in semnatics, as compared to accessors.
>
> How so?
>
> The syntax required to use a property would match the syntax used to
> access member data: the -> or . operator, followed by the property name.
> The syntax required to declare a property in a class would no doubt
> startle you by being in some way "new." Perhaps we might even (gasp)
> use a new keyword. This is by far the most radical part of the idea.
> On the other hand we might use some new syntax just for properties,
> if we can find anything intuitive enough. Since one way to implement
> this requires us to name one or two member functions, maybe the
> notation to specify that would be enough to mark it as a property
> in the first place:
>
> class foo {
> int mypropget() { return 1; }
> void mypropset(int i); // Defined elsewhere
>
> int getROprop() { return 2; }
>
> void setWOprop(int x); // Defined elsewhere
> public:
> int myproperty = { mypropget, mypropset };
> int myROproperty = { getROprop };
> int myWOproperty = { 0, setWOprop };
> };
>
In Borland C++ Builder, the syntax is very similar to what you have above if
a little more wordy:
class foo {
int mypropget() { return 1; }
void mypropset(int i); // Defined elsewhere
int getROprop() { return 2; }
void setWOprop(int x); // Defined elsewhere
public:
__property int myproperty = { read= mypropget, write = mypropset };
__property int myROproperty = { read = getROprop };
__property int myWOproperty = { write = setWOprop };
};
Most obviously Borland included the __property extended keyword more as a
mnemonic to alert programmers to the way of declaring properties than as a
problem for the compiler to parse a property. Read and write properties can
also specify a data member rather than just a member function accessor.
There are also a few more keywords, besides "read" and "write" within the
parentheses, which relate to C++ Builder RAD programming with properties but
that is not apropos for this specific discussion.
I support the syntax for properties also because I think it represents a
concept, essentially a data member with possible member function accessors
behind it, which is clearer to understand than the getX, setX syntax. As
such I believe there are areas in C++ where the syntax can and should be
simplified if there is little problem for the compiler, no ramifications
upon the existing language syntax and constructs, and the simplified syntax
makes the language easier to use.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Sat, 1 Feb 2003 00:36:11 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0301301435.5434b017@posting.google.com>...
> Back to properties, as I understand them. (Since they don't really
> exist in C++ yet, we may be talking about two or more different
> concepts -- I'll stick to what I know.) You call them "syntactic
> sugar" (with negative connotations) for get/set accessor functions.
I intended no negative connotations. If they provide the exact same
semantics as accessor functions, but use a different syntax, then they
are syntactic sugar for accessors. That appears to be the case under
discussion.
> There is a lot of parallel there. The same thing applies to any
> other operator. operator[]() is syntactic sugar for index(), and
> operator+() is syntactic sugar for add(), and so on.
>
> There is something to be said for inline notation, however. If users
> can use a property "as if" it was a data member, they no longer need
> to be concerned about the distinction unless they plan to alter the
> implementation.
I see allowing/encouraging programmers to use classes "as if" they
were unencapsulated collections of data as a step backwards,
personally.
> std::cout << "Changing customer " << cust.id << "'s name from \""
> << cust.name;
> std::cout << "\" to \"" << (cust.name=newname); << "\"!\n";
>
> Much easier to read, write, and understand than
>
> std::cout << "Changing customer " << cust.getID() << "'s name from \""
> << cust.getName();
> cust.setName(newname);
> std::cout << "\" to \"" << cust.getName(); << "\"!\n";
>
> I'll respect your right to disagree, if you choose to ... but then please
> tell me if you dislike operator overloading as well.
It's irrelevant, since operator overloading is already part of the
language. We're talking about a proposal to add to the language.
> > In addition, the syntactic changes required for references were
> > extremely minor compared to the syntactic changes required for
> > properties. So with references we had a small change in syntax with a
> > change in semantics, as compared to pointers. With properties (as
> > discussed in this post) we have a big change in syntax and no change
> > in semnatics, as compared to accessors.
>
> How so?
There is a change to class declaration syntax.
> > But if there's no need to use properities at all, this huge advantage
> > is moot. So when would you need to? Why is that need so strong as to
> > justify such a large language change?
>
> I don't see it as a large change.
The point is that, whether you see it as large or small, the change is
there; what justifies it? What problems do properties solve? What is
it that can't be done with today's C++ that properties would enable?
The "syntax sugar for accessors" properties we are discussing here
solve no problems of this type, since they don't provide any
additional semantics beyond accessors. In fact, this kind of property
can be implemented today, with no language change:
template<typename T, typename Owner>
class Property {
public:
typedef void (Owner::* Setter)(T);
typedef T (Owner::* Getter)(void) const;
Property(Owner* iOwner,
Setter iSetter,
Getter iGetter);
operator T(void) const;
Property& operator=(const T& iArg);
private:
Owner* mOwner;
Setter mSetter;
Getter mGetter;
};
template<typename T, typename Owner>
Property<T, Owner>::Property(Owner* iOwner, Setter iSetter, Getter
iGetter) :
mOwner(iOwner),
mSetter(iSetter),
mGetter(iGetter)
{
}
template<typename T, typename Owner>
Property<T, Owner>::operator T(void) const
{
return (mOwner->*mGetter)();
}
template<typename T, typename Owner>
Property<T, Owner>& Property<T, Owner>::operator=(const T& iArg)
{
(mOwner->*mSetter)(iArg);
}
class Foo {
public:
Foo(void);
Property<int, Foo> propX;
private:
void SetX(int iX);
int GetX(void) const;
int mX;
};
Foo::Foo(void) :
propX(this, &Foo::SetX, &Foo::GetX),
mX(0)
{
}
void Foo::SetX(int iX)
{
mX = iX;
}
int Foo::GetX(void) const
{
return mX;
}
// Usage:
void F(void)
{
Foo f;
f.propX = 10;
std::cout << f.propX << "\n";
f.propX = 20;
std::cout << f.propX << "\n";
}
I don't think there's anything you can do with the "syntax sugar"
properties that this template doesn't do.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Sat, 1 Feb 2003 02:13:52 +0000 (UTC) Raw View
"Bob Bell" <belvis@pacbell.net> wrote in message
news:c87c1cfb.0301311245.3db27b2d@posting.google.com...
> [...]
> I don't think there's anything you can do with the "syntax sugar"
> properties that this template doesn't do.
> [...]
> Owner* mOwner;
> Setter mSetter;
> Getter mGetter;
Except save sizeof(Owner*) + sizeof(Setter) + sizeof(Getter)
bytes for each property. Typical classes in the VCL have
upwards of 20 properties. On BCB, sizeof(void (T::*)()) == 12.
That gives an overhead of 28 bytes per property, or 560 bytes
per VCL class, on average. You think that over half a KB of
memory *per object* is an acceptable price to pay?
On VC++, sizeof(void (T::*)()) is only 4, but that still means you
have 12 bytes of overhead for each property. Considering a
typical property is an int or a pointer, that's 300% overhead!!
You can save a lot of memory by making the Setter and Getter
template parameters, but native properties would presumably
have 0 memory overhead (just like class members don't need
a pointer to their enclosing class to work properly). The best
you can do to eliminate memory overhead for properties
today is some highly non-portable and questionable pointer
arithmetic to get a pointer to the enclosing class. Odds are,
there's no legal way to do this for all scenarios.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.@@xmission.dot.com (llewelly)
Date: Mon, 3 Feb 2003 19:56:39 +0000 (UTC) Raw View
dheld@codelogicconsulting.com ("David B. Held") writes:
F> "Bob Bell" <belvis@pacbell.net> wrote in message
> news:c87c1cfb.0301251136.5be433c2@posting.google.com...
> > [...]
> > In addition, the syntactic changes required for references were
> > extremely minor compared to the syntactic changes required for
> > properties. So with references we had a small change in syntax
> > with a change in semantics, as compared to pointers. With
> > properties (as discussed in this post) we have a big change in
> > syntax and no change in semnatics, as compared to accessors.
> > [...]
>
> I personally believe there is one very good reason why Borland
> uses properties in BCB instead of accessors: __published.
I think you mean introspection. When an object is examined at run
time, its __published members can be identified by querying
it. This is called introspection. Properties are independent of
introspection. Plenty of languages - Objective C, smalltalk, java,
etc, support introspection, but do not have properties.
[snip]
> Anyone who has used BCB for 10 minutes to build a Windows
> app knows how powerful it is. M$ knows how powerful it is,
> because we now have C#. Let's stop pretending graphical
> OSes don't exist. They do. You're using one right now. If we
> want C++ to continue to be relevant, we must help it become
> aware of the world, and that world includes GUIs. Support
> properties. The fate of C++ just might depend on it. ;>
[snip]
On introspection? Likely, but far from proven. On properties? No.
I've used a fair variety of gui toolkits and rad builders in C++. I
don't think any of them came within 2% of C++'s potential. Yes,
that does include BCB and MFC, though it's been years since I used
BCB. Most of them relied on extensions - most of which I believe
can be improved on by infrastructures written in standard C++. For
example: The functionality Qt's messaging extensions (provided by
the Qt moc) can be replaced by a templated messaging
infrastructure like libsigc++, with two big gains: (a) compile
time type (and other) guarantees on messages, and vastly superior
performance.
Introspection can be written in C++ if (and only if) the compiler can
be relied upon to generate necessary information, and store it in
the executable, (or known related file) preferably in a section
that gets loaded. Most compilers can be configured to generate
debuggin info, and a library can usually be found to read it.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Tue, 4 Feb 2003 06:40:23 +0000 (UTC) Raw View
"llewelly" <llewelly.@@xmission.dot.com> wrote in message
news:8665s377sv.fsf@Zorthluthik.foo...
> [...]
> I think you mean introspection. When an object is examined at
> run time, its __published members can be identified by querying
> it. This is called introspection. Properties are independent of
> introspection. Plenty of languages - Objective C, smalltalk,
> java, etc, support introspection, but do not have properties.
In BCB, properties enable compile-time introspection, not run-
time. Nor do properties enable full introspection, as you say.
While introspection is a useful concept in and of itself, full
introspection is not necessary to get useful IDE assistance.
> [...]
> I've used a fair variety of gui toolkits and rad builders in C++. I
> don't think any of them came within 2% of C++'s potential.
> Yes, that does include BCB and MFC, though it's been years
> since I used BCB. Most of them relied on extensions - most of
> which I believe can be improved on by infrastructures written
> in standard C++.
Then propose an alternative design using only C++, and ask the
compiler vendors why they aren't using it.
> For example: The functionality Qt's messaging extensions
> (provided by the Qt moc) can be replaced by a templated
> messaging infrastructure like libsigc++, with two big gains: (a)
> compile ime type (and other) guarantees on messages, and vastly
> superior erformance.
I'm not familiar with Qt, so I can't comment on that. But I know
that properties have been attempted in C++, and they are always
bigger, slower, or as unportable as the extensions. If you have a
C++ alternative to native properties, I'm sure Borland and
Microsoft ould love to see it (and probably a lot of others too).
> Introspection can be written in C++ if (and only if) the compiler
> can be relied upon to generate necessary information, and store
> it in the executable, (or known related file) preferably in a section
> that gets loaded. Most compilers can be configured to generate
> debuggin info, and a library can usually be found to read it.
But C++ doesn't guarantee that a compiler will generate such
information, which is why we have the extensions in the first place.
If you think C++ needs native introspection facilities, then propose
it. If you think it can all be done in current C++, show us how.
If neither of those is the case, then I think properties are a
reasonable way forward.
Dave
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Mon, 27 Jan 2003 20:27:33 +0000 (UTC) Raw View
allan_w@my-dejanews.com (Allan W) wrote in message news:<7f2735a5.0301241554.1f5c1e92@posting.google.com>...
> belvis@pacbell.net (Bob Bell) wrote
> > > - See proposal http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1384.pdf
> >
> > OK, I read the proposal. Unless I missed something, the section on
> > properties didn't describe anything that can't be done today with
> > get/set functions. In fact, properties were described as nothing more
> > than syntactic sugar for accessors. There was some mention of
> > introspection, but it was defined very loosely, so it's not clear what
> > it means.
>
> Syntactic Sugar. An interesting phrase. The same thing was said about
> references -- and sure enough, everything that can be done with
> references can also be done with pointers, if you don't mind completely
> rewriting the code to use a different syntax.
Yet references are not syntactic sugar for pointers, regardless of
what was "said". Pointers can be reseated while references can't,
failed dynamic_cast of pointers returns NULL while failed dynamic_cast
of references throws std::bad_cast, and there is no equivalent for
pointer arithmetic with references. A reference is permanently tied to
the object it's bound to, while no such restriction exists for
pointers. References have very different semantics from pointers.
In addition, the syntactic changes required for references were
extremely minor compared to the syntactic changes required for
properties. So with references we had a small change in syntax with a
change in semantics, as compared to pointers. With properties (as
discussed in this post) we have a big change in syntax and no change
in semnatics, as compared to accessors.
> The Borland proposal for properties is very useful. You're right,
> it doesn't explicitly state the syntax for accessing properties, but
> I assume it would be absolutely identical to public data members.
> One huge advantage of this approach is that you wouldn't have to
> use properties until there's some motivating need to.
But if there's no need to use properities at all, this huge advantage
is moot. So when would you need to? Why is that need so strong as to
justify such a large language change?
> class Foo {
> // ...
> public:
> std::string FooName; // The foo name
> };
>
> // Display the current FooName
> std::cout << foo.FooName;
>
> // Read a new FooName
> std::cin >> foo.FooName;
>
> Tomorrow we decide to use an enhanced string class, to replace the
> standard one.
>
> class Foo {
> // ...
> // These convert EnhancedString to/from std::string
> std::string getFooName() { return FooName2.getStdString(); }
> void setFooName(std::string ss) { FooName2 = ss; }
> public:
> SomeVendor::enhancedstring FooName2; // The enhanced foo name
> property<std::string> FooName = {
> read = getFooName,
> write = setFooName
> }
> };
> New code can use FooName2 instead, and get all the enhancements.
> Old code doesn't have to change at all; the data is still available
> as promised.
Your example could just have easily been satisfied using accessor
functions directly, with the same advantages of old code not having to
change at all. So why do we need to add properties to the language?
> > Getting back to my question: how do you want properties to behave
> > exactly? I gather that this spec doesn't really answer the question,
> > since you seem to think properties are more than just accessors. Or do
> > you want the whole thing? Properties, methods, and events?
>
> Properties are just accessors, plus syntax that makes them look like
> member data.
I got the impression that the OP thought properties were more than
that. Which, if true, demonstrates my other point that properties mean
different things to different people. I'm not even sure we're all
talking about the same thing.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: eldiener@earthlink.net ("Edward Diener")
Date: Fri, 24 Jan 2003 19:23:31 +0000 (UTC) Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uadhrgnzv.fsf@boost-consulting.com...
> belvis@pacbell.net (Bob Bell) writes:
>
> FWIW I reviewed their proposal with some Borland representatives at
> the last standards committee meeting. When I pointed them at the
> combination of the Boost.Bind and Boost.Function libraries, which
> together accomplish nearly everything their proposal does, IIRC they
> seemed pretty satisfied that no core language change was needed. You
> can check these libraries out at http://www.boost.org.
Boost.Bind and Boost.Function cover events pretty well, along with
Boost.Signal, but I don't see their relevance to a discussion of properties.
That is not to say that a template-based property along the lines of what
the original poster proposed isn't doable for all I know.
There are really two issues in the original post. One is property and the
other is a C++ introspection mechanism which would allow the types of member
functions and member data to be discoverable at run-time. The latter could
be used for RAD programming environments in C++, such as Borland has done
with their C++ Builder product with its C++ language extensions, but I think
these are two separate proposals and should not be lumped into one idea.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Sat, 25 Jan 2003 02:26:57 +0000 (UTC) Raw View
eldiener@earthlink.net ("Edward Diener") writes:
> "David Abrahams" <dave@boost-consulting.com> wrote in message
> news:uadhrgnzv.fsf@boost-consulting.com...
>> belvis@pacbell.net (Bob Bell) writes:
>>
>> FWIW I reviewed their proposal with some Borland representatives at
>> the last standards committee meeting. When I pointed them at the
>> combination of the Boost.Bind and Boost.Function libraries, which
>> together accomplish nearly everything their proposal does, IIRC they
>> seemed pretty satisfied that no core language change was needed. You
>> can check these libraries out at http://www.boost.org.
>
> Boost.Bind and Boost.Function cover events pretty well, along with
> Boost.Signal, but I don't see their relevance to a discussion of
> properties.
Ah, good point. I had forgotten a part of that discussion after all.
> That is not to say that a template-based property along the lines of what
> the original poster proposed isn't doable for all I know.
It really isn't, without a nasty amount of overhead.
> There are really two issues in the original post. One is property
> and the other is a C++ introspection mechanism which would allow the
> types of member functions and member data to be discoverable at
> run-time. The latter could be used for RAD programming environments
> in C++, such as Borland has done with their C++ Builder product with
> its C++ language extensions, but I think these are two separate
> proposals and should not be lumped into one idea.
Yup. And the introspection should be available at compile-time ;-)
--
David Abrahams
dave@boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Sat, 25 Jan 2003 02:31:17 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote
> > - See proposal http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1384.pdf
>
> OK, I read the proposal. Unless I missed something, the section on
> properties didn't describe anything that can't be done today with
> get/set functions. In fact, properties were described as nothing more
> than syntactic sugar for accessors. There was some mention of
> introspection, but it was defined very loosely, so it's not clear what
> it means.
Syntactic Sugar. An interesting phrase. The same thing was said about
references -- and sure enough, everything that can be done with
references can also be done with pointers, if you don't mind completely
rewriting the code to use a different syntax.
The Borland proposal for properties is very useful. You're right,
it doesn't explicitly state the syntax for accessing properties, but
I assume it would be absolutely identical to public data members.
One huge advantage of this approach is that you wouldn't have to
use properties until there's some motivating need to.
class Foo {
// ...
public:
std::string FooName; // The foo name
};
// Display the current FooName
std::cout << foo.FooName;
// Read a new FooName
std::cin >> foo.FooName;
Tomorrow we decide to use an enhanced string class, to replace the
standard one.
class Foo {
// ...
// These convert EnhancedString to/from std::string
std::string getFooName() { return FooName2.getStdString(); }
void setFooName(std::string ss) { FooName2 = ss; }
public:
SomeVendor::enhancedstring FooName2; // The enhanced foo name
property<std::string> FooName = {
read = getFooName,
write = setFooName
}
};
New code can use FooName2 instead, and get all the enhancements.
Old code doesn't have to change at all; the data is still available
as promised.
> Getting back to my question: how do you want properties to behave
> exactly? I gather that this spec doesn't really answer the question,
> since you seem to think properties are more than just accessors. Or do
> you want the whole thing? Properties, methods, and events?
Properties are just accessors, plus syntax that makes them look like
member data.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Thu, 23 Jan 2003 00:33:41 +0000 (UTC) Raw View
witless@attbi.com (Witless) wrote in message news:<3E2D51F4.DE67FD6C@attbi.com>...
>
> Much of that was driven by their resistance to OOD. They admitted that MFC was not OO and that they
> designed it that way on purpose. They also claimed to have "dumbed down" the design in order to address
> their perception of their customers needs.
>
> So MFC is not a good example of the use of C++.
>
In the case of MFC how does one design and develop a GUI framework
with (to an extent) ANSI C++? I claim that it is very difficult.
Despite what mistakes Microsoft made with MFC, it is not entirely
their fault and not because they have an aversion towards OOD. I
think both Microsoft's MFC, Troll Tech's Qt, Borland's products
clearly show that current ANSI C++ lacks some needed programming
constructs that are important in the world of graphical user
interfaces. MFC is cumbersome with their message maps, dialog
templates, and DDX code (and Class Wizard does not always take care of
everthing for you). Qt is a lot nicer than MFC, however, to implement
an elegant object communication mechanism that is nicer than MFC
message maps, Troll Tech has introduced a whole new compilation phase
known as the Meta-Object Compiler. Borland, in my opinion, has the
best C++ IDE. Unfortunately I cannot count them as a ANSI C++
solution because they extended the language. Are they trying to tell
us something?
> >
> > Sophisticated GUI tools that rely on object properties are going to
> > demand a certain level of RTTI that is beyond the current C++ RTTI
> > capabilities.
>
> Like what?
>
Delphi. C++ Builder. Visual BASIC (via the COM/ActiveX technology).
As much as I like Qt it does not compare to the elegance of graphical
application development that the above tools can provide.
Nicholas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Thu, 23 Jan 2003 01:05:18 +0000 (UTC) Raw View
bob.news@gmx.net ("Robert Klemme") wrote in message news:<b0jh4d$pp2f5$1@ID-52924.news.dfncis.de>...
>
> And I'm still missing the proof that the introduction of properties in C++
> is such a major improvement that it outweights the price we all would have
> to pay.
I can not prove any of my claims. I would actually like to conduct a
study of many C++ projects to find what paradigms and coding idioms
proved to be a boon or a bane to C++ developers, but that is beyond my
expertise and resources. However, is my belief of the
properties-methods-events (PME) paradigm just blind faith? I would
like to think not. I wouldn't request properties as a new feature for
C++ if I didn't see it have success in other languages.
Here is something for the C++ community to think about. Where is the
proof that the feature of templates, the generic paradigm, was a major
improvement that outweighed its price? Only recently have commercial
vendors provided C++ compilers that support the ANSI C++ standard, and
even then they are not always available (I still can't convince my
employers to switch from the Microsoft compiler to the Intel
compiler). From my perspective, through the whole decade of the 90's
a lot of people put time and energy into the development of the
generic paradigm. After all that I still can't develop in the generic
paradigm because of some compiler limitation or some nasty workaround
that just makes the resulting code not worth wanting to maintain in
production code. I have been part of C++ projects that didn't use
templates (except for using STL classes). They were either in the
style of single inheritance multiple interface (class of only pure
virtual methods, that is) or the style of multiple inheritance using
the notion of mixin classes. I have seen both success of failure of
it. I have also met C++ programmers that develop in similiar
fashions. I have met developers who use other languages that employ
the PME paradigm (like Delphi or C++ Builder) and they have achieved a
certain level of success. As far as I am concerned the only people
that I know of that use templates and the generic paradigm are you
people in the newsgroups, and I have never met any of you.
If you think I am making this up then I'll summarize my experience
with the generic paradigm. Partial specializations. Nuff' said. I
wish I could use that feature, but I gues I have to wait a little
longer for standards compliant compilers to become ubiquitous. Type
lists, from Andrei Alexandrescu, are a really weird but awesome thing.
I tried to employ it in one project but type lists in Microsoft
Visual C++ 6.0 are difficult. As I stated earlier I would rather not
use templates at all then deal with code with all the workarounds
involved.
> If you're in urgent need for properties, then maybe other
> languages (C# comes to mind, Java as well) are better suited for the
> problems you are trying to solve.
>
Well, I am not in urgent need of it. Obviously I am able to develop
C++ applications without them. This is about making my job easier
while making the code elegant. As for using another language,
professionally speaking, I do not always have choice about which
language I will use on a particular project. Sometimes some people
from high up, other than the developers, mandate that a particular
language and even a particular vendor must be used. But that is not a
problem me. I do not hate C++. I do not write it off because some
feature annoys me. Every piece of technology is going to some problem
or another that annoys somebody. I just think it would be nice for
C++ if it would incorporate the PME paradigm. People always like to
tout how C++ is a "multi-paradigm" language. So why the resistance?
Nicholas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Thu, 23 Jan 2003 01:05:24 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) wrote in message news:<c87c1cfb.0301211404.2bfec32e@posting.google.com>...
>
> I think for this discussion to continue, you should define your terms
> a little more clearly. How do you want properties to behave exactly?
> The term "properties" means different things to different people.
>
> Bob
>
Sure. In fact a response to this thread, from Pavel Vozenilek,
already contains an good link that describes what I am writing about.
>From Pavel's response:
- Borland had proposed to add properties (as implemented in BCB6.0)
- into the Standard.
- See proposal http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1384.pdf
Nicholas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 23 Jan 2003 03:48:56 +0000 (UTC) Raw View
ndsalerno@yahoo.com (Nicholas Salerno) wrote
> there are two types of entities: programming constructs and things
> of the problem domain. For example, a for loop is a programming
> construct. A bank transaction is not a programming construct. It
> is an entity of the problem domain. Obviously nobody wants bank
> transaction support to be built into the language. We make classes
> and libraries for financial applications. However, could we make a
> for loop class? Yes.
You think so? for_each() comes close, but even that isn't a class.
I'd be mildly interested in how this would work... but don't bother
explaining. We've got enough distractions already.
> Is it a good idea? (I am inclined to say no but I can imagine
> someone making an argument for a language where not only int,
> char, and double are classes
In a "pure" world this might make sense. The idea behind may C++
features (user-defined types with overloaded constructors, operators,
and conversion functions) is to make a user-defined class look as
close to a built-in as possible. And yet we sometimes have to draw a
huge distinction between user-defined types and built-in types. All
built-ins are PODs. Built-ins can use short-circuit evaluation but
user-defined types cannot. And so on. It's disappointing, really.
On the other hand, reality check. Suppose adding two ints inline was
considered an "optimization." C++ would be doggedly slow! Even in
user-defined types, addition usually boils down (at some level) to
operations involving integers and floating-point types. So they
really should get special treatment.
> but so are if, switch, and for)
Again, I can't see this. Maybe I'm just blinded by conventional wisdom.
If switch was a class, would it be possible to instantiate one?
void foo(switch &s) {
switch t(s); // Local copy of the switch
// ...
I just can't bend my mind 'round how that would be useful.
In C++, the most common statement type is the expression statement.
That doesn't mean we don't have other types of statements!
Many languages have a "let" or "assignment" statement, but C++ doesn't
need this because expressions can use assignment operators. Also,
variable declarations can include expressions in initializers.
Conceivably we could have always used the trinary operator to replace
if-then-else constructs. But that would change if from a statement into
an operator, not a class. For switch and for, I don't think you can
even do that with a straight face -- and if you tried at all, the
syntax would have to be wildly different from what it is today.
> * Properties help define an interface.
Not certain what you mean by that. What kind of properties are
you referring to? Classwide properties, such as used in C#?
Or are you referring to properties in the OO sense; something
similar to C++ "public data members"?
> Also, they do not violate encapsulation or expose implementation
> any more than get_value/set_value methods.
I think what you're talking about is the Microsoft-style properties.
They are declared as part of the class interface, and they have a
data type, but they don't take up space in the class. Instead, any
attempt to read this "data member" invokes a special member function,
and any attempt to write it invokes another one. Microsoft has provided
this for years in Visual C++ as a local extension. Also, the same thing
was made part of the C# language.
In that case, I'll agree with you. The reason that C++ public data
members are normally considered to violate encapsulation, is that if
the data type of those members were ever to change, all client code
would have to adapt. By constrast, if you declare a "property" which
can be read or changed with (probably) the same syntax as a public
data member, it would be easy to change the get/set methods so that
the interface still uses the same data type, even though internally
we could use something quite different.
> Properties are a natural element in the object oriented paradigm.
Yes, I agree.
> * Properties are an opportunity to provide a clearer syntax for
> defining class interfaces. YES! This is important.
Okay.
> * Along with RTTI, properties can provide an elegant way to
> stream classes. In the domain of GUI development this can help
> foster RAD style tools for the C++ community.
I'm sorry, I just don't see the connection. Maybe I was wrong after
all about what you meant by "properties" -- my version has nothing
to do with RTTI.
> RTTI Revisited
Again, I don't see the connection, and your rant about RTTI (which I
snipped) didn't clear it up for me.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: allan_w@my-dejanews.com (Allan W)
Date: Thu, 23 Jan 2003 08:13:17 +0000 (UTC) Raw View
bob.news@gmx.net ("Robert Klemme") wrote
> I'm still missing the proof that the introduction of properties in C++
> is such a major improvement that it outweights the price we all would have
> to pay [in broken legacy code]. If you're in urgent need for properties,
> then maybe other languages (C# comes to mind, Java as well) are better
> suited for the problems you are trying to solve.
Hold on. Of all the "radical" proposals I've seen, this may be the
least radical. Let's study them one at a time.
> Introduction of properties in C++ is a major improvement?
Well, let's point out that people have been doing the same thing manually
for many years, in the form of accessor functions.
class BadWay {
public:
int secret;
};
This way is Bad(tm), because if "secret" ever changes to a floating-point
value, all client code breaks.
class BetterWay {
int m_secret;
// Lots of other stuff
public:
int getSecret();
void setSecret(int);
// alternatively:
int Secret();
int Secret(int newSecret);
};
// These are trivial, so they absolutely ought to be inline (according
// to many).
// Inline functions are evil, because if the class changes all clients
// need to recompile (according to others).
// Whatever.
int BetterWay::getSecret() { return m_secret; }
void BetterWay::setSecret(int newSecret) { m_secret = newsecret; }
// Alternatively
int BetterWay::Secret() { return m_secret; }
int BetterWay::Secret(int newSecret) {
int oldSecret = m_secret;
m_secret=newSecret;
return oldSecret;
}
The reason this is Better, according to most people that tout it, is
that m_secret can change to a floating-point value without breaking
client code. We would simply let the accessor functions convert the
floating-point value to int, or vice-versa. We could also add new
accessor functions to support new code that uses the float, but the
main point is we wouldn't break any client code (it might need a
recompile, if we used inline...)
class BetterWay {
float m_secret; // Used to be int!
// Lots of other stuff
public:
// Shown with inline to simplify the coding
float getSecret2() { return m_secret; }
void setSecret2(float newSecret) { m_secret = newSecret; }
// Deprecated: to support old code
int getSecret() { return static_cast<int>(m_secret); }
void setSecret(int n) { m_secret = static_cast<float>(n); }
int Secret() { return getSecret(); }
int Secret(int n) { int old=getSecret(); setSecret(n); return old; }
};
Properties give you that too.
> outweights (sic) the price we all would have to pay [in broken legacy code]?
In an earlier post, you suggested that the major "price" would be
yet another keyword. Presumably, if we implemented this feature without
using a new keyword, you would be convinced.
class NewWay {
int m_secret;
public:
int Secret const { return m_secret; }
int Secret { m_secret = Secret; }
};
// Usage:
NewWay nw;
nw.Secret = 2; // Sets value to 2
std::cout << nw.Secret; // Prints 2
The syntax resembles a pair of member functions, except that it has
no parameter list. The const function is the "property get." The
non-const function is the "property set." The only place where I
would consider using a new keyword is for the value being assigned.
Rather than use a keyword, I'll use the property name instead. (This
means that the Property Set code can't be recursive or call the
Property Get code, but that's a small loss.)
Notice that access to the property looks exactly like access to
public member data.
The compiler "knows" if this is a read or write access, and handles
it accordingly. This also means that a large class of proxy classes
are no longer needed. For instance, if std::string uses COW
(copy-on-write), reading the third character in the string can get
the data directly without triggering COW, and changing the third
character can trigger COW directly without using a proxy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: witless@attbi.com (Witless)
Date: Thu, 23 Jan 2003 08:14:20 +0000 (UTC) Raw View
===================================== MODERATOR'S COMMENT:
Please tell your newsreader to wrap lines at 80 chars.
===================================== END OF MODERATOR'S COMMENT
Nicholas Salerno wrote:
> witless@attbi.com (Witless) wrote in message news:<3E2D51F4.DE67FD6C@attbi.com>...
>
Attribution previously deleted .
> > >
> > > Sophisticated GUI tools that rely on object properties are going to
> > > demand a certain level of RTTI that is beyond the current C++ RTTI
> > > capabilities.
> >
> > Like what?
> >
>
> Delphi. C++ Builder. Visual BASIC (via the COM/ActiveX technology).
Ahem. You said that a higher level of RTTI was needed. Listing products that you claim contain those aspects
of RTTI does not answer the question. So I'll repeat it: What level of RTTI is required by sophisticated
GUI tools?
In my experience of designing GUIs architecture, designing GUI tools, and using both I found little or no need
for RTTI at all. So I would claim that the more sophisticated the GUI tool the less RTTI is needed..
>
> As much as I like Qt it does not compare to the elegance of graphical
> application development that the above tools can provide.
What has graphical application development have to do with RTTI? You do understand that applications are
independent of their interface, right? Commingling the two is not elegance, it is bad design.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 23 Jan 2003 17:45:59 +0000 (UTC) Raw View
ndsalerno@yahoo.com (Nicholas Salerno) writes:
> I think both Microsoft's MFC, Troll Tech's Qt, Borland's products
> clearly show that current ANSI C++ lacks some needed programming
> constructs that are important in the world of graphical user
> interfaces.
I think that's all true, but I'd like any expansion of C++
introspection capability to be operable at compile-time, not just at
runtime as RTTI is. We need it at compile time as well, for lots of
applications (see language binding [Boost.Python], serialization,
persistence, ...)
-Dave
--
David Abrahams
dave@boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Thu, 23 Jan 2003 22:19:10 +0000 (UTC) Raw View
ndsalerno@yahoo.com (Nicholas Salerno) wrote in message news:<b9da50a9.0301221652.79a1b631@posting.google.com>...
> belvis@pacbell.net (Bob Bell) wrote in message news:<c87c1cfb.0301211404.2bfec32e@posting.google.com>...
> >
> > I think for this discussion to continue, you should define your terms
> > a little more clearly. How do you want properties to behave exactly?
> > The term "properties" means different things to different people.
> >
> > Bob
> >
>
> Sure. In fact a response to this thread, from Pavel Vozenilek,
> already contains an good link that describes what I am writing about.
>
> >From Pavel's response:
> - Borland had proposed to add properties (as implemented in BCB6.0)
> - into the Standard.
>
> - See proposal http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1384.pdf
OK, I read the proposal. Unless I missed something, the section on
properties didn't describe anything that can't be done today with
get/set functions. In fact, properties were described as nothing more
than syntactic sugar for accessors. There was some mention of
introspection, but it was defined very loosely, so it's not clear what
it means.
Getting back to my question: how do you want properties to behave
exactly? I gather that this spec doesn't really answer the question,
since you seem to think properties are more than just accessors. Or do
you want the whole thing? Properties, methods, and events?
Bob Bell
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 24 Jan 2003 04:47:17 +0000 (UTC) Raw View
belvis@pacbell.net (Bob Bell) writes:
> ndsalerno@yahoo.com (Nicholas Salerno) wrote in message news:<b9da50a9.0301221652.79a1b631@posting.google.com>...
>> Sure. In fact a response to this thread, from Pavel Vozenilek,
>> already contains an good link that describes what I am writing about.
>>
>> >From Pavel's response:
>> - Borland had proposed to add properties (as implemented in BCB6.0)
>> - into the Standard.
>>
>> - See proposal http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1384.pdf
>
> OK, I read the proposal. Unless I missed something, the section on
> properties didn't describe anything that can't be done today with
> get/set functions. In fact, properties were described as nothing more
> than syntactic sugar for accessors. There was some mention of
> introspection, but it was defined very loosely, so it's not clear what
> it means.
>
> Getting back to my question: how do you want properties to behave
> exactly? I gather that this spec doesn't really answer the question,
> since you seem to think properties are more than just accessors. Or do
> you want the whole thing? Properties, methods, and events?
FWIW I reviewed their proposal with some Borland representatives at
the last standards committee meeting. When I pointed them at the
combination of the Boost.Bind and Boost.Function libraries, which
together accomplish nearly everything their proposal does, IIRC they
seemed pretty satisfied that no core language change was needed. You
can check these libraries out at http://www.boost.org.
-Dave
--
David Abrahams
dave@boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Sun, 19 Jan 2003 21:14:11 CST Raw View
On Features Being Native or Being A Class
(Properties and RTTI Revisited)
Summary: This is a plea for the addition of properties to the C++ language.
However, in thinking about properties an even bigger issue exists. What
qualifies as being part of a language or being implemented using a class.
My Rant
Like anyone else, I read the newsgroups, both new and old postings, to become a
better C++ programmer. One common theme I have noticed among the C++ community
is that people are opposed to adding new features to the language. They prefer
it if the new feature is implemented as a class (template or non-template).
But does it always make sense to represent something as a class? I figure that
there are two types of entities: programming constructs and things of the
problem domain. For example, a for loop is a programming construct. A bank
transaction is not a programming construct. It is an entity of the problem
domain. Obviously nobody wants bank transaction support to be built into the
language. We make classes and libraries for financial applications. However,
could we make a for loop class? Yes. Is it a good idea? (I am inclined to
say no but I can imagine someone making an argument for a language where not
only int, char, and double are classes but so are if, switch, and for)
My Claim
Entities that are programming constructs should be native to a language.
Entities that are from the problem domain should be implemented as classes.
Programming constructs help implement entities from the problem domain.
Furthermore, a property is NOT an entity from the problem domain, it is a
programming construct. That is my claim. You may disagree.
Why Properties?
I will not give a full lecture about properties because that issue has already
been beaten to death in past postings to lang.c++ and std.c++. I will just
state the conclusions that I believe are true.
* Properties help define an interface. Also, they do not violate encapsulation
or expose implementation any more than get_value/set_value methods. Properties
are a natural element in the object oriented paradigm.
* Properties are an opportunity to provide a clearer syntax for defining class
interfaces. YES! This is important.
* Along with RTTI, properties can provide an elegant way to stream classes. In
the domain of GUI development this can help foster RAD style tools for the C++
community.
RTTI Revisited
RTTI would also have to be enhanced in the language. Basically the feature is
that a programmer can choose to "publish" a property. A published property is
a property with RTTI information. Please do not get me wrong. I am not
advocating RTTI be used all over the place. I will be the first to agree that
abundant usage of RTTI is a sign of a bad object oriented design. However,
RTTI is not to be completely avoided. I liken RTTI to the goto statement. The
goto statement is not automatically evil as some people want you to believe.
Goto has a niche role in programming. It can be a good thing for low level
programming. However, it is bad for high level programming. If we are talking
about developing an online shopping cart system then I would agree that goto
statements should not be seen in good object oriented code. However, if we are
talking about a SCSI driver, or an OS kernel, then goto can be your friend for
efficiency and compactness. In my experience I have always found GUI tools,
based on RTTI techniques, to be far superior.
Importance of Clearer Syntax
"Any fool can write code that a computer can understand. Good programmers
write code that humans can understand"
-- Martin Folwer
I believe this to be true and important. Readable code is a valuable asset for
any software project. By the way, I am not writing about
if( (not (p eq NULL)) and (p->do_this()) ) // this reads like English
VS
if(p && p->do_this()) // this doesn't, however, it is readable code
no, no, no. That is not what I am writing about. What I am writing about is a
programming construct that is clear and concise verses some contorted template
class, which most likely doesn't work for all major compiler vendors without
additional preprocessor directives. Some template classes are easy to read and
some template classes read like hardcore Perl code. Like it or not that is the
current state of C++ template syntax. Some classes are just plain funky. Add
insult to injury, depending on the compiler being used, you can't seperate
interface from implementation. So now the implementation code is inside the
class interface. Lovely. (Yes, I know Intel C++ and Visual C++.NET allow for
out of class template definitions but they are not in wide spread use. I still
have to deal with Visual C++ 6.0 and I am sure other people have to as well)
Please don't post property template class examples. I have seen it all
before. They just aren't good enough. I know what I am talking about. Before
posting this I have read whatever old postings on the issue I could find.
Everybody loves to simply cast off properties and say that it should be
implemented using template classes. However, most people can't do it. Of the
people who did post a code example, their code has either one of two main
problems. 1) It didn't compile (don't these people check their work before
posting code?) 2) It did work but the usage of the class was the usual
contorted template syntax and was inefficient. Pete Becker, of Dinkumware,
even pointed it out that the proposed template solutions required properties
template classes to maintain pointers to their parents, which could get out of
hand and waste memory easily. In my opinion he has successfully challenged all
the naysayers and shown that properties are better off being implmented native
to the language for efficiency.
But then again, this all comes back to my original claim. Properties are
language constructs. Languages constructs are best implmented native to the
language.
On a final note, if C++ should have properties and you hate properties then
just don't use them. I never proposed that all programmers must use properties.
Nicholas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: pavel_vozenilek@yahoo.co.uk (Pavel Vozenilek)
Date: Tue, 21 Jan 2003 19:04:55 +0000 (UTC) Raw View
ndsalerno@yahoo.com (Nicholas Salerno) wrote in message news:<b9da50a9.0301191408.59a44c76@posting.google.com>...
> On Features Being Native or Being A Class
>
> (Properties and RTTI Revisited)
>
> Summary: This is a plea for the addition of properties to the C++ language.
>
[snip]
Borland had proposed to add properties (as implemented in BCB6.0) into
the Standard.
See proposal http://std.dkuug.dk/jtc1/sc22/wg21/docs/papers/2002/n1384.pdf
or discussion http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&frame=right&rnum=1&thl=0,1005396851,1005392949,1002346702,1002098980,1001824599,1001815213,1001795061,1001670025,1001555561,1001534475,1001257262&seekm=3DA9E299.4FBEC030%40bcbdev.com#link1.
I use BCB, use properties and find them useful.
/Pavel
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: witless@attbi.com (Witless)
Date: Tue, 21 Jan 2003 19:17:23 +0000 (UTC) Raw View
Nicholas Salerno wrote:
> bob.news@gmx.net ("Robert Klemme") wrote in message news:<b0h8r1$pntod$1@ID-52924.news.dfncis.de>...
> >
> > In such a situation, if you can implement a new feature by means of older
> > features present in the language you are more likely to reach a win-win
> > situation: you standardize the new feature but you break less code -
> > especially since namespace std is reserved for these kinds of things. So
> > new classes / methods will not interfere with other code.
> >
>
> Yes, however, my understanding of the situation is that there is no
> sufficient class (template or non-template) that can implement
> properties to rival a native implementation. There is always somekind
> of trade-off. Also, RTTI still needs some enhancements. Even if you
> could write a class to implement properties how would you expose the
> property to RTTI? Look at the Microsoft Foundation Class (MFC)
> library. When initially developed, Microsoft added its own code to
> simulate RTTI because it was absent from the language. When RTTI was
> officially part of C++ Microsoft still stuck with their own code
> because the standard RTTI mechanism of C++ didn't meet their needs.
Much of that was driven by their resistance to OOD. They admitted that MFC was not OO and that they
designed it that way on purpose. They also claimed to have "dumbed down" the design in order to address
their perception of their customers needs.
So MFC is not a good example of the use of C++.
>
> Sophisticated GUI tools that rely on object properties are going to
> demand a certain level of RTTI that is beyond the current C++ RTTI
> capabilities.
Like what?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bob.news@gmx.net ("Robert Klemme")
Date: Tue, 21 Jan 2003 19:34:16 +0000 (UTC) Raw View
"Nicholas Salerno" <ndsalerno@yahoo.com> schrieb im Newsbeitrag
news:b9da50a9.0301201642.63400976@posting.google.com...
> bob.news@gmx.net ("Robert Klemme") wrote in message
news:<b0h8r1$pntod$1@ID-52924.news.dfncis.de>...
> >
> > In such a situation, if you can implement a new feature by means of
older
> > features present in the language you are more likely to reach a win-win
> > situation: you standardize the new feature but you break less code -
> > especially since namespace std is reserved for these kinds of things.
So
> > new classes / methods will not interfere with other code.
>
> Yes, however, my understanding of the situation is that there is no
> sufficient class (template or non-template) that can implement
> properties to rival a native implementation. There is always somekind
> of trade-off. Also, RTTI still needs some enhancements. Even if you
> could write a class to implement properties how would you expose the
> property to RTTI? Look at the Microsoft Foundation Class (MFC)
> library. When initially developed, Microsoft added its own code to
> simulate RTTI because it was absent from the language. When RTTI was
> officially part of C++ Microsoft still stuck with their own code
> because the standard RTTI mechanism of C++ didn't meet their needs.
> Sophisticated GUI tools that rely on object properties are going to
> demand a certain level of RTTI that is beyond the current C++ RTTI
> capabilities.
I see, but then wouldn't it be wiser to *first* improve RTTI to a level
where it reasonable supports current language features and *then* build new
features into RTTI as well as the language? If RTTI reaches functionality
similar to Java Reflection then there is possibly no more need for adding
properties to the language.
And I'm still missing the proof that the introduction of properties in C++
is such a major improvement that it outweights the price we all would have
to pay. If you're in urgent need for properties, then maybe other
languages (C# comes to mind, Java as well) are better suited for the
problems you are trying to solve.
Regards
robert
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Tue, 21 Jan 2003 22:11:47 +0000 (UTC) Raw View
ndsalerno@yahoo.com (Nicholas Salerno) wrote in message news:<b9da50a9.0301201642.63400976@posting.google.com>...
> bob.news@gmx.net ("Robert Klemme") wrote in message news:<b0h8r1$pntod$1@ID-52924.news.dfncis.de>...
> >
> > In such a situation, if you can implement a new feature by means of older
> > features present in the language you are more likely to reach a win-win
> > situation: you standardize the new feature but you break less code -
> > especially since namespace std is reserved for these kinds of things. So
> > new classes / methods will not interfere with other code.
> >
>
> Yes, however, my understanding of the situation is that there is no
> sufficient class (template or non-template) that can implement
> properties to rival a native implementation. There is always somekind
> of trade-off. Also, RTTI still needs some enhancements. Even if you
> could write a class to implement properties how would you expose the
> property to RTTI? Look at the Microsoft Foundation Class (MFC)
> library. When initially developed, Microsoft added its own code to
> simulate RTTI because it was absent from the language. When RTTI was
> officially part of C++ Microsoft still stuck with their own code
> because the standard RTTI mechanism of C++ didn't meet their needs.
> Sophisticated GUI tools that rely on object properties are going to
> demand a certain level of RTTI that is beyond the current C++ RTTI
> capabilities.
I think for this discussion to continue, you should define your terms
a little more clearly. How do you want properties to behave exactly?
The term "properties" means different things to different people.
Bob
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: bob.news@gmx.net ("Robert Klemme")
Date: Mon, 20 Jan 2003 18:35:19 +0000 (UTC) Raw View
"Nicholas Salerno" <ndsalerno@yahoo.com> schrieb im Newsbeitrag
news:b9da50a9.0301191408.59a44c76@posting.google.com...
> Like anyone else, I read the newsgroups, both new and old postings, to
become a
> better C++ programmer. One common theme I have noticed among the C++
community
> is that people are opposed to adding new features to the language. They
prefer
> it if the new feature is implemented as a class (template or
non-template).
> But does it always make sense to represent something as a class?
The usual tradeoff with language changes is what do we gain vs. how what
will be broken by a language change. Since a change like the one you
propose is likely to introduce a new keyword which is not reserved yet,
there is a high chance that much of the existing code breaks - except you
choose "uzwionbskgadvmaloksoid" as keyword... :-) Thus the price the
community would have to pay would likely be higher than what is gained.
In such a situation, if you can implement a new feature by means of older
features present in the language you are more likely to reach a win-win
situation: you standardize the new feature but you break less code -
especially since namespace std is reserved for these kinds of things. So
new classes / methods will not interfere with other code.
Regards
robert
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Tue, 21 Jan 2003 07:56:33 +0000 (UTC) Raw View
bob.news@gmx.net ("Robert Klemme") wrote in message news:<b0h8r1$pntod$1@ID-52924.news.dfncis.de>...
>
> In such a situation, if you can implement a new feature by means of older
> features present in the language you are more likely to reach a win-win
> situation: you standardize the new feature but you break less code -
> especially since namespace std is reserved for these kinds of things. So
> new classes / methods will not interfere with other code.
>
Yes, however, my understanding of the situation is that there is no
sufficient class (template or non-template) that can implement
properties to rival a native implementation. There is always somekind
of trade-off. Also, RTTI still needs some enhancements. Even if you
could write a class to implement properties how would you expose the
property to RTTI? Look at the Microsoft Foundation Class (MFC)
library. When initially developed, Microsoft added its own code to
simulate RTTI because it was absent from the language. When RTTI was
officially part of C++ Microsoft still stuck with their own code
because the standard RTTI mechanism of C++ didn't meet their needs.
Sophisticated GUI tools that rely on object properties are going to
demand a certain level of RTTI that is beyond the current C++ RTTI
capabilities.
Nicholas
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]