During the fantastic Monad session at PDC 2005*, Jeffrey Snover and Jim Truher illustrated the tradeoff between verbosity and conciseness:
cp c:\apples c:\oranges -fo -r
copy-item c:\apples c:\oranges -force -recurse
Monad has a ton of aliases for common commands (eg, echo is the same as write-object), and it's smart enough to disambiguate parameters if you type enough characters. You get to choose: do I want to be verbose, or do I want to be concise?
Even UNIX tools, which aren't exactly known for their user friendliness, typically offer both verbose and concise options. Consider the excellent wget utility as an example. What the heck does this mean:
wget -m -k -K -E http://www.gnu.org/ -o /home/me/weeklog
Who knows? It could be doing anything. But if we disambiguate with the verbose parameters...
wget --mirror --convert-links --backup-converted
--html-extension -o /home/me/weeklog
http://www.gnu.org/
Suddenly it's quite plain what is happening.
People say VB.NET is too verbose like that's a bad thing. Is English too verbose? Would this post be easier to read in a court reporter's shorthand? Would it be easier to read if I dropped the vowels and the stopwords?
Compare this elegant, concise C# code..
}
}
}
.. to its VB.NET equivalent:
End Select
End If
End If
VB.NET has its problems, to be sure, but verbosity isn't one of them. Saving keystrokes while writing code is a fool's economy. Isn't that why we have these fancy IDEs? As Steve McConnell notes in Write Programs for People First, Computers Second, optimizing for conciseness is a poor tradeoff. Most code is written only once, but read dozens of times:
The computer doesn't care whether your code is readable. It's better at reading binary machine instructions than it is at reading high-level language statements. You write readable code because it helps other people to read your code.Readable code doesn't take any longer to write than confusing code does, at least not in the long run. It's easier to be sure your code works if you easily read what you wrote. That should be a sufficent reason to write readable code. But code is also read during reviews. It's read when you or someone else fixes an error. It's read when the code is modified. It's read when someone tries to use part of your code in a similar program.
Making code readable is not an optional part of the development process, and favoring write-time convenience over read-time convenience is a false economy. You should go to the effort of writing good code, which you can do once, rather than the effort of reading bad code, which you'd have to do again and again.
The idea of writing unreadable code because you're the only person working on a project sets a dangerous precedent. Your mother used to say, "What if your face froze in that expression?" And your dad used to say, "You play how you practice." Habits affect all your work; you can't turn them on and off at will, so be sure that what you're doing is something that you want to become a habit. A professional programmer writes readable code, period.
Even if you think you're the only one who will read your code, in the real world chances are good that someone else will need to modify your code. One study found that 10 generations of maintenance programmers work on an average program before it gets rewritten (Thomas 1984). Maintenance programmers spend 50 to 60 percent of their time trying to understand the code they have to maintain, and they appreciate the time you put into documenting it (Parikh and Zvegintzov 1983).
The ethic Steve is promoting here isn't specific to any language, of course. But it certainly does skew the results in favor of verbosity-- if it's available.
* Which were evidently rated #3 right after Anders' two talks, so if you didn't go, you missed a great session!
So how do your ideas relate to Paul Graham's?
a href="http://www.paulgraham.com/power.html"http://www.paulgraham.com/power.html/a
:)
Kartik Agaram on September 24, 2005 2:54 AMEh, I don't buy that. As far as I'm concerned the most readable code is the _shortest_ code that clearly conveys the intended meaning. Reading lots of text is itself an effort that inherently degrades readability.
Sure, reporter shorthand isn't more readable than plain English. But what about elaborate Victorian style, laden with adjectives and parentheses?
Or a code example: compare "2 + 2 = 4" to "Equals(Plus(Two, Two), Four)". The second is more verbose, ergo it's more readable, right? Didn't think so... the symbols in the first example are both clear and concise, which is the optimum case.
Chris Nahr on September 24, 2005 3:31 AM"Even if you think you're the only one who will read your code"
Looking at code you wrote more than two weeks ago is like looking at code you are seeing for the first time.
— Alzheimer's Law of Programming
mike on September 24, 2005 4:47 AMKatrik, the way I read Graham's essay, he does not consider the difference between "}" and "End Function" a measure of conciseness:
"I think a better measure of the size of a program would be the number of elements, where an element is anything that would be a distinct node if you drew a tree representing the source code."
Furthermore:
"Ultimately, I think you have to go with your gut. What does it feel like to program in the language? I think the way to find (or design) the best language is to become hypersensitive to how well a language lets you think, then choose/design the language that feels best. If some language feature is awkward or restricting, don't worry, you'll know about it.
Such hypersensitivity will come at a cost. You'll find that you can't stand programming in clumsy languages. [...] someone used to dynamic typing finds it unbearably restrictive to have to go back to programming in a language where you have to declare the type of every variable, and can't make a list of objects of different types."
In fact, I have a hard time getting from the essay where exactly his complaints about Basic lie. In the first quote, he's basically (ha) saying that the use of syntactic sugar should not be counted toward the measure of verbosity. Yet he freely says that Basic is verbose. On what basis, then, if a) the number of elements is the same between, say, VB and C#, and b) if (second quote) VB permits dynamic typing, therefore reducing the verbosity of explicit declarations? Perhaps I'm missing something. That happens a lot, actually.
Chris, interestingly you're showing Basic-like syntax (algebraic) vs. Lisp-like syntax (nested functions), speaking broadly. Yet Basic is considered the more verbose language. Not here, though. So is Basic better than Lisp?
In C-like languages, the tertiary operator is definitely more succinct than the equivalent if() block. It compiles down to the same object code. Is it better? Does it make programming easier a) for the original programmer and b) for those who must maintain the code later?
mike on September 24, 2005 5:03 AMNo one seems to be buying anything!
:-)
mike on September 24, 2005 6:45 AM"I think you mean the "ternary" operator (eg, IIf() in vb)"
Dunno, Jeff -- the following is from MSDN (http://msdn2.microsoft.com/en-us/library/ms173145]):
"In C#, an operator is a term or a symbol that takes one or more expressions, called operands, as input and returns a value. Operators that take one operand, such as the increment operator (++) or new, are called unary operators. Operators that take two operands, such as arithmetic operators (+,-,*,/) are called binary operators. One operator, the conditional operator (?:), takes three operands and is the sole tertiary operator in C#."
mike on September 24, 2005 6:49 AMuses 'end' for everything and it isn't at all confusing.
Hear, hear. The compiler can certainly sort these things out, so why the extra terms?
(Sorry to clog up your comments, Jeff.)
mike on September 24, 2005 6:55 AMReading lots of text is itself an effort that inherently degrades readability
Then it must be really hard to read, you know, English. I don't buy this. At all. We read so much text every day! Our brains are highly optimized for this task.
You're really talking about *unnecessary* code, which I agree is a bad thing. But it has nothing to do with my point about verbosity-- "}" vs "End If".
the tertiary operator is definitely more succinct than the equivalent if() block
I think you mean the "ternary" operator (eg, IIf() in vb), but I agree. I hate it in both languages. It's a perfect example of trading off an utterly meaningless one time write-time savings against dozens of read-time comprehension penalties-- It Makes Me Think.
It's just a bad deal no matter how you slice it.
Jeff Atwood on September 24, 2005 7:07 AMSo how do your ideas relate to Paul Graham's?
Paul's point is that high level dynamically typed languages (Perl, Lisp, Ruby, etc) can do more in fewer lines of code compared to your traditional static, strongly typed languages like C#, Java, etc.
It's really a different point than mine. I'm saying we should use plain, simple English instead of geek-speak when defining language keywords. Failing that, at least give us the option to be verbose or succinct as we please, as shown in my command line options examples.
On the other hand, .NET seems to be evolving towards dynamic languages at a fairly rapid rate, and that's a good thing!
C# 3.0, VB 9, and D/X/LINQ, the language features being added to .NET are influenced *heavily* by dynamic languages, eg:
http://www.interact-sw.co.uk/iangblog/2005/09/23/varisntobject
Jeff Atwood on September 24, 2005 7:18 AMThe compiler can certainly sort these things out, so why the extra terms?
Because our brains aren't compilers? Of course, there is a point of diminishing returns on both sides, but it's always better to err on the side of verbosity when possible.
Dunno, Jeff -- the following is from MSDN (
I can find tons of references to "ternary operator" in google.
http://discuss.fogcreek.com/joelonsoftware/default.asp?cmd=showixPost=142517
To be fair, there are 2x as many google hits for "tertiary operator" (521k vs 260k) so I'm not sure which one is correct.
At any rate, they're a prime example of the false economy of trading write-time conciseness compared to readability, so whatever they're called, we can agree on that ;)
Jeff Atwood on September 24, 2005 9:51 AMIn all fairness, your C vs VB example is quite contrived since it is taken completely out of context and not indented at all.
if (true = isVBVerbose())
{
Console.WriteLine("Carpal Tunnel hurts.");
}
else
{
Console.WriteLine("Rubbish.");
}
If (true = isVBVerbose())
Console.WriteLine("Carpal Tunnel hurts.")
Else
Console.WriteLine("Rubbish.")
End If
There is a comparison that is more fair. In any case, if verbosity is great, perhaps the VB team should have called 'Else' 'Otherwise' since it reads more like English. I just don't buy it. Interestingly, Ruby (can any language conversation nowadays omit a Ruby reference?) uses 'end' for everything and it isn't at all confusing. It eliminates the need for the End If End While End Function etc. To me, this is a great middle ground.
Christian Romney on September 24, 2005 10:47 AMAll this talk of language affordances makes me think of Ken Arnold's post, Style is Substance:
a href="http://www.artima.com/weblogs/viewpost.jsp?thread=74230"http://www.artima.com/weblogs/viewpost.jsp?thread=74230/a
He takes Python's use of whitespace defining block structure to a logical (perhaps absurd) extension.
To join in the fun I'd add to his list, making the use of uppercase characters in an identifier, and the tab character outside a literal, lexical errors. The formatting differences used to write code tend to be larger barriers to readability then the syntax of the langauge. VB is largely readable because much of the style is enforced by the language rules, rather than simply because it uses tokens with more characters. Also I imagine few VB users use vi, vim, emacs, edlin, etc. making editor consistency another big plus.
One other random point, I always wondered what Python did about tab vs spaces, and finally I looked in wikipedia and found out. They did nothing! a href="http://en.wikipedia.org/wiki/Python_programming_language"http://en.wikipedia.org/wiki/Python_programming_language/a
"The whitespace thing has minor disadvantages. Both space characters and tab characters are currently accepted as forms of indentation. Since they are not visually distinguishable (in many tools), mixing spaces and tabs can create bugs that are particularly difficult to find (a perennial suggestion among Python users has been removing tabs as block markers—except, of course, among those Python users who propound removing spaces instead)."
To my mind that erases the goodness created by the design choice to make whitespace matter. You can write obfuscated Python by mixing tabs and spaces. Doh!
(Yes despite the evidence to the contrary, in my head, these are on topic. :-)
Steve Steiner on September 24, 2005 12:41 PMAdequate programming is whatever consistently works for you.
If writing nearly-unreadable code works for you because you want to save a keystroke here and there, fine then, you go do your thing...
...Elsewhere.
I won't work with you. None of the people on my team will.
Documentation is the most important part of a program. Developer time is more valuable than any other resource.
So, if we can't tell at a glance what someone else's program does, or we can't tell exactly what a program written a year or two ago does, then it's useless to us. We do not have the time or the inclination to study programs again and again to rediscover their tasks.
Once compiled, the programs'll be plenty small and fast.
UNTIL they are compiled, the source code is intended for HUMANS to read. And it had better do a damned good job at that or we'll throw it out and replace it (and the developer that wrote it!)
Eric K. on September 26, 2005 11:41 AMThanks for the clarification, Todd.
That's a Mortal Kombat style coding fatality! So Mike, consider your virtua spine ripped out.
Here's a write up of verbosity taken way too far:
http://daringfireball.net/2005/09/englishlikeness_monster
"ternary" means "comprised of three parts", "tertiary" means "the third in a series". Besides, KR call it the "ternary operator".
I think the reference in the MSDN docs is a goof especially directly after they use "unary" and "binary". How about utiary and bitiary? =)
As for the Google results, try putting those terms in quotes and you get 68,100 versus 593, which seems more reasonable.
Entering "tertiary operator" into Wikipedia brings one to "Ternary Operator" which explains the root "arity" and mentions "tertiary" as an inaccurate usage.
I have always liked the iif() function since I first encountered it in dBase III+, but I think that in code as in prose, readability is a balance between brevity and verbosity each in its right place. Sometimes the latter comes after the comment symbol.
Excellent:
--
But saying what you mean, in English, almost never “just works” and compiles successfully as AppleScript, and so to be productive you still have to understand all of the ways that AppleScript actually works. But this is difficult, because the language syntax is optimized for English-likeness, rather than being optimized for making it clear just what the fuck is actually going on.
--
Unambiguous, descriptive keywords (eg, not {) is one thing, but I don't think I'd ever advocate making a language out of English sentence structures.
We definitely want to "optimize for making it clear just what the fuck is actually going on" ;)
Jeff Atwood on September 27, 2005 1:55 PM"Sure, reporter shorthand isn't more readable than plain English. But what about elaborate Victorian style, laden with adjectives and parentheses?"
While taking the point, it could also be noted that Victorian prose contains more detail and shades of meaning than modern styles.
It concerns me a bit that I find it harder to read Darwin than Sagan, because the implication is that people in Darwin's time had no trouble understanding him, which means I'm not as literate as they were.
Paul Coddington on October 4, 2005 1:14 PMVB hurts my eyes to read.
C syntax is simple and elegant.
I really don't see where you feel that VB gains ANYTHING by substituting END X in for braces.
MS is putting all of its money on C#, not on VB.
C# uses similar syntax, in this respect, to C, not to VB.
Justin on December 18, 2005 7:20 AMI may be in the minority, but I love ?: and use it constantly in Java. It's perfect for null-checking, like so:
return (name==null?"%":name);
return (active==null?"0":active);
Ruby also has an operator exclusively for "assign only if variable is nil":
active ||= "0"
In my mind this is infinitely better than writing if/else's everwhere, but as Eric pointed out above, whatever works for you and your team is best.
So, I came across this article because I am trying to come up with support for putting the smack down on one of my coders and getting him to stop using the ternary operator for everything.
I honestly had no idea that there was even a single coder who thought as I, let alone a group. (though I am a bit miffed that my "source is for humans, not machines" philosophy is not as original as I once thought)
Like pretty much anything in the universe, the issue comes down to approriate usage. The ternary operator is perfect for things like:
String myWords = "You have " + cntItems + cntItems 0 ? "item" : "items" + "in your shopping cart."
(or the return statements above, THAT is what I call elegant code, as opposed to "how much disconnected crap can I jam on a single 399 column line??")
It is HORRENDOUS when there are 13 different things, several constructors, a method call or two, a cast and a kitchen sink all sandwiched in a ?:
Again, source is for humnas. Too often, it is used by humans to attept to display how crazy mad cool they are and as a result comes out being utterly useless.
Thanks for the great conversation.
J. on April 4, 2007 1:47 PMLet's be honest- VB is for BASIC coders and C# is for C++/Java coders, it's that simple. I coded for years in C/C++ and Java so C# is my choice when I'm in the MS env.
Chris Henry on November 20, 2007 12:50 PMI think this a real strawman argument. I'm moving from VBA (visual basic for applications) to VB.Net, and I find the verbosity somewhat appauling. I'm fine with "End If" and "End Select"--these add some readability. From my old days in C, I'm also fine with "}"--concision cumulatively saves much time and (eye) space without losing much; more elegant.
The problem I DO have is more with the whole new generation of verbosity--all of .NET, and others--as a result of classing everything, and burying every last function in some deep tree, and recasting the most basic functions into object orientation. I understand that thinking in terms of objects brings a certain fluidity of use between libraries. But I find it really disturbing that the most basic needs (e.g. string handling) have been converted to OO; it seems unnaturally rigid; verbose; a typing tax and a reading tax; and most of all, mental convolution.
I wrote a brief blog post on this topic here: http://www.cooltechblog.com/?p=51
I suppose I'll get over it, but it makes working in VB.Net seem a lot more work than something before all the classism (e.g. VB, VBA). There must be a better way...
Greg on January 31, 2008 4:30 AM and burying every last function in some deep tree,
and recasting the most basic functions into object orientation
Oh, I always want to scream in horror when I have to write those int-to-short casts (among others). I understand the technical side (and I even agree), but hey... tons of casts make the code really unreadable.
Rodrigo on February 12, 2008 7:44 AMThere are a couple things stopping me from switching to C#, the major obstacle being that I use KNF style intention, yet C# forces me to use Allman style. I could just disable the auto-complete and get around it, but then why should I even use the IDE at all and just edit my code in vim or something instead?
My other main argument is that C# does not allow for integer expansion. Preventing a cast from Button to XmlNode is one thing, but when I can't do something like:
int16 plus_six(int16 n){
return n + 6;
}
int32 five_plus_six = plus_six(5);
When it works in Visual Basic?
Miff on February 13, 2008 12:16 PMGod what a load of crap. C# vs VB.Net is an old, tired and ultimately pointless argument. It all boils down to developer familiarity/preference, although I would recommend a new starter use C# as the syntax is closer to other modern languages. They both compile down to virtually identical IL and can accomplish the same tasks (aside from VB being unable to make use of pointers). I use both interchangably without problems, although given the option I will use C# since I am more productive with it and find it easier to scan through when I come back to old code. Yes, I DO like the ternary operator - this is one case where I find VB a pain since IIf does NOT accomplish the same thing (as some people mistakenly think). Consider:
C#
--
public string GetDBText(Nullableint value)prefer
{
return value.HasValue ? value.Value.ToString("0") : "NULL"
}
VB.Net
------
Public Function GetDBText(ByVal value As Nullable(Of Integer)) As String
Return IIf(value.HasValue, value.Value.ToString("0"), "NULL")
End Function
Aside from the fact that *personally* I find the C# variant to be much easier to read, the VB.Net function will generate a runtime exception whenever the HasValue property of the supplied value is False, because IIf is a function and therefore evaluates every argument passed to it. But as this can be worked around, it isn't a problem unless such a statement has been added by a coder who is ignorant of the consequences.
All the rest of you spouting "VB.Net does this but C# won't let me" and vice versa should perhaps realize that since the languages are not the same you therefore cannot expect identical behaviour. Read a book and learn the language before you dismiss it, otherwise your opinion is uninformed and therefore of no true value.
ShitsNGiggles on June 10, 2008 1:59 PMC# vs VB.Net is an old, tired and ultimately pointless argument.
To be fair, this was posted in 2005!
Adam on June 20, 2008 3:29 AMWait a minute, so how does this apply to the _var_ keyword (http://www.codinghorror.com/blog/archives/001136.html)?
What a difference 2.5 years seems to make, eh? How long until verbosity is back in style?
Nick on June 25, 2008 2:37 AMPersonally I find C style syntax a little easier to read because it makes it easier to skip the chaff.
Basically since we generally associate blocks with tabbing amount, the End/} endings are basically overkill. Not to say I think they should be removed, Python has a good idea with making whitespace matter, but there is just something about making an invisible entity syntactically important that doesn't sit well with me.
So it comes down to which one is easier to filter out, I would say }, since End X always makes me read the line to figure out what is going on, while } I mentally block out (Although if I am thinking there is a mistake it is easy to figure everything out via Ctrl + ])
Either way it really comes down to taste. Do you like the verbosity of saying explicitly what is going on, or the simplicity of saying the minimum required to get the point across. Speed of coding has always been a BS argument anyways. Even a slow typist would only take a second to type End Select, without the IDE's help, and that is cake compared to the amount of timing writing the contents of the clause, not to mention planning etc.
When I read code, I'm not reading English. There's a reason code is normally in monospace and English usually has a less fixed width. I can't stand operators that are spelt out, because that screws up my mental parsing of what's an operator and what's not. Math is also a language, and you'll find English is clumsy when it comes to conveying the elegance of a concise mathematical statement
G on July 13, 2008 1:31 PMIMHO, saving keystrokes is important.
Verbosity takes valuable screen space, and may force more scrolling than necessary.
In fact, when cleaning up code, I sometimes make it less descriptive voluntarily. This is to avoid wasting space on routine operations and keep the focus on what is important
>At any rate, they're a prime example of the false economy of trading write-time conciseness compared to readability, so whatever they're called, we can agree on that ;)
Actually, I disagree. If statements and the ternary operator don't do the same thing. The ternary operator actually returns a value.
So:
string value = item != null ? item : "[Empty]";
Versus:
string value = "[Empty]";
if(item != null)
{
value = item;
}
Great post--as always. Since I know how much you do care about the quality of your posts though, I believe there's a broken link at "dropped the vowels and the stopwords." Just wanted to let you know : )
Cameron B on February 6, 2010 9:46 PMThe comments to this entry are closed.
|
|
Traffic Stats |