Topic: Property Syntax (and answers to questions)


Author: dheld@codelogicconsulting.com ("David B. Held")
Date: Mon, 17 Feb 2003 17:20:32 +0000 (UTC)
Raw View
"Peter Roozemaal" <dont.spam.mathfox@xs4all.nl> wrote in message
news:3E4D1971.6030804@xs4all.nl...
> [...]
> May I suggest a completely approach to properties: a template
> called property that could be used as:
> [...]
> I would like to invite some of the C++ generic programming
> Gurus to investigate the possibilities of creating such a template
> within the  current C++ standards.

Guess what?  They already have.  And guess what the consensus
is?  "Not possible with 0 overhead."  I don't know how many times
this needs to be said before people believe it, but a very cursory
review of the property threads here will show that this claim has
been made time and again, and nobody has presented code to
refute it.

Please consult:

http://lists.boost.org/MailArchives/boost/thrd186.php

and

http://lists.boost.org/MailArchives/boost/thrd185.php

And look for "properties in C++" or "Properties implementation".

Note that both BCB and VC++ support a native properties
extension, so it's obviously doable already, and it's clearly useful,
or they wouldn't have bothered.  And of the RAD designers I'm
aware (BCB, Delphi, Java, VB, and C#), they all use properties
for design-time introspection.  Properties are a de-facto standard,
and they need compiler support to do them "right".  Let's make
them standard C++, too.

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: ndsalerno@yahoo.com (Nicholas Salerno)
Date: Thu, 13 Feb 2003 00:26:31 +0000 (UTC)
Raw View
Torsten_Franz@agilent.com ("Torsten Franz") wrote in message news:<1044968723.572599@cswreg.cos.agilent.com>...
>
> What about const correctness?

That can be done in similiar style like const correct member
functions.

class Control
{
protected:
    int get_width() const;
    int get_height();

    bool is_enabled() const;
    void set_enabled(bool value);

    bool is_visible() const; // Calls some external API
    void set_visible(bool value) const; // Calls some external API

    color_t f_foreground_color;

public:
    int width = get_width const;   // OK, get_width is const
    int height = get_height const; // Compile error:
                                   // get_height() not const

    // If this is a const object then one can read the property
    // but not assign to it
    bool enabled = is_enabled const, set_enabled;

    // If this is a const object then one can read and write
    // to the property.  I admit this probably doesn't make sense,
    // but it is legal.
    bool visible = is_visible const, set_visible const;

    // Const correctness even for member variables
    color_t foreground_color = f_foreground_color const;
};

Note the similarities in that the const keyword comes after the
identifer just like the const keyword comes after the member function
name in a member function declaration.  Now if you pass a Control
object as a constant you can only call const declared member functions
and only access const declared properties.  However, I do admit that
it gets tedious from the redundancy of typing const.

For the last item, the color of the control, note that the property is
const correct.  Clients only depend on the "foreground_color"
property, which is const and guarantees that the state of the object
doesn't get changed.  If for any reason the developer later decides to
change

    color_t foreground_color = f_foreground_color const;

into

    color_t foreground_color = get_foreground_color const;

then the clients who use this object do not have to change.

> What about const reference return types instead of objects?
>

That should be straight forward.

class Control
{
protected:
    int get_width();
    int* get_height(); // Pointers as well
    std::string& get_caption() const;

public:
    int width = get_width;
    int* height = get_height;
    const std::string& caption = get_caption const;
};

>
> What about write only properties?
>

Hmmm.  That may require a keyword, but the point of this syntax is to
avoid new keywords as well as provide a syntax familiar to current C++
syntax.  Besides, is that really neccessary?  I really can't imagine
the need for a property that you can write a bunch of values to but
can't query it for anything.  Properties, to the extent that I have
used and seen used in other languages, are either read-write or
read-only.  Let's see.  ...  I can't even come up with an example to
refute against.  The way I see it, whatever you had in mind doesn't
sound like it should be a property.  It is probably best to have it as
a public member function.

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: Torsten_Franz@agilent.com ("Torsten Franz")
Date: Thu, 13 Feb 2003 17:49:46 +0000 (UTC)
Raw View
>> What about const correctness?
>
> That can be done in similiar style like const correct member
> functions.
>
...
>
> public:
>     int width = get_width const;   // OK, get_width is const
>     int height = get_height const; // Compile error:
>                                    // get_height() not const
>
>     // If this is a const object then one can read the property
>     // but not assign to it
>     bool enabled = is_enabled const, set_enabled;
>
>     // If this is a const object then one can read and write
>     // to the property.  I admit this probably doesn't make sense,
>     // but it is legal.
>     bool visible = is_visible const, set_visible const;
>
>     // Const correctness even for member variables
>     color_t foreground_color = f_foreground_color const;
> };
> Note the similarities in that the const keyword comes after the
> identifer just like the const keyword comes after the member function
> name in a member function declaration.  Now if you pass a Control
> object as a constant you can only call const declared member functions
> and only access const declared properties.  However, I do admit that
> it gets tedious from the redundancy of typing const.

Ok, this seems to be the natural way with your properties to declare const
but as you already pointed out, the property declaration may become tedious
to write correct
(I think there must also be kind of a check that function and property
declarations are the same)

class Test
{
private:
    int GetValue(); //func is not const, some side effect possible here
public:
    int Value = GetValue const; //Hmm, what happens here?
};

void funcA(const Test& test)
{
    int n = test.Value; //Is this allowed?
}

The initial question about const correctness came up while using the Borland
C++ Builder implementation
of properties on a daily basis. I always ran into situations where I needed
to call the 'Get' part of a property
on a const reference passed object. Although the property simply returned
some value (thus didn't change
the object) the compiler complained about accessing a non-const function of
a const object.
(Un-)Fortunatly the Borland compiler issued only a warning here.
After using the available property concept in my own classes when I started
with Borland I now avoid properties
whenever I can. The only useful usage in case of Borland is to use
properties in components used at design-time

>> What about const reference return types instead of objects?
>>
>
> That should be straight forward.
>
> class Control
> {
> protected:
>     int get_width();
>     int* get_height(); // Pointers as well
>     std::string& get_caption() const;
>
> public:
>     int width = get_width;
>     int* height = get_height;
>     const std::string& caption = get_caption const;
> };
>
You just showed getters here.
What about this example

class Test
{
private:
    int m_nValue;
    void SetValue(const int& Val);
public:
    //what is the property type here
    //int Value = m_nValue,SetValue;
    //or
    //const int& Value = m_nValue,SetValue;
};


>> What about write only properties?
>>
>
> Hmmm.  That may require a keyword, but the point of this syntax is to
> avoid new keywords as well as provide a syntax familiar to current C++
> syntax.  Besides, is that really neccessary?  I really can't imagine
> the need for a property that you can write a bunch of values to but
> can't query it for anything.  Properties, to the extent that I have
> used and seen used in other languages, are either read-write or
> read-only.  Let's see.  ...  I can't even come up with an example to
> refute against.  The way I see it, whatever you had in mind doesn't
> sound like it should be a property.  It is probably best to have it as
> a public member function.

I have no use for such a property in mind. But just for symmetry reasons I
think
write only properties need to be avialable. Maybe someone else will find
useful
applications for such properties.

Ciao
Torsten


---
[ 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: Fri, 14 Feb 2003 02:04:51 +0000 (UTC)
Raw View
Torsten_Franz@agilent.com ("Torsten Franz") wrote in message news:<1045124695.303959@cswreg.cos.agilent.com>...
> Ok, this seems to be the natural way with your properties to declare const
> but as you already pointed out, the property declaration may become tedious
> to write correct
> (I think there must also be kind of a check that function and property
> declarations are the same)

I agree

>
> class Test
> {
> private:
>     int GetValue(); //func is not const, some side effect possible here
> public:
>     int Value = GetValue const; //Hmm, what happens here?
> };
>
> void funcA(const Test& test)
> {
>     int n = test.Value; //Is this allowed?
> }
>

I would state that the compiler should provide an error that the
'GetValue' member function was not a const function.  Thus it can't be
used as the accessor for the property.  In fact I stated that in the
comment for the example class I provided.

>>     int height = get_height const; // Compile error:
>>                                    // get_height() not const

such that get_height was declared as a non-const member function.

> >> What about const reference return types instead of objects?
> >>
> >
> > That should be straight forward.
> >
> > class Control
> > {
> > protected:
> >     int get_width();
> >     int* get_height(); // Pointers as well
> >     std::string& get_caption() const;
> >
> > public:
> >     int width = get_width;
> >     int* height = get_height;
> >     const std::string& caption = get_caption const;
> > };
> >
> You just showed getters here.
> What about this example
>
> class Test
> {
> private:
>     int m_nValue;
>     void SetValue(const int& Val);
> public:
>     //what is the property type here
>     //int Value = m_nValue,SetValue;
>     //or
>     //const int& Value = m_nValue,SetValue;
> };
>

In the event that you want to work with data types by reference
instead of by value, for efficiency reasons, then it would have to be
done with pointers as the type.  References don't work well here
because a property that is a reference can only be read-only.

>
> >> What about write only properties?
> >>
> >
> > Hmmm.  That may require a keyword, but the point of this syntax is to
> > avoid new keywords as well as provide a syntax familiar to current C++
> > syntax.  Besides, is that really neccessary?  I really can't imagine
> > the need for a property that you can write a bunch of values to but
> > can't query it for anything.  Properties, to the extent that I have
> > used and seen used in other languages, are either read-write or
> > read-only.  Let's see.  ...  I can't even come up with an example to
> > refute against.  The way I see it, whatever you had in mind doesn't
> > sound like it should be a property.  It is probably best to have it as
> > a public member function.
>
> I have no use for such a property in mind. But just for symmetry reasons I
> think
> write only properties need to be avialable. Maybe someone else will find
> useful
> applications for such properties.
>

I don't think symmetry is sufficient reason to add write-only
properties.  Consistency and orthogonality are good qualities for a
language's syntax and semantics, but not symmetry.

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: dont.spam.mathfox@xs4all.nl (Peter Roozemaal)
Date: Sat, 15 Feb 2003 00:52:07 +0000 (UTC)
Raw View
Nicholas Salerno wrote:

 > PART I - A Syntax For Properties

May I suggest a completely approach to properties: a template called
property that could be used as:

 // define property named aap with integer type
 //   get calls aap_getter; set calls aap_setter.
 //
 property<int, aap_getter, aap_setter> aap;

Read-only and write-only template variants could be provided too. We
don't need to introduce new syntax to C++ this way.
I would like to invite some of the C++ generic programming Gurus to
investigate the possibilities of creating such a template within the
current C++ standards.

Peter Roozemaal.

---
[ 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, 7 Feb 2003 20:52:56 +0000 (UTC)
Raw View
"Nicholas Salerno" <ndsalerno@yahoo.com> wrote in message
news:b9da50a9.0302071056.1aa4dfb4@posting.google.com...
> [...]
> This is a syntax driven from the need to keep old compatible with
> new language enhancements.  It follows the style of declaring
> abstract member functions.  The key to this syntax is that there is
> no need for new keywords.

I think properties are a sufficient change to justify adding a keyword.
I think 'property' should be a keyword, but I'm not sure about 'read'
and 'write'.  Those should almost certainly not be keywords, but I'm
not sure how you would go about defining the language in a way that
requires those to have a special meaning in the property context
without being keywords.

> [...]
> public:
>     int width = f_width, f_width; // Read and write
>     int height = f_height;        // Read only
> };

I prefer the Borland syntax, because it makes explicit that you intend
for a given member to be a property.

> [...]
> * In the comma seperated list the first item is the read and the
> second item is the write.  The second item is optional.  This allows
> read-only properties.

I don't like this implicit positional notation.  I think this is not natural
C++.  Borland also uses "default" to indicate a default value for
the property, but the way it is used is peculiar.  I don't know if it
should be added to the language or not, but it's something to be
considered.

> [...]
> Q) Properties violate encapsulation?
> A) No more than get and set methods.

Exactly.

> [...]
> Q) What price do we all have to pay for this feature?
> A) If you don't use properties then you should have to pay no
> penalty.  However, even if you do use properties, if you do not
> publish RTTI information for the property then you still don't pay
> any penalty.  There should be zero overhead in this respect.

Which is why template solutions thus far are not adequate, IMO.

> [...]
> Q) Boost bind and function do everything you want.  Case closed!
> A) I have looked that these sets of classes.  I still maintain my
> criticisms of a template solution.  A template class provides
> overhead that I do not want for all my objects that use the template
> class.  The code also becomes harder and less readable as the
> template class becomes more sophisticated.

I don't like this answer.  Boost.Bind & Boost.Function provide
Borland's closures, which are just one component of the PME
model.  They are very powerful, and I use them regularly.  However,
they have nothing to do with properties.  Also, there might be an
efficiency argument to be made for native closures, but I think
closures are a sufficiently important topic that they should be
discussed separately (for example, that might wander into
discussions of local functions, etc.).

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: nid_oizo@yahoo.com_removethe_ (Nicolas Fleury)
Date: Fri, 7 Feb 2003 21:23:57 +0000 (UTC)
Raw View
David B. Held wrote:
> "Nicholas Salerno" <ndsalerno@yahoo.com> wrote in message
> news:b9da50a9.0302071056.1aa4dfb4@posting.google.com...
>
>>[...]
>>This is a syntax driven from the need to keep old compatible with
>>new language enhancements.  It follows the style of declaring
>>abstract member functions.  The key to this syntax is that there is
>>no need for new keywords.
>
>
> I think properties are a sufficient change to justify adding a keyword.

Agree.

> I think 'property' should be a keyword, but I'm not sure about 'read'
> and 'write'.  Those should almost certainly not be keywords, but I'm
> not sure how you would go about defining the language in a way that
> requires those to have a special meaning in the property context
> without being keywords.

Having two keywords, property_get and property_set, could produce less
problems with existing code than property, and you would not need write
or read keywords.

Regards,

Nicolas

---
[ 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: Torsten_Franz@agilent.com ("Torsten Franz")
Date: Wed, 12 Feb 2003 04:04:31 +0000 (UTC)
Raw View
> // 1. Wrapping a variable
> class Control
> {
> protected:
>     int f_width;
>     int f_height;
>
> public:
>     int width = f_width, f_width; // Read and write
>     int height = f_height;        // Read only
> };

What about write only access?

> // 2. Wrapping a member function
> class Control
> {
> protected:
>     int get_width(); // Calls some external API
>     void set_width(int width); // Calls some external API
>     int get_height(); // Calls some external API
>
> public:
>     int width = get_width, set_height; // Read and write
>     int height = get_height;           // Read only
> };

What about const correctness?
What about const reference return types instead of objects?

> Some notes on the syntax:
> * Resolution is done by the type of the property.  For example,
> "width" is an int so any variable must be of type int.  Likewise, any
> accessor/mutator must return an int and accept an argument of type
> int, respectively.

> * In the comma seperated list the first item is the read and the
> second item is the write.  The second item is optional.  This allows
> read-only properties.

What about write only properties?

Ciao
Torsten


---
[ 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: Fri, 7 Feb 2003 19:33:28 +0000 (UTC)
Raw View
This post contains two things.  First I want to show a syntax for
properties and then I want to answer some common questions and
concerns from the "Properties & RTTI" thread.  Sorry for the late
response.

PART I - A Syntax For Properties

This is a syntax driven from the need to keep old compatible with new
language enhancements.  It follows the style of declaring abstract
member functions.  The key to this syntax is that there is no need for
new keywords.

// 1. Wrapping a variable
class Control
{
protected:
    int f_width;
    int f_height;

public:
    int width = f_width, f_width; // Read and write
    int height = f_height;        // Read only
};

// 2. Wrapping a member function
class Control
{
protected:
    int get_width(); // Calls some external API
    void set_width(int width); // Calls some external API
    int get_height(); // Calls some external API

public:
    int width = get_width, set_height; // Read and write
    int height = get_height;           // Read only
};

// 3. Mixing 1 and 2
class Control
{
protected:
    int f_width;
    void set_width(int width); // Calls some external API
    int f_height;
    int get_height(); // Calls some external API

public:
    int width = f_width, set_width;    // read variable, write
function
    int height = get_height, f_height; // read function, write
variable
};

Some notes on the syntax:
* Resolution is done by the type of the property.  For example,
"width" is an int so any variable must be of type int.  Likewise, any
accessor/mutator must return an int and accept an argument of type
int, respectively.

* In the comma seperated list the first item is the read and the
second item is the write.  The second item is optional.  This allows
read-only properties.

* There is a logical binding of two entities to a concept.  For
example, in case 2, the width property establishes a relation between
get_width() and set_width().  This information can be useful (example:
graphical user interface development tools).

* There is no RTTI information generated for properties (especially
since C++ doesn't have an introspection capability).

* There should be no penalty for people who do not use properties.
Likewise an optimal implementation should also have no penalty for
people who do use properties (without RTTI).  The resulting backend
code must either be an access to a variable or a function call.

* Coupled with a runtime introspection capability, properties can open
the door for a host of advanced graphical user interface development
tools.  This is known as "publishing" properties.  It basically means
that the class contains RTTI information for that property.  An
object's published properties can be accessed and manipulated at
runtime by any external client.

Personally I don't like the syntax for the same reason I don't like
the fact that virtual member functions have to be assigned a value of
zero to make them abstract.  However, this is not about my favorite
syntax, this is about a practical syntax that coincides with the
language.  Let me know what you think.

PART II - The SoapBox Chronicles

My answers to the most common questions and concerns:

Q) Properties violate encapsulation?
A) No more than get and set methods.

Q) Properties are just syntatic sugar.  What else do they do?
A) Not neccessarily true.  Properties establish a relation between
accessing and manipulating an attribute of a class.  This information
can be used by the compiler.  As of now compilers do not see the
relationship between get_width() and set_width().  Why?  Because there
is none.  Maybe there is to us humans, but not to the software.  If I
were to make a widget that shows a list of the attributes, of an
object, and their values then how does that widget know that
get_width() and set_width() work together for the logical attribute
"width"?  How do I do that without extra work on my part as a
programmer?

Q) What price do we all have to pay for this feature?
A) If you don't use properties then you should have to pay no penalty.
 However, even if you do use properties, if you do not publish RTTI
information for the property then you still don't pay any penalty.
There should be zero overhead in this respect.

Q) Why did properties and RTTI (introspection) get lumped into the
same thread?
A) True, these are two seperate language features that deserve their
own attention.  However, properties really do show their worth when
coupled with introspection.  Instead of me explaining this, just use
Visual BASIC, Delphi,  and/or C++ Builder and judge for yourself if
properties and RTTI do not go hand and hand.

Q) Boost bind and function do everything you want.  Case closed!
A) I have looked that these sets of classes.  I still maintain my
criticisms of a template solution.  A template class provides overhead
that I do not want for all my objects that use the template class.
The code also becomes harder and less readable as the template class
becomes more sophisticated.

Q) Oh please!  I can make a template solution for you.  Case closed!
A) I have been reading this issue of properties on the newsgroup
archives for the whole entire decade of the 90's.  Nobody has
successfully shown a template class that contains no overhead,
implements the feature of properties, compiles, and has no variable
side affects between major compiler vendors.  Talk is cheap.

Q) Hey, if you want introspection at runtime then I want introspection
at compile time.
A) Fine by me.  I am not even sure how this would work but as long as
I get what I want then you can get what you want.  Introspection all
around! :-)

Q) What proof do you have that properties are all that?
A) I have no proof and I do not intend to state that properties are
the answer to all programming problems.  I admit they are a niche part
of software development.  However, I believe it is an important niche,
the one of graphical user interface development and the notion of
rapid application development (RAD).

Q) What benefits do properties provide than what C++ currently
provides?
A) Compare MFC, Qt, and gtk towards Delphi, Visual BASIC, and C++
Builder.  Do you mean to tell me that message maps, meta-object
compilation phases, eye-sore boiler-plate code, and comments (DON'T
TOUCH THIS OR ELSE CLASS WIZARD BREAKS) is proof that C++ provides the
neccessary means to create elegant and advanced RAD tools?  Yes?  Ok,
that is your opinion and I respect that.  I also have to disagree.

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                       ]