The phrase “Kernighan and Ritchie” has entered computing jargon independently of the lexical tokens from which it is constituted. I talked on Friday with Brian Kernighan about Dennis Ritchie, who sadly passed away two weeks ago at the age of 70. Brian had gotten to know me a bit when he contributed a chapter on regular expressions to the O’Reilly book Beautiful Code. He said, “It’s just remarkable how much we all still depend on things Dennis created.” Kernighan went on to say that Ritchie was not self-promotional, but just quietly went about doing the work he saw needed to be done.
Plenty of ink has been devoted over the past 40 years to the impacts of the C language and of the Unix operating system, both of which sprang to a great extent from Ritchie’s work, and more ink on the key principles they raised that have enabled key advances in computing: portability, encapsulation, many small programs cooperating through pipelining, a preference for representing data in text format, and so on. So I did not concentrate on these hoary, familiar insights, but talked to Kernighan about a few other aspects of Ritchie’s work.
More than bits of C remain
It’s noteworthy that Android added C support through the Native Development Kit. They needed the support in order to offer 3D graphics through the OpenGL libraries, which were written in C, but the NDK has proven very popular with developers who embellish their applications with device-specific code that has to be written in C.
Apple’s Cocoa and iOS have an easier time with C support, because their Objective-C code can directly call C functions. The “C family” that includes Objective-C and C++ is obviously thriving, but plain old C is still a key language too. Kernighan freely admits, “A lot of things are done better in other languages,” but C is still queen for its “efficiency and expressiveness” at low-level computing.
Ritchie created C with hardware in mind, and with the goal of making access to this hardware as efficient as possible while preserving the readability and portability that assembly language lacks. So it’s not surprising that C is still used for embedded systems and other code that refers to hardware ports or specific memory locations. But C has also proven a darn good fit for any code requiring bit-level operations. Finally, it is still first choice for blazingly fast applications, which is why every modern scripting language has some kind of C gateway and why programmers still “drop down to C” for some operations. And of course, if you use a function such printf or cos from your favorite scripting language, you are most likely standing on the shoulders of the people who wrote those C library functions.
Kernighan told me that Ritchie was always conscious of the benefits of using minimal resources. Much of what he did was a reaction against the systems he was working with when creating Unix with Ken Thompson (a reaction to the Multics operating system) and C (a reaction to the PL/1 language that Multics was based on). EPL, Bliss, and especially BCPL were more positive influences on C. The things that made C successful not only inspired languages and systems that followed, but kept C a serious contender even after they were developed.
After Unix, Ritchie worked a great deal on Rob Pike’s Plan 9 system. Not only did Ritchie use it exclusively, but he contributed to the code and helped manage the project at Bell Labs.
The computing environment of the 1970s was unbelievably limited by modern standards. Kernighan said that Ritchie and Thompson had to design Unix to run in 24,000 bytes. And similar constraints existed in everything: disk space, bandwidth (when networks were invented!), and even I/O devices. The infamous terseness of Unix commands and output were predicated on their use at printers, and helped to save paper.
But that was OK back then. You could make do with a fourteen-character limit on filenames, because programs were divided into relatively few files and you might have to manage only a few hundred files in your own work. You’d never need to run more than 32,768 processes or listen on more than 1024 incoming connections on your system. The Unix definition of time soon proved to be more problematic, both because some Unix programs may last beyond 2038 and because a granularity of less than a second is often important.
But Kernighan points out that keeping things within the limits of a word (16 bits on the PDP-11 that Ritchie wrote for) had additional benefits by reducing complexity and hence the chance for error. If you want to accommodate huge numbers of files within a directory, you have to create a complex addressing system for files. And because the complex system is costly, you need to keep the old, simple system with it and create a series of levels that can be climbed as the user adds more files to the directory. All this makes it harder to program a system that is bug-free, not to mention lean and fast.
The joys of pure computer science
Kernighan’s and Ritchie’s seminal work came in the 1970s, when Kernighan said the computer field still presented “low-hanging fruit.” Partly because they and their cohorts did so well, we don’t have much more to do in the basic computer development that underlies the ever-changing cornucopia of protocols and applications that are the current focus of programmers. New algorithms will continue to develop, particularly thanks to the growth of multiprocessing and especially heterogeneous processors. New operating system constructs will be needed in those environments too. But most of the field has moved away from basic computer science toward various applications that deal directly with real-world activities.
We know there are more Dennis Ritchies out there, but they won’t be working heavily in the areas that Ritchie worked in. To a large extent, he completed what he started, and inspired many others of his own generation.