Clojure Gazette 1.39
Issue 1.39 --- May 13, 2013
Programming has come a long way since the early days of programs written in assembly. Most notably, programs are much larger today. The size of current programs makes them prohibitive to understand all at once. The obvious question then is how to divide the programs into pieces that are easier to understand. As code grew, we needed better and better answers to that question.
The answers were not always obvious. While today we take for granted lexical scoping, it was not always the most common scoping mechanism. Many programs used only global variables for state. Structured programming (using subroutines, ifs, and loop constructs instead of gotos and other jumps) was not common until the 1970s. And the idea of module or object boundaries which would hide implementation details was not obvious when it was invented. The history is rich with missteps andcontroversies.
But this history is still unfolding. It is important to keep that in mind as we face an ever-growing codebase. What structures will help us build more powerful software more easily? Can we find new ways to group and separate pieces of software so that we can compose them later? From where we stand today, libraries and APIs seem to be the largest structures that are still recomposable. What is next?
Clojure is exploring this space at many levels. At the level of the let statement, it has non-rebindable names for values. It is pioneering the use of small interfaces not merely for implementation hiding but for composability. And at the largest level, how systems can communicate with structured and extensible data.
P.S. Feel free to email me any time. I love hearing from readers.
The Power of
Barbara Liskov won the Turing Award for her research into programming with modules. This talk reviews the history of the research that influenced her. I love these historical talks that give lots of insight into how ideas we take for granted today came to be. Liskov was also instrumental to the development of our common notion of interfaces.
Go Ahead, Make a
Sandi Metz walks us through structuring code in a practical example. Although it is object oriented code, the principles apply to all software. Metz distinguishes between code that is messy because it could be written better and code that has unnecessary dependencies. The former is benign while the latter is costly to maintain.
The Language of the System
Rich Hickey explores what systems of programs might look like. How do they communicate? What are their responsibilities toward each other? One interesting idea he relates is that systems can decouple themselves by communicating using queues.
Simplicity Matters (video)
Hickey explores the meaning of "simple" and how it relates to software modularity and composition.
Way back in 1971, David Parnas wrote this paper giving a very good account of what most of us believe today: that modules boundaries should be chosen to isolate things that aremore likely to change from those that are less likely to change. Modules become an information-hiding mechanism. They are hiding the unnecessary details of implementation so that the modules can be understood, developed, and modified independently.
Open Implementations (pdf)
Gregor Kiczales explores how we can build systems that allow the programmer to change them to suit his/her needs. Instead of building a perfect black box, what if the system provided introspection , invocation, and intercession? To find out what these are, read the paper!
A cool tool for exploring the contents of the loaded namespaces. Written byFrank Siebenlist and Andy Fingerhut.
A library for reloading namespaces in the correct order without restarting the JVM. It parses the (ns ..) declarations, searches the filesystem for dependencies, and constructs a graph. It then uses that graph to intelligently reload the files. Written by Stuart Sierra.
Jason Wolfe presents Prismatic's Graph library and demonstrates that it captures a very common pattern in a useful abstraction. Like most patterns, it is useful at every level of scale, from the smallest function to large composites of whole systems.