[phobos] Fw: Time to get ready for the next release

Steve Schveighoffer schveiguy at yahoo.com
Mon Apr 25 04:57:45 PDT 2011


Sorry, I keep forgetting to change the reply to address to phobos.

grrrrr....

-Steve


----- Forwarded Message -----
> From: Steve Schveighoffer <schveiguy at yahoo.com>
> To: Robert Jacques <sandford at jhu.edu>
> Cc: 
> Sent: Monday, April 25, 2011 7:57 AM
> Subject: Re: [phobos] Time to get ready for the next release
> 
> 
> 
> 
>> ________________________________
>> 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: Saturday, April 23, 2011 1:03 PM
>> Subject: Re: [phobos] Time to get ready for the next release
>> 
>> On Fri, 22 Apr 2011 13:22:31 -0400, Steve Schveighoffer 
> <schveiguy at yahoo.com> wrote:
>>>>  From: Robert Jacques <sandford at jhu.edu>
>> [snip]
>>>>  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.
>> 
>> I understand. But I think you side-stepped my actually thought a bit, so let 
> me be a bit more verbose. Conciseness and clarity are probably the two most at 
> odds aspects of any API design. The general conventions are 
> variables/fields/'property's should be names and functions/methods 
> should be verbs. I have seen many a post in the 'property' discussions 
> regarding how verb = value or noun(value) is Evil(TM). Personally, I take it as 
> a rule of thumb and not as a hard and fast rule. Anyways, any designer who uses 
> a noun for an action, should be aware that they are actively courting the very 
> confusion in this bug report. So, from an API design perspective, the author 
> sacrificed too much clarity for consciousness. And this criticism remains true 
> even with @property, enabled. Users are still going to try compile s.seconds = 
> 5, because the API design of 'seconds' differs from the design of its 
> class, its module, its library and general expectations. They are
> just going to get a compiler error, instead of a do nothing expression. And 
> while we deal with non-standard designs all the time, in the form of DSLs, 
> mini-DSLs and 'by convention' frameworks, a single, non-standard 
> function generally only increases a programmer's cognitive load, without any 
> additional benefits. And proposing the creation/justification of a language 
> level features in order to mitigate (not fix) a minor issue with an API, which 
> exists solely due to the API's poor design (which violates its class's 
> design guides), is like taking a sledge hammer to kill a fly.
> 
> I agree with all of this, actually.  I don't love the interface, but it was 
> a compromise, and as far as intuitiveness goes, it's pretty low on the 
> scale.  However, you have to pick your battles, and having a much better time 
> API in tango was better than having the code refused over somewhat bikeshed 
> issues.
> 
> 
> I think this was half a victim of D's flawed property design, and half a 
> victim of being able to call static functions using an instance for namespace.  
> Fix the latter problem in the compiler, and the function can only be called with 
> the struct name as the namespace.  However, it does not remove the property 
> issue:
> 
> TimeSpan.seconds(5); // looks ok to me, not great, but not misleading either.  
> It looks like a constructor, which it actually is.
> 
> 
> TimeSpan.seconds = 5; // absolutely misleading.
> 
> So I think even though it's somewhat of a combination of issues, the 
> property issue is not invalid.
> 
> The issue is more prevalent when talking about ambiguous words, especially ones 
> that can be both nouns/adjectives and verbs.  The issue I have with not being 
> able to require parentheses is, lack of parentheses evoke an expectation of a 
> field, either setting or getting that field.  Parentheses evoke more of an 
> action than a field, but that's not as strong, because you can easily make a 
> function that is a property.
> 
> If you just require @properties to be called without parentheses, it doesn't 
> solve the largest problem with D's property system -- that is, being able to 
> omit parentheses for things that should clearly be viewed as actions.
> 
> Here is an artificial, but not so improbable example:
> 
> stream.read = buf;
> 
> what does this mean?  Does it mean, set the read buffer to buf?  Does it mean 
> read buf into the stream?  I have no idea.  But this is completely clear:
> 
> stream.read(buf);
> 
> it means, read the stream data into buf.
> 
> However, D treats them both equivalently, and throws no error on the 
> super-confusing usage.  I understand that *most* people won't use it that 
> way, but as a library designer, I want to patch all the holes, and make the API 
> as tight as possible.  I want code that uses the library to read as naturally as 
> possible.  So I might rename the function "readTo" to ensure the verb 
> status of "read."  To me, this is a sucky compromise that feels 
> artificially created by the compiler.
> 
> You might have different design goals, and different opinions, but the reality 
> is, we have to choose one way or the other, we can't have both.  Well, we 
> could have both, if we could annotate both styles, but then the question 
> becomes, is it worth complicating the language to have one style over the other.
> 
> D should either adopt @property as a strict enforcement, or not have it at all.  
> Having it half-ass reflects poorly on the language design.
> 
> 
>>>>  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?
>> 
>> Capitalization in D and other languages is generally used for user defined 
> types (structs/classes)[1], while variable, field and method names use camelCase 
> or under_scores (i.e. they start with a lower case). The primary exception to 
> this are constructors, which used the type name and therefore are capitalized. 
> Since a factory method is conceptually identical to a constructor, capitalizing 
> factory methods provides an innate understanding of what the method does, what 
> it is used for and how you should call it, to both the corder and code reviewer. 
> Mandated parenthesis, on the other hand, allows the code reviewer only to 
> understand that it is an action, not what type of action it is and the for coder 
> to get a compiler error when they misunderstand, because the API is poorly 
> designed, what the method does, what it is used for and how you should call it.
>> 
>> [1] Of course, sometimes UDTs use lower case, like float3, to make them feel 
> more like built-in types.
> 
> 
> C# is drastically different.  Capitalization is used for all methods, all custom 
> types, and properties.  I can't say I like that style, but that's the 
> style.
> 
> See here: http://msdn.microsoft.com/en-us/library/x2dbyw72%28v=vs.71%29.aspx
> 
> 
> In neither C# nor D are these rules enforced by the compiler.  BUT, the decision 
> to capitalize or not is up to the library designer, *not* the caller, and the 
> compiler *does* enforce capitalization as decided by the library designer.  This 
> is a large difference from loose properties, where the caller gets to decide the 
> semantics, not the library designer.  All the library designer can do is try and 
> pick names (which he can control) that make one syntax look utterly horrific.
> 
> And that is my point, the library designer is forced to exclude some names that 
> might be unconfusing (if the usage was enforced) in order to compensate for the 
> possibility that the user uses the code the wrong way.
> 
> It's like having a car with a switch that goes from two wheel drive to one 
> wheel drive.  And then in order to persuade the driver to not use that switch, 
> you make the car beep annoyingly if they engage the swtich to one-wheel drive.  
> The better design is to not include the switch at all.
> 
> -Steve
>


More information about the phobos mailing list