letters to the editor
DOI: 10.1145/2133806.2133808
the Beauty of Simplicity
As an admirer of the “artis- tic flare, nuanced style, and technical prowess that separates good code from great code” explored
by Robert Green and Henry Ledgard
in their article “Coding Guidelines:
Finding the Art in the Science” (Dec.
2011), I was disappointed by the authors’ emphasis on “alignment, naming, use of white space, use of context,
syntax highlighting, and IDE choice.”
As effective as these aspects of beautiful code may be, they are at best only
skin deep.
Beauty may indeed be in the eye of
the beholder, but there is a more compelling beauty in the deeper semantic properties of code than layout and
naming. I also include judicious use
of abstraction, deftly balancing precision and generality; elegant structuring of class hierarchies, carefully trading between breadth and depth; artful
ordering of parameter lists, neatly supporting common cases of partial application; and efficient reuse of library
code, leveraging existing definitions
with minimum effort. These are subjective characteristics, beyond the
reach of objective scientific analysis—
matters of taste not of fact—so represent aspects of the art rather than the
science of software.
Formalizing such semantic properties is more difficult than establishing
uniform coding conventions; we programmers spend our professional lifetimes honing our writing skills, not unlike novelists and journalists. Indeed,
the great American essayist Ralph
Waldo Emerson (1803–1882) anticipated the art in the science of software
like this: “We ascribe beauty to that
which is simple; which has no superfluous parts; which exactly answers its
end; which stands related to all things;
which is the mean of many extremes.”
It is to this standard I aspire.
Jeremy Gibbons, oxford, u.K.
Since programs are meant to be read,
they should also be spell-checked, with
each name parsed into separate words
that are checked against a dictionary,
and common shortenings and abbreviations (such as “num” for “number”
and “EL” for “estimated lifetime”) included in the dictionary to help standardize ways of expressing names and
making programs more readable.
The exception to this spelling rule,
as suggested in the article, is the locality of reference, such that index variables like “I” do not have to be spelled
out when used locally within a loop.
However, newer program constructs
(such as for _ each) would mostly
eliminate the need for such variables.
Meanwhile, parameter names should
have fuller names, so their intent
could be determined by reading the
header without also having to refer to
the implementation.
Moreover, the code in the article’s
Figure 13 (an example of the kind of
code covered in the article) could have
been broken into multiple routines at
the points each comment was inserted. This would have separated the flow
from the details and made the code
easier to understand. This way, each
of the smaller functions would have
been simpler to test, with testability a
proven indicator of code quality.
Ken Pugh, durham, nC
I fully agree with Kamp that the
decision, conscience or not, was a
mistake, and ultimately a very costly
one. In my own C programming in the
1970s I found it a frequent source of
frustration but believe I understand its
motivation: C was designed with the
PDP- 11 instruction set very much in
mind. The celebrated C one-liner
while (*s++ = *t++) ;
copies the string at s to the string at
t. Elegant indeed! But what may have
been lost in the fog of time is the fact
that it compiles into a loop of just two
PDP- 11 instructions, where register R0
contains the location of s and register
R1 contains the location of t:
A mov (@R0)++,(@R1)++
bne A test result for nonzero and
branch
Still Paying for a c mistake
In “The Most Expensive One-Byte
Mistake” (Sept. 2011), Poul-Henning
Kamp addressed the decision taken
by “the dynamic trio” Ken Thompson, Dennis Ritchie, and Brian Ker-nighan when they designed C to
represent strings as null-terminated
rather than measure them through
a preceding length count. Kamp said
he found no record of such a decision
and no proof it was even a conscious
decision in the first place. However,
he did speculate it might have been
motivated by a desire to conserve
memory at a time when memory was
an expensive resource.
Such concise code was seductive and,
as I recall, mentioned often in discussions of C. A preceding length count
would have required at least three instructions.
But even at this level of coding,
the economy of the code for moving a string was purchased for a high
price: having to search for the terminating null in order to determine the
length of a string; that price was also
paid when concatenating strings. The
security issues resulting from potential buffer overruns could hardly have
been anticipated at the time, but,
even then, such computational costs
were apparent.
“X-Rays will prove to be a hoax”:
Lord Kelvin, 1883. Even the most
brilliant scientists sometimes get it
wrong.
Paul W. abrahams, deerfield, Ma
Along with the solid rules of programming laid out by Robert Green and
Henry Ledgard (Dec. 2011), I add:
Beware this fatal instruction?
Regarding the article “Postmortem
Debugging in Dynamic Environments” by David Pacheco (Dec. 2011),
I have a question regarding the broken code example in the section on