[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