On Fri, 22 Apr 2011 13:22:31 -0400, Steve Schveighoffer <[email protected]> wrote:
From: Robert Jacques <[email protected]>
[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.

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?

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.
_______________________________________________
phobos mailing list
[email protected]
http://lists.puremagic.com/mailman/listinfo/phobos

Reply via email to