[phobos] Time to get ready for the next release

Steve Schveighoffer schveiguy at yahoo.com
Mon Apr 25 06:42:28 PDT 2011





----- Original Message -----
> From: Robert Jacques <sandford at jhu.edu>
> To: Discuss the phobos library for D <phobos at puremagic.com>
> Cc: 
> Sent: Saturday, April 23, 2011 1:05 AM
> Subject: Re: [phobos] Time to get ready for the next release
> 
> On Fri, 22 Apr 2011 07:59:54 -0400, Steve Schveighoffer 
> <schveiguy at yahoo.com> wrote:
>>>  From: Robert Jacques <sandford at jhu.edu>
>>>  To: Discuss the phobos library for D <phobos at puremagic.com>
>>>  Sent: Thursday, April 21, 2011 4:05 PM
>>>  Subject: Re: [phobos] Time to get ready for the next release
>>> 
>>>  On Thu, 21 Apr 2011 15:57:57 -0400, Jonathan M Davis 
> <jmdavisProg at gmx.com> wrote:
>>> 
>>>>>  How about the amount of existing code it breaks?  How about the 
> fact that
>>>>>  it breaks using the same function for both method chaining and 
> with
>>>>>  property syntax?
>>>> 
>>>>  Something like
>>>> 
>>>>  auto b = a.prop1.prop2.prop3;
>>>> 
>>>>  should work. I doesn't at present, but it should. There's a 
> bug report on it.
>>> 
>>>  What about auto b = a.prop1(5).prop2(6).prop3(7); ?
>> 
>>  Looks like a poor design.  If a setter property returns anything, it should 
> return the value set.  Otherwise:
>>  auto b = a.prop1 = 5; // I would expect b == 5
> 
> I both David and I have responded in depth to this in other threads. In short, 
> trying to decide the goodness of an API design using an abstracted, out of 
> context, reduced code snippet designed to highlight the syntactic constructs it 
> uses is fallacious.

For you to reject my rebuttal of your obviously abstract example by saying my rebuttal is too abstract is also fallacious.

David did bring up his library, and it works pretty well with the dual property/function API, but there are some parts that could be used incorrectly, and I pointed those out.

>>  my solution:
>> 
>>  define a setProp1, setProp2, and setProp3 without property semantics.  It 
> also reads better:
>> 
>>  auto b = a.setProp1(5).setProp2(6).setProp3(7);
> 
> However, in the real API, setProp is a strictly inferior design. In point of 
> fact, your proposed solution suffers from several issues:
> 
> 1) It isn't DRY (Don't Repeat Yourself). Not only do you have simple 
> code duplication, but you also have to maintain equality of implementation, not 
> just bug updates.

This isn't quite true, the setX is simply a wrapper for the property setter:

typeof(this) setX(int newval) { x = newval; return this; }

This can be reduced to a mixin.

> 2) You've increased the radius of comprehension of your library. Users have 
> to remember that both functions do the same thing and have to assign two 
> different names to the action in their head and then use them appropriately in 
> there code, based on the syntax they wish to use.

No they don't.  This is a common argument against larger APIs.  I know many many APIs where I don't *know* the whole API, I just know what I need to get my work done, and lookup anything else.  If you want to use the setX version all the time, there is no need to learn the property functions.  In fact, there is no more learning required for the setX version and the dual property/function version -- both have the same number of API calls.

Bottom line, increasing the number of documented calls does not make it harder to learn one of those calls.

> 3) If setProp actually read better in real life, we'd use it. But it 
> doesn't, so we aren't. By the way, I would hazard that setX/getX are one 
> of the most famous/infamous pieces of API design out there and that everyone 
> can/does consider it.

Your opinion.  I have used it, and have had no complaints.

>>>>  As for breaking existing code, _of course_ it's going to. 
> That's to be
>>>>  expected, and I would have thought that that was expected when 
> @property was
>>>>  introduced in the first place.
>>> 
>>>  Actually, no it wasn't expected. @property was introduced with 
> loose semantics, not strict semantics. And, by the way, it was judged worth 
> while with only loose semantics.
>> 
>>  I don't know what messages you read, but strict properties were what 
> was approved.  There have been numerous discussions on the NG regarding 
> properties, some pro-strict, some pro-loose, but the one which got the deal done 
> was pro-strict.
> 
> I've been following/part of the 'property' discussions from day 1. 
> My memory was that @property was 'accepted' inside a pro-strict thread, 
> but wasn't pro-strict itself, and that there was a follow-up confirmation of 
> loose-ness. But, alas, I've deleted my own local newsgroup history and my 
> search-fu is weak. So I can't even find any kind of 'acceptance' 
> post let alone it's context and follow-up. About the best I could find, one 
> way or the other, is a bunch of circumstantial posts indicating the desire to 
> patch a hole, as opposed to replacing the ship. But that could just have been 
> earlier in the decision process. Anyways, my searching did turn up some apropos 
> comments from Andrei:

Andrei has always been against properties from day one, there is no secret on that.

I seriously doubt Andrei would put properties as being strict into TDPL unless that was the intention.

BTW, I searched using opera news (I have the entire news archive on my laptop, well, headers at least), and I could not find where the decision was made to include @property, but it seems it was added to the compiler on 12/2009, and the decision was made somewhere between August of that year and December.

>>  Without strict properties, the author of the code cannot enforce usage 
> semantics, and therefore, will lead to ambiguities.  The only exception I can 
> see is calling a function with no arguments which returns void without the 
> parentheses.  It cannot be mistaken for a property getter, because it can't 
> be used as a getter.
> 
> Could you please present an example of an ambiguity in the general case? (i.e. 
> excluding assignment to const/immutable/(static pure) functions and the 
> delegate() foo(){})

I mean semantic ambiguity, not compiler ambiguity.  I mean, the choice of how the symbol can be used makes the symbol name ambiguous where it wouldn't be if the usage was locked to one way or the other.

-Steve



More information about the phobos mailing list