blogstrapping

Programming With Discretion

In Reviews: The Book of (Weird) Ruby, and Eloquent Ruby, I commented on the coding style Huw Collingbourne uses for Ruby in The Book of Ruby. One statement I made was:

I spent about ten minutes thinking about, and refreshing my memory of, idiomatic styles for other languages, with Google as my guide; I was trying to figure out what language might have been the foundation for this author developing the style he uses. I thought maybe he was doing something like writing C++ in Ruby (as an example -- despite the wide range of styles considered "idiomatic" for C++, none of which I am aware exactly fit the bill). I have not yet come up with a language whose idiomatic style could explain this.

There are two discussions on reddit following Reviews. In one of them, user redditornongrata said:

The camelCaseWithoutLeadingCaps convention in The Book of Ruby is a Javaism. The strange indentation and whitespace is just bizarre.

I responded:

I saw a number of different bits of formatting style in that book's sample code that could be blamed on several different languages' idiomatic styles; the Javaism is one of them. I still have no idea of any single language that could account for all, or even most, of them.

Eventually, Huw Collingbourne commented as well, in one case to offer a link to his response to my Reviews: Programming With Style. He admits right away, at the beginning of Style, that he makes an effort to avoid adopting idiomatic style for the language:

So, when I switch from one programming language to another do I change my coding style to fit the language? The answer is: up to a point. Or, to put it another way: as little as possible.

His explanation involved thinly veiled statements that adherence to idiomatic style for a language when programming in that language is essentially slavish attachment to empty traditions. His choice of terms is not quite so blunt, using phrasing like "fiercely devoted to language-specific idioms". He also states that he dislikes underscores in method names for "aesthetic" reasons.

He goes on to explain that, though apparently people often think he gets his programming style from Java, "That is simply not the case. For some insight into my stylistic preferences, however, you may want to take a look at a series of articles I wrote called Ruby The Smalltalk Way."

I suddenly recalled some similarities between his style and that of some Smalltalk code I have seen following a TechRepublic article of mine, Understanding Ruby Blocks, including the camelCaseWithoutLeadingCaps style of labeling. I have, of course, seen more Smalltalk code than that -- but not recently, so it was not the first thing that came to mind.

Even so, Smalltalk does not explain everything about Huw Collingbourne's style. For instance, I have never seen any Smalltalk code formatted quite the way he did at times. Compare this Ruby code from his book:

["hello","good day","how do you do"].each{
    |s|
    caps( s ){ |x| x.capitalize!
        puts( x )
    }
}

. . . with this Smalltalk code from a discussion comment at TR by Mark Miller:

foo := #(1 2 3 4 5 6 7 8 9 10). "1-based array"
vals := #(0 1) asOrderedCollection.
foo do: [:n |
   Transcript
      show: n asString, ': ',
            (vals at: n
                  ifAbsentPut: [(vals at: n - 1) +
                                (vals at: n - 2)]) asString;
      cr]

Note the way Mark Miller did not for some reason orphan the block argument on its own line, did not place one expression or statement on the same line as a block argument and opening delimiter while placing others on their own lines, and tended to line up indentations with placement of associated tokens on preceding lines. The style in Mark Miller's code sample tends to match the idiomatic style of Smalltalk that I have seen in the past fairly well, in addition to matching some conventions that are typically observed across different languages. It is reasonably clear and readable, tailored to the linguistic context of Smalltalk syntax, and maintains conceptual clarity by accounting well for the semantic elements of the language.

Though Smalltalk clearly does not account for all of Huw Collingbourne's quirks in Ruby programming style (one might say it does not account consistently for most of them), I can see that Smalltalk might well have had some influence on his style. The fact he writes a lot of C# might account for some parts of it as well, such as the choice of four-space indents. The weird inconsistencies, however, still seem inexplicable to me.

For those of you who are not very familiar with Ruby code, the above Ruby sample would more idiomatically be formatted thusly:

["hello", "good day", "how do you do"].each do |s|
  caps(s) do |x|
    x.capitalize!
    puts x
  end
end

. . . though most Rubyists would probably rewrite parts of it as well. A quick rewrite to suit my preferences and Ruby idioms might look like this:

['hello', 'good day', 'how do you do'].each do |s|
  caps(s) {|x| puts x.capitalize }
end

We will just ignore for now that, in The Book of Ruby, the definition of the caps method is completely useless and makes it a redundant piece of code that adds nothing but complexity to the task. The implementation of caps was used as an example of how to implement a method that takes a block as an argument, and not as an example of good software design (I hope).

In the end, I do not buy into his argument that his personal biases trump the stylistic idioms adopted by the language's community, for reasons I will touch on a bit more in a moment. Before we get there, though, I think it worth mentioning that even if I did buy his argument, I would certainly not buy his notion of the best-ever code formatting style to try to cram into the context of every language I use. I shudder at the thought of how Scheme would look using his preferred style.

On the subject of why I do not buy his argument, let us consider his objections to employing the idioms of the language as jumping-off points for arguments in favor of Ruby's idiomatic style when coding in Ruby, some of which come from Style and some from the introduction to The Book of Ruby:

Ultimately, I do not begrudge anyone the right or desire to do his or her own thing in the privacy of his or her editor of choice. I believe that programmers' lives can often be made easier by adopting good coding style idioms, but if they for some reason find those idioms limiting, let them do what they wish when it affects only their own circumstances. A problem arises when their choices affect others, however.

First, it is in your own best interest to employ a coding style calculated to maximize the comfort of readers and the clarity and rapid comprehension of the code for readers when you wish to get any kind of input from them. That input might involve code contributions to your open source project or help from a mailing list, for instance.

Second, it is in the best interests of any goals you may have for reuse of your code to employ such a coding style, because given a choice between two codebases -- one of which they find easily readable and another of which uses inconsistent, alien stylistic choices -- the would-be user of your code will generally choose the codebase he or she finds most readily comprehensible.

Third, it is in the best interests of whoever ends up using the software in any case where anyone else will have access to your code, and -- where those users are your customers -- it is again in your own best intersts to use common, effective idioms. That is because readability is an important component of maintainability, and if other programmers are likely to have to maintain your code it needs to be readable to them.

Finally, writing a book intended to be used to introduce new Rubyists to the language should consider the maximum value such a book can provide, and make stylistic choices consistently and with the good of the reader in mind. If you must, make a case for particular deviations from idiomatic style in a limited part of the text; if the deviations are not too great, you can even use them, so long as you make it clear how and why you deviate from the norm. Overall, however, it is for the best to adhere to idiomatic style in any case where an alternate style is not the point of the book. To do otherwise is to do your readers the disservice of indoctrinating them in stylistic conventions that will set them at odds with the rest of the language's community.

. . . and that is really my biggest problem with the code style in The Book of Ruby. I may disagree with Huw Collingbourne's choice of coding style, but do not much care if he uses it for his own private purposes. I just care that he replaces idiomatic style in a book designed to impress good programming practice on new students of the Ruby language. Even that was not the reason I objected to the coding style in my review, though: ultimately, the reason I rated the coding style poorly in the context of that book is that it becomes less readable for me, thus dissuading me from buying it.

I was glad someone else mentioned the un-idiomatic style of the book before I bought it, increasing the likelihood I would give it a critical look for such problems. I figured someone else might benefit from my experience as well.