Alec Nevala-Lee

Thoughts on art, creativity, and the writing life.

Posts Tagged ‘Brian Kernighan

Quote of the Day

leave a comment »

Brian Kernighan

Debugging is at least twice as hard as writing the program in the first place. So if your code is as clever as you can possibly make it, then by definition you’re not smart enough to debug it.

Brian Kernighan

Written by nevalalee

November 24, 2015 at 6:30 am

Posted in Quote of the Day

Tagged with

How to debug a novel

with 4 comments

Sad Mac

The most effective debugging tool is still careful thought, coupled with judiciously placed print statements.
—Brian Kernighan

Revising a novel and debugging a computer program may seem like very different activities, but they have one important thing in common: when something breaks, you usually don’t know the hell why. With a program, at least, it’s often clear when you have a problem. You’ve carefully written a bunch of code—or typed it in verbatim from a textbook—and checked it over for mistakes, but when you compile and run it, you end up with an error message, a bunch of garbage, or nothing at all. When a novel is failing, it isn’t always as obvious. You’ve invested months into telling a particular story, which you wouldn’t have done if you didn’t care about it, but when you take a few weeks off and go back to reread it, the result seems inert: the characters are flat, the events don’t pop the way they did in your imagination, and you find yourself getting bored by your own story before you’re halfway done. What’s required, in short, is debugging. And while coders have access to a range of useful debugging tools, if you’re writing fiction, you’ve got no choice but to do it the old-fashioned way.

The first step in traditional debugging is to carefully read over the code, preferably on paper. Sometimes you find that you’ve made a stupid syntactical mistake—there’s a missing semicolon or closing parenthesis that throws the entire program out of whack. The equivalent in fiction is bad grammar or sloppy sentence construction, which makes even the best stories die on the page. (Here the best guide, as usual, is Strunk and White, and it’s no accident that its example inspired Brian Kernighan and P.J. Plauger to write The Elements of Programming Style.) On a somewhat higher level, you can ask yourself whether the story follows the few objective rules of storytelling in which you have any confidence. These vary from one genre to another, as well as between authors, but most writers eventually figure out a set of their own. Does the protagonist have a logical objective from one moment to the next? Does each scene start as late and end as early as possible? Does every chapter open with a clear situation? These are the building blocks of narrative, and if they don’t work on the lowest level, the story is likely to fall apart on the highest.

Charles Dickens's manuscript for A Christmas Carol

Which brings us to the print statement. It’s a trick that most beginning programmers figure out on their own: if a program is breaking, it’s often because one or more variables aren’t receiving the values they should. Modern debuggers have tools for tracking down such problems, but the most basic solution is to insert print statements into the code to display the value of the suspect variables at each stage in the process. It’s a window into the program, allowing you to follow it step by step. And although there isn’t an exact equivalent in writing fiction—in which everything is right there on the page—it can often be useful to pause the story to ask yourself where exactly you stand. As a writer reading over your own work, you have full knowledge of where the story is going, and you know that a slow stretch in Chapter 5 is necessary to set up an exciting sequence in Chapter 6. But a reader doesn’t know this. As difficult as it might be, then, you need to ask yourself what a reader encountering the story for the first time will think of a scene on its own terms. And writing it out often helps. Like a print statement, it’s a snapshot of where the story is right now, which is all the reader—or computer—can be expected to care about.

The last technique worth mentioning is the wolf fence algorithm, as first described by Edward Gauss:

There’s one wolf in Alaska, how do you find it? First build a fence down the middle of the state, wait for the wolf to howl, determine which side of the fence it is on. Repeat process on that side only, until you get to the point where you can see the wolf.

In programming, this means subdividing the code until you find the section where the program is failing, then repeating the process until you’ve zeroed in on the problem. Most novelists tend to do this intuitively. When you’re reading over a novel, you start to think of it in large chunks: you know that the sequence from page 150 to 250 works fine, while the first forty pages are giving you trouble, even if you’re not sure how or where. Instead of trying to crack the novel as a whole, it makes sense to focus on the trouble spots, continuing to narrow the scope as you iteratively revise . After the first revision, you find that three out of the five chapters in question seem fine, even though the overall section is still giving you trouble, which implies that the problem is in one of the two chapters remaining. And you repeat as necessary, homing in on something as small as a misconceived page or paragraph, until you’ve found your wolf.

Written by nevalalee

September 12, 2013 at 8:48 am

Quote of the Day

leave a comment »

Written by nevalalee

September 2, 2013 at 7:00 am

The recursive art of fiction

with 3 comments

Quicksort

One of the most striking things about writing fiction is how the strategies you apply to the highest level of story often work on the smallest pieces as well. Take, for instance, one of the most basic rules of craft: start the story as late in the action as possible, and end it as soon after the climax as you can. In the rewrite, jumping in late and getting out early sometimes means cutting pages from the beginning and end to remove extraneous material, or engaging in slightly more sophisticated surgery: the pulp novelist Jack Woodford, in two brilliant pieces of advice I’ve quoted here before, notes that you can keep much of the “the usual driveling collection” of exposition and anticlimaxes if you restructure the novel so that the real beginning and end come before and after the boring parts. The same rule applies to individual chapters, scenes, and beats. William Goldman famously advises writers to omit the beginning and end of each scene so the story jumps from middle to middle, and I’ve often fixed a sequence of chapters that didn’t work by cutting the first and last paragraphs of each.

In other words, a rule that works for the overall shape of the story also helps you make decisions about the structure of its smallest components. This isn’t so far from the principle of recursion as understood in computer science. Recursion means writing a function—a set of instructions—that at one point in the process calls on itself to deal with a subset of the larger problem. The most famous example is Quicksort, the sorting algorithm developed in the sixties by C.A.R. Hoare. Quicksort begins with a string of numbers to be sorted, picks one number at random from the middle of the string, then sorts the entire list into two parts, with all the larger numbers in one half and the smaller ones in the other. Then it applies itself to each smaller piece, dividing and sorting until a subset has fewer than two elements, which means we’re done. And although recursion doesn’t always result in saving time or storage, it’s a useful way to think about problems, as Kernighan and Ritchie note: “Recursive code is more compact, and often much easier to write and understand, than the non-recursive equivalent.”

Quicksort tree

That’s the benefit of a recursive approach to fiction, too: it tackles big problems in ways that are intuitively easier to understand because you’ve already used them on a lower level, and vice-versa. I’ve found that when a novel gets off track, it’s often because the writer has gotten lost in the weeds: you get hung up on little details—like how to get a character out of a room—until you’re so close to the problem that you can no longer see it. The solution is to remember that each chapter, scene, or paragraph is really a story in miniature, and it can be hacked in the same way you found the novel’s three acts. A recursive set of rules for writing fiction might look something like this, starting at the level of the story as a whole and working your way down:

  1. Divide the narrative unit into three parts. (This is usually a matter of intuition, and, like choosing the initial element in Quicksort, it doesn’t really matter at first where you draw the lines. We divide the story into three parts, rather than two, in deference to the rule of three.)
  2. For each unit, figure out the protagonist’s objective and the action he or she needs to take to achieve it.
  3. Repeat for each subsidiary unit until it can’t be divided any further.

In practice, this means that the story as a whole falls into three acts; each act falls into three sequences, with each one consisting of, say, ten chapters; each sequence yields three smaller sequences; each chapter has its own beginning, middle, and end; and so on down to the level of the page and paragraph, until you’re down to a single beat—a unit of narrative that can’t be divided any more. For that beat, you find the protagonist’s objective and concrete, physical actions, which, when taken together, add up to the overall objective for the scene, all the way up to the superobjective for the novel as a whole. (This way of breaking down scenes into beats and thinking in terms of objectives is more fully explored in David Mamet’s On Directing Film, which does for storytelling what The C Programming Language does for coding.) Put this way, it may sound mechanical, and it is: in practice, it’s more of a dialogue between the writer’s intuition and rational mind, as you try to fit in scenes that have seized your imagination into the overall logic of the narrative. Like coding, it’s rarely as neat in practice as in theory. But thinking about it recursively helps us remember that the rules at the top are often the same as the ones at the bottom.

Written by nevalalee

August 19, 2013 at 9:31 am

A writer’s code

with 3 comments

Anagram generator from Foucault's Pendulum

One of the small pleasures in writing this blog—and in particular in coming up with the quotes of the day—has been a renewed appreciation of the affinities between writing fiction and computer programming. There’s a remarkably rich body of literature on the art of coding, and simply by browsing through the available works in search of memorable insights, I’ve come to realize that coders deal with many of the same problems that I’ve had to confront in my novels, especially structure, clarity, and managing complexity. Hacking, like writing, requires a balance between formal elegance and quick and dirty fixes, and a coder is often required to choose between ingenuity and readability: a clever solution may be beautiful in the moment, but it can be all but impenetrable if the author—or anyone else—comes back to pick it apart months or years later. And unlike novelists, coders get immediate feedback on the validity of their solutions from a rigorous, if somewhat unimaginative, reader.

The problem is that I haven’t done a lot of hacking on my own. Growing up, I spent hours messing with BASIC on an ancient “portable” computer that didn’t even have a hard drive. (My earliest program, written when I was thirteen or so, involved expanding the anagram generator that Umberto Eco provides in Foucault’s Pendulum to handle words of more than four characters.) Later, I took a computer science class or two in high school, but I haven’t done anything meaningful since.  More recently, I’ve found myself longing to jump back into programming for a fairly specific reason: not to do any serious coding of my own, and certainly not to get paid for it, but simply to gain access to the enormous amount of material written by coders on how they approach their work. Compared to the handful of well-worn tidbits that writers repeatedly invoke on craft, it strikes me as admirably pragmatic, dense, and varied, and even at a glance, it clearly has elements that I can put into practice.

A snippet of source code from Doom 3

This leaves me with the question of which language to learn, an issue that inspires predictably strong opinions on all sides. Not surprisingly, I made the final call based on the books I wanted to read. At the moment, I’m working through The C Programming Language by Dennis Ritchie and Brian Kernighan, which is generally regard as the best book of its kind, and I’m planning to follow it up with The Design and Evolution of C++ by Bjarne Stroustrup, which is one of those extended looks into a sustained design process that I find so irresistible, whether the subject is writing, animation, or cuisine. C and C++ might seem like odd choices for recreational coding, but they’re useful for my purposes because there’s so much source code available, along with what I can only describe as a highly specialized form of literary criticism, like Shawn McGrath’s recent appreciation of the beauty of Doom 3. There’s a whole world of material out there, and I’ve found that it only takes a little work to start to appreciate the basics.

Once I’ve played with C and C++ to my satisfaction, I’m hoping to jump into Lisp. This might seem like another strange choice, and I hope to explore it further in a future post. Suffice to say that Lisp, like C, offers a range of interesting reading material, from Paul Graham’s books on the subject to Douglas Hofstadter’s three essays in Metamagical Themas to Peter Seibel’s Practical Common Lisp. (Seibel, a former English major, is also the author of Coders at Work, which attempts to do for hacking what the Paris Review interviews did for fiction.) Lisp also strikes me as the most novelistic programming language, and the one with the greatest natural affinities to creative writing—but we’ll see. When you’re a writer, you’re always looking for tricks that your peers haven’t discovered yet, as well as any source of insight or competitive advantage, and given my interests and approach to craft, I think a deep dive into coding is the next logical step. Whether or not it yields anything useful is something I’m still waiting to find out. But if it does, you’ll be reading about it here.

Quote of the Day

with one comment

Written by nevalalee

December 12, 2012 at 7:30 am

Posted in Quote of the Day

Tagged with

Quote of the Day

leave a comment »

Debugging is twice as hard as writing the code in the first place.  Therefore, if you write the code as cleverly as possible, you are—by definition—not smart enough to debug it.

Brian Kernighan

Written by nevalalee

October 22, 2012 at 7:30 am

Posted in Quote of the Day

Tagged with

%d bloggers like this: