new DIP5: Properties 2

Andrei Alexandrescu SeeWebsiteForEmail at erdani.org
Fri Jul 31 22:04:49 PDT 2009


Steven Schveighoffer wrote:
> On Fri, 31 Jul 2009 22:37:06 -0400, Andrei Alexandrescu 
> <SeeWebsiteForEmail at erdani.org> wrote:
> 
>> Steven Schveighoffer wrote:
>>> On Fri, 31 Jul 2009 16:53:12 -0400, Andrei Alexandrescu 
>>> <SeeWebsiteForEmail at erdani.org> wrote:
>>>
>>>> Steven Schveighoffer wrote:
>>>>> But in the case of properties only allowed without parens, 
>>>>> functions require parens, you are defining a rule for the 
>>>>> compiler.  Think of the parentheses as an extension of the function 
>>>>> name, like punctuation.
>>>>
>>>> But you say no parens means query, parens means action. This is 
>>>> sheer unchecked convention.
>>>  But we already have sheer unchecked convention!  I could make a 
>>> function called sort that reverses an array.
>>
>> Of course we do. My point is that there's no need to add gratuitous 
>> mechanisms fostering conventions that go unchecked.
> 
> We already had those conventions.  D took them away by allowing any 
> function to be treated as a property.

In C and C++ there was no convention: a.b was a field name and a.b() was
a function call. It was a language reality. C# added properties that
allow establishing a convention.

> You could argue the same points 
> for the current D property system -- specifying x = y translating to x = 
> y() doesn't add any extra checking or benefit at all except for you like 
> the way it looks better.

That's why we need to restrict it.

> I still am amazed that you see no benefit to 
> punctuation differences in names.

I do see benefit, but I also see cost.

>>> I don't get why it makes any difference to you that the meaning of 
>>> parentheses and no parentheses is used by the author of the 
>>> function.  How is this bad or somehow worse than what we have now?  
>>> If you don't trust the author's functions do what they are named for, 
>>> don't use his functions and properties.
>>
>> Well you can trivialize all you want but the matters are different. 
>> It's one thing to have good names, good designs, trusted code etc. and 
>> a whole different thing to define a feature of which entire existence 
>> only serves only an unchecked convention.
> 
> It serves a purpose -- one that is not functionally checkable or 
> definable, but is interface to a human being.

The problem is that it's all loss, no gain: the callee must make the
decision whether the call must be with or without parens, and the caller
must obey that decision. There is no guarantee gained, only effort.

> Look, if D decided to make function calls case insensitive because "some 
> people like to call with their own case", nobody would go for it.  But 
> let's say it did happen, and people requested that we make things case 
> sensitive again.  The argument that it doesn't serve any checked 
> convention is ludicrous!  I don't want a checked convention, I just want 
> to name my classes with capital letters for my conventions dammit!  The 
> ability to name things how we want and expect them to be called by the 
> name we give them is fundamental in human interface definition!  Not 
> being able to specify the calling convention makes you A) come up with 
> ugly verbose names like isEmpty, getProperty, C_classname, or B) deal 
> with the ensuing bug reports "how come you named it empty instead of 
> isEmpty because if you call it like empty(), it looks like you are 
> emptying something".

I was careful to specify that things like naming conventions are useful
when/because they are simple. There are naming conventions that don't
scale and are mentioned mostly derisively, such as the Hungarian
notation. Apparently I wasn't careful enough, I should have stressed
that point. Again: beyond the simplest ones, unchecked conventions in
programming languages are a dicey proposition. I believe a good language
should not define features that serve solely for cute but useless
conventions.

> How about I just start calling you Andray because it's the same to me as 
> Andrei.
> 
>>
>>> Since C was invented, we have had the convention that () means 
>>> function, lack of () means property.  You are acting like the last 37 
>>> years of programming languages never existed, and this is some "new 
>>> radical" convention.  D is of C lineage, so using long standing C 
>>> conventions should not confuse people.
>>
>> Well C never had properties that executed code, so following the 
>> lineage is a moot point. C also didn't have a variety of other things, 
>> such as member functions. But we do have now. All I want is to not add 
>> undue burden. To me, it would be a mistake if D defined a special 
>> syntax for defining properties as if they were some big deal, to then 
>> not check in any way that they behave any different than regular 
>> functions.
> 
> The check is in the implication the human sees.  x.empty() => empty x; 
> x.empty => is x empty.

I bet money someone somewhere will want to define an API where x.sort()
sorts something in-place and x.sort returns a sorted copy; or where
x.empty() clears something and x.empty tells whether it's empty. Kind of
interesting I guess :o).

> No functional check is necessary just like no 
> check is necessary to ensure that empty doesn't print "asshole" to the 
> screen.  The implication is in the meaning of the word coupled with 
> punctuation long perceived *by the user* as defining an action.  C had 
> properties, but they were limited to only returning a value and setting 
> a value.

So that distinction got lost once C# introduced properties as a distinct
language feature. What was gained?

> Why do you think Java defines properties as getX and setX instead of 
> just x?  Because they don't have a way to get rid of the parentheses.  
> So they want to make it clear because parantheses imply action that the 
> action is getting or setting x, not x'ing.

"Convention are good if they're simple."

>>>> Maybe less confusion, definitely more burden.
>>>  The burden is on the author to come up with meaningful function 
>>> names already.  With real properties, at least that task is easier 
>>> because you don't need to add extra context to ensure a word is 
>>> treated as a verb or a noun (e.g. 'isEmpty' in order to make sure 
>>> someone doesn't mistake 'empty' for an action).  The compiler 
>>> enforces the requirement of property syntax vs. function syntax, so 
>>> no burden there.
>>
>> No, you add burden by posing the question, do I want people to call 
>> with parens or without? There's always going to be a gray area and 
>> there's always going to be surprising APIs (see e.g. Daniel Keep's 
>> point about range APIs that must actually do stuff in r.empty). With a 
>> uniform convention, all of these issues vanish.
> 
> I grant you that people will certainly stray from the norm, gray areas 
> are unavoidable.  Sometimes you have to bend the rules a little bit to 
> achieve what you want, this is no exception.  But for 99.99% of the 
> time, the convention can be used.  That one or two times you have to 
> implement something weird that doesn't follow the convention doesn't 
> make the whole convention invalid! You note the exception and move on.  
> For example, look at Rebindable!(T) where you clearly violate the rules 
> of const, does that make all of const invalid?  Oops, I can't implement 
> Rebindable without breaking the rules, this const shit can't be 
> guaranteed, so I reject the idea of const altogether.
> 
> Daniel's point about range APIs doing stuff in r.empty has nothing to do 
> with it, since the meaning is "is this range empty."  Some would like 
> that to mean "you're just giving me a simple value so you shouldn't have 
> to mutate the object,"  but to me it *reads* "is this thing empty, do 
> whatever it takes to answer that question, including mutating the object 
> if you have to."  Guess what, you still have to deal with that problem, 
> even without property syntax.
> 
>> To clarify: if there was any extra checking by the compiler, any 
>> guarantee that the feature would provide at all, I'd be glad to pay 
>> the price of thinking more when putting together a design. But you 
>> want to define a language feature that allows people to require "()" 
>> or not as they please, and that's all. It's a frivolous detail to be 
>> spending time on when designing an API. I simply don't believe that's 
>> good language design.
> 
> Yeah, those moronic language designers who make C#, Java, Python, etc. 
> don't know what they're talking about.
> 
> I give up.  I don't see any way to break through to you.  Hopefully 
> someday someone whose opinion you *do* value criticizes D for having 
> ambiguous calling conventions, and then you are forced to change it.

I don't think you can reasonably conclude there's anything personal in
this. What you need in order to be convincing are better arguments, not 
more clout.


Andrei



More information about the Digitalmars-d mailing list