January 25, 2013
On Friday, January 25, 2013 12:24:56 monarch_dodra wrote:
> On Friday, 25 January 2013 at 11:01:31 UTC, mist wrote:
> > On Friday, 25 January 2013 at 10:26:14 UTC, Robert burner
> > 
> > Schadek wrote:
> >> ...
> >> Yes, the syntax is legit. It's the semantic that "scares" me.
> >> IMHO it feels strange that assigning a variable resizes a
> >> array. Something like a.resize(10) would make me feel better.
> > 
> > Ye, it was one of the first "Erm wtf?" moments when I started to learn D. And living confirmation that core developers don't really have a strong vision what properties should be.
> 
> I can view *reading* size as a property, but I don't think the setter itself should be a property, since it actually *does* something. Heck, it can throw an exception (!)

So? Of course, setters can throw exceptions. Why wouldn't they be able to? For instance, if you try and set the hour on a TimeOfDay to 25, it's going to throw a DateTimeException. I could see an argument that the operations that length does when set are expensive enough that it shouldn't be a setter property, but setters are not necessarily going to be as simple as setting a variable, and throwing exceptions from them is normal, depending on what they need to do. I could see generally restricting them to operations which are O(1) or O(log n) rather than O(n) or worse (and I think that C#'s guidelines on properties say something along those lines), but you make it sound as if all a setter property should ever do is simply set a variable, and if that were the case, you might as well just make it a public variable.

> However, I really think we are way past the point we can change array's interface. I'd just leave it be.

It's far too late at this point. I don't know if it was a good design choice or not (and I rarely use it myself), but it's not going to change.

- Jonathan M Davis
January 25, 2013
On Fri, 25 Jan 2013 10:39:50 -0800, H. S. Teoh <hsteoh@quickfur.ath.cx> wrote:

> On Thu, Jan 24, 2013 at 12:34:42AM -0800, Walter Bright wrote:
>> This has turned into a monster. We've taken 2 or 3 wrong turns
>> somewhere.
>>
>> Perhaps we should revert to a simple set of rules.
>>
>> 1. Empty parens are optional. If there is an ambiguity with the
>> return value taking (), the () go on the return value.
>>
>> 2. the:
>>    f = g
>> rewrite to:
>>    f(g)
>> only happens if f is a function that only has overloads for () and
>> (one argument). No variadics.
>>
>> 3. Parens are required for calling delegates or function pointers.
>>
>> 4. No more @property.
>
> I've refrained so far from participating in this thread, but maybe it's
> time to say something.
>
> 1) @property and optional parentheses are orthogonal issues. Let's not
>    conflate them and cause more unnecessary confusion in what is already
>    a complex and convoluted discussion.
>
> 2) Personally, I don't like leaving out parentheses, but I don't really
>    care either way. In any case, this has nothing to do with @property.
>
> 3) So, as far as @property is concerned, let's forget about optional
>    parentheses or not.
>
> 3) @property is necessary for good abstraction. Yes, there have been
>    precedents of abuse (like .dup and .idup, which really should *not*
>    be properties but methods), and there are problems in the current
>    implementation of @property, but the _concept_ of @property itself is
>    a sound one. People have already mentioned the use case of a member
>    variable that needs to be replaced with a getter/setter method.
>    Conceptually speaking, the user of the class should not need to know
>    or care whether it's just a POD field or an abstract entity
>    manipulated by @property functions.
>   For example, an Array class has a .length property, and user code
>    should not need to know nor care if this length is an actual size_t
>    field, or something else. All it needs to know is you can get a
>    size_t out of it, and (optionally) change its value (if it's
>    non-const, or if there's a setter method).
>
>    Sometimes, you get into the situation where it's *possible* to
>    implement a @property as a plain old field, but not desirable because
>    of the SSOT (single source of truth) principle. It could be a
>    computed value based on implementation-specific parameters, for
>    example. It would not be nice if you had to store its value, then
>    change code everywhere to make sure that it's always updated when the
>    underlying parameters change. Lots of ugly, unnecessary, inefficient,
>    and fragile code.
>
>    Therefore, @property is necessary. If it causes a problem with the
>    syntax, well, that's a problem with the syntax, not with the concept
>    of @property itself.
>
> As far as syntax is concerned, it should be very straightforward. Given
> that the goal of @property is to simulate a variable, it should
> syntactically be identical to a variable, regardless of what it returns.
> So, given:
>
> 	struct S {
> 		@property T prop() { ... }
> 	}
> 	S s;
>
> Then:
>
> a) Writing s.prop returns a value of type T, for any type T (POD or
>    struct or class or delegate or whatever);
> b) Writing s.prop() invokes opCall on the *return value* (because .prop
>    behaves exactly as though it were an actual field);
> c) As a corollary, if T is not callable, then s.prop() is illegal;
> d) &s.prop returns a pointer to T (if .prop returns a ref).
> e) As for taking the address of the .prop function itself, my take on it
>    is that (i) from a user's POV, .prop should be indistinguishable from
>    a plain old field, so you shouldn't ever need to do this, and
>    therefore (ii) it's impossible, and (iii) if you *really* need to do
>    it, do this instead:
>
> 	struct S {
> 		@property T prop() { return this.propImpl(); }
>
> 		// You really only need to know about propImpl if you're
> 		// inside S's implementation anyway, so this is private.
> 		private T propImpl() { ... }
>
> 		void someMethod() {
> 			auto ptr = &propImpl;
> 			// There, now you have it.
> 		}
> 	}
>
> f) IOW, .prop cannot be distinguished from an actual field under normal
>    circumstances. If you *really* need to do this (e.g. in serialization
>    code), then use __traits.
>
> Consequently:
>
> - Assignment syntax like f=g should NOT be treated equivalently to f(g)
>   because conceptually it makes no sense. Writing writeln = "abc"; makes
>   no sense because writeln is not a value that you write to. Writing
>   s.prop = "abc" *does* make sense, because S.prop is a @property, and
>   therefore behaves like a variable. Writeln is a function, not a
>   @property, so this is illegal.
>
> - Syntax like s.prop++ should work automatically (equivalent to
>   s.prop(s.prop+1)), if .prop has both a getter and setter @property.
>   It should NOT be allowed for arbitrary methods m just because m has
>   both overloads of m() and m(T).
>
> - It's illegal to mark a function that takes 2 or more arguments as
>   @property, because it makes no sense.
>
> The bottom line is, if you mark a function as @property, then it should
> behave as if it were a variable of its return type. This has nothing to
> do with optional parentheses or not, and assignment syntax should be
> reserved for variables (and by extension @property, because @property
> means something behaves like a variable), not arbitrary functions.
>
>
> T
>

++

-- 
Adam Wilson
IRC: LightBender
Project Coordinator
The Horizon Project
http://www.thehorizonproject.org/
January 25, 2013
On 01/25/13 15:28, Andrei Alexandrescu wrote:
> On 1/25/13 5:56 AM, Artur Skawina wrote:
>> On 01/25/13 08:39, Andrei Alexandrescu wrote:
>>> On 1/25/13 2:12 AM, Artur Skawina wrote:
>>>> On 01/24/13 21:13, Andrei Alexandrescu wrote:
>>>>> On 1/24/13 2:03 PM, Artur Skawina wrote:
>>>>>> Trying to make arguments you don't like go away and silencing the messenger is your MO.
>>>>>
>>>>> Now that's what's called "ad hominem".
>>>>
>>>> No, it's not - it's just stating the facts; this was not the first such incident.
>>>
>>> Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
>>
>> Hmm, I can see how you could view this as an ad hominem, given that definition,
> 
> How can that be seen as anything else? What definition do you have?
> 
> You made a mistake under the heat of the argument. We all do. Don't try to explain how actually you didn't. The right course is to casually apologize and move on.

No. Please don't try to reinterpret what I said, this is the second time you did this. But, like i said, I can see that you view it like that. Fact is that that comment had absolutely nothing to do with the argument itself - I was only replying to your response, which was unacceptable. So, yes, I am talking about what you did, but that does not automatically mean it's an ad hominem, otherwise any critical comment about how the conversation is handled by the other side would be. I did make that comment too generic, and for that I'll apologize - I really should have said that /it happens/, and not used a figure of speech that can reasonably be misunderstood. I should have reread and caught that, I'm sorry. I'm still saying that these types of responses, when uncalled for (at least I didn't say 'in a well defined language..."), but caused only by your dislike of the argument or form thereof, are inappropriate.


> I kept the sentence that I had a reply for. The rest I understood and agreed with.

It contained examples showing how all '()' could be omitted within ufcs chains,
except the last pair. That would be a reasonable compromise, make code concise and
unambiguous to read, but I guess you don't agree that doing it like that would be enough.

artur
January 25, 2013
On Friday, January 25, 2013 22:09:18 Dmitry Olshansky wrote:
> 25-Jan-2013 02:32, Adam D. Ruppe пишет:
> > On Thursday, 24 January 2013 at 22:28:04 UTC, Jonathan M Davis wrote:
> >> However, I do think that would be able to mark variables such that
> >> they're treated as rvalues such that swapping a
> >> variable out with a property function dosen't break code
> 
> IMHO this is a critical part of what a property should do - transparently swapping fields with some functional accessors.

And for that, we need to keep @property. It's impossible without explicit properties (though there are obviously some improvements that we have to make in order to make it work properly with @property).

- Jonathan M Davis
January 25, 2013
On Friday, January 25, 2013 19:51:53 mist wrote:
> On Friday, 25 January 2013 at 18:41:46 UTC, H. S. Teoh wrote:
> > ...
> 
> Sound base that avoid discussion of controversial topics :) Looks like I can agree with almost everything. Probably even everything.
> 
> Only thing that needs to be defined is @property on free-functions: disallow, treat as global variable or treat as an extension methods. We has small discussion on this topic with deadalanix afair somewhere up the topic.

So, you're arguing that @property shouldn't be usable on anything but member functions? We've had discussions on that in the past, and most everyone agreed that it should be legal to use @property on module-level variables, and I've never heard anyone try to argue before that it shouldn't work with UFCS (which is what I assume you mean by extension methods - I don't know what else you would mean). There's an ambiguity problem that needs to be solved with free functions where in some cases, you can't properly distinguish between whether it's supposed to be a getter or a setter, but that can be fixed (e.g. @property(get) and @property(set)), but I think that if you're going to argue that something like

bool exists(string filename) {...}
if(filename.exists)

or

S globalVar() {...}
if(globalVar == blah)

shouldn't work, then you're fighting a losing battle. An both of those idioms are used in Phobos. I agree that calling it a property is a little silly when it's a module-level variable, since there's no object for it to be a property of, but really, @property is an abstraction for variables in general, not just member variables.

- Jonathan M Davis
January 25, 2013
On Friday, January 25, 2013 10:39:50 H. S. Teoh wrote:
> I've refrained so far from participating in this thread, but maybe it's time to say something.
[snip]

I agree with pretty much everything that you said, and it's exactly why we need explicit properties. So, we need to keep @property and make whatever adjustments are necessary in order to make it function like a variable would to the point that you can swap out variables and property functions without breaking code (though that will probably mean allowing something like marking variables with @property to make them be treated as rvalues rather than just improving the handling of property functions).

- Jonathan M Davis
January 25, 2013
On Friday, January 25, 2013 17:37:48 eles wrote:
> On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright wrote:
> 
> One more thing (see also this:
> http://www.25hoursaday.com/CsharpVsJava.html#properties)
> 
> In order to avoid properties throwing exceptions, maybe is wise to impose getters and setters to be nothrow.
> 
> Why? Because code like this (C#) seems a bit unnatural:
> 
> try{
> 
> myClock.Hours = 28; /* setter throws exception because 28 is
> an invalid hour value */
> myClock.Minutes = 15;
> myClock.Seconds = 39;
> 
> }catch(InvalidTimeValueException itve){
> 
> /* figure out which field was invalid and report error */
> 
> }

And why wouldn't setters be able to throw. Why on earth would you do other than throw in code like you have above? How on earth would a setter report a bad argument if it was forced to be nothrow? Exceptions are the correct solution. Setters _need_ to be able to throw. Plenty of them don't need to, but plenty of them do. For instance, many of the properties in std.datetime will throw if you give them invalid values (like setting the hour to 28). I don't see how you could possibly argue that a setter should not be able to throw.

- Jonathan M Davis
January 25, 2013
On Friday, 25 January 2013 at 19:30:41 UTC, Jonathan M Davis wrote:
> On Friday, January 25, 2013 17:37:48 eles wrote:
>> On Thursday, 24 January 2013 at 08:35:01 UTC, Walter Bright
> And why wouldn't setters be able to throw. Why on earth would you do other
> than throw in code like you have above? How on earth would a setter report a
> bad argument if it was forced to be nothrow? Exceptions are the correct
> solution. Setters _need_ to be able to throw. Plenty of them don't need to,
> but plenty of them do. For instance, many of the properties in std.datetime
> will throw if you give them invalid values (like setting the hour to 28). I
> don't see how you could possibly argue that a setter should not be able to
> throw.

You are right. In fact, just after I post the message, I was hit by second toughts.

But a issue still remains: assignments of variables are not usually checked for exceptions. Programmers do not have in mind that they could trigger exceptions.

However, properties could do.

The danger that I see is that programmers will start to "preventively" check everything for exceptions, "just in case" that those current variable assignments would be latter turned into properties.

Do you feel like embracing all your code in try/catch?
January 25, 2013
On Fri, 25 Jan 2013 02:39:15 -0500
Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 1/25/13 2:12 AM, Artur Skawina wrote:
> > On 01/24/13 21:13, Andrei Alexandrescu wrote:
> >> On 1/24/13 2:03 PM, Artur Skawina wrote:
> >>> Trying to make arguments you don't like go away and silencing the messenger is your MO.
> >>
> >> Now that's what's called "ad hominem".
> >
> > No, it's not - it's just stating the facts; this was not the first such incident.
> 
> Of course it is. The definition is simple enough, e.g. from Wikipedia: An ad hominem (Latin for "to the man"), short for argumentum ad hominem, is an argument made personally against an opponent instead of against their argument.
> 

"Ad hominem" *as a logical fallacy* is only applicable when the argument against the person is *intended* to prove something unrelated to the targeted person.

For example, "Joe Schmo is a known asshole" *could* very easily be a logical fallacy. But it clearly *isn't* a fallacy if the speaker is using it to show: "Joe Schmo, your request to be a kindergarten teacher should be rejected."

Artur was clearly making a side note about an unfortunate tendency in some of your posts that I've noticed as well. This was to make you aware of it and hopefully do it less. It was NOT, as you suggest, being put forth as evidence for Artur's property-related arguments.

January 25, 2013
On Friday, 25 January 2013 at 19:30:26 UTC, Jonathan M Davis wrote:
> ...

I am not going to argue anything, I am just asking _how_ they are supposed to work, what are exact semantic. I have added various syntax cases to wiki:
http://wiki.dlang.org/Property_Discussion_Wrap-up#.40property_on_free_functions

What I am going to argue is if all of those example are supposed to work. We can't define property semantics to be "just like data" when property symbol can't be just interchanged with data symbol.

From the syntax point of view no issues there.