[phobos] Time to get ready for the next release

Steve Schveighoffer schveiguy at yahoo.com
Fri Apr 22 10:22:31 PDT 2011




>________________________________
>From: Robert Jacques <sandford at jhu.edu>
>To: Steve Schveighoffer <schveiguy at yahoo.com>; Discuss the phobos library for D <phobos at puremagic.com>
>Sent: Friday, April 22, 2011 12:09 PM
>Subject: Re: [phobos] Time to get ready for the next release
>
>On Fri, 22 Apr 2011 10:39:02 -0400, Steve Schveighoffer <schveiguy at yahoo.com> wrote:
>
>> Bug reports.  People having stupid arguments just like this one on why you should change how the code works to fit their style ;)
>> 
>> Essentially, ambiguously named functions in the context of "I can call this as a property or a function" lead to people getting surprising behavior and then complaining about the surprise, when I can do nothing about it.
>> 
>> I've actually had this happen.  I had to change function names in Tango in order to avoid people complaining.  The example was, I had a bunch of generator functions in TimeSpan, like
>> 
>> // create a time spand that represents the given number of seconds
>> 
>> static TimeSpan seconds(int s)
>> 
>> 
>> which would be used like this:
>> 
>> auto s = TimeSpan.seconds(5);
>> 
>> But it could also be used as a property.  So this compiled and constructed a temporary time span and throw it away:
>> 
>> TimeSpan s;
>> 
>> s.seconds = 5;
>> 
>> So we had to change seconds to fromSeconds.  It still allows code like this:
>> 
>> s.fromSeconds = 5;
>> 
>> but instead of being disallowed, it just looks horrible, hopefully cluing the reader to go examine the documentation for TimeSpan.  That's the best we can do.  I have no power to enforce the usage.
>
>You know, the first thought I had when seeing this code was, "Why didn't you capitalize the name of your inner struct/class in the first place?".

Obviously because it's not an inner struct :)  seconds is a factory method to create a time span from seconds.  It's akin to core.time's Duration:

dur!"seconds"(5)

> My second thought was, hmm..., I wonder if there would be a way to prevent accessing static members from instances? (There's a pretty serious loss of functionality bug regarding struct opCall being overloaded by ctors that's basically the same thing.)

This was also my wish to fix the problem originally, I kind of still don't like that static functions are not required to be called via the class/struct name (from outside the scope of course).


> Third, came criticisms of naming a factory method 'seconds' in the first place (noun/verb distinctions, etc), and the associative criticisms of fixing a bad design via a proverbial sledgehammer.

The goal was to have something short.  At the time, I was fighting for changing the time code in Tango, and one of the criticisms was that the factory method names were too long (don't remember what I originally had).  Code like Socket.select(5.0) was going to be replaced with Socket.select(TimeSpan.seconds(5)).  This was sort of a compromise.  Ironically, we had to change it to something more verbose because of this problem.


> Forth, came the realization that in D2 'seconds' would probably be pure, which would cause s.seconds = 5 to be compiler error.

No, it wouldn't be an error.  s.seconds(5) is exactly the same as TimeSpan.seconds(5), both would be callable as pure functions.  In other words, s isn't actually passed to the function, it's just used as a namespace.


> Currently I'm pondering whether capitalized factory methods, in order to mimic ctor syntax, would be an acceptable design. I doubt anyone would every have tried s.Seconds = 5, and thanks to auto, I also doubt anyone would call TimeSpan.Seconds s. And unlike (an impure) s.seconds = 5, TimeSpan.Seconds s; simply doesn't compile. Plus, it self-documents the factory concept in the name.

If you used C# regularly, where everything is capitalized, you might expect capitalized method names and properties.  But in any case, why is capitalization more of a distinguisher than parentheses or lack thereof?  Both are part of the name of the function.  It's a matter of taste, but the distinction between capitalization and D's current loose properties is that in the latter, the name is under the control of the *user*, not the author.


>Still, this feels like a valid point weakened by a poor (or at least debatable) example. You wouldn't have additional examples handy, would you? (links to bug reports, would be more than acceptable)


here is the bug report from Tango: http://www.dsource.org/projects/tango/ticket/1184 .  It's the only one that stands out in my memory as something I had to change because of a user complaint of usage.

So I don't have any personal experience with other examples.  Perhaps this is because I learned to be more explicit with method names?  I don't know.  Others may have better examples.


-Steve



More information about the phobos mailing list