January 28, 2013
On Monday, 28 January 2013 at 13:37:36 UTC, Andrei Alexandrescu wrote:
> If we talk about _reasoning_, then properties have already broken that because a.b may be a function invocation. Probably it's about something weaker.
>
> Andrei

No, it has been stated few times already (actually I have just given answer to the same question to Adam) - properties should be reasoned AS IF they are fields/variables, by design. They are abstraction/encapsulation tools and their implementation details should not matter to the reader. You see property - you assume it is as field, because it looks like one.

That is why having .length of array as a property that reallocates is so horrible.
January 28, 2013
On Monday, 28 January 2013 at 13:41:00 UTC, Dicebot wrote:
> On Monday, 28 January 2013 at 13:37:36 UTC, Andrei Alexandrescu wrote:
>> If we talk about _reasoning_, then properties have already broken that because a.b may be a function invocation. Probably it's about something weaker.
>>
>> Andrei
>
> No, it has been stated few times already (actually I have just given answer to the same question to Adam) - properties should be reasoned AS IF they are fields/variables, by design. They are abstraction/encapsulation tools and their implementation details should not matter to the reader. You see property - you assume it is as field, because it looks like one.
>
> That is why having .length of array as a property that reallocates is so horrible.

I do agree, and want to push forward even more with an actual example : TLS. TLS is implemented as a function call on some systems. However, you manipulate TLS variable as variable in your code.

This is the intended abstraction. The fact that a function is called is an implementation detail. That is what a property is about : providing data with an access pattern different than what is wired in the compiler.
January 28, 2013
On 1/28/13 8:40 AM, Dicebot wrote:
> On Monday, 28 January 2013 at 13:37:36 UTC, Andrei Alexandrescu wrote:
>> If we talk about _reasoning_, then properties have already broken that
>> because a.b may be a function invocation. Probably it's about
>> something weaker.
>>
>> Andrei
>
> No, it has been stated few times already (actually I have just given
> answer to the same question to Adam) - properties should be reasoned AS
> IF they are fields/variables, by design. They are
> abstraction/encapsulation tools and their implementation details should
> not matter to the reader. You see property - you assume it is as field,
> because it looks like one.

But this gets back to faith-based programming. I associate "reasoning" with much more rigorous processes.

> That is why having .length of array as a property that reallocates is so
> horrible.

Well it's worked hasn't it.


Andrei
January 28, 2013
On Monday, 28 January 2013 at 13:49:14 UTC, Andrei Alexandrescu wrote:
> But this gets back to faith-based programming. I associate "reasoning" with much more rigorous processes.
>

It is not faith, it is the abstraction that is presented to you. Presenting abstraction is one of the most important task when doing programming. As I explained already, the compiler does teh exact same thing when implementing TLS.

>> That is why having .length of array as a property that reallocates is so
>> horrible.
>
> Well it's worked hasn't it.
>

You can't really argue that phobos is crowded with @property for no benefice when you see that.

Everything has been made a property even when it doesn't make any sense.
January 28, 2013
On Monday, 28 January 2013 at 13:49:14 UTC, Andrei Alexandrescu wrote:
> But this gets back to faith-based programming. I associate "reasoning" with much more rigorous processes.

System-level programming is a lot about faith-based programming. I.e. you have some faith that "writeln" won't modify some random functions instructions at run-time, despite it possibly could have done it. This is very reason to push for idiomatic code and discipline when working with few million loc of system code - otherwise things might just blow up from any seemingly innocent action.

Compiler may help here or may not. Strict and well-defined property enforcement helps. Lax parens-les chaos leaves you no place for trust and forces either to spent much more time to maintain code or resort to verbal project-level restrictions and external verification tools.

>
>> That is why having .length of array as a property that reallocates is so
>> horrible.
>
> Well it's worked hasn't it.

If anyone can give me a language with half D features but with this part done right - I ll switch immediately. I have no other candidates though and am doomed to sit tight and suffer. Makes me rage every time I see it though. Recently another example of wrong property usage was given: range.save

Phobos is kind of fucked up in this regard.
January 28, 2013
On Monday, 28 January 2013 at 13:49:14 UTC, Andrei Alexandrescu wrote:
> Well it's worked hasn't it.

It works because it's a one-off case that people get used to, and it's a builtin so people expect slightly "special" behaviour.

An even worse example of this is rehash for AAs.
January 28, 2013
On 1/28/13 9:06 AM, Dicebot wrote:
> On Monday, 28 January 2013 at 13:49:14 UTC, Andrei Alexandrescu wrote:
>> But this gets back to faith-based programming. I associate "reasoning"
>> with much more rigorous processes.
>
> System-level programming is a lot about faith-based programming. I.e.
> you have some faith that "writeln" won't modify some random functions
> instructions at run-time, despite it possibly could have done it. This
> is very reason to push for idiomatic code and discipline when working
> with few million loc of system code - otherwise things might just blow
> up from any seemingly innocent action.

But D aims at general-purpose programming with only tidbits of systems-level code. The pure and @safe features are intended to enable actual reasoning (in the rigorous sense) on portions of programs or entire programs.

> Compiler may help here or may not. Strict and well-defined property
> enforcement helps. Lax parens-les chaos leaves you no place for trust
> and forces either to spent much more time to maintain code or resort to
> verbal project-level restrictions and external verification tools.
>
>>
>>> That is why having .length of array as a property that reallocates is so
>>> horrible.
>>
>> Well it's worked hasn't it.
>
> If anyone can give me a language with half D features but with this part
> done right - I ll switch immediately. I have no other candidates though
> and am doomed to sit tight and suffer. Makes me rage every time I see it
> though. Recently another example of wrong property usage was given:
> range.save
>
> Phobos is kind of fucked up in this regard.

I understand how you feel though you probably are overstating it. No language can please everyone, and nobody will be pleased by all aspects of a language.


Andrei
January 28, 2013
On Monday, 28 January 2013 at 15:44:28 UTC, Andrei Alexandrescu wrote:
> But D aims at general-purpose programming with only tidbits of systems-level code. The pure and @safe features are intended to enable actual reasoning (in the rigorous sense) on portions of programs or entire programs.

I suppose the same applies also for large size general-purpose programs. But I have no personal experience in development and/or maintenance of those, thus have no rights to push for their interests.

I wonder though, what about "pure" for getters and setters? Making compiler enforce contract "this function only modifies class field and has no side-effects other than that" could have solved reasoning issue.

> I understand how you feel though you probably are overstating it. No language can please everyone, and nobody will be pleased by all aspects of a language.

Sure, I have said I am raging when thinking about it, makes me overstate :) Hope no offense done. Still, argument "it has worked so far" does not really mean that stuff really works good - lack of alternatives will also do. There are no perfect languages and I will always use something I do not like - because other features do matter more.
January 28, 2013
On Monday, 28 January 2013 at 15:44:28 UTC, Andrei Alexandrescu wrote:
>> Phobos is kind of fucked up in this regard.
>
> I understand how you feel though you probably are overstating it. No language can please everyone, and nobody will be pleased by all aspects of a language.
>

Yes that is probably overstated. But please consider that this state of thing in phobos comes from the lax property enforcement in the first place, which mitigate greatly your argument about phobos codebase.
January 28, 2013
On Mon, 28 Jan 2013 08:20:23 -0500, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> One interesting fact is that we have evidence at hand. Optional parens _exist_ today in D, and have for a while. The language has worked. They haven't been a disaster.

I've seen some issues, but mostly for allowing normal functions as setters.

> Aside from discussions about @property itself, optional parens have just worked. We also have evidence that UFCS is convenient and useful. People use it and like it. And arguably UFCS and optional parens combine in a lovely way.

optional parens are something that has been difficult to argue against.  There is always the workaround of making your method names more verbose so they aren't mistaken for properties.

> We've also converted the Phobos codebase to work with the half-strong -property switch. We've adorned a lot of functions with @property. I don't see evidence of found bugs or improved code quality. (Subjectively, I'd argue we actually degraded esthetics. There's no love lost between me and that "@property" plastered everywhere.)

the improvement of @property is all in the eye of the code reader.  There are no "bugs" or code quality improvements, the improvements are for the sole benefit of reading the code, and defining the API.  If something is a @property, it should be accessed as a property.  Being able to enforce this results in cleaner and clearer code.

I've been doing mostly Objective C for the last 10 months.  Interestingly enough, objective C has a notion of @property that is quite similar to D.

You declare in the interface a property like:

@property(attributes) int value;

Where attributes can describe something about the property, is it atomic, is it reference counted, etc.

What does this mean?  It means there is a method for accessing value implicitly declared as:

-(int) value; // translates to int value(); in D

If attributes does not include "readonly", it also means there is a method for setting the value, implicitly declared as:

-(void) setValue:(int)val; // translates to void setValue(int val); in D

Now, note here that the @property declaration is COMPLETELY optional.  One can simply declare the two methods value and setValue:, and then Objective C allows the syntax:

int x = obj.value; // translates in objective C to [obj value];, a.k.a. obj.value(); in D
obj.value = x; // translates in objective C to [obj setValue:x];, a.k.a. obj.setValue(x); in D

note that dot syntax is reserved strictly for property access in Obj-C, field access is done via obj->field, and methods are done via [obj method].  So the comparison to D must take into account that D uses . notation for everything, making it a bit more confusing.

@property here serves two purposes.  Since properties are the ONLY way to publicly access class fields, it provides a very commonly-used boilerplate generation.  Second, with the given attributes, there is a corresponding @synthesize directive in the implementation that will create a default accessor and optional setter (assuming attributes does not include "readonly") that do the right thing, depending on whether the value is atomic, whether it needs it's reference count updated, etc.

But what is really interesting here is that like D's current implementation, the getter looks the same as a property or a method -- and this hasn't caused much confusion for the langauge.  However, UNLIKE D, the setter is unmistakable as a normal function when you use the method form!  [obj setValue:x] cannot be mistaken for something that doesn't set a field.

I would be perfectly fine ONLY defining @property on setters, and getters where the parentheses are confusing (i.e. getting a delegate/function pointer/functor).

I would be fine with D CANCELLING @property as long as we had something like Objective C, where the function form of a setter CANNOT be mistaken for a normal function.  In this case, we would have to live with delegate properties requiring two sets of parentheses.

But if you get rid of @property and we are back to D1-style properties, please acknowledge that the abuse of functions as setters is not a good situation.  I had "bugs" in prior D1 projects where a normal non-property function was easily misinterpreted as a property, and I ended up having to rename the function to something weird so it couldn't be mistaken as a property.  The nice thing about the objective-c solution is it puts the burden of naming convention on the *property* function.  With D1, the burden is on *all* functions to broadcast "no, I'm not a property".

>
> These are not "what if" hypotheses; they describe experience accumulated from past events. Even people who dislike optional parens or UFCS must agree that their sentiment is far from widespread - unlike, for example, was the case for string lambdas.

These "past events" should be taken with a grain of salt, since @property was never fully realized.  In languages where properties were fully enforced, it has not caused problems or undue headaches.

-Steve