One-letter method names, good design?
Friday, November 20th, 2009
Sometime short one-letter names are to be preferred as method names.
Don’t get me wrong. Naming conventions are one of the most important achievements of programming culture in the recent decade. No doubt, generalMatrixMultiplication is more readable than dgemm, but sometimes a simple p just beats the hell out of clumsy System.out.println and friends.
Akira Tanaka refers to this as the “Huffman coding” of API design.
The library design also utilize the usage frequency. For
example, Ruby definespmethod which is usable anywhere.
It prints arguments for debugging purpose which is easy to
understand for programmers. The method namepis inconsistent
with other methods because it is too short in the sense
of Ruby naming convention. It is intentional because debug
printings are very common. In general, too short names are
incomprehensible and tends to conflict. Butphas no such
problem because almost all Ruby programmers knows it.This kind of naming convention, assigning short names
for features frequently used, are called “Huffman coding”
which term is borrowed from data compression.
He goes on to provide more example. In particular he proposes an API design life cycle, where method names start with full-length English terms and get shortened as they raise in popularity. There is two ways to shorten method names, either down to a single letter, or even more powerful, to pick an operator as its name.
I’ll gonna apply the same to Smalltalk now. For the full story of Ruby’s core API design, please refer to Akira Tanaka’s recent paper “Language and Library API Design for Usability of Ruby” from the PLATEAU workshop at this year’s OOPSLA.
First we define p as follows
Object >> p
Transcript show: self; cr.
^self
the implementation is taken from Travis Griggs’s Out package. Now we can insert a print statement wherever we need debug output.
Printing is not the pinnacle of debugging, so let’s do the same with breakpoints
Object >> h
self halt
If you are using Pharo, add h to the methods listed in OBInheritanceFilter >> icon:forNode: to make sure our new breakpoint command is marked with a red flag in the class browser.
Next let’s rename OrderedCollection to List
Smalltalk at: #List put: OrderedCollection.
And introduce the << operator for addition
OrderedCollection >> << element
self add: element.
^self
which allows us to write concise code such as
List new << 'Lorem' << 'ipsum' << 'dolor
Next is string concatenation. Such a basic feature that many languages include string interpolation at their very core. Alas, Smalltalk is a bit dated to that regard (at least unless Pharo includes Lukas’s awesome Helvetia one day) and we are left with String >> #expandMacrosWithArguments:, which shall be Huffman encoded to
String >> e: argument
^self expandMacrosWith: argument
String >> e: first e: second
^self expandMacrosWith: first with: second
String >> e: first e: second e: third
^self expandMacrosWith: first with: second with: third
String >> e: first e: second e: third e: fourth
^self expandMacrosWith: first with: second with: third with: fourth
And welcome to Phexample’s expectation failure message
'Expected <1p> but got <2p> (using <3s>)' e: value e: expected e: symbol
And eventually, regular expressions. Again such a basic feature that most languages include regex literals at their very core, and again we have to wait for Lukas’s Helvetia until we get the same awesomeness in Pharo. Until then, let’s pirate Groovy’s r syntax
String >> r
^self asRegex
String >> =~ regex
^self matchesRegex: regex
RmMatcher >> asRegex
^self
And, “Hup hup hup, barbatruc”
| regex |
regex := 'a*wesome'r
'Regex are aaaaaaaaaawesome!' =~ regex
Well then
Gofer new
squeaksource: 'akuhn';
addPackage: 'Akuhn-Huffman';
load
Gofer it!