Thread overview
Re: read-only access
Nov 02, 2010
Jonathan M Davis
Nov 02, 2010
spir
Nov 02, 2010
Jonathan M Davis
Nov 03, 2010
spir
Nov 03, 2010
bearophile
Nov 03, 2010
Jonathan M Davis
November 02, 2010
On Tuesday 02 November 2010 12:33:41 spir wrote:
> Hello,
> 
> Is the D way to make read-only symbols (of a class, struct, module) to write a getter for a private symbols?
> 
> Additional question: just realised one can omit () on func calls! Is this
> systematic when a func has no param? I thought it was not the case,
> because it does not work with writeln (the first func on which I tried,
> indeed!). Is it only because writeln is parameterized (with (T...)) or is
> there any other reason I'm not aware of?
> 
> struct P {
>     private int my_i;
>     int i() {return this.my_i;}
>     void doit() {writeln("...doing...");}
> }
> void main () {
>     auto p = P(1);
>     writeln("p.i: ",p.i);
>     p.doit;
> }
> 
> 
> Denis
> -- -- -- -- -- -- --
> vit esse estrany ☣
> 
> spir.wikidot.com

Historically, you could call any function which returned a value and took no parameters without parens, and you could call any function that was void and took a single parameter by assigning to it. e.g.

int getter() { return value;}
void setter((int value} {this. value = value;}

auto x = obj.getter;
obj.setter = x;

This included non-member functions, which meant that you could do things like writeln = 7; instead of writeln(7); Something was done a while back to make it so that writeln() didn't work that way. I don't know what. Eventually, however, the idea is that only functions marked with @property will work that way. e.g.

@property int getter() { return value;}
@property void setter((int value} {this. value = value;}

If they don't have the property attribute, then they won't work without parens (and in fact, you won't be able to use parens with them). That is how it's outlined in TPDL (The D Programming Language by Andrei Alexandrescu). However, dmd has not reached that point. It will still allow property functions to be used with parens and non-property functions to be used as property functions as long as they're void and take one parameter or return a value and take no parameters. So, once dmd is up-to-date with regards to TDPL, you'll no longer be able to use arbitrary functions as properties, but for the moment, you can.

- Jonathan M Davis
November 02, 2010
On Tue, 2 Nov 2010 12:47:21 -0700
Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> If they don't have the property attribute, then they won't work without parens (and in fact, you won't be able to use parens with them). That is how it's outlined in TPDL (The D Programming Language by Andrei Alexandrescu). However, dmd has not reached that point. It will still allow property functions to be used with parens and non-property functions to be used as property functions as long as they're void and take one parameter or return a value and take no parameters. So, once dmd is up-to-date with regards to TDPL, you'll no longer be able to use arbitrary functions as properties, but for the moment, you can.

I'm not sure I like it, that properties have distinct syntax -- unless there's really distinct meaning/semantics I don't know yet.

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 02, 2010
On Tuesday, November 02, 2010 14:14:22 spir wrote:
> On Tue, 2 Nov 2010 12:47:21 -0700
> 
> Jonathan M Davis <jmdavisProg@gmx.com> wrote:
> > If they don't have the property attribute, then they won't work without parens (and in fact, you won't be able to use parens with them). That is how it's outlined in TPDL (The D Programming Language by Andrei Alexandrescu). However, dmd has not reached that point. It will still allow property functions to be used with parens and non-property functions to be used as property functions as long as they're void and take one parameter or return a value and take no parameters. So, once dmd is up-to-date with regards to TDPL, you'll no longer be able to use arbitrary functions as properties, but for the moment, you can.
> 
> I'm not sure I like it, that properties have distinct syntax -- unless there's really distinct meaning/semantics I don't know yet.

The idea is that a property is like a public member variable except that it's a function underneath the hood. So, you can write code as if it were a public member variable and yet it's value could be calculated instead of actually having a corresponding variable in the object, or it could have extra code verifying that the value you're setting it to is valid. A definite benefit of it is that you can have a public member variable and then later make it a property (because it becomes a calculated value, or you need extra code checking it's value, or whatever) without having to change all of the code where it's used. The abstraction is somewhat leaking because you can't take the address of a property function in the same way you can with a public member variable, and thing like += don't work because it's two different function calls instead of acting directly on the variable, but it can be quite useful. Other languages such as C# and Delphi have the same feature (though they have different syntax for indicating when a function is a property).

It makes sense for the programmer to want to indicate when a function (generally when it represents a getter or setter) rather than have _all_ functions with a certain signature becoming properties automatically (which is what has happened in D historically). Otherwise, functions which don't really represent properties are used as if they did, and there's no consistency (except perhaps by convention) as to whether parens are used when calling functions which could be property functions. @property  was the syntax chosen to indicate that a function is intended to be used as a property. It's just that dmd doesn't entirely match TDPL yet (TDPL only having come out a few months ago and Walter having been busy on stuff like 64-bit support), so functions can still be called as if they were properties even though they're not.

- Jonathan M Davis
November 03, 2010
On Tue, 2 Nov 2010 16:32:53 -0700
Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> On Tuesday, November 02, 2010 14:14:22 spir wrote:
> > I'm not sure I like it, that properties have distinct syntax -- unless there's really distinct meaning/semantics I don't know yet.
> 
> The idea is that a property is like a public member variable except that it's a function underneath the hood. So, you can write code as if it were a public member variable and yet it's value could be calculated instead of actually having a corresponding variable in the object, or it could have extra code verifying that the value you're setting it to is valid. A definite benefit of it is that you can have a public member variable and then later make it a property (because it becomes a calculated value, or you need extra code checking it's value, or whatever) without having to change all of the code where it's used. The abstraction is somewhat leaking because you can't take the address of a property function in the same way you can with a public member variable, and thing like += don't work because it's two different function calls instead of acting directly on the variable, but it can be quite useful. Other languages such as C# and Delphi have the same feature (though they have different syntax for indicating when a function is a property).

Right. I know properties from python. This is also very close to the "principle of uniform access" supported by Bertrand Meyer for Eiffel. The latter means, from the client side, a "query" like obj.prop should not expose whether prop is directly accessed or computed and returned. This has the advantages you note above.
But, in addition to the drawbacks you also note, there are 2 other relevant ones that make this scheme, indeed attractive at first sight, rather limited and risky in practice:
* The advantage of beeing able to change direct access by computation only works when the comutation reqires no parameter! One obviously cannot opaquely change obj.prop to a call like obj.getProp(param)... So that using properties is only useful in practice when (1) the query was first direct (2) this needs to be replaced by computaton (3) this computation requires no parameter. Else, one would have to force the client to set parameters somewhere on the interface, before using the property; thus re-exposing the implementation.
* From the efficiency pov, a client cannot know whether a given property is computed or not; worse, because of using ordinary direct access syntax it looks like cheap; moreover, the programmer may simply not know it is a property instead of an ordinary slot! This leads to blind overuse of property access, possibly severely affecting efficieny. In particular, client code may simply neglect to locally cache a property value and "read" it multiple times instead.

This abstraction is simply wrong in my sense, both from generality and efficiency points of view. ...

> It makes sense for the programmer to want to indicate when a function (generally when it represents a getter or setter) rather than have _all_ functions with a certain signature becoming properties automatically (which is what has happened in D historically). Otherwise, functions which don't really represent properties are used as if they did, and there's no consistency (except perhaps by convention) as to whether parens are used when calling functions which could be property functions. @property  was the syntax chosen to indicate that a function is intended to be used as a property. It's just that dmd doesn't entirely match TDPL yet (TDPL only having come out a few months ago and Walter having been busy on stuff like 64-bit support), so functions can still be called as if they were properties even though they're not.

...
It also introduces synactic noise, and trouble for newcomers to the language.
Python was forced to invent the @xyz format for its decorators (of which @property is an example), because of its overall syntactic esign.
But D does not need that: it already has a whole set of modifiers or qualifiers well integrated in the language's syntax: private, static, override, etc. All of these key terms express the fact that a given language element (variable, function, class...) has alternate semantics and must be processed differently by D. Why make a syntactic exception for property? (I mean, if ever advantage/drawback ratio proved we simply cannot live without the feature.)

> - Jonathan M Davis

Sorry for the extensive answer (it's a topic I have explored in the past).

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com

November 03, 2010
spir:

> Why make a syntactic exception for property? (I mean, if ever advantage/drawback ratio proved we simply cannot live without the feature.)

To avoid another true keyword, and for its marked value, now you may say "D has attributes and properties". @ attributes will be hopefully useful for other purposes too (see @disable and more).

Bye,
bearophile
November 03, 2010
On Wed, 03 Nov 2010 06:02:28 -0400, spir <denis.spir@gmail.com> wrote:

> Right. I know properties from python. This is also very close to the "principle of uniform access" supported by Bertrand Meyer for Eiffel. The latter means, from the client side, a "query" like obj.prop should not expose whether prop is directly accessed or computed and returned. This has the advantages you note above.
> But, in addition to the drawbacks you also note, there are 2 other relevant ones that make this scheme, indeed attractive at first sight, rather limited and risky in practice:
> * The advantage of beeing able to change direct access by computation only works when the comutation reqires no parameter! One obviously cannot opaquely change obj.prop to a call like obj.getProp(param)... So that using properties is only useful in practice when (1) the query was first direct (2) this needs to be replaced by computaton (3) this computation requires no parameter. Else, one would have to force the client to set parameters somewhere on the interface, before using the property; thus re-exposing the implementation.

The idea is that a property acts like a field, but is really a function under the hood.  There are no parameters for property getters.

> * From the efficiency pov, a client cannot know whether a given property is computed or not; worse, because of using ordinary direct access syntax it looks like cheap; moreover, the programmer may simply not know it is a property instead of an ordinary slot! This leads to blind overuse of property access, possibly severely affecting efficieny. In particular, client code may simply neglect to locally cache a property value and "read" it multiple times instead.

This is quite well solved by inlining.  You should not notice any significant reduction in performance.

> It also introduces synactic noise, and trouble for newcomers to the language.
> Python was forced to invent the @xyz format for its decorators (of which @property is an example), because of its overall syntactic esign.
> But D does not need that: it already has a whole set of modifiers or qualifiers well integrated in the language's syntax: private, static, override, etc. All of these key terms express the fact that a given language element (variable, function, class...) has alternate semantics and must be processed differently by D. Why make a syntactic exception for property? (I mean, if ever advantage/drawback ratio proved we simply cannot live without the feature.)

This is really a bikeshed discussion.  The syntax for declaring properties was discussed at length, and @property was chosen.  It's too late to change it now.  Note you can use @property to describe multiple functions at once via:

@property:

or

@property
{
   ...
}


-Steve
November 03, 2010
On Wednesday, November 03, 2010 03:02:28 spir wrote:
> Right. I know properties from python. This is also very close to the "principle of uniform access" supported by Bertrand Meyer for Eiffel. The latter means, from the client side, a "query" like obj.prop should not expose whether prop is directly accessed or computed and returned. This has the advantages you note above. But, in addition to the drawbacks you also note, there are 2 other relevant ones that make this scheme, indeed attractive at first sight, rather limited and risky in practice: * The advantage of beeing able to change direct access by computation only works when the comutation reqires no parameter! One obviously cannot opaquely change obj.prop to a call like obj.getProp(param)... So that using properties is only useful in practice when (1) the query was first direct (2) this needs to be replaced by computaton (3) this computation requires no parameter. Else, one would have to force the client to set parameters somewhere on the interface, before using the property; thus re-exposing the implementation. * From the efficiency pov, a client cannot know whether a given property is computed or not; worse, because of using ordinary direct access syntax it looks like cheap; moreover, the programmer may simply not know it is a property instead of an ordinary slot! This leads to blind overuse of property access, possibly severely affecting efficieny. In particular, client code may simply neglect to locally cache a property value and "read" it multiple times instead.
> 
> This abstraction is simply wrong in my sense, both from generality and efficiency points of view. ...

The programmer does have some responsibility to avoid overly-expensive property functions, and properties definitely can become a problem if not used responsibly, but there are plenty of other features that can be abused, and properties is one which can be avoided if you don't want to use them, though D convention favors using properties over explicit getters and setters.

> It also introduces synactic noise, and trouble for newcomers to the language. Python was forced to invent the @xyz format for its decorators (of which @property is an example), because of its overall syntactic esign. But D does not need that: it already has a whole set of modifiers or qualifiers well integrated in the language's syntax: private, static, override, etc. All of these key terms express the fact that a given language element (variable, function, class...) has alternate semantics and must be processed differently by D. Why make a syntactic exception for property? (I mean, if ever advantage/drawback ratio proved we simply cannot live without the feature.)

Java and C# have a syntax similar to D, only it's way more powerful for them, because you can have user-defined attributes. It allows for a lot of cool stuff that D can't currently do (though some of the nicer benefits may require runtime reflection whereas D only has builtin compile-time reflection). If anything, I'd like to see D go the Java and C# route on this. It can be extremely useful. However, in the short term, I believe that the main reason for using @ was to save on keywords, since Walter and Andrei don't seem to like having lots of keywords in the language if they can avoid it.

- Jonathan M Davis