Something I plan never to say in class again:
If this were a real program...
... because when I say it, it is almost always code for "I haven't bothered to show you a complete and useful program in which this idea (or pattern or construct) actually matters." Usually, the students and I both deserve better.
Of course, it's easy for me to say this on the last day of classes before summer break. Let's see how well my resolve holds up in the heat of classes next fall.
And for those of you who don't teach university courses, here is what most professors are thinking on the last day of classes before summer break:
While doing some link surfing yesterday, I ran across an old blog entry that has a neat programming languages idea in it: Wouldn't it be nice if we could encapsulate language features.
The essay considers the difference between two kinds of complexity we encounter in programs. One is complexity in the language features themselves. First-class closures or call-with-current-continuation are examples. Just having them in a language seems to complicate matters, because then we feel a need to teach people to use them. Even if we don't, some programmer may stumble across them, try to use them, and shoot himself in the foot. Such abstractions are sometimes more than the so-called ordinary programmer needs.
Another kind of complexity comes from the code we write. We build a library of functions, a package of classes, or a framework. These abstractions can also be difficult to use, or it may be difficult to understand their inner workings. Yet far fewer people complain about a language having too many libraries. (*)
Why? Because we can hide details in libraries, in two ways. First, in order to use Java's HashMap class, I must import java.util.HashMap explicitly. Second, once I have imported the class, I don't really need to know anything about the inner workings of the class or its package. The class exposes only a set of public methods for my use. I can write some pretty sophisticated code before I need to delve into the details of the class.
Alexander asks the natural question: Why can't we encapsulate language features in a similar way?
Following his example, suppose that Sun adds operator overloading to Java but doesn't want every programmer to have to deal with it. I could write a package that uses it and then add a new sort of directive at the top of my source file:
Then, if other programmers wanted to use my package, they would have to import that feature into their programs:
Such an information-hiding mechanism might make adding more powerful features to a language less onerous on everyday programmers, and thus more attractive to language designers. We might even so languages grow in different and more interesting ways.
Allowing us to reveal complex language features incrementally would also change the way we teach and write about programming. I am reminded of the concept of "language levels" found in Dr. Scheme (and now in Dr. Java). But the idea of the programmer controlling the exposure of his code to individual language features seems to add a new dimension of power -- and fun -- to the mix.
More grist for my Programming Languages and Compilers courses next year...
(*) Well, unless we want to use the language to teach introductory CS courses, of course.
I've been negligent in posting the next installment of my Running on the Road series, to detail my experiences and recommendations for running in Tucson and Carefree, Arizona. That won't likely come for a couple of weeks, until my semester has ended. By then, I hope to have an entry on running in San Diego, too. But I can report a great spring running here at home. In January, I reported my plan for the winter: get faster. I kept up weekly track work-outs through February, when conference trips interrupted. When I returned home and got back into my routine, gorgeous spring weather and rising temperatures made outdoor running so attractive that I hit the trails inside of the track, though I still pushed myself hard a couple of days a week.
The last two weeks have seen a culmination of the winter running. Two weeks ago, I ran three times that were either personal bests or personal #2s on their respective routes. I ended the week with a hilly and credible 14-miler. This week, I recovered from all that exertion with easy runs until Friday, when I got back on the track for the first time in a couple of months. The results pleased me:
I guess I have to rate my winter "maintenance mileage" a success. I enjoyed my runs and got a little faster in the process. Now comes a season in which I can enjoy the outdoors even more, boost my mileage, and start thinking about running 8-minute miles or better for 15, 18, 20, ..., 26.2 miles. The race goal: run the Twin Cities Marathon on October 2. The pace goal: 3:30. That's aggressive, given that I ran 3:45 in my second marathon last October. But an aggressive goal supported by good preparation and tempered by a healthy dose of realism is okay. Let's just see how I feel in September.
Every once in a while I am jolted from my own parochial concerns by a reminder that we in computing have an opportunity to do so much more than just train tomorrow's Java or C++ programmers. On Friday, Darren Hobbs reminded me with his blog Programming as Literacy. Darren begins:
In what's typically called 'the western world', before literacy became essentially ubiquitous it was limited to a select few. Monks originally, then scribes. These individuals possessed a truly remarkable skill. They could make marks on paper that could remember things. They could capture information and retrieve it later. Associated with this skill was the ability to make marks that could perform complex computations and produce an answer. People with these skills were hired by nobles and merchants to increase business value.
I have mentioned this idea before, looking to computer scientists such as Alan Kay and Ward Cunningham, for whom computing is more than just a technical skill reserved to a special few. Ward's wiki enables a new kind of conversation. In Kay's vision, computing is
a new kind of reading and writing medium that allows some of the most important powerful ideas to be discussed and played with and learned
in ways more profound than any book. (See his essay Background on How Children Learn for more.)
Alan often speaks passionately that we hold in our hands the most powerful tool for changing the world since the printing press five hundred years ago. I do not think that the passion in his words in out of place. Like Alan, I believe that we are creating the medium that people will use to create the next Renaissance.
When we think about computing and computing education in such terms, the problems we encounter teaching CS majors to program seem small. But these problems also point out just how much work we have to do if we want to effect the sort of change that our opportunity affords. I suspect that the sort of things we need to do to make programming a new form of general literacy available to all would only make teaching CS majors easier.
Others are thinking about this problem, too. Darren Hobbs' blog was a nice reminder of that. And John Mitchell responds to my blog on accountability through conversation by suggesting that our programming languages should be more conversational. I think that natural language will always have an advantage over programming language in this regard, but John's idea that we can create little languages that are structured, predictable, comprehensible, and concise enough to support more natural interaction is worth thought. The work of Alan Kay's group on eToys and Active Essays, described at Squeakland, is certainly aimed in this direction.
I am glad summer is almost here. I need some time to back away from day-to-day classroom issues to think about loftier goals, and concrete plans to move toward them.
Some fun for a Friday afternoon late in the semester.
Hitachi is promoting a new method of data storage called "Perpendicular Recording", in which bits are stacked in order to save real estate on the disk. The idea itself is interesting, but even better is the promotional cartoon the company is using to teach us about it. You can't tell that some animators working these days were influenced by Schoolhouse Rock, can you?
I Answered the Email, But I Didn't Inhale
This from Clive Thompson:
According to a new study commissioned by Hewlett Packard -- and conducted by psychologists at King's College in London -- extensive use email and instant messaging can drop your IQ by 10 per cent. In comparison, smoking pot regularly dents your IQ by only 4 per cent.
The first one is always free...
(The explanation for this anomaly apparently involves the unsuccessful attempt to multitask, which must lead to some sort of thrashing.)
Need a Cluestick?
Okay, this is just silly. But I chuckled.
The users I know are so clueless, that if they were dipped in clue musk and dropped in the middle of a pack of horny clues, on clue prom night during clue happy hour, they still couldn't get a clue.
".. dropped in the middle of a pack of horny clues ..." And you thought I was having a bad day.
(And I would never say this about my students. No--really.)
Do you ever feel as if the gods are telling you to change your plans?
I came to campus today planning to "go public" about my intention to apply for a job opening here.
First, I walk to my office in a steady rain, and my umbrella deconstructs spontaneously. When I get to my office to make a phone call, I realize that I left my my food and drinks for the day back in the car. After I make my call, I head back to the car, taking my laptop with me so that I can head over to the library for some work. Still pouring down rain. On my way to the library, the metal clasp on the shoulder strap of my soft leather laptop bag breaks, and my laptop plummets to the sidewalk pavement.
At this point, I'm starting to wonder.
I get to the library. The laptop survived the fall. I survived the rain. I fire up an episode of Bob and Tom to bring me some laughs. I do some work.
The gods have quieted down, or I am in denial.
UPDATE: Mixed Messages
When I went to leave my library office to go to lunch, I found that I had left my keys in the door outside for over three hours. The good news is that no enterprising student had decided to make them his own.
And, though it may sound like I'm having a bad day, I don't really feel like that. Maybe that is a sign in its own right...
A professor who shall remain anonymous once thanked me for including him in the bibliography of AIMA. I told him that his work was seminal to the field, so of course I included it. "Yeah, yeah, I don't care about that," he said, "what I care about is that students look in the back of the book to see if my name is there, and if it is they think I'm important and they don't bother me in office hours as much."
I am not cited in AIMA, but whatever I am doing to scare them off must be working.
By the way, Norvig also wrote one of my favorite books on programming, Paradigms of AI Programming. Nominally, this book teaches AI programming in Lisp, but really it teaches the reader how to program, period. Norvig re-implements many of the classic AI programs, such as Eliza, GPS, and Danny Bobrow's Student, showing design and implementation decisions along the way. His use of case studies provides a lot of context in which to learn about building a programming.
Scott Hastings, a journeyman NBA player from a decade ago, used to joke that, no matter how good Michael Jordan, Isiah Thomas, and Magic Johnson were, he himself always led the league in millions.
Huh? Consider Hastings' typical line in the daily box score. He would get into the game at the very end, play a minute or two, shoot 0-0 from the field and 0-0 from the free-throw line, grab 0 rebounds, and have 0 assists. So his stat line always read something like this:
1 0 0 0 0 0 0
And there's his million. Michael, Zeke, and Magic could only dream of such a stat line!
I claim bragging rights locally for another, perhaps less dubious, statistical feat, this one in the university library:
I almost certainly lead the UNI community in most times checking a book out for the first time.
I can't tell you how many times I've gone over to pick up a book only to find it in mint condition, not a blemish to be seen, with no stamps on the Date Due slip. This experience always gives me a little buzz, a sense that I am on the frontier. False pride, I know, but mostly a harmless diversion during a busy day.
Just as Hastings owed his good fortune to the coaches, who put him into the game for garbage minutes each night, I owe my good fortune to colleagues like Rich Pattis and the many bloggers I read, who suggest hot and important books to me. By having well-read and deeply interesting friends and colleagues, I come into contact with books and ideas I'd otherwise only stumble across much later. I'm often surprised to find these books already on the library shelves -- a testimony to the good work done by by our bibliographers, both technical and general.
Now, I just need a catchy name for this feat, so that I can impress unsuspecting friends and colleagues with a passing remark. Any suggestions?
(In a similar vein, on Friday I checked out a book that had been on the shelves unread since 1971! A first-time reader, but only in the last two generations.)
I sometimes like to think about ways in which learning to program is like learning to speak a foreign language. Usually, I focus on similarities between the two, to see whether I can use a correspondence to improve how I present an idea. In the middle of class this morning, a difference between the two occurred to me, and now I wonder how I can use this idea to improve my courses on a daily basis.
The difference: Students of foreign language are more easily, more obviously, and more naturally held accountable for their level of preparation and their current state of proficiency than are students of computer programming.
There has been a lot of discussion recently on the XP discussion list about the idea of accountability. Apparently, this concept is a driving force behind the "new P" described in Kent Beck's second edition of XP Explained. (I haven't had a chance to read it yet.) Much of the discussion concerns just what the word means. For me, Merriam-Webster's definition seems clear enough:
... an obligation or willingness to accept responsibility or to account for one's actions
Am I obliged to account for my actions and take responsibility for them? Then I am being held accountable. Am I willing to account for my actions and take responsibility for them? Then I am being accountable. (*)
My compiler holds me accountable for the correctness of the code I write. Each time I compile, I find out if my program is syntactically correct. My unit tests hold me accountable for the correctness of the code I write. Each time I run my tests, the green bar tells me that my program is functionally correct -- or the red bar tells me otherwise.
Of course, I have to compile my program (at least once :-), but I am not obliged to write and run tests. One of the beauties of the agile programming practices is their demonstration of programmers' willingness to be held accountable for their time and their efforts. Obligation is supplanted by willingness, which opens the programmer to a new level of growth and performance.
The compiler holds students accountable, too. As they learn and use new ideas, the compiler and their testing give them a measure of their accomplishments. So, the more practice they get -- the more code they write, the more projects they do -- the more feedback they get about their level of proficiency.
In a typical computer science course, the instructor has only a small number of opportunities to gauge each student's development. In my most programming-intensive courses, I ask students to write only 12 programs for evaluation. That is quite a lot in a fifteen-week semester, but it's not enough. I wish that I could interact with each student every day, gauging preparation and proficiency, folding what I learn back into my instruction.
What do I do now? I give students in-class exercises and discuss solutions every day. But some students work on the exercises only half-heartedly, if only because the absence of a keyboard and a compiler makes writing much code tedious. The discussion usually goes pretty well, but only a small subset of the students tend to participate actively. In class this morning, the inadequacy of my seemed especially obvious.
So, my mind wanders... How would a course in spoken German or French differ? My in-class exercises and discussions pale in comparison to what a foreign language teacher can do so naturally: start a conversation with a student! A classroom discussion can grow quite easily to include many students, because each interaction with a student exposes the student's level of preparation and proficiency. Human conversation works that way.
I can draw students into classroom discussions, but there is a big difference between writing code and talking about code, even talking about writing code. Someone can talk about code, or the ideas underlying code, even if they have difficulty writing the same.
Students who are willing to account for their work sometimes find that they are not asked to. Students who need to be obliged to account for their work -- who would benefit greatly from being held more accountable -- come to count on not being so held.
This line of thought was triggered today by my recognition that a couple of students came to class unprepared this morning. A couple said so, honest that they hadn't studied the reading assignment yet wanting to ask questions. A couple tried to blend in, relying on the fact that they would probably manage to get by. I wasn't in the mood to call them to account, but I was in the mood to think about the attitude itself.
Owen Astrachan uses a great strategy for driving classroom interaction that has a side effect of holding students accountable for the time they spend in class on exercises. He passes blank transparencies out to groups of students working together on an exercise. They write their code on the transparencies. Finally Owen collects them and puts them on the projector for everyone to see and discuss. I don't know how often he makes the authors of a slide known to the class, or if he ever does In either case, I think that this strategy creates an environment in which students feel accountable.
Some students are intrinsically motivated to learn. They hold themselves accountable no matter what the instructor or other students do. But some university students are not quite ready for this level of autonomy. Some instructors and universities seem to adopt an attitude of sink-or-swim, leaving it to students to figure out that they have to take control of their own learning. In some contexts, this is the right thing to do. Ultimately, each student is responsible for his or her own learning, accountable only to themselves.
The role of a teacher, though, is more I think. Especially when working with children and even university freshmen, a teacher should help students learn to hold themselves accountable. I'd like to be able to readily recognize students who are struggling with material or not doing the work so that I can intervene. My German teachers could readily assess my level of preparation and proficiency by walking into the room, saying, "Guten Tag, Eugen! Wie geht's?" -- and then simply listening. Strategies like Owen's may be the best we can do in computer science, so we need to share them when we have them.
When you have to write your code on a slide and give it to the professor for possible display in front of the whole class, you have a built-in accountability partner. The success of groups such as Alcoholics Anonymous is founded in large part on relationships in which one person helps another to hold himself accountable. Sometimes, just telling someone else that you are quitting smoking or trying to curb your profanity can be enough external support to do a better job. Who wants to disappoint a friend, or look weak? You might even tell the Internet.
When a student signs up for a formal course in a topic, one element of the action is to put themselves in a formal accountability relationship. The teacher and the classmates act as accountability partners. Obviously, this isn't the only responsibility of a teacher, nor even the most important, but it is a good part of the deal for the learner.
This is wandered a bit from thought that triggered all this, which was something like, "If a student went to a French class as unprepared as some students come to their programming classes, they would be found out quickly. That would straighten them up!" (In moments of weakness, I sometimes surrender to temptation.) But ultimately I am motivated by a desire to do a better job as a teacher.
It occurs to me that I have written a similar entry before...
(*) I've not gotten into the mailing list discussion much, but this seems to be what Kent asks of himself and other programmers. It seems pretty reasonable to me, and at the heart of many agile development practices.
Agile methods aren't just for managing individual projects. They may be an essential component in a start-up company's long-term strategy.
In his recent essay, How to Start a Startup, Paul Graham talks about how important the choice of type of software to write is for the success of a start-up. He suggests that a start-up write software for smaller companies, where the competition and sums of money are smaller. But then he says:
They're the more strategically valuable part of the market anyway. In technology, the low end always eats the high end. It's easier to make an inexpensive product more powerful than to make a powerful product cheaper. So the products that start as cheap, simple options tend to gradually grow more powerful till, like water rising in a room, they squash the "high-end" products against the ceiling.
He cites several examples from the recent history of technology, from digital cameras to desktop publishing to Henry Ford and the automobile. In any case, this sounds like a harnessing of simplicity-first and piecemeal growth as a business strategy for product and market selection.
Once you know the kind of product you want to sell, you have to find out what customers want. How best to do that?
... get a version 1 out as soon as you can. ... The only way to make something customers want is to get a prototype in front of them and refine it based on their reactions.
Graham calls the alternative a "Hail Mary" strategy: do a lot of planning, generate a big design up front, develop a finished working product -- and then pray that enough customers will pay you for it.
Graham's own start-up benefited greatly from its agility. ViaWeb's initial target market consisted of web consultants, but it soon learned that its software made the consultants disposable which, needless to say, didn't endear the idea to the consultants. As a result of early experience with customers, the company shifted its market focus to small merchants and its software focus to ease of use: making a product that users could actually use to do their job better. The customer played a central role in defining and refining the requirements of the project.
Graham is not an "agile guy", and from my reading of him I'd guess he's a bit suspicious of all the hype around agile methods. Lisp hackers and Smalltalk hackers have long had the patterns that make up the agile development methods. It seems that an agile mindset on the technology side of things is compatible with an agile mindset on the business side of things -- and perhaps crucial to the viability of new companies.
While I'm on the topic of Graham's essays, if you are a student, you should definitely read his recent articles Undergraduation and What You'll Wish You'd Known. They give an interesting perspective on how to approach your high school and college years. Heck, even if you aren't a student you might well enjoy them.
On the flight home from ChiliPLoP, I read a review of a patterns book -- though neither the book's title nor the review itself ever used 'patterns'. And it isn't a software book; it's on graphic design. The book is Problem Solved: A Primer for Design and Communication, by Michael Johnson.
The review begins with a quote from the book that distinguishes artists from designers:
[While] a fine art student can get away with creating his or her own problems to solve, a communications student is usually handed someone else's, with a looming deadline thrown in.
Designers create, but what they create is usually circumscribed by the needs of a client, and the act of creation itself is circumscribed by limitations of time and budget, style and material. Of course, limitations don't eliminate the need for creativity. In fact, they may enhance creativity. But working in the presence of limitations means that designers are also problem solvers.
Problem Solved addresses the needs of designer-as-problem-solver by compiling "a typology ... of kinds of problems" and identifies "trustworthy, time-saving means to address those problems." Each section of the book focuses on a particular kind of communication problem, such as how to use a historical style in a "fresh" way or how to resolve ethical dilemmas. Each problem is
summed up by a memorable heading that (consistent with the samples shown) is both surprising and suitable.
This sounds like a patterns catalog, and the headings and photo illustrations that lead its sections sound a lot like the iconic photos that Alexander uses to evoke his patterns.
I'd think that graphic design is an area ripe for mining patterns. I also wonder to what extent Alexander's work has had an effect in design disciplines outside of architecture and software. One of my favorite non-software patterns projects was a crossover: Rosemary Michelle Simpson's work on patterns of information structure indices. (Rosemary is a master indexer and created the indices for many of the best-known patterns and java books.)
I read this book review in the Autumn 2004 issue of Ballast Quarterly Review. The editor, publisher, and primary writer of Ballast is Roy Behrens, a design professor at the University of Northern Iowa. This little journal is a pastiche of passages from books, witty quotes, curious illustrations, and book reviews, with bias toward the arts. Check it out -- it'll only cost you a few postage stamps.
Oh, and this issue of Ballast did review a book with the word 'pattern' in the title: DPM: Disruptive Pattern Material. DPM is an encyclopedia of camouflage in nature, the military, and culture. The title of this book is just what I want some of my own work to be... :-)
After teaching Agile Software Development to university juniors and seniors last semester for the second time, and introducing test-driven design early in CS II this semester, I am coming to a deeper appreciation for how much agile methods require a change in deeply-rooted habits.
It is easy for a person who have already developed a new habit (read: me) to walk into classroom and make assumptions about what will motivate students to change their habits. It doesn't take long before new practices become uncomfortable enough that a learner prefers to drop back to what she knows best. In CS II, students soon bump into objects that are hard for them to test, file processors and GUIs among them. And, as Bill Caputo points out, the benefits of TDD don't just happen, "you have to want to find a way to structure the code so that it can be tested without resorting to resources beyond the test." That can be hard for any programmer learning to do TDD, and it's harder for students who are still learning how to program at all.
I've been thinking been thinking about how to introduce these new ideas more effectively in the classroom. We university educators have something to learn from industry trainers who introduce agile methods to their clients. Brian Marick's recent article describes advice he gives to clients who ask him for help. Some of the details don't apply to my usual situation, such as "read Michael Feathers' wonderful Working Effectively with Legacy Code". Not that the book isn't wonderful -- it is! It's just that my students aren't usually ready for this book yet. But the more general advice -- work on developing habits deliberately, focus on test writing before refactoring, encourage collective learning and sharing -- can help me. I need to find ways to implement this advice in my context.
Writing my previous entry on designing the negative space around software reminded me of a couple of related techniques for learning. Like the negative space idea, both draw on ideas from other disciplines.
Brian Marick once wrote about the technique known as "averted vision" in astronomy. It turns out that we can only see some objects if we don't look directly at them. Rather than looking directly at a faint object in the sky, astronomers look a little to the side of the object and find that they can see an otherwise invisible object in their peripheral vision. This bit of magic follows directly from the structure of the human eye: while the center of the eye needs relatively bright light in order to focus on an object, the outer portions of our eye require less light to focus on the same object.
Brian reported success in applying this technique to learning a new topic. Rather attacking the topic head on, he sometimes goes near it, studying its periphery and in particular its effects on other topics and ideas. I think this bit of magic follows directly from how the human mind works. Without much prompting, it tries to build a picture of what is happening in front of it, even when the particular thing isn't expressed or seen implicitly. Then, once our minds has constructed a topic in terms of its boundaries and effects, we can more effectively go into the heart of the topic. Indeed, our understanding of it may be stronger for having first situated it in its context.
As one of my readers pointed out in response to the negative space piece, this is something that good writers take advantage of when describing a situation. Sometimes, you are better off saying less about something and letting the reader create her own image of it from what surrounds it. The image will be more vivid -- and the writing less blunt, more artful.
I have lost my link to Brian's discussion of this. If anyone has it, please let me know.
The Unsharp Mask Algorithm
Andy Hunt describes how to apply the Unsharp Mask algorithm when learning. Unsharp Mask comes from the world of image-processing programs such as Photoshop, in which it is used to make images sharper. It does so by first blurring the image. You might not think this could work, but it does. By taking the image out of focus, the software softens lines that may be the side effect of noise or other anomalies. When the program tries to focus the image again, we sometimes discover details and boundaries that were not obvious at all before.
Andy says, "I like to try to do something similar when faced with a sticky problem." He does so by taking his mind off the problem, doing something completely unrelated. That allows his mind to blur the edges of the problem for him, so that when he comes back to it he has to re-focus. In doing so, he may see something that he was missing before.
I imagine that we all have this pattern. I also wonder if there might not be a more direct application of the pattern to sticky problems. Rather than going off for a walk or to wash dishes, maybe we could continue working -- but by stepping back from the problem to a larger context. From a distance, the edges of our problem begin to blur. They don't look quite as imposing. After thinking about the larger context for a while, we can slowly focus back in on the tough problem. As we return, we may re-form those edges in a different way, helping us to see finer details than we did before.
That's all speculation, for now. I now go off in search for a problem to try it out on. :-)
I started college as an architecture major. In the first year, architecture students took two courses each semester: Studio and Design Communications Media. The latter had a lofty title, but it focused on the most basic drawing skills needed in order to communicate ideas visually in architecture. At the time, we all considered it a freehand art class, and on the surface it was. But even then I realized that I was learning more.
The textbook for DCM was Betty Edwards's Drawing on the Right Side of the Brain. It is about more than drawing as a skill; it is also about drawing out one's creativity. Studying this book, for the first time I realized that what we do in life depends intimately on what we see.
Often, when people try to draw a common object, such as a chair, they don't really draw the chair in front of them but rather some idealized form, a Chair, seen in their mind's eye. This chair is like a Platonic ideal, an exemplar, that represents the idea of a chair but is like no chair in particular. When the mind focuses on this ideal chair, it stops seeing the real chair in front of it, and the hands go onto cruise control drawing the ideal.
The great wonder in Edwards's book was that I could learn to see the objects in front of me. And, in doing so, I could learn to see things differently.
Drawing on the Right Side of the Brain introduces a number of techniques for seeing an object, for the first time or in a new way, with exercises aimed at translating this new vision into more realistic depictions of those items on paper or canvas.
I recently found myself thinking again about one of the techniques that Edwards taught me, in the realm of software. Alan Kay has often said that we computer computer scientists focus so intently on the objects in our object-oriented programming that we miss something much more important: the space between the objects. He speaks of the Japanese word ma, which can refer to the "interstitial tissue" in the web of relationships that make up a complex system. On this view, the greater value in creating software lies in getting the ma right.
This reminds me of the idea of negative space discussed in Edwards's book. One of her exercises asked the student to draw a chair. But, rather than trying to draw the chair itself, the student is to draw the space around the chair. You know, that little area hemmed in between the legs of the chair and the floor; the space between the bottom of the chair's back and its seat; and the space that is the rest of the room around the chair. In focusing on these spaces, I had to actually look at the space, because I don't have an image in my brain of an idealized space between the bottom of the chair's back and its seat. I had to look at the angles, and the shading, and that flaw in the seat fabric that makes the space seem a little ragged.
In a sense, the negative space technique is merely a way to trick one's mind into paying attention to the world in a situation when it would prefer to lazily haul out a stock "kitchen chair" image from its vault and send it to the fingers for drawing. But the trick works! I found myself able to draw much more convincing likenesses than I ever could before. And, if we trick ourselves repeatedly, we soon form a new habit for paying attention to the world.
This technique applies beyond the task of drawing, though. For example, it proves quite useful in communicating more effectively. Often, what isn't said is more important than what is said. The communication lies in the idea-space around the words spoken, its meaning borne out in the phrasing and intonation.
The trigger for this line of thought was my reading an entry in Brad Appleton's blog:
... the biggest thing [about software design] that I learned from [my undergraduate experience] was the importance of what I believe Christopher Alexander calls "negative space", only for software architecture. I glibly summarized it as
There is no CODE that is more flexible than NO Code!
The "secret" to good software design wasn't in knowing what to put into the code; it was in knowing what to leave OUT! It was in recognizing where the hard-spots and soft-spots were, and knowing where to leave space/room rather than trying to cram in more design.
Software designers could use this idea in different ways. Brad looks at the level of design and code: Leave room in a design, rather than overspecifying every behavior and entity that a program may need. But this sense of negative space is about what to leave out, not what to put in. The big surprise I had when using Edwards's negative space technique was that it helped me put the right things into my drawings -- by focusing on their complement.
I often think that the Decorator design pattern embodies negative space: Rather than designing new classes for each orthogonal behavior, define objects as behaviors with receptacles into which we can plug other objects. The negative space in a Decorator is what makes the Decorator powerful; it leaves as many details uncommitted as possible while still defining a meaningful behavior. I suppose that the Strategy pattern does the same sort of thing, turned inside out.
Maybe we can take this idea farther. What would it be like to design a program not as a set of objects, or a set of functions, but as Kay's ma? Rather than design actors, design the spaces in between them. Interfaces are a simple form of this, but I think that there is something deeper here. What if all we defined were an amorphous network of messages which some nebulous agents were able to snatch and answer? Blackboard architectures, once quite common in artificial intelligence, work something like this, but the focus there is still on creating knowledge sources, not their interactions. (Indeed, that was the whole point!)
Even crazier: what it would be like to design software not by focusing on the requirements that our users give us, but on the "negative space" around them? Instead of adding stuff to a concoction that we build, we could carve away the unwanted stuff from a block of software, the way a sculptor creates a statue. What would be our initial block of granite or marble? What would the carving feel like?
Whether any of these farfetched ideas bears fruit, thinking about them might be worthwhile. If Alan Kay is right, then we need to think about them.
Edwards's negative space technique makes for a powerful thinking strategy. Like any good metaphor, it helps us to ask different questions, ones that can help us to expose our preconceptions and subconscious biases.
And it could be of practical value to software designers, too. The next time you are stumped by a design problem, focus on the negative space around the thing you are building. What do you see?
The notion that practices from agile software development work outside of software should not surprise us too much. Agile practices emphasize individuals and interactions, doing things rather than talking about things, collaboration and communication, and openness to change. They reflect patterns of organization and interaction that are much bigger than the software world. (This reminds me of an idea that was hot a few years ago: design patterns occur in the real world, too.)
Oh, and good luck, Brian! I know the feeling. Two years ago, I had broken the 190-pound barrier and, despite recreational jogging, felt soft and out of shape. By exercising more and eating less (okay, exercising a lot more and eating a lot less), I returned to the healthier and happier 160-pound range. I'll keep an eye on your big visible chart.
On the flight home from my ChiliPLoP hot topic, I thought of a possible instance of creativity in sticking to a form, an unusual one in the realm of teaching. I wonder if I would be more creative when teaching a course if I subordinated my creative impulses to the design of someone's textbook.
When I first started teaching as a graduate student, I followed the assigned textbook rather closely. I remember clearly a comment a student made in my course evaluation one semester: "This is a great course to take at 2:00 PM in the spring. The instructor follows the textbook, so I can skip class on Friday and know just what he will cover." Usually, I was teaching one section of a multiple-section course with real faculty teaching the other sections. Between having little experience for deviating from the book and not wanting to cause a problem in the department, sticking to the book seemed like the Right Thing to do.
As I taught more and became 'real faculty' myself, I found myself deviating more and more. New ideas, new examples, new order of presentation -- all entered my mind and flowed out into my courses. Students had the textbook to read, for different coverage of the material, if not more complete. And I got to do more of my own thing.
These days, I tend to do my own thing all the time.
For example: In Programming Languages, I loved the approach of Essentials of Programming Languages, but my students had no background in Scheme coming into the course, so we didn't get very deep into the book. As my lecture notes became quite extensive, and deviated from the book in places, I found the book to be less and less help. Eventually, I just jettisoned it.
I just started teaching Algorithms last fall and so stuck with textbook the previous instructor had used, Anany Levitin's The Design and Analysis of Algorithms. My lecture notes are not yet nearly complete enough to replace a textbook, so I continue to assign substantial readings from the book. But I have several units during the semester that are do-my-own-thing (including Bloom filters and some fun pattern-based material) where the book is just along for the ride.
I've never written up all the lecture material for my object-oriented programming course in a readable form, so they remain a hodge-podge of readable stuff, slides, and pointers to outside reading. Even still, my dissatisfaction with the available books led me to drop my textbook requirement beginning this spring. I don't know if this was a good idea from the students' perspective and won't know for sure until after the course is over. However, I don't yet see a marked difference in student performance between this semester and last.
I wonder, though, if I have limited myself by giving myself too much freedom in some of these courses. Maybe if I stuck more closely to some textbook's topics and ordering, I would put myself in a position where I had to create something new and wonderful just to be able to say what I really want to say. Then again maybe I'm just following a natural progression in my each of my courses, starting close to some book and then growing into my own approach. The fact that every course I teach seems to follow a similar trajectory leads me to believe that the latter is happening and that everything is just fine.
But I still have an incomplete feeling in the back of my mind that strapping onto a decent textbook might be a great way to energize myself again in some course, and unleash a burst of creativity.
Maybe next fall. I teach Programming Languages again for the first time in a while, and graduate-level Algorithms for the first time ever.
Yesterday morning, one of my students told me that he was thinking of changing his major. It turns out that he was English major before switching to CS, and he is thinking about switching back. We got to talking about the similarities and differences between the majors and how much fun it would be to major in English or literature.
Some salesman I am! We need more CS majors, so I should probably have tried to convince to stay with us. Discussing the relative value in the two majors was beyond the scope of our short discussion, though, and that's not really what I want to write about.
The student mentioned that he knew of other folks who have bounced between CS and English in school, or who have studied in one field and ended up working in the other. I wasn't too surprised, as I know of several strong students in both disciplines who have performed well in the other and, more importantly, have deep interests in both. Writing and programming have a lot more in common than most people realize, and people who love to communicate in written form may well enjoy programming.
I myself love to read books by artists about their crafts. The "recommended reading list" that I give to students who ask includes two books on writing: William Zinsser's On Writing Well and Joseph Williams's Style. But I've enjoyed many wonderful books on writing over the years, often on recommendation from other software developers...
Each has taught me something about how to write. They have helped me write better technical papers and better instructional material. But I have to admit that I don't usually read these books for such practical reasons. I just like to feel what it's like to be a writer: the need to have a voice, the passion for craft. These books keep me motivated as a computer scientist, and they have indirectly helped me to write better programs.
Writers aren't the only artists whose introspective writing I like to read. The next book to read on my nightstand is Twyla Tharp's The Creative Habit. Dance is much different than fiction, but it, too, has something to teach us software folks. (I seem to recall a dinner at PLoP many years ago at which Brad Appleton suggested dance as a metaphor for software development.)
When I started writing this essay, I thought that it would be about my recommended reading list. That's not how it turned out. Writing is like that. So is software development sometimes.