Thread overview
Getters and Setters
Aug 16, 2001
Sheldon Simms
Re: Getters and Setters -- great idea
Aug 16, 2001
Chris Friesen
Getters and setters
Aug 18, 2001
Tim Sweeney
Aug 20, 2001
Charles Hixson
Aug 22, 2001
Walter
Aug 24, 2001
Dan Hursh
Aug 24, 2001
Walter
Sep 04, 2001
Anthony Steele
August 16, 2001
From the Documentation:

>>>>
In D, get'ers and set'ers take advantage of the idea that an lvalue is a set'er, and an rvalue is a get'er:

class Abc
{
    int myprop;
    void property(int newproperty) { myprop = newproperty; } // set'er
    int property() { return myprop; }	// get'er
}

which is used as:

Abc a;
a.property = 3;		// equivalent to a.property(3)
int x = a.property;		// equivalent to int x = a.property()

Thus, in D you can treat a property like it was a simple field name.
A property can start out actually being a simple field name, but if
later if becomes necessary to make getting and setting it function
calls, no code needs to be modified other than the class definition.
<<<<

I've been wishing Java had this for a long time. The given examples,
though, seem kind of funny. Why shouldn't the getter and setter
names be exactly the same as the property name? That way, you
don't even have to define the getter and setter methods to get
the default functionality:

class ABC
{
public:
   int property;
   // getter and setter automatically defined
   ...
}

ABC a;
a.property = 3; // equivalent to a.property(3)
int x = a.property; // equivalent to int x = a.property()

Now if there is some reason to change the semantics of getters or setters, you can do so by defining the method explicitly:

class Doubler
{
public:
    ABC property;
    void property (ABC foo)
    {
        // don't just reference it (default), make a copy
        property = foo.deep_copy();
    }
}

Doubler d;
d.property = a;
assert(a != d.property);
// succeeds, assuming != compares object identity

As far as access control goes, this would act as if the attribute value itself was always private, and the getters and setters were whatever is specificied in the class definition. Assuming class members are private by default, you could make an attribute read- only like this:

class DEF
{
   void property(int); // the property-setter is private
public:
   int property; // but the property is in general public
}

Or like this:

class GHI
{
   int property; // the property is in general private
public:
   int property(); // but the property-getter is public
}

I'm using this "declaration-like" syntax above to keep from having to redefine the method, when all I'm interested is access-control.

-- 
Sheldon Simms / sheldon@semanticedge.com
August 16, 2001
Sheldon Simms wrote:

> I've been wishing Java had this for a long time. The given examples,
> though, seem kind of funny. Why shouldn't the getter and setter
> names be exactly the same as the property name? That way, you
> don't even have to define the getter and setter methods to get
> the default functionality:
> 
> class ABC
> {
> public:
>    int property;
>    // getter and setter automatically defined
>    ...
> }
> 
> ABC a;
> a.property = 3; // equivalent to a.property(3)
> int x = a.property; // equivalent to int x = a.property()
> 
> Now if there is some reason to change the semantics of getters or setters, you can do so by defining the method explicitly:

This is a great idea.  I'm all for it.


-- 
Chris Friesen                    | MailStop: 043/33/F10
Nortel Networks                  | work: (613) 765-0557
3500 Carling Avenue              | fax:  (613) 765-2986
Nepean, ON K2H 8E9 Canada        | email: cfriesen@nortelnetworks.com
August 18, 2001
> In D, get'ers and set'ers take advantage of the idea that an lvalue is a set'er, and an rvalue is a get'er:
>
> class Abc
> {
>     int myprop;
>     void property(int newproperty) { myprop = newproperty; } // set'er
>     int property() { return myprop; } // get'er
> }
>
> which is used as:
>
> Abc a;
> a.property = 3; // equivalent to a.property(3)
> int x = a.property; // equivalent to int x = a.property()

Why??!? :-) In current reasonable languages "a.x" is a variable access and
"a.f(x)" is a function call.

Why complicate this so that "a.x" could either be a function call or a variable access, depending on its (possibly very complicated) context?

Also, this seems to create ambiguity (or context-specific special-casing of sematics) with function pointers.  Given a reference to a function p taking a parameter, p=a could either mean calling it with a parameter of a, or initializing it to a.

I know Bertrand Meyer advocated this approach in Eiffel, but this has been shown to be one of several areas (along with, i.e. covariant typing on function parameters) where Eiffel's type system is unsafe and problematic.

> Thus, in D you can treat a property like it was a simple field name. A property can start out actually being a simple field name, but if later if becomes necessary to make getting and setting it function calls, no code needs to be modified other than the class definition.

That breaks with open-world modules.  For example, given a module declaring a class like:

class c
{
    int a;
};

How can you subclass it later on in another module like:

class d: public c
{
    int a() {...}
};

The similar question comes up with binary-compatible evolution of modules (i.e. Java's list of rules, "You can do the following things to evolve a class without breaking existing precompiled modules that depend on it". That's an essential thing that's vital to writing real-world programs, such as applications supporting plug-ins.  The only sound solution to this is that every variable access in a program has to translate to a virtual function call, which obviously isn't reasonable.

-Tim


August 20, 2001
Tim Sweeney wrote:
>...
> Why??!? :-) In current reasonable languages "a.x" is a variable access and
> "a.f(x)" is a function call.
> 
> ...
> I know Bertrand Meyer advocated this approach in Eiffel, but this has been
> shown to be one of several areas (along with, i.e. covariant typing on
> function parameters) where Eiffel's type system is unsafe and problematic.
> 
> ...
> -Tim

I've never seen that shown.  I know that Eiffel tends to be a bit inflexible, but this is one (of several) areas that I feel it got right.  Especially if one is going to be having overridden-via-inheritance classes.  It's quite reasonable that some classes would implement, e.g., a counter by a function and others by a variable.  And a reference via inheritance shouldn't be required to know ahead of time which kind of reference the exact class is making.  I think that information hiding is in favor of this, also, but the main thrust comes from simple utility and code re-use.


August 22, 2001
I have mixed feelings about the getters and setters. They are turning out to be a problem in the compiler, and may wind up getting dumped.

Charles Hixson wrote in message <3B8163BE.6080402@earthlink.net>...
>Tim Sweeney wrote:
>>...
>> Why??!? :-) In current reasonable languages "a.x" is a variable access
and
>> "a.f(x)" is a function call.
>>
>> ...
>> I know Bertrand Meyer advocated this approach in Eiffel, but this has
been
>> shown to be one of several areas (along with, i.e. covariant typing on function parameters) where Eiffel's type system is unsafe and
problematic.
>>
>> ...
>> -Tim
>
>I've never seen that shown.  I know that Eiffel tends to be a bit inflexible, but this is one (of several) areas that I feel it got right.
>  Especially if one is going to be having overridden-via-inheritance
>classes.  It's quite reasonable that some classes would implement, e.g., a counter by a function and others by a variable.  And a reference via inheritance shouldn't be required to know ahead of time which kind of reference the exact class is making.  I think that information hiding is in favor of this, also, but the main thrust comes from simple utility and code re-use.
>
>


August 24, 2001
	That's a shame.  I get it would be to ask for an enhancement to it
then, right?  I'll do it anyhow.  It looks like a setter/getter pair
cannot have the same name as a data member.  (reasonable enough.)  Would
it be possible for a sub-class to hide an inherited data member behind a
setter/getter pair and then allow the sub-class to access the parent
data via super?  This would only allow you to access you parent's data
and not your grandparent's, but that may not be all bad.
	Of course, if it doesn't make it in then this is moot.  On a related
note (at least in my mind), is it expected to be possible to have lvalue
function calls?

Dan

Walter wrote:
> 
> I have mixed feelings about the getters and setters. They are turning out to be a problem in the compiler, and may wind up getting dumped.
> 
> Charles Hixson wrote in message <3B8163BE.6080402@earthlink.net>...
> >Tim Sweeney wrote:
> >>...
> >> Why??!? :-) In current reasonable languages "a.x" is a variable access
> and
> >> "a.f(x)" is a function call.
> >>
> >> ...
> >> I know Bertrand Meyer advocated this approach in Eiffel, but this has
> been
> >> shown to be one of several areas (along with, i.e. covariant typing on function parameters) where Eiffel's type system is unsafe and
> problematic.
> >>
> >> ...
> >> -Tim
> >
> >I've never seen that shown.  I know that Eiffel tends to be a bit inflexible, but this is one (of several) areas that I feel it got right.
> >  Especially if one is going to be having overridden-via-inheritance
> >classes.  It's quite reasonable that some classes would implement, e.g., a counter by a function and others by a variable.  And a reference via inheritance shouldn't be required to know ahead of time which kind of reference the exact class is making.  I think that information hiding is in favor of this, also, but the main thrust comes from simple utility and code re-use.
> >
> >
August 24, 2001
Dan Hursh wrote in message <3B85D1A1.9EF78A97@infonet.isl.net>...
> That's a shame.  I get it would be to ask for an enhancement to it
>then, right?  I'll do it anyhow.  It looks like a setter/getter pair cannot have the same name as a data member.  (reasonable enough.)  Would it be possible for a sub-class to hide an inherited data member behind a setter/getter pair and then allow the sub-class to access the parent data via super?  This would only allow you to access you parent's data and not your grandparent's, but that may not be all bad.


Yes.

> Of course, if it doesn't make it in then this is moot.  On a related
>note (at least in my mind), is it expected to be possible to have lvalue
>function calls?


No, no lvalue function calls unless the function returns a reference. -Walter



September 04, 2001
"Tim Sweeney" <tim@epicgames.com> wrote in message news:9lkhq6$2p61$1@digitaldaemon.com...'

> Why??!? :-) In current reasonable languages "a.x" is a variable access and
> "a.f(x)" is a function call.
>
Transation: it's like that in C, and you can't think any further.  In Delphi, which I think is current and reasonable, if y := a.x(); is a function call with no params, then the brackets may be and usually are omitted, giving y := a.x;

If you are using an object, and want to read a value off it, you care about the meaning of that value, not if it it returned by public data, public function or public property (in Delphi it could be any of the three).  In java, you have x = myArray.length; y = myString.length(); What is the semantic difference? none. So why the syntactic difference?

Even better - public data can can be turned into private data acessed through a gettor and  a settor that checks it's args *without the client code knowing or caring* about the implementation of the public contract. That to me is a win. A public fn can be replaced by the gettors and settors of a property, as the system grows. I've found this feature to be usefull.

> Also, this seems to create ambiguity (or context-specific special-casing
of sematics) with function pointers.

True, this is a drawback. You don't get something for nothing.

> That breaks with open-world modules.
> How can you subclass it

I don't really see why not allowing non-private methods and data with the same name is a major loss.