“How do I program thee? Let me count the ways.” So might Lopes paraphrase the well-known poet Elizabeth Barrett Browning. In this book, she writes the same program in 33 different programming styles.
The idea is borrowed from a book by a French author that repeats a simple story in 99 different literary styles. The story itself was trivial in order to emphasize the form of each style rather than the content. Likewise, Lopes chooses a simple program to highlight the differences in programming styles, using Python as the programming language. The program used is term frequency: count the occurrences of each unique word in a text and print the most common 25 words, ignoring a list of common stop words (pronouns, prepositions, and so on). Jane Austen’s Pride and prejudice was used as the sample input.
Of course, 33 styles are not intended to exhaust all the possibilities. Most programmers will recognize many of the styles: actors, pipelines, aspects, object-oriented variants, MapReduce, and even representational state transfer (REST). Many of the other styles will also be familiar, once their confusing names are deciphered. For no apparent reason, some common styles are given nonstandard names. For example, the recursive program style is named infinite mirrors, and the model-view-controller (MVC) style is called trinity (even though it’s acknowledged as being known by MVC).
There is one chapter for each of the 33 styles. Related styles are grouped into nine parts: historical, basic, function composition, objects, reflection and metaprogramming, adversity, data centric, concurrency, and interactivity. Each style is presented in the same way: first the program, then a discussion and commentary explaining the style and the program, a brief look at the use of the style in system design, and some historical notes. This is followed by a glossary of terms relevant to the style and references for further reading, often citing some of the original papers on the style or the theory behind the style. A few exercises are included, though these are mostly the same for each style (such as implement the program in the same style in another language).
Not discussed is how programs combine multiple styles. The five styles in the adversity grouping are really different ways of handling errors (such as using exceptions); hence, almost any program in any of the other styles will actually be a hybrid incorporating one of these error styles.
This is an excellent work, and readers may be inspired to add additional styles. One missing style is what I would call performance optimized, where every central processing unit (CPU) cycle counts and everything is done to minimize program execution time. This would seem a natural style to include, both because of its importance and because this style can lead to complicated, nonintuitive ways of doing things solely to gain performance.
Writing the programs in Python is a somewhat mixed blessing. The powerful features of Python minimize some of the programming (so, for example, a sort routine is never needed; reading and parsing the input is typically reduced to a single line). That helps focus on the styles rather than the details of sorting or input. On the other hand, when the language used has built-in support for a feature, a style depending on that feature can appear overly simple and easy to use compared to the same style in another language without that support. Error handling using exceptions is an example. Language matters in style, both in natural languages and in programming languages.
Source programs are available at an accompanying website (https://github.com/crista/exercises-in-programming-style). Neither the book nor the website specify the version of Python the sources were written for. The current Windows 3.4.1 version of Python does not run most of the programs. Nor does an old 2.4.3 Python installed on my Linux system. Most of the necessary changes are simple syntax changes (such as adding parentheses around the items in print statements), but a few are not, and as a novice to Python I was unable to get several of them to run.
There are some things missing from the book. One omission is any comparison of program size between the various styles. The programs range in size from eight source lines (for a script-like style) to 136 (for the actors style). No performance comparison was done either. I found this surprising since style is often a major determinant of performance. My own measurements showed that as with program size, the performance varied widely. Most of the programs run in under one second, but four needed a few seconds (two to five) and two required tens of seconds (24 and 37). Orders of magnitude differences in size and performance for the same program are normal, but style’s impact is not mentioned.
This is an intriguing and thought-provoking book. It is highly recommended to everyone interested in programming, especially those who write programs regularly. It should be of particular interest to architects searching for alternatives and to students and beginners who want to expand their experience and knowledge of different styles.
More reviews about this item: Amazon