One comment that comes up over and over is “Why did you chose <fill in some keyword or syntax>? It looks <ugly, stupid, non-VB-like, inconsistent>!” So, how do we come up with new syntax?
We put all the options up on a dart board and throw darts at them blindfolded.
OK, not seriously. But sometimes it seems that way. You see, I’d like to pretend here that we have some formal intellectual process that allows us to arrive at the ideal syntax 100% of the time with complete accuracy. But the sad fact of the matter is that syntax, for better or for worse, is largely a matter of personal preference. Show the same syntax to 10 different people, and you’re going to get 10 different opinions. In the end, it almost comes down to just picking a damn syntax and sticking with it no matter what.
This isn’t to say that there aren’t considerations that come into play when thinking about syntax. Reusing characters already used in another context is not something that shouldn’t be done lightly. The availability of keys on the majority of keyboards in the world is another consideration. (Our test lead took to joking for a while that we should use the euro character for something, just to give the Europeans a leg up on the Americans for once.) And the number of characters in a keyword is a real consideration. I personally have some regrets about the length of some of the keywords that we chose for inheritance, for example.
But in the end, it comes down to aesthetics and that is totally a personal thing. The bitshift operators are an excellent example of this: when we first discussed them in the VS 2002 timeframe, we ended up having to table the whole feature because none of us could agree on whether we should choose <<, Shl, BitShl, ShiftTheValueLeftTheFollowingNumberOfBits, etc. We would have ended up cutting the feature because of time anyway, but it’s an instructive example.
The problem with something like choosing a bitshift operator is that everyone’s cultural context comes into play. For people familiar with C++, choosing << and >> seems natural because that’s what they’re used to. For people familiar with assembly, Shl and Shr might seem more natural. But given that VB has never had them, what to choose? Even looking at the issue of “word vs character” doesn’t help here, because even though we do have a tradition of using words for operators (“Mod”), we also have a tradition of using obscure characters for operators, too (“^”). In the end, my view was that the fact that << and >> visually encoded some indication of their function made them slightly preferable over Shl and Shr, which seemed a bit cryptic to my eyes.
My view eventually prevailed, by the way, because everybody else who disagreed with me left the team in the interim. Victory by attrition. But that just emphasizes the personal nature of the choice. In the end, I think it’s more of an artistic decision than a technical decision – less “how strong does this beam need to be to hold this ceiling up?” and more “what color should we paint the bedroom?”
Which doesn’t mean that we don’t agonize endlessly over what the right syntax is for something. The generics syntax is an excellent example of this, and deserves an entry of it’s own in the near future.
I guess the main reason why I dislike the bitshifting syntax is because I’ve got the wrong kind of experience with C++. I’m used to thinking of << and >> as the stream operators. Intellectually, I understand that the << and >> syntax for streams is just some weird operator overloading in the C++ iostream library, and bit shifting is what the operators are "really" for. But I certainly used << and >> for streams a lot more than I did for bit shifts.
Very interesting, though given the majority of the target audience of VB.NET, the operation itself is probably more cryptic than its syntax.
How would someone using VB.NET shift bits before the shift operators (are/were) introduced? A math library method? C#?
Pingback: .NET From India
I honnestly always thought the process might be more…uhmm..scientific. I guess my vision of microsoft is a little off. I kinda thought this kinda stuff would be left to some fancy Microsoft-resident Ph.D psychologist.
For the same reason _most_ programmers can’t write good documentation, I would imagine most can’t write visually nice or easy to use languages. I always thought Perl, PHP, STL, and other convoluted stuff like those were always the result of a programmer stepping outside his or her area of exepertise.
Then again, maybe a language designed by a linguist or psychologist wouldn’t be all that good..too early right now…too stupid 🙂
What’s interesting is that APIs have a definite area of expertise and often get reviewed as you mention, Karl. You can look at http://blogs.msdn.com/stevencl for interesting information on the psychology of API development.
I wanted to pass on a good idea:
Roland Weigelt (‘Born to Code’) makes a suggestion on his blog that you might like:
He recommends that when you go to implement an interface in VS.net, it not only copies the functional prototypes in for you (which is brilliant, by the way) it also copies in the XML comments from the interface.
thanks Paul — keep up the blogging! yours is one of the best.
Paul, some of the new keywords in VB.NET are indeed kinda long, but I think you and your team chose them well..sure they can be a pain to type, but their clarity and ability to directly convey their semantics, far outweights the cost of extra keystrokes (which by the way could be alleviated if you extend Intellisense further, like you do for Exit Sub/For/Try etc).
Since keywords are just like identifiers (but reserved to mean something special), picking a good one is akin to the task of picking a good identifier.
Personally, I follow what i humorously call The Principle of Least Mumble-Jumble (LMJ). It basically means that a good identifier is one the purpose of which can be described using a single sentence. To achieve this, the identifier is usually the abbreviated form of that single sentence.
*NotInheritable – indicates a class is not inheritable to other classes.
*NotOverridable – indicates a procedure is not overridable by other procedures.
*Implements – indicates that a class implements the specified interface.
*Inherits – indicates that a class inherits from the specified base class.
*DirectCast – directly casts the given value to the given type without attempting any conversions.
It seems you and your team follow the LMJ principle too :-)..its what makes VB such a joy to use and learn and you guys have done a great job 🙂
The only keyword I really dislike is DirectCast – not only is it long, but it doesn’t work well with the 10 finger typing system (Dire-c-t-c-ast makes hopping your left hand up and down the keyboard). And I use this keyword dozens of time a day – a lot of jumping around for my left hand!
I look with envy at the C# guys which just type open-and-close parenthesis to get the same result…