February 05, 2013
On Tuesday, February 05, 2013 09:34:06 Jacob Carlborg wrote:
> BTW, if it does get lowered to methods, do we want to be able to access the instance variable directly?

No, because the variable would presumably end up with a compiler-chosen name which would presumably be implementation-dependent. All that the programmer has defined is the name of the property, not the name of the underlying variable.

And for the most part, it wouldn't matter. For structs, inlining would fix the problem, and for classes, if you really want to be able to access the member variable directly for efficiency, you can always declare the property functions explicitly.

- Jonathan M Davis
February 05, 2013
On 02/05/2013 12:34 PM, Jacob Carlborg wrote:
> On 2013-02-05 07:13, Jonathan M Davis wrote:
>
>> One of the main purposes generally given for having properties is so
>> that you
>> can make them public variables when you don't need them to do anything
>> but get
>> and set the member variable, but you can still make it a function
>> later when
>> you need to add other stuff to it (such as checking the value that
>> it's being
>> set to). One of the primary reasons for making a property function act
>> like a
>> variable is precisely so that you can switch between variables and
>> functions
>> when refactoring without breaking code.
>>
>> Also, being able to mark variables as @property would save us a lot of
>> boilerplate. Instead, it's incredibly common to do stuff like
>>
>> struct S
>> {
>>      @property int prop() @safe const pure nothrow
>>      { return _prop; }
>>
>>      @property int prop(int value) @safe pure
>>      { return _prop =  value; }
>>
>>      private int _prop;
>> }
>>
>> That's a lot of extra code just to buy some encapsulation. If we could do
>>
>> struct S
>> {
>>      @property int prop;
>> }
>>
>> we could really reduce the amount of boilerplate code surrounding member
>> variables. Even if putting @property on a variable simply lowered to the
>> property functions rather than it still be a variable, it would be a
>> big help.
>> But without either that or marking variables with @property so that
>> you can't
>> do anything to them that you can't do to a property function, we lose the
>> ability to make a property a variable when the getters and setters are
>> unnecessary, and that means that we're stuck with a lot of extra
>> boilerplate.
>
> BTW, if it does get lowered to methods, do we want to be able to access
> the instance variable directly? I think it's good to be able to bypass
> the setter/getter sometimes internally. Alternatively there could be a
> __traits to access the instance variable.

I like the general idea. But to access variable one can still use tupleof, so there should be a guarantee that the hidden field layout is the same as if it was declared as variable.

February 05, 2013
On 2013-02-05 10:10, Dmitry Olshansky wrote:

> I like the general idea. But to access variable one can still use
> tupleof, so there should be a guarantee that the hidden field layout is
> the same as if it was declared as variable.

As long as accessing it via tupleof works it would be fine. A serializer would be quite crippled otherwise.

-- 
/Jacob Carlborg
February 05, 2013
> And how often do you think you'll find yourself in the situation of needing to get a delegate from a property anyway? Can't we just make »@property getter expressions are always equivalent to their return value« a hard (simple!) rule and add something like __traits(propertyGetter, ...) for the rare cases where you really need to get hold of the underlying function?

As a beginner D user this seems like a far better solution, it's much clearer and doesn't violate one's normal understanding of parentheses (which is exactly as you've outlined). &(a.b) feels very much like a hack.
February 05, 2013
On 2/5/13 3:39 AM, Dmitry Olshansky wrote:
> On 02/05/2013 02:28 AM, Andrei Alexandrescu wrote:> On 2/4/13 2:04 PM,
> Jonathan M Davis wrote:
>  >> We could save a lot of boilerplate code if we can simply make it
>  >> variables and
>  >> property functions guaranteed to be swappable without breaking code.
>  >
>  > I think this is quite powerful. The way we can do this is by making
>  > properties emulate a subset of actual variables.
>  >
>
> This is the primary real-world proble to solve.

The problem with this approach is feature creep - there will always be yet another possible case in which a feature helps some case. We need to put a halt on that.

Unprotected, unchecked member variables that can be get and set without any hooks into the enclosing structure are rare. That's not the case we should help and cater for. When that's the case, the entire object is legitimately a "bag of values" that has only public data.


Andrei


February 05, 2013
On 02/05/2013 08:31 AM, Andrei Alexandrescu wrote:
> On 2/5/13 3:39 AM, Dmitry Olshansky wrote:
>> On 02/05/2013 02:28 AM, Andrei Alexandrescu wrote:> On 2/4/13 2:04 PM,
>> Jonathan M Davis wrote:
>> >> We could save a lot of boilerplate code if we can simply make it
>> >> variables and
>> >> property functions guaranteed to be swappable without breaking code.
>> >
>> > I think this is quite powerful. The way we can do this is by making
>> > properties emulate a subset of actual variables.
>> >
>>
>> This is the primary real-world proble to solve.
>
> The problem with this approach is feature creep - there will always be
> yet another possible case in which a feature helps some case. We need to
> put a halt on that.
>
> Unprotected, unchecked member variables that can be get and set without
> any hooks into the enclosing structure are rare. That's not the case we
> should help and cater for. When that's the case, the entire object is
> legitimately a "bag of values" that has only public data.
>
>
> Andrei
>
>

Rare?  What?  No.  Where is your data?

My anecdotal experience is contradictory.  I tend to end up with A LOT of things that I'd like to make into public variables but don't due to the risk of breaking encapsulation.  The boilerplate can really suck.

I would argue that being able to do the /right/ thing in a /convenient/ way is a very important feature.

I also do not see how this would lead to more features.  If anything, everyone seems to draw the line at address-of: it's a potential feature that we /don't/ want because it's too complicated and introduces harmful semantics.

There are a finite amount of features that are needed to make D's property implementation very complete.  Throw them all on the table and D will have /the best/ property implementation.  If, instead, you are chintzy and give people only some of them, then you will get constant property discussions on the news group and it will /seem/ like you're having to implement an endless stream of features.

February 05, 2013
On 02/05/2013 08:31 AM, Andrei Alexandrescu wrote:
> On 2/5/13 3:39 AM, Dmitry Olshansky wrote:
>> On 02/05/2013 02:28 AM, Andrei Alexandrescu wrote:> On 2/4/13 2:04 PM,
>> Jonathan M Davis wrote:
>> >> We could save a lot of boilerplate code if we can simply make it
>> >> variables and
>> >> property functions guaranteed to be swappable without breaking code.
>> >
>> > I think this is quite powerful. The way we can do this is by making
>> > properties emulate a subset of actual variables.
>> >
>>
>> This is the primary real-world proble to solve.
>
> The problem with this approach is feature creep - there will always be
> yet another possible case in which a feature helps some case. We need to
> put a halt on that.
>
> Unprotected, unchecked member variables that can be get and set without
> any hooks into the enclosing structure are rare. That's not the case we
> should help and cater for. When that's the case, the entire object is
> legitimately a "bag of values" that has only public data.
>
>
> Andrei
>
>

Hmmm.  This statement that unchecked public members are rare makes me wonder if there is a fundamental difference of background here.  Things might be much different if you came from C# or Java instead of C++.

I always get this feeling that Walter and Andrei never truly understood how to use properties effectively.  That's why I bring up C# and Java: those programmers are very comfortable with properties and know how to use them.  Properties are an alien concept in C programming, and probably C++ as well.  As a result, I wouldn't be surprised at all of Walter and Andrei haven't really used properties in the same capacity as the typical C# or Java coder, and thus would think things like "unchecked public members are rare".

This isn't a bashing post or an ad hominem; I'll try to be informative.

In C# properties actually work very well, or at least they did 8 years ago when I used them (ignoring Java: those programmers use properties a lot, but it is a pain).  They did not require an enormous amount of features to gain their power, and D shouldn't either.  The primary differences are these:
(1) C# usually doesn't allow address-of on /anything/.
(2) User-defined value types are rare in C#.
(3) Unambiguous property declaration syntax.

In C# if you try to use a property to return a struct and manipulate a variable off of that, then the compiler will error because C# never implemented property rewrites.  It didn't matter because value types are rare.  (This may be dated by about 3 years.)

I think that those differences are very solvable in D:
(1) Disallow address-of on anything dealing with @property.  No one will miss it; they didn't expect it to exist in the first place.
(2) Do semantic rewriting on properties.  Once you have semantic rewriting, the value-type-properties problem is SOLVED and never needs to be revisited again.  (Disallowing value types in properties would be poor course in a language where user-defined value types are very common.)
(3) This is pretty much solved in DIP23 already.

In both Java and C# the initial state of properties has always been a huge pain.  Just because something /might/ be a property in the future, you always have to make a bunch of boilerplate.  Java/C# programmers probably don't believe in "bags of values"; such things are nonsense if you want proper encapsulation!  People coming from this background are going to LOVE having a shorthand like "public @property int foo;" that removes all of the pain from properly encapsulating public state.

Using properties in a properly-constrained system was actually very enjoyable.

The above is why I don't see feature creep.  The D designers probably don't see where it ends because they've never been to that edge.

I worry that I could be totally wrong about Andrei/Walter's experiences in these arenas.  I don't assert these notions as truth, but instead as a way of communicating my perceptions.  I hope this is informative and not insulting.
February 05, 2013
On Tuesday, 5 February 2013 at 15:08:55 UTC, Chad Joan wrote:
> Hmmm.  This statement that unchecked public members are rare makes me wonder if there is a fundamental difference of background here.  Things might be much different if you came from C# or Java instead of C++.

Well, Andrei background is easy to check: http://en.wikipedia.org/wiki/Andrei_Alexandrescu
;)
February 05, 2013
On 02/05/2013 10:11 AM, Dicebot wrote:
> On Tuesday, 5 February 2013 at 15:08:55 UTC, Chad Joan wrote:
>> Hmmm. This statement that unchecked public members are rare makes me
>> wonder if there is a fundamental difference of background here. Things
>> might be much different if you came from C# or Java instead of C++.
>
> Well, Andrei background is easy to check:
> http://en.wikipedia.org/wiki/Andrei_Alexandrescu
> ;)

I know I know ;)

C++ guru, which is why I say what I say.

It's still possible that he got a good dosage of property usage somewhere.  If that happened and I based an argument off of it, then that would make me an ass.  I also wouldn't notice because I don't stalk Andrei ;)
February 05, 2013
05-Feb-2013 17:31, Andrei Alexandrescu пишет:
> On 2/5/13 3:39 AM, Dmitry Olshansky wrote:
>> On 02/05/2013 02:28 AM, Andrei Alexandrescu wrote:> On 2/4/13 2:04 PM,
>> Jonathan M Davis wrote:
>>  >> We could save a lot of boilerplate code if we can simply make it
>>  >> variables and
>>  >> property functions guaranteed to be swappable without breaking code.
>>  >
>>  > I think this is quite powerful. The way we can do this is by making
>>  > properties emulate a subset of actual variables.
>>  >
>>
>> This is the primary real-world proble to solve.
>
> The problem with this approach is feature creep - there will always be
> yet another possible case in which a feature helps some case. We need to
> put a halt on that.
>
> Unprotected, unchecked member variables that can be get and set without
> any hooks into the enclosing structure are rare. That's not the case we
> should help and cater for. When that's the case, the entire object is
> legitimately a "bag of values" that has only public data.
>
>

Thinking more of it with proper properties it would be doable with a half-decent template mixin. Then it'd better be in Phobos one day as that would make it readily accessible but separate from the language.
-- 
Dmitry Olshansky