www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The problem with properties in D

reply Mehrdad <wfunction hotmail.com> writes:
In every language I've seen that has "properties" (C#, Python), they are:

     - _Defined_ like methods
     - _Used_ like variables

The trouble is, this isn't true with D.

Consider:

struct Struct
{
     int delegate() randgen1 = ...;
      property
     int delegate() randgen2() { ... }
}

Struct s;
auto result = s.randgen2();    // This doesn't do the user expects

It is *not* possible, in D, to transparently use either one -- you have 
to treat properties, like methods, not like variables. Except that this 
is inconsistent -- in most other cases, you don't need to do that.

Or for example:

Struct s;
auto a = &s.randgen1;
auto b = &s.randgen2;  // Should be an error

IMO, properties should not be callable with parentheses at all. 
Something like C# -- they should generate getter and setter methods 
instead, or the like.
Furthermore, taking the address of a property should only work if you 
can take the address of its _value_. If you need the address of the 
actual function, then I think a corresponding getter method might be 
easier to use.

It gets even /worse/ in templated code, because you have no idea whether 
an alias is referring to a property or to a variable or whatever.

Making this change would obviously break code, but the break is 
obviously _trivial_ to fix: just remove extra parentheses. It won't 
exactly be the kind of breakage that causes headaches.

So should this be fixed?
Dec 12 2011
next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Monday, December 12, 2011 16:25:33 Mehrdad wrote:
 In every language I've seen that has "properties" (C#, Python), they are:
 
 - _Defined_ like methods
 - _Used_ like variables
 
 The trouble is, this isn't true with D.
 
 Consider:
 
 struct Struct
 {
 int delegate() randgen1 = ...;
  property
 int delegate() randgen2() { ... }
 }
 
 Struct s;
 auto result = s.randgen2(); // This doesn't do the user expects
 
 It is *not* possible, in D, to transparently use either one -- you have
 to treat properties, like methods, not like variables. Except that this
 is inconsistent -- in most other cases, you don't need to do that.
 
 Or for example:
 
 Struct s;
 auto a = &s.randgen1;
 auto b = &s.randgen2; // Should be an error
 
 IMO, properties should not be callable with parentheses at all.
 Something like C# -- they should generate getter and setter methods
 instead, or the like.
 Furthermore, taking the address of a property should only work if you
 can take the address of its _value_. If you need the address of the
 actual function, then I think a corresponding getter method might be
 easier to use.
 
 It gets even /worse/ in templated code, because you have no idea whether
 an alias is referring to a property or to a variable or whatever.
 
 Making this change would obviously break code, but the break is
 obviously _trivial_ to fix: just remove extra parentheses. It won't
 exactly be the kind of breakage that causes headaches.
 
 So should this be fixed?

Originally, it was the case that there was no property, and any function with no arguments could be used like a property. It was decided to add property to enforce that certain functions be treated as properties and some not. But the fact that property was not how properties were initially implemented has caused issues in migrating. -property makes it so that properties must be used like variables and non- property functions cannot be. In theory, that will become the default behavior of the compiler eventually, but we couldn't enable it immediately due to a combination of bugs with property and the fact that it would break code. For now, people can build with -property to make sure that their code uses properties properly. - Jonathan M Davis
Dec 12 2011
parent Mehrdad <wfunction hotmail.com> writes:
On 12/12/2011 4:52 PM, Steven Schveighoffer wrote:
 On Mon, 12 Dec 2011 19:42:48 -0500, Jonathan M Davis 
 <jmdavisProg gmx.com> wrote:

 -property makes it so that properties must be used like variables and 
 non-
 property functions cannot be. In theory, that will become the default 
 behavior
 of the compiler eventually, but we couldn't enable it immediately due 
 to a
 combination of bugs with  property and the fact that it would break 
 code. For
 now, people can build with -property to make sure that their code uses
 properties properly.

To clarify, Jonathan is talking about using the -property command line switch for dmd. -Steve

Dec 12 2011
prev sibling next sibling parent "Nick Sabalausky" <a a.a> writes:
"Mehrdad" <wfunction hotmail.com> wrote in message 
news:jc661t$2mo5$1 digitalmars.com...
 In every language I've seen that has "properties" (C#, Python), they are:

     - _Defined_ like methods
     - _Used_ like variables

 The trouble is, this isn't true with D.

 Consider:

 struct Struct
 {
     int delegate() randgen1 = ...;
      property
     int delegate() randgen2() { ... }
 }

 Struct s;
 auto result = s.randgen2();    // This doesn't do the user expects

 It is *not* possible, in D, to transparently use either one -- you have to 
 treat properties, like methods, not like variables. Except that this is 
 inconsistent -- in most other cases, you don't need to do that.

 Or for example:

 Struct s;
 auto a = &s.randgen1;
 auto b = &s.randgen2;  // Should be an error

 IMO, properties should not be callable with parentheses at all. Something 
 like C# -- they should generate getter and setter methods instead, or the 
 like.
 Furthermore, taking the address of a property should only work if you can 
 take the address of its _value_. If you need the address of the actual 
 function, then I think a corresponding getter method might be easier to 
 use.

 It gets even /worse/ in templated code, because you have no idea whether 
 an alias is referring to a property or to a variable or whatever.

 Making this change would obviously break code, but the break is obviously 
 _trivial_ to fix: just remove extra parentheses. It won't exactly be the 
 kind of breakage that causes headaches.

 So should this be fixed?

At the moment, you have to give DMD the "-property" switch to make it actually enforce the correct syntax/semantics for properties. When the feature was first put in a few releases ago, it was done like this to avoid breaking lots of code and to give people a chance to transition to it before finally forcing it (properties used to be done differently, and the problems with delegates, like you noticed, were a major reason for this property stuff in the first place). Not sure when they were planning on finally flipping the switch and turning it on permanently, or at least on by default. Has it maybe been long enough now?
Dec 12 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 12 Dec 2011 19:42:48 -0500, Jonathan M Davis <jmdavisProg gmx.com>  
wrote:

 -property makes it so that properties must be used like variables and  
 non-
 property functions cannot be. In theory, that will become the default  
 behavior
 of the compiler eventually, but we couldn't enable it immediately due to  
 a
 combination of bugs with  property and the fact that it would break  
 code. For
 now, people can build with -property to make sure that their code uses
 properties properly.

To clarify, Jonathan is talking about using the -property command line switch for dmd. -Steve
Dec 12 2011
prev sibling next sibling parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Mon, 12 Dec 2011 19:25:33 -0500, Mehrdad <wfunction hotmail.com> wrote:
 In every language I've seen that has "properties" (C#, Python), they are:

      - _Defined_ like methods
      - _Used_ like variables

 The trouble is, this isn't true with D.

Neither is it true (by your definition) in a lot of other languages (Ruby, Eiffel) which have properties. D originally implemented a concept called Methods-as-Properties, which in terms of paradigms lies somewhere between "properties" and the "Uniform access principle". This naturally caused a bunch of cognitive dissonance for people coming from C#/python, which lead to the introduction of property. Originally, property and MaP were suppose to co-exist. As this was a compromise, the property can-of-worms occasionally gets re-opened in these forums.
Dec 12 2011
parent Don <nospam nospam.com> writes:
On 13.12.2011 17:03, Robert Jacques wrote:
 On Tue, 13 Dec 2011 03:50:13 -0500, Manu <turkeyman gmail.com> wrote:

 On 13 December 2011 09:53, Jonathan M Davis <jmdavisProg gmx.com> wrote:

 On Tuesday, December 13, 2011 07:28:18 F i L wrote:
 Can someone please explain why  property and  disabled have a ' '
 symbol in front of them?

So that they don't have to be keywords.

What is the rule for use of ' '? It does feel inconsistent to me too...

word are attributes. Attributes were added late to the D language in order to minimize the effects of adding new keywords,

That isn't true. Reducing keywords was NOT presented a primary rationale for adding attributes. so there are some
 keywords (i.e. pure) that might have been considered for attribute
 status had they been incorporated after attributes were available. At
 one point in time, user defined attributes were to be allowed but that's
 still on the enhancement list. We haven't gone back and normalized the
 older keywords as that would result in the pointless breaking of
 existing code.

I think the answer is simply: yes, it is inconsistent. I don't think there's any justification for it. The "breaking code" argument is spurious, there's hardly any extant code from that era which hasn't already been broken. Note that the decision to retain the inconsistency dates from *before* TDPL was published. It's just inconsistent. It's stupid that's inconsistent, but it's not terribly important.
Dec 13 2011
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
Can someone please explain why  property and  disabled have a ' ' 
symbol in front of them?
Dec 12 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, December 13, 2011 07:28:18 F i L wrote:
 Can someone please explain why  property and  disabled have a ' '
 symbol in front of them?

So that they don't have to be keywords. - Jonathan M Davis
Dec 12 2011
prev sibling next sibling parent Manu <turkeyman gmail.com> writes:
--bcaec51962e3ef19b404b3f5561a
Content-Type: text/plain; charset=UTF-8

On 13 December 2011 09:53, Jonathan M Davis <jmdavisProg gmx.com> wrote:

 On Tuesday, December 13, 2011 07:28:18 F i L wrote:
 Can someone please explain why  property and  disabled have a ' '
 symbol in front of them?

So that they don't have to be keywords.

What is the rule for use of ' '? It does feel inconsistent to me too... --bcaec51962e3ef19b404b3f5561a Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div class=3D"gmail_quote">On 13 December 2011 09:53, Jonathan M Davis <spa= n dir=3D"ltr">&lt;<a href=3D"mailto:jmdavisProg gmx.com">jmdavisProg gmx.co= m</a>&gt;</span> wrote:<br><blockquote class=3D"gmail_quote" style=3D"margi= n:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <div class=3D"im">On Tuesday, December 13, 2011 07:28:18 F i L wrote:<br> &gt; Can someone please explain why property and disabled have a &#39; &#= 39;<br> &gt; symbol in front of them?<br> <br> </div>So that they don&#39;t have to be keywords.<br></blockquote><div><br>= </div><div>What is the rule for use of &#39; &#39;?</div><div>It does feel = inconsistent to me too...</div></div> --bcaec51962e3ef19b404b3f5561a--
Dec 13 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Tuesday, December 13, 2011 10:50:13 Manu wrote:
 On 13 December 2011 09:53, Jonathan M Davis <jmdavisProg gmx.com> wrote:
 On Tuesday, December 13, 2011 07:28:18 F i L wrote:
 Can someone please explain why  property and  disabled have a ' '
 symbol in front of them?

So that they don't have to be keywords.

What is the rule for use of ' '? It does feel inconsistent to me too...

It _is_ inconsistent. The decisions as to what would have and what wouldn't was a combination of arbitrariness and what was added when. The keywords have generally been around much longer, whereas the symbols which start with are generally newer, but there was a bit of discussion at one point as to which ones would and wouldn't have in front of them. The decision was ultimately rather arbitrary. All symbols are attributes, but there are plenty of keywords which are attributes as well. There are those of use who would like to be used for user-defined attributes like occurs in Java, but that hasn't happened yet and it may never happen. That wouldn't really conflict with the current usage though. The current ones would just be system-defined and would be treated like any other system-defined attribute. - Jonathan M Davis
Dec 13 2011
prev sibling next sibling parent reply Somedude <lovelydear mailmetrash.com> writes:
Le 13/12/2011 01:25, Mehrdad a écrit :
 In every language I've seen that has "properties" (C#, Python), they are:
 
     - _Defined_ like methods
     - _Used_ like variables
 
 The trouble is, this isn't true with D.
 
 Consider:
 
 struct Struct
 {
     int delegate() randgen1 = ...;
      property
     int delegate() randgen2() { ... }
 }
 
 Struct s;
 auto result = s.randgen2();    // This doesn't do the user expects
 
 It is *not* possible, in D, to transparently use either one -- you have
 to treat properties, like methods, not like variables. Except that this
 is inconsistent -- in most other cases, you don't need to do that.
 
 Or for example:
 
 Struct s;
 auto a = &s.randgen1;
 auto b = &s.randgen2;  // Should be an error
 
 IMO, properties should not be callable with parentheses at all.
 Something like C# -- they should generate getter and setter methods
 instead, or the like.
 Furthermore, taking the address of a property should only work if you
 can take the address of its _value_. If you need the address of the
 actual function, then I think a corresponding getter method might be
 easier to use.
 
 It gets even /worse/ in templated code, because you have no idea whether
 an alias is referring to a property or to a variable or whatever.
 
 Making this change would obviously break code, but the break is
 obviously _trivial_ to fix: just remove extra parentheses. It won't
 exactly be the kind of breakage that causes headaches.
 
 So should this be fixed?

My question is: what is the use case for properties in D ?
Dec 13 2011
parent reply "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 13 Dec 2011 07:25:10 -0500, Somedude <lovelydear mailmetrash.com> wrote:
 Le 13/12/2011 01:25, Mehrdad a écrit :
 In every language I've seen that has "properties" (C#, Python), they are:

     - _Defined_ like methods
     - _Used_ like variables

 The trouble is, this isn't true with D.

 Consider:

 struct Struct
 {
     int delegate() randgen1 = ...;
      property
     int delegate() randgen2() { ... }
 }

 Struct s;
 auto result = s.randgen2();    // This doesn't do the user expects

 It is *not* possible, in D, to transparently use either one -- you have
 to treat properties, like methods, not like variables. Except that this
 is inconsistent -- in most other cases, you don't need to do that.

 Or for example:

 Struct s;
 auto a = &s.randgen1;
 auto b = &s.randgen2;  // Should be an error

 IMO, properties should not be callable with parentheses at all.
 Something like C# -- they should generate getter and setter methods
 instead, or the like.
 Furthermore, taking the address of a property should only work if you
 can take the address of its _value_. If you need the address of the
 actual function, then I think a corresponding getter method might be
 easier to use.

 It gets even /worse/ in templated code, because you have no idea whether
 an alias is referring to a property or to a variable or whatever.

 Making this change would obviously break code, but the break is
 obviously _trivial_ to fix: just remove extra parentheses. It won't
 exactly be the kind of breakage that causes headaches.

 So should this be fixed?

My question is: what is the use case for properties in D ?

The original use case for properties (in general) was to allow source level compatibility when one re-factored a public field from a variable to a method. Since then, properties have become a common tool to hide fields from the public interface (to allow for overloading, etc) but retain field like syntax. In D, the technical use case for property was to resolve an ambiguity when re-factoring a zero argument delegate field to a method. Also, there was a cognitive dissonance between D's properties and those of C# and python.
Dec 13 2011
parent Somedude <lovelydear mailmetrash.com> writes:
Le 13/12/2011 17:15, Robert Jacques a écrit :
 On Tue, 13 Dec 2011 07:25:10 -0500, Somedude
 My question is: what is the use case for properties in D ?

The original use case for properties (in general) was to allow source level compatibility when one re-factored a public field from a variable to a method. Since then, properties have become a common tool to hide fields from the public interface (to allow for overloading, etc) but retain field like syntax. In D, the technical use case for property was to resolve an ambiguity when re-factoring a zero argument delegate field to a method. Also, there was a cognitive dissonance between D's properties and those of C# and python.

Thank you.
Dec 13 2011
prev sibling next sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 13 Dec 2011 03:50:13 -0500, Manu <turkeyman gmail.com> wrote:

 On 13 December 2011 09:53, Jonathan M Davis <jmdavisProg gmx.com> wrote:

 On Tuesday, December 13, 2011 07:28:18 F i L wrote:
 Can someone please explain why  property and  disabled have a ' '
 symbol in front of them?

So that they don't have to be keywords.

What is the rule for use of ' '? It does feel inconsistent to me too...

word are attributes. Attributes were added late to the D language in order to minimize the effects of adding new keywords, so there are some keywords (i.e. pure) that might have been considered for attribute status had they been incorporated after attributes were available. At one point in time, user defined attributes were to be allowed but that's still on the enhancement list. We haven't gone back and normalized the older keywords as that would result in the pointless breaking of existing code.
Dec 13 2011
prev sibling next sibling parent "F i L" <witte2008 gmail.com> writes:
Robert Jacques wrote:
 We haven't gone back and normalized the older keywords as that 
 would result in the pointless breaking of existing code.

I know attributes are of minor importance at this time, however, I don't think "can't change it cause people use it" is an effective strategy when evolving a language. Any core changes could be bundled into a D3 spec and major D version could maintain a support lifetime which more accurately reflects community version dependency. I see the recently announced death of D1 as a step in this direction.
Dec 13 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, December 14, 2011 00:07:53 F i L wrote:
 Robert Jacques wrote:
 We haven't gone back and normalized the older keywords as that
 would result in the pointless breaking of existing code.

I know attributes are of minor importance at this time, however, I don't think "can't change it cause people use it" is an effective strategy when evolving a language. Any core changes could be bundled into a D3 spec and major D version could maintain a support lifetime which more accurately reflects community version dependency. I see the recently announced death of D1 as a step in this direction.

Once enough has stabilized in a language, it becomes much more costly to change stuff, and the attributes were not added early in the development of D2. Also, some changes would arguably just be too much for too little gain. For instance, public, private, etc. are all attributes. It would make porting to D2 more of a pain and add extra cognitive load to anyone coming from languages such as C++, Java, and C# for little gain to make them public, private, etc. And at this point, D2 is far enough along that breaking changes need fairly strong justification to be made. If/When we do D3 (it won't be for years), then more breaking changes can be added to the language, but there's no way that something like attributes would be changed for D2 at this point. The gain is debatable and trivial, and the cost is huge. D2 already breaks plenty of stuff from D1, C++, Java. etc. as it is, so it's not like it's always taken the stance of avoiding breaking changes. It's just that it's too far along now to make breaking changes without a really good reason. - Jonathan M Davis
Dec 13 2011
prev sibling parent "Robert Jacques" <sandford jhu.edu> writes:
On Tue, 13 Dec 2011 13:02:46 -0500, Don <nospam nospam.com> wrote:

 On 13.12.2011 17:03, Robert Jacques wrote:
 On Tue, 13 Dec 2011 03:50:13 -0500, Manu <turkeyman gmail.com> wrote:

 On 13 December 2011 09:53, Jonathan M Davis <jmdavisProg gmx.com> wrote:

 On Tuesday, December 13, 2011 07:28:18 F i L wrote:
 Can someone please explain why  property and  disabled have a ' '
 symbol in front of them?

So that they don't have to be keywords.

What is the rule for use of ' '? It does feel inconsistent to me too...

word are attributes. Attributes were added late to the D language in order to minimize the effects of adding new keywords,

That isn't true. Reducing keywords was NOT presented a primary rationale for adding attributes.

Thanks for clearing up my memory. Was the primary rational user attributes or something else?
Dec 13 2011