Do you trust nuclear energy? I know, it’s a complex question — not the kind that easily leads to a “yes” or “no” answer. Let me rephrase it into a possibly less controversial form: do you trust nuclear engineers? Now, the odds are turning, and there’s a good chance Joe or Jane Sixpack would answer in the affirmative, without feeling the need to add qualifications to their answer.

Indeed, for all the negative stereotyping about being boring or uncreative, engineers have a generally solid reputation among the general public of being trustworthy and competent professionals. Well, I mean, traditional engineers have. Those who build bridges, buildings, and power plants. Those are the guys you can trust. Ah, if only software development were a solid engineering discipline in the same league with civil, mechanical, and nuclear engineering! We wouldn’t have to deal with lousy apps or insecure systems anymore! We could enjoy the same level of reliability and safety of, say, nuclear power which, in the immortal words of Homer J. Simpson, “has yet to cause a single proven fatality.”

Seriously, I don’t want to compare apples and oranges, but it is true that software developers may enjoy a generally poorer reputation than other professionals. The latest outcry follows an all too familiar argument: 1. Software is spectacularly unreliable; 2. Traditional engineering delivers highly reliable products; 3. Ergo, software development should adopt engineering practices (or, as the article goes, stop calling itself software engineering).

I will not pick on that particular article, even though it’d be a particularly easy target given its technical shallowness and shaky arguments (how is the dieselgate an indictment of software’s low quality?). Instead I’m interested in the more general issue of what traditional engineering has to teach to software engineering. I also want to avoid going down the line of nominalism — which all too often emerges in debating these kinds of topics — looking for the “essence” of engineering, software development, or the like. That’d be neither useful nor particularly interesting.

First of all, I believe that the gap of reliability between the best software systems and the best artifacts produced by traditional engineering is much smaller than the common opinion would lead us to believe. In fact, the line between the two is blurry, in that some of the most reliable complex software lies at the core of airplanes, cars, or control plants. If the latter are reliable, it is largely because the former is. As another, historical but still very significant, example see Feynman’s report on the Challenger disaster: among the various engineering divisions, the one responsible for avionics software is the only one whose practices pass with flying colors: “the computer software checking system and attitude is of the highest quality.” Of course most software development does not come even close to complying with the standards of quality of avionics software; but neither is the engineering of the majority of traditional consumer products with no mission-critical requirements.

Another feature traditionally ascribed to traditional engineering as opposed to software engineering is a rigorous, systematic approach that does not leave anything to chance. A nuclear engineer, for example, knows exactly what goes on in every stage of development and deployment of a nuclear power plant, and knows how to ensure that no accidents occur. Except this is not exactly true. It turns out that [Mahaffey, 2015] the riskiest activity related to harnessing nuclear power is fuel (re)processing, where fissile fuel is produced by chemical means. The major risk is that some of the fuel becomes critical, that is capable of sustaining a spontaneous chain reaction. Criticality does not only depend on the amount of fuel but also on its geometric configuration. It is practically impossible to predict every possible configuration the fuel may take while being processed, and in fact several accidents occurred due to unexpected accumulation of material in what turned out to be criticality-inducing configurations. This does not mean that the whole enterprise is left to chance, only that perfect planning is unattainable and one must deal flexibly with uncertainties. The best practices are to ensure that the operators are thoroughly trained not only in the procedures but are also fully aware of the general issues that may arise and on the lookout for unpredicted sources of danger. This attitude towards prevention and awareness was first adopted in the fuel processing plants of the Manhattan Project, when a young Feynman (him again) pointed out to his superiors that the excessive secrecy initially imposed, which prevented workers from knowing what exactly they were doing and what risks they could encounter, was counterproductive and foolishly dangerous. Prevention is the best protection, and prevention requires knowledgeable people, not drones.

Which leads us to the other main point: what can software engineering really learn from traditional engineering — and nuclear engineering in particular? It’s not the scientific foundations: informatics provides rock-solid foundations. It’s not so much the institutionalization as a licensed profession: while it may be useful in certain contexts (for example for freelance software developers) it’d have little or no relevance in others. The attitude that software engineering can learn from nuclear engineering is what to in the aftermath of an accident.

When something goes wrong in a nuclear reactor and it gets scrammed, it is imperative that the dynamics of the accident be understood down to minute details. This involves understanding the physics of the reaction, any failure of the equipment against its supposed behavior, how the personnel reacted, what practices were followed up to the time of the accident that may have altered operating conditions or generally increased risks. Based on an exhaustive post mortem, procedures, technologies, equipment, and training are revised. These activities have top priority, and must be completed to satisfaction before operations can restart. The net effect is that the chances of the same kind of problem occurring twice are minimal, and reliability improves by building on an ever growing knowledge base. (Bertrand Meyer made similar remarks about aerospace engineering.)

Two final comments. First, I believe such kind of practices are already in place, in some form at least, in the best software development environments. Besides safety-critical software, where we have several well-known case studies, the practice of large-scale software development includes inspections, regressions, and rigorous analysis. Even Facebook has given up on their “move fast and break things”, and realized the importance of stable infrastructure and rigorous analysis. Second, engineering is ultimately all about trade-offs. If you’re developing a silly app, you may just accept that “mediocre” is good enough. And that what you’re doing is not quite “engineering”.

Reference

  1. James A. Mahaffey: Atomic Accidents: A History of Nuclear Meltdowns and Disasters: From the Ozark Mountains to Fukushima. Pegasus, 2015.

If you’re familiar with computer science, you’re also familiar with the notion of abstraction. Abstraction is ubiquitous in computing. Whereas it belongs to all of science in one way or another, it has a pivotal role in computing where everything abstracts something more concrete and concrete computations are made of abstractions.

If you’re familiar with music, you’re also familiar with the notion of abstraction. Abstraction is ubiquitous in music. Whereas it belongs to all of the arts in one way or another, it has a pivotal role in music where everything abstracts something more concrete and concrete music is made of abstractions.

The similarity between computing and music with respect to abstraction runs deeper. Abstraction is introduced to solve similar problems that originate in a tension between flexibility and stability, generality and concreteness, effectiveness and understandability. In this post, I illustrate the analogy with one concrete example in music and one concrete example in computing. To make sure that the discussion does not become too — ahem — abstract, I recommend you first read the part you’re more familiar with, so that the analogies in describing its counterpart will be easier to follow.

Abstraction in music: the sonata form

A music composer has to reconcile his aspiration of creativity with the listener’s expectation of a structure familiar to her. Ideally, the composer’s be unencumbered, free to express his ideas by whatever musical items he deems appropriate; but such an approach has a high risk of alienating the listener, who may not be able to follow the ideas expressed in music without any structure for orientation. This is why music (like other arts) has developed forms, which are conventions that help achieve trade-offs between constraining the composer and convincing the listener. The sonata form is one of the most popular of such musical forms as proved by its malleability and longevity.

The sonata form is a prescription to organize the structure of a musical piece in a way that is regular but also leaves plenty of room for the outcomes of artistic creativity. A piece in this form consists of three main sequential parts: exposition, development, and recapitulation. Let’s illustrate them on the first movement of Beethoven’s Piano Sonata #9 (Op. 14 No. 1); you can listen to it played by Claudio Arrau in this YouTube video (I’ll link to specific segments as I introduce the sonata’s parts) and follow the music on one of these scores in the public domain.

The exposition (bars 1–60) introduces a number of themes (or subjects), which are melodies expressing the ground content of the whole piece. By opening with a presentation of unadulterated themes, the composer offers a convenient entry point to the listener: by becoming familiar with the primary ingredients of the sonata, she becomes capable of following the composer’s creation into unexpected territory without losing a general sense of direction. Beethoven’s sonata introduces three themes: the first theme (bars 1–21) begins with a first melodic line in the tonic (E major), which is then varied to construct a modulation into the dominant (B major); the second theme (bars 22–38) takes over in this key with a cantabile character, contrasted by the ensuing third theme (bars 39–56) which is more rhythmic in nature. A codetta (bars 57–60) takes up the last bars of the exposition and connects the third theme to a repetition of the exposition and then, after the repetition, to the second main sonata part: the development.

The development (bars 61–90) is a sonata’s central part, where the composer has substantial freedom to explore his ideas without major structural constraints. By varying and recombining the thematic material previously presented, he can lay out a compelling and imaginative musical argument while building atop the foundations laid in the exposition. The development in Beethoven’s sonata is fairly short, but it manages to explore some interesting fluid tonal contrasts between major and minor keys, and to expand the scant material of the codetta in a more dignified context (from bar 83).

The development is followed by the third sonata part: the recapitulation (bars 91–147). As the name suggests, the recapitulation is a concluding summary where the by-now familiar themes make their last appearance. The composer still has room for expressing his creative ideas in the recapitulation, as themes often change attributes such as presentation order, key, rhythm, and other melodic or harmonic details. Beethoven, for example, ventures into a minor key while transitioning from the first to the second theme in the recapitulation, and introduces other ingenious surprises that reward the attentive listener. The movement closes with a coda (from bar 148), which expands the material of the exposition’s codetta while restoring the awaited tonic key for an irenic conclusion.

The imperfectly symmetric exposition and recapitulation constitute an interface between the deep concrete musical ideas stirring in the composer’s mind and the ears and brains of the listener, who can so appropriate, in a generalized form, some of those ideas and enjoy them.

Abstraction in computing: the modular routine

A computer programmer has to reconcile her creative aspiration of producing an efficient implementation with the user’s expectation of an interface easy to understand and exporting predictable behavior. Ideally, the programmer’s be free to resort to any technical means she deems appropriate to build an implementation that is fast, uses little memory, or is idiomatic in the chosen programming language; but too much freedom has a high risk of producing a program that is hard to use because its exact requirements and guarantees are arduous to fathom. This is why computing (like other scientific and engineering disciplines) has developed techniques for modularization, which are approaches that discipline how program code is structured in such a way that the effects of modular components can be understood in isolation as well as in combination. The modular routine is one of the most popular elements of modular design as proved by its ubiquity across programming languages.

The modular routine combines a piece of code (the body or implementation) with a well-defined interface. The interface consists of a signature, a precondition, and a postcondition. Let’s illustrate these parts on the algorithm for binary search in sorted arrays; here’s an implementation taken from Tim Bray’s, which I adapted to pseudo-Eiffel and annotated with a suitable complete functional specification.

The program text begins (line 1) with the signature, which declares the data the routine operates on. The input data consists of the integer array a, which includes a.count elements from a[0] to a[a.count - 1], and of the integer scalar target, whose value is searched among a‘s elements. The output data is also an integer scalar, referred to as Result in the rest of search_binary.

Routine search_binary works correctly under certain assumptions about properties of the input data passed to it by callers. These assumptions are encoded as the precondition (lines 2–4) which includes two clauses. First, a must refer to a valid array object (line 3). Second, a‘s content must be sorted in nondecreasing order (line 4). The second precondition clause is specific to binary search, whose algorithm leads meaningless results if applied to sequences that are not ordered.

The body (lines 5–27) is a routine’s central part, where the programmer has substantial freedom to work out a suitable implementation without major restrictions beyond those given by the programming language’s features. The body of search_binary begins with a declaration of three integer local variables (line 6), which will be used to keep track of intermediate states in the computation. A loop occupies the major part of the body and does the heavy lifting of searching for the target. As we understand from the loop invariant (lines 10–13), the interval that goes from low to high (excluded) marks, at any point during the computation, the range of values in a that have not been searched for yet. Conversely, the elements at indexes from 0 to low are not greater than target; and the elements at indexes from high to a.count - 1 are greater than it. The body of search_binary exits the loop only when the whole array a has been searched. At that point, the final conditional (lines 23–27) can conclude whether a value equal to target exists at all in a: if low is still -1 or points to an element not equal to — and hence less than because of the invariant — target, the routine returns the invalid index -1 to denote “element not found”; otherwise, a[low] is a valid array element equal to target, and the routine returns its index. The choice of decoupling searching from determining whether target is in the array is an example of the programmer’s freedom to design an implementation that achieves specific, advantageous trade-offs. Bray points out why this approach is preferable to performing two tests in the loop (one for less than, and one for equal to) in the hope of exiting the loop earlier if target is found: in a search where the search interval shrinks exponentially, “nearly all” values are found in the last iteration; hence minimizing the operations per iteration is the most efficient solution. Other programmers, given different constraints, may however follow other approaches; for example, Joshua Bloch’s implementation of binary search in Java’s OpenJDK uses a loop with three-way comparison.

Understanding all these details of the implementation would be burdensome to users who just want to call search_binary to avail of its functionality. This is why the body is followed by the last routine part: the postcondition (lines 28–31), which summarizes the routine’s output in relation to the value of the input arguments. The postcondition of search_binary includes three clauses, defining the output whether the value searched for has been found or not. If Result denotes a valid index of a (line 29), then it points to an element with value target; otherwise Result is -1 (line 30), and hence a has no such element. The last postcondition clause (line 31) specifies that these are the only possible values Result may take; that is, the postcondition is complete. The functional postcondition nicely abstracts not only the details of the specific implementation of binary search, but even the fact that a binary search algorithm has been executed. Any search routine, be it binary, sequential, or following any other technique, could export the same postcondition in its interface to communicate to the user its input/output behavior.

The mirroring precondition and postcondition constitute a rigorous interface between the ingenious ephemeral details of the efficient implementation engineered by the programmer and the general terse information that is available to the user, who can so reuse, in different contexts, the programmer’s code and take advantage of its reliable behavior.

Coda

Although the analogy between sonatas and routines is imperfect, it unveils deep conceptual connections. As the key to managing complexity, abstraction underpins any efforts to further knowledge; and helps push to new horizons music and programs alike.

Good technical writing is largely an acquired skill. Like other elements of expertise necessary for research, one learns it by reading the classics, following expert‘s advice, and practicing a lot. After sufficiently extensive training and experience, one interiorizes rules and tips as second nature, and applies them whenever they are writing a technical piece.

In this post, I want to discuss what sometimes may happen as a side effect of extensively practicing the necessary imitative efforts that one goes through to master technical writing. Some assimilated rules may survive that are mere relics of outdated practices; others misinterpret the original intentions behind sound advice, or its right scope, and become unnecessary constraints that make for duller rather than more convincing writing. I call these “myths” of technical writing, because they are uncritically assumed in spite of lacking a convincing justification only because they appear, or are believed, to be common accepted practice. Some of them are about writing style, others are about typographical conventions.

Not all the myths I discuss have the same relevance or widespread usage. The selection is also somewhat a matter of personal opinion. My ultimate intent is to revisit some knee-jerk habits rather than uncritically perpetuating them without a convincing understanding of their rationale — as I certainly have done on occasion too. Since good writing is also a matter of taste, I believe that for every rule, and for every anti-rule, there are plausible exceptions. The bottom line really is: let’s be critical in choosing our writing style as we should be in our research activity.

Two columns are better than one.
A specter is haunting scientific publishing — the specter of two-column layouts. Multi-column page layouts were introduced at times when printing was expensive with the goal of cramming as much content as possible in the fewest pages. Compared to single-column layouts, two-column layouts require text in smaller fonts, complicate the placing of figures and tables, and make formatting of special text (such as equations and program code) and text justification more troublesome (a narrow horizontal space for text can accommodate few extra spaces for justification before it becomes ugly). All these features translate into less readable texts. I suspect the reason many publishers of scientific articles still insist on multi-column layouts is largely out of outdated practices rather than conscious decisions. I say we try to use single-column layouts whenever we have a choice, such as for technical reports and extended versions.
You can’t use contracted forms of verbs.
When I started writing research papers, I was told to absolutely avoid contracted verbal forms (can’t, won’t, aren’t, …); the reason given for this restriction was that they are not acceptable in formal, rigorous writing. You may have heard and followed similar rules; indeed, it seems that a large part of scientific writing avoids contracted forms. However, the justification for this recommendation is questionable: there’s nothing inherently informal, let alone sloppy, about contracted forms. Modern English writing, including technical texts, admits contracted forms as legitimate; up-to-date copyeditors do not correct them away. The recommendation to avoid them is still sensible when a true ambiguity may arise. For instance, “it’s” is the contracted form of both “it is” and “it has”: if the intended meaning is not clear from the context, it’s advisable to disambiguate by conjugating the verb in full. When ambiguity is not an issue, using contracted or full forms is a matter of flow and pace that each sentence should have. Not abusing contracted forms is the real rule to follow; but there is no need to ban them.
Italicizing foreign words is de rigueur.
Maybe in Elizabethan English; not anymore in the twenty-first century. Italic should mainly be used to emphasize words; just because a word has foreign origin it does not mean one should emphasize it. I recommend the following rule of thumb to decide whether a foreign word should be typeset in italic: if it’s included in a standard English dictionary, do not italicize; if it’s not included in the dictionary, are you sure you want to use the word at all?
The passive voice is to be avoided: we always avoid it.
I believe passive forms used to be quite common in scientific writing (they may still be so in some scientific fields other than computer science). The rationale: scientific content should be objective; since the passive voice can deemphasize the subject by omitting it, it makes it easy to achieve an impersonal style that can be mistaken for an objective one. However, a sweeping usage of passive forms tends to communicate indecisiveness and vagueness; therefore it has lost popularity in technical writing, where clarity and assertiveness are paramount.
Unfortunately, these considerations sometimes are turned into a ban of the passive voice, whereas they should be indications regarding when and how to use it to the best effect. Another incongruous reaction to the suggestion of limiting the usage of passive is overusing the first person plural — we — as sentence subject. Ironically, an indiscriminate usage of “we” has the same problem as an indiscriminate usage of passive voice: the subject becomes unclear and impersonality prevails. Indeed, some papers may use the first person plural for such diverse subjects as:

  • the paper’s text: “we describe in this paragraph” — this paragraph’s text describes;
  • the paper’s authors: “we hope that the results are useful” — the authors hope;
  • a subset of the paper’s authors: “we ran the experiments” — the graduate student ran;
  • an algorithm, program, or technique: “we generate a set of unit tests” — the test-case generation algorithm generates;
  • the paper’s authors together with readers: “we can see that the correlation is strong” — anyone looking at the figures can see.

The last form is the preferred meaning to be attributed to the first person plural. In all other cases, we’d better clarify the subject or use the passive voice to deemphasize it.

Different floats should be numbered independently: is Figure 2 before or after Table 1?
Another mainstream practice of typography is the habit of using independent numberings for different kinds of floats (such as figures, tables, and listings) and environments (such as numbered theorems, definitions, and remarks). For example, if a document contains two tables and two figures, they are referred to as Table 1, Table 2, Figure 1, and Figure 2. The problem with this practice is that the numbering does not carry any information about the relative order of the various floats: the first figure is Figure 1 regardless of whether other floats appeared before it. If it were readily available, the missing information would help readability by suggesting whether one should search forward or backward for a certain float given any current position in the paper. A similar argument applies to numbered environments. There are few authors who dare to change the common practice and adopt more practical numbering schemes. The classic Concrete mathematics [Graham, 1994], for example, numbers each theorem by the page of the book where it appears; it looks outlandish the first time you encounter it, but then it’s easy to understand and very convenient for browsing. I try to override the numbering scheme to one that is more reasonable whenever I write documents past a certain length — even if some copyeditors have occasionally enforced the standard, inconvenient scheme.
Never use citations as nouns; see [7] for an example.
Using citations as nouns — writing “see [3]” instead of “see Graham et al. [3]” — is possibly the only writing practice among those introduced to save every bit of space to comply with the strict page limits common to conference publishing that I find attractive for general usage even if it is normally shunned by copyeditors. It may not be very elegant, but there are cases in which none of the alternatives seems any better.
Of course, if we have no space constraints whatsoever, and are citing few references by well-known authors, writing their names out in full is clearer. But things are very different when we’re writing a “Related work” section full of citations and we are trying to combine readability and brevity. As a simple example, imagine three references [A], [B], and [C] all originating in the same research group, lead by Prof. Smith, but with slightly different (and long) authors lists. We would like to give a general introduction to the three works, and then perhaps single out [C] as the most closely related to our own. Which solution do you prefer?

  • Smith’s group has worked on baz in [A], [B], and [C]. [B] describes technique foo which is most similar to ours.
  • Prancer et al. [A], Donner et al. [B], and Blitzen et al. [C] have worked on baz. Donner et al. [B] describe technique foo which is most similar to ours.

I find the first option much more readable; I’m willing to accept a tad of informality in exchange for that.

Avoid repetitions; do not reiterate but use synonyms.
Of course superfluous repetitions should be avoided. But the suggestion to use synonyms is easily misunderstood as a requirement to uncritically use up the thesaurus as extensively as possible.
Italian journalist Cesare Marchi told a funny story [Quartu, 1986] to illustrate the perils of overdoing searching for synonyms. A student overly committed to avoiding repetitions had to write a passage on Hannibal’s armed expedition across the Alps during the second Punic war. The student mentioned that the Carthaginian general “crossed the Alps with elephants“, in the hope that Romans would be “shocked by those behemoths“; he went on telling the challenges of “climbing mountains with those mastodons“; he continued by describing the “death of many ungulate trunked herbivore mammals“. As you can see, avoiding repetitions is not a protection against unintended comedy.
Strunk and White [1999] give a great recommendation about repetitions: express coordinate ideas in coordinate form. Indiscriminately using synonyms may blur the connections between parts and thus render a text less clear and less cogent. There is another point to make in favor of repetition that is particularly relevant to technical writing: using a synonym for words that should have a precise well-defined meaning incurs the risk of insinuating the doubt regarding what the real writer’s intentions were. If I write of bugs in section 2 of my paper and go on about faults in section 3, am I referring to the same things in both sections? A little repetitiveness is worth having for greater clarity.
Paper structure is rigid; in particular, the first section is Introduction, the last section is Conclusion(s).
Have you noticed that the first section of most papers, invariably titled “Introduction”, is often not really introductory in character? More commonly, it contains motivations for the work presented in the paper and, more extensively, an overview or summary of the main content — more detailed than the abstract but still not requiring too much background or definitions. If this is the case, how come we always title that first section “Introduction”? This stale convention misses the opportunity to give it a more informative title, preferably connected to the actual content rather than completely generic. Or, if it really requires no title, why not omitting the title altogether? Though less strongly, similar observations apply to other standard sections of scientific articles. For example, it’s not compulsory to have a “Conclusion(s)” section unless there is some interesting material to be put there. In this respect, I welcome a practice of fields such as mathematics (as well as theoretical computer science) where there’s no stigma in ending a paper abruptly with a theorem or a proof. Provided, of course, that is the best usage of the available space.
IOKTUAP (i.e., It’s OK To Use Abbreviations Profusely)
Computer science jargon is already rife with acronyms and abbreviations, possibly more than any other technical discipline; this should be enough a reason already to limit the introduction of new abbreviations to few cases of necessity. As a minimum, every abbreviation or acronym but the most widely used ones should be spelled out in full the first time it is introduced in a paper. However, if an abbreviation is used only once or twice in a whole document, it’s advisable to avoid introducing it in the first place.
A related problem when using abbreviations is how to choose indefinite articles: “an LTL formula” or “a LTL formula”? The rule of thumb I follow chooses according to whether the acronym is usually pronounced as such or read out in full. “LTL” is usually read “/ell tee ell/”, and hence the indefinite article should be “an”; in contrast, I prefer “a FOL formula” to “an FOL (/eff oh ell/) formula” since “FOL” is normally read out in full as “First Order Logic”.
As usual, transgressions against any of these rules may be excusable if trying to save space to conform to rigid page limits.
Sentences should be kept short.
Unqualified criticism about sentences being “too long” reminds me of the (possibly apocryphal, but popularized by the movie Amadeus) comment “too many notes” attributed to Emperor Joseph II after watching Mozart’s Die Entführung aus dem Serail (by the way, it’s in italic because it’s a title, not because it’s German ;-). I do not condone, let alone encourage, habits of writing long, convoluted, obscure sentences, but I object to the notion that there is a limit to how long a sentence should be that cannot be trespassed without sacrificing clarity. Sentence length, like many other issues discussed in this post, is a matter of style and content. Dry, somewhat minimalistic writing à la Dalton Trumbo does not best suit every text.
If we diligently polish our writing aiming for clarity and crispness and calibrate our style to maximize expressiveness, we will be able to quip in response to nonspecific criticism about excessive sentence length, like Mozart quipped in response to the Emperor, that, in our sentences, there are just as many words as there should be.

If you have more myths that you’d like to discuss, or if you disagree with parts of my assessment, you are welcome to leave a comment.

References

  1. B. M. Quartu, editor: Dizionario dei sinonimi e dei contrari, Rizzoli, 1986. Foreword by Cesare Marchi.
  2. William Strunk Jr. and E. B. White: The elements of style, 4th edition, Longman, 1986.
  3. Ronald L. Graham, Donald E. Knuth, and Oren Patashnik: Concrete mathematics: A foundation for computer science, 2nd edition, Addison-Wesley, 1994.

One of Tolstoy’s least known works [Tolstoy, 1886], published during the ascetic spiritual phase that characterized his late life, criticizes science (as well as art) as irrelevant because it gives no answer to the eponymous question “What shall we do then?”. While Tolstoy’s intentions were right-minded, his criticism remains misplaced: science may not give ready-made direct answers to moral questions, but certainly provides highly relevant information to help answer them.

Tolstoy’s superficial description of the scientist’s work as consisting of “counting invisible bugs and stars” caught Poincaré’s attention. In a talk given in 1906, later published in his trilogy of essays on epistemology [Poincaré, 1914], Poincaré discusses how science goes well beyond merely “counting bugs” or, beyond metaphor, amassing facts. As he says in a famous quotation in another part of the trilogy:

Science is built up with facts, as a house is with stones. But a collection of facts is no more a science than a heap of stones is a house.

This story explains the origin of this blog’s name, but you may still be wondering why a blog mainly about science (and enthusiastic about it!) is named after a misconception.

To address this objection, we have to think about the derivative meaning of “bug” as “defect” or “error” — particularly widespread in computer science to describe software faults, but whose introduction predates even Tolstoy’s observations. Under this new meaning, Tolstoy’s sentence is not so infelicitous. On the contrary, finding and counting errors are efforts fundamental to the progress of science. At another level, there are entire fields devoted to counting bugs: software verification, one of my main research interests and a recurring topic in this blog, is concerned with finding, characterizing, removing, and establishing the absence of software bugs.

I’m sure Poincaré would approve of this view. After all he developed one of his most important breakthroughs — chaotic behavior of nonlinear dynamical systems — as an attempt to patch a mistake (a bug!) in his initial submission of an award-winning paper (interestingly, a reviewer helped catch the mistake, but this makes for another story [Diacu, 1996]).

The slogan “counting bugs” also vindicates the unquantifiable value of science from below, where every effort that satisfies curiosity and contributes, no matter how modestly, to improving knowledge and understanding is worthy regardless of utility or practicality.

This blog will try to follow such an inquisitive but also lightsome spirit while discussing sundry topics in science and beyond. If you’re sympathetic, I hope you will join us!

References

  1. Leo Tolstoy: What shall we do?, 1886. Available here in English.
  2. Henry Poincaré: Science and hypothesis. The value of science. Science and method., 1914. English edition: The value of science, edited by Stephen Jay Gould, Modern Library, 2001.
  3. Florin Diacu: The solution of the n-body problem, The Mathematical Intelligencer, 18(3):66–70, 1996. Available here.