The purpose of art is to delight us; certain men and women (no smarter than you or I) whose art can delight us have been given dispensation from going out and fetching water and carrying wood. It's no more elaborate than that. — David Mamet

Apr 14 23 2014

Driven

David Heinemeier Hansson recants test-driven development:

Test-first fundamentalism is like abstinence-only sex ed: An unrealistic, ineffective morality campaign for self-loathing and shaming.

In effect, Hansson echoes Jim Coplien’s complaints in Why Most Unit Testing Is A Waste. Coplien is a fascinating character in the C++ world , an exponent of astonishing techniques for doing things that, perhaps, are sometimes best left undone but which are great to know how to do. Coplien argue, in essence, that:

  • Unit testing is bound to miss lots of bugs, because you can test only a small fraction of the state space for even trivial objects.
  • Finding the right seams and the crucial boundary conditions is not harder than simply proving correctness, which is where we got on the bus.
  • What we really need to do is to test systems and subsystems, anyway.

Hansson writes that

Test-first units leads to an overly complex web of intermediary objects and indirection in order to avoid doing anything that's "slow". Like hitting the database. Or file IO. Or going through the browser to test the whole system. It's given birth to some truly horrendous monstrosities of architecture. A dense jungle of service objects, command patterns, and worse.

This echoes Brent’s concern about splitting big objects into a basket of bunnies, but it’s essential to understand how good design rules can lead to bad design if you don’t keep your eyes open.

The Primrose Path

Isolated behavior is good. Being able to instantiate an object simply is good. Avoiding complex dependency graphs is good. Being able to use an object without a database or the network is good.

But it’s never good to go overboard and let the pursuit of the good create disaster; you seldom want to give the bunnies a skein of colorful yarn and hope for the best. Specifically, it’s quite easy, when splitting a messy big object into smaller objects, to choose bad boundaries. It’s good to be simple here, but only if that doesn’t add too much complexity there. It’s good to isolate this, but only if isolating it doesn’t mean that everything else has to jump through hoops.

This happens all the time in design. A friend of mine was designing an embassy for a funny-sized lot. The reception areas gradually grew to make them lighter and grander. The staircase grew to balance the reception area. A garden pavilion provided a great space for casual entertaining and only required moving the whole building a bit on the site. Small, sensible adjustments. And then: it turned out that the driveway radius was now smaller than the turning radius of a limousine. And while you or I could live with that, an embassy can’t, and you really don’t want to discover this after you’ve done all the drawings of the beautiful but impossible garden pavilion.

Aye, madame, ’tis common

One of the core design assumptions in Tinderbox is that a map’s or an outline’s LayoutPolicy doesn’t know about the DrawingPolicy, and the DrawingPolicy doesn’t know about the LayoutPolicy. That seems a sensible separation of concerns. I wasn’t sure it was right when I first tried it, ten years back. I’m still not sure it’s right. Perhaps they really belong together. Or perhaps they should have been divided differently. One day, we’ll see what the alternatives are; until then, it works.

Another design decision involves the way timeline bands are managed. My reflex is to put all the work into the TimelandBand and make the list of bands, BandList, a simple composite. One day, I tried something different: I made BandList the smart class and hollowed out TimelineBand until it was little more than an BandListIterator. That worked, but it never felt right, and I spent last weekend moving functionality around until timelines felt less acrobatic.

Tech Fundamentalism Is Scary

Methodological fundamentalists descend on technology from time to time. Hell, TDD and agile started as a rebellion against an older tech fundamentalism. As a profession, we’re suckers for The Word and want to know The True Way. Sometimes, the methodologies do help: structured programming, literate programming, strong types, weak types, objects, patterns, functional, agile: it’s all been good for us.

But, perversely, these helpful little ideas often become modes of punishment. The zealots with fire in their eyes arrive to tell us that you’re doing it wrong. Pointy-haired managers support them because it reinforces their authority, and because it’s easy to see surface flaws and hard to understand deep structure. And – let’s face it – a lot of us are all too receptive of that message. The beatings will continue.

The mass of guilt that weighs upon the field deadens our conferences. That guilt arises from the divergence of what we like from what we think we should like. We enjoy exciting new systems that do what nothing else could do; we think we should like systematic demonstrations that this widget lets students do a task 5% faster than that one. We enjoy daring prototypes and agile development; we think we should be planning our work and proving correctness. We enjoy astonishing code; we think we should write code so clear that our most mediocre students (and the management team) will grasp it without effort.
Apr 14 15 2014

How I Live Now

by Meg Rosoff

A delightful YA dystopia in which Daisy, an American teenager with a temper and a bit of an eating disorder, spends a summer with her Aunt’s English family in order to get away from her newly pregnant stepmother. Unfortunately, this turns out to be the summer of World War III.

The superbly-paced book differs in important directions from the recent (and superb) film, and the differences repay thought. Some are mere abridgments, some heighten the drama, some exploit aural or visual references (Fairport Convention, the Dursley’s neighborhood) that wouldn’t work on the page.

The English setting works very well, and though the details of this war are not terrifically plausible, this is surely a story that unfolded in the south of France in 1940, in Kosovo, in Iraq and Afghanistan and probably in villages not far from Thermopylae and Jericho.

In passive vs. imperative linking, Mark Baker discusses the difference between imperative links – links that tell you to Click Here! – and what he calls passive links – everything else.

A friend wrote to ask whether this distinction has a counterpart in hypertext theory. I don’t believe it does, in part because most students of hypertext rhetoric always viewed imperative links as a mistake or an anomaly. Baker agrees.

What we’re really talking about here is not the link but the link anchor, and the distinction is really one of voice: do we tell the reader what to do, or do we lay the matter out in front of the reader and trust the audience. Lots of current Web practice despises the audience, treating it as a herd to be lured into whatever lurid sideshow you’re using today to decorate your ads. That’s clearly neither sustainable nor desirable.

In his Hypertext ’87 keynote, Ted Nelson drew pictures of what we today would call banner ads, shouting “Click Me!” Everyone assumed this was satire.

Are imperative links ever useful? I think they make sense in only a few contexts:

  • Where the link appears in the form of an image or UI widgets, the instruction to “Click here…” indicates that this is an active link, not merely an illustration.
  • Where the link is an instrument for taking an action, the imperative voice fits well with direct address. “Use the inspector to change the properties of the selected item. Click here to open the inspector now.”
  • Where the link cannot appear in its natural context. Baker identifies the most common cause for this, the style rule that prohibits links in body text. That custom is a mistake. Occasionally, though, no appropriate anchor can be found, or placing a link in its natural place might overload a sentence. A footnote or sidebar can be valuable.

The most important point in Baker’s piece is that writers must not presume to know what the reader wants or needs, or why they are reading. The reader’s purposes are hidden from us. They are hidden from the reader. No one knows, from moment to moment, why they’re reading what they are; endless studies of hypertext reading behavior have revealed little, but this much we know. When it comes to reading, nobody knows what the hell they’re doing, but never imagine that you know better than your reader what she needs or wants.

Apr 14 13 2014

It’s Not C

Brent Simmons looks at there Heartbleed Bug and the Goto Fail and blames C: That Pretty Much Wraps it Up for C.

This is wrong, and also dangerous.

Wrong: Any computer language capable of doing real work is also capable of being confusing, capable of being misused, capable of being subverted. That’s why they call it a language. Both these errors were deep in trusted system code, written and reviewed by experts and hiding in plain sight; bugs are like that. The open source charlatans have been shouting for years that it Can’t Happen Here. It did. Twice in two months.

Dangerous: Powerful people wish folks like Brent and me – people who write programs – were all safely inside the military-entertainment complex. If they could lock down computing even more – licenses for programmers, permits for running applications, banning software not sanctioned by the government or by a Fortune 500 company – they could extract better prices. You wouldn’t actually get fewer bugs: you’d just never find out about them. Your mail wouldn’t be more secure; you’d only find out about the insecurity when they knocked on your door, or mysteriously misdirected an embarrassing email to the press, or somehow your “sealed bid” was leaked to your rival, or your daughter’s chat transcript mysteriously got posted to Facebook.

There’s reason to think that goto, and maybe Heartbleed, were deliberate errors introduced by subverted programmers. Abjuring C isn’t going to protect you from that. Hell: we can barely protect against embezzlement – the introduction of intentional errors in adding up a bunch of numbers. Most programs are more complicated than that.

If you have free speech, you risk dangerous speech. If you have free computing, you risk dangerous programs.


Update: Brent’s reply is generous and absolutely right.

Apr 14 11 2014

Sisterland

by Curtis Sittenfeld

The latest novel by the author of the estimable Prep shares many of its strengths. Twin sisters grow up in St. Louis. They’re a lot alike, and they’re a lot like everyone else, except that they have occasional precognitive dreams. Violet grows up to be a psychic, Daisy suppresses her talent and grows up to be a faculty wife, and then one day Violet predicts an earthquake and winds up on the Today Show. A sensitive portrait of relationships, not only between the twins but also a remarkable picture of Daisy and her sensitive, caring, and non-psychic husband.

In the current New Yorker, Daniel Mendelsohn looks at a new book, The Parthenon Enigma, in which Joan Breton Connelly proposes that a central theme in the temple was the human sacrifice of the daughters of the mythical king Erechtheus. This has provoked some shock and fuss, though it seems to me that everyone knows the Greeks had a thing for sacrificing young girls: Polyxena, Antigone, Iphigenia, and who knows what I’m forgetting.

In passing, Mendelsohn explains (and the New Yorker fact checkers approved) an explanation of the size of the Delian League’s treasury.

At that time, it was valued at eight thousand talents – roughly $4.8 billion in today’s money, by one estimate. Another six hundred talents, or about three hundred and sixty million dollars, rolled in annually as tribute from Athens’ ‘allies.’”

Can this possibly be right?

It’s impossible, really, to work out exchange rates for the ancient world. The wealth of Croesus would not suffice to buy a bottle of penicillin. Not only could Midas himself not have bought an iPhone: he couldn’t have bought a window pane. Conversely, you could walk down to the agora and pick up a nice mixing bowl for spare change that would today command millions of dollars.

A talent was literally 25.86 kg of gold. If you assume that ancient gold was worth today’s price of $1318/troy oz, the 5000 talents in the treasury do work out to about five billion dollars. That’s a million dollars a talent.

But that’s probably not a great way to look at things. Herodotos thought there were about 30,000 Athenian citizens in the 5th century. Atheneaus reports 21,000 in the late 4th century. This doesn’t count women, children, and slaves, so perhaps there were 100,000 people in all of Attica. Maybe 150,000. Athens proper would have been much smaller; it would be another five hundred years before technology could support a city of perhaps a million people.

A workman or civil servant in Athens might earn between 1/3 and 1 drachma a day; there were 6000 drachmae to a talent. So one talent is enough money to take care of 20 households for a year. If you say that’s, say, $45,000 per household, a talent works out to about $900K – pretty close to our million bucks. Of course, $45K today buys you air conditioning and television and HBO and fresh fruit; even rich Athenians didn’t have any of that stuff. They lived like village people in Southeast Asia; maybe we’re really talking $4,500/year and we’re an order of magnitude high. Even so, I’m really surprised it’s that close.

On the other hand, a market price requires a willing buyer. Who would have – who could have – bought 5000 talents? Centuries later, this would be a real problem with the Roman economy; Tiberius Caesar tried to live a frugal life and nearly wrecked the economy of the world because he had all the money there was.

Apr 14 7 2014

How I Live Now

I generally don’t comment about films here: I don’t know much about making them, and everyone who cares has already heard about movies before I see them.

But I hadn’t heard anything at all about How I Live Now, and you ought to take a look. (Streaming from Netflix). Its director thinks it’s too dark for the US, but it’s a terrific YA dystopia. Daisy is an American (played wonderfully by Irish actress Saoirse Ronan, even though she is never convincingly Yankee) who is sent to visit her British cousins. One of them picks her up at Heathrow and drives her far, far into the countryside. Fairport’s Tam Lin is on the radio; Daisy rolls her eyes. The cousins are irritating and charming and the oldest boy is gorgeous and sweet.

And then World War III breaks out.

by James White

A correspondent mentioned the idea of culinary science fiction, and this seemed such a surprising concept that I went looking for precedents in the superb Encyclopedia of Science Fiction.

This is a charming, if simple, book about a great cook who decides to join Sector General, the great galactic hospital, in order to do something about the food. All the usual challenges of hospital food are present, along with such inter-species challenges as table manners in a cafeteria where the physician sitting next to you might look a lot like your dinner.

We won. Phew. Great relief. Celebrated until the wee hours, slept in, cleaned up.

For getting out the vote (which turned out to be the difference in this close race), I did a lot of cooking for volunteers. I’ve done this now for a series of campaigns. I’m not a pro — I’ve never cooked this much stuff. Here are some notes about cooking for a bunch of volunteers.

  • Timing matters. Getting the food to the right place at the right time is the most important thing. It’s better to have mediocre food where the hungry people are than to have perfectly good food in an empty room when everyone’s gone back out to their turf.
  • Organizers don’t know what they need. This has been a constant for all the campaigns: the people in charge never seem to have very good plans for how they’ll organize and staff the final push. This seems strange to me: they’re running an engagement campaign dedicated to identifying and turning out your voters, and you’d think they’d spend a lot of energy planning the endgame. They don’t. But you need to know how much stuff to buy and cook, and how you’re going to get it where it needs to be. Expect last minute changes, and prepare for them.
  • Vegetarians. It’s a big tent, and people have different tastes. Our side, I think, is especially challenging because we’ve got the vegetarians and the vegans and all sorts of other dietary needs. I’ve been trying to be sure there’s a vegetarian option (though not necessarily vegan), and that’s been popular. On election day, we went through more of the vegetarian posole than the pork picadillo.
  • Allergies and Religious Diets. Keep people informed, and let the chips fall where they may. Volunteers with really tight constraints are probably in the habit of packing their own snacks. But people will want to know whether those crunchy bits are peanuts or tree nuts, or whether that’s beef, pork, or chicken.
  • Signs. Make a nice sign describing the food. This makes people comfortable, and shows consideration, and also gives you a chance to show that care was taken. One point of cooking for volunteers is just logistics – feed the volunteers so they can get back on the street faster – but another point is social. If you’re using good ingredients (organic flour, home-grown basil, your mother’s pie crust) tell them.
  • Limits. You’re cooking at home. It’s not a restaurant kitchen. You’re not a line cook. Know your limits, and think about the limits of your equipment. Banging out sixty meals in one day reduced me to a quivering jello. Lots of people do that for lunch, literally.

Equipment limits you want to consider include:

  • Your oven: can you fit everything you need? If you have to do the bread then the roast for dinner and dinner’s 40 minutes late, that’s an extra margarita. If you do that on election day, everyone goes hungry.
  • Your refrigerator: will everything fit? You’ll be cooking in larger quantities than usual; do your big bowls even fit in your refrigerator?
  • Your bowls: maybe it’s just me, but I’m always running out of bowls for election day. (Parties, it’s usually spoons.)
  • Your stand mixer. This is a hard limit and it matters. Usually, it’s no big deal to double a recipe. If you’ve got a honking big mixer like mine, you may be able to quadruple it. After than, you’re doing multiple batches. When it comes to your mixer, a little too much is a big mess.
  • Look out: things are going to be a lot less fun if you get a cut or a burn. Be especially careful with the mandolin and the vegetable peeler; they’re not interesting the way a knife is, but they can be painful. In school, they taut us a mantra back when chemists actually blew glass: “hot glass looks like cold glass.” Repeat it early and often.
  • Four hours. This is home cooking, and it’s going to be sitting in the kitchens of strangers. You’re not a pro. Cook clean and do your best. The rule of thumb is that everything that can spoil gets at most 4 hours at room temperature – including prep and sitting around on the table. You want as much of that four hours to be for the volunteers. This, incidentally, is the genius of the kolache as election food: the smoked sausage and the jam are both preserved and then they’re sterilized and protected by the bread baked around them. That’s better engineering than a plate full of sandwiches or a box of cold pizza.

Stop Crying About Choice is an oddly-named but unusually perceptive discussion of choice at the boundary of hypertext fiction and games, written by “HM” who might perhaps be Joel Goodwin.

I disagree with much of the argument – I think the author mistakes the importance of rereading and of contemplation, having little patience for or interest in lyric – but this is the way to do it: serious and thoughtful discussion based on familiarity with lots of works.

I’ve forgotten a detail of C++ semantics; perhaps a reader can give me a hand.

We have a simple function, Mill, the does a task. We create an object saved for its side effects: for example, the constructor saves the graphic state and the destructor restores it.

void MyClass::Mill() {
	GraphicState saved(albatross,ptarmigan);
	doSomething();
	}

This is straightforward and idiomatic C++.

Now, let the optimizing compiler into the mix. In principle, it could see that tail call of doSomething and say to itself, “I could avoid a procedure call by inlining doSomething inside Mill.” And so it could. What I think it cannot do, though, and what I think LLVM is doing, is to call the destructor of saved before it calls doSomething.

So: am I correct in thinking that the GraphicState destructor should not be called until after doSomething returns? And could LLVM really be doing this wrong? It’s been years – like a decade – since I even smelled a compiler bug.

We’re having a special election for the State Senate. It’s the latest in the chain. Obama appointed John Kerry, our US Senator, to the cabinet. So we had an election — and we elected Ed Markey, our Representative, to the Senate. So then we had a special election, and we elected Katherine Clark, our state senator, to the House. Today, we have another election for her seat.

Kate’s Fourth Rule of political volunteers reads:

4) FEED US. This can be as simple as offering us a cup of coffee during a cold standout or a bottle of water to bring with us on a hot canvass. Granola bars and raisins are easy to manage food. Some of us might find providing homemade snacks to be an enjoyable way to help. There are great cooks and bakers in the volunteer ranks. It saves money and adds a nice atmosphere. A little sustenance will make us more efficient, obviating the need for breaks to buy food.

I’ve been trying to help all these campaigns with social media, web sites, online strategy, email — you know, the stuff I do. But I’m a volunteer, so all they want is knocking doors and making phone calls. I’m no good at that, so I cook.

If our team wants volunteers – and the powers that be say we do – we’ve got to do a better job at attracting volunteers under the age of seventy. Decent food might make things a little more fun. Of course, real work that uses real skills would help even more. One fact of the new reality that still hasn’t quite dawned on these old political groups is that the Democratic rank and file has changed. Sure, in 1932, we had a disadvantage because the other team had all the doctors and lawyers and writers; we had pipe fitters and longshoremen, but what does a campaign need with a pipe fitter? But nowadays we have all the doctors and writers, and we treat them like pipe fitters.

I’m OK cooking for two, or maybe the occasional eight-person dinner party. Today, we needed sixty — 20 breakfast, 20 lunch, 20 afternoon sustenance — for different groups at different staging areas. So I’ve been cooking since 6PM yesterday, with six hours off (11PM-5am) for sleep.

Breakfast

  • Current Affairs (currant scones, a double batch)
  • Bagel Bombs
  • Onion bacon focaccia

The scones are Alice Waters, the Bagel Bombs are Christina Tosi, and the focaccia is Susan Goin. So a feminist breakfast, too, in its way.

Lunch

  • Picadillo
  • Posole with poblano creme
  • Potato bread rolls

Our candidate was born in South Africa, which is meaningless in the campaign but a Fun Fact. So I did an improvised take on South Africa’s bunny chow, curries served in a hollowed out bread loaf. Canonically it’s wonder bread, but this crowd isn’t going for white bread and, if you want Democratic volunteers to eat anything, you have to provide small portions. (They’ll eat lots of little things, but if it looks big they won’t touch it.)

Afternoon

  • Kolachki (smoked sausage rolls with fig jam)
  • Koeksisters

I started with the kolachkis for the Markey campaign. They’re a good campaign food: around here, they’re interesting enough for everyone but not scary enough to frighten the proverbial old ladies. I’ve done them with apricot, but fig’s a lovely combination with smoked sausage.

Koeksisters, as far as I can tell, are the South African member of the churros family, a relative of the doughnut. I have some trisol I wanted to try again, so this made sense. But some disaster befell my choux paste and it was not nearly thick enough to pipe, even after adding additional flour. So, they’re messy and incoherent koeksisters.

Bottom line

Sixty is a lot more than eight. I sure hope people enjoy this stuff. I sure hope we win.

Most of the tech press acts as if the surface design of gadgets is what that matters. Sometimes, they’re right. Most of the time, design lies deeper.

Lots of programming pundits right now will tell you that simplicity is what matters. Or testing. Sometimes, they’re right. A lot of the time, design lies deeper

The Problem

In a Tinderbox Six outline, pressing up-arrow moves the selection up, and pressing down-arrow moves the selection down. In a long, long outline, press and hold an arrow key. You might scroll through a page or two of notes and then, suddenly, stall. Now when it ought to be scrolling, Tinderbox would beep at you.

Clues

You always scroll through all the currently-visible notes, and then some more notes, before stalling; you never seem to stall immediately. ❧ There’s nothing special about the note on which you stall. ❧ Things are worse when you press and hold the arrow keys. Moving more deliberately, one click at a time, you’re less likely to stall.

Note that all these hints can be explained away by saying, “It’s unlikely that you’ll stall on any given note.” That turns out not to be the explanation, but that is the simplest explanation and Occam is often a terrific companion for the software detective.

Undercover

In an outline, each note has a MapItemView that represents the note on screen. Inside a MapItemView, we have a text field for the name of the note, and some other subviews. When we press the arrow key, we do several things:

  1. figure out which note is the next or previous note.
  2. select it, giving it first responsibility for handling events
  3. if that note is off screen, scroll until it is visible.

This is pretty simple, and it’s hard to see how you could make it simpler and still do what needs to be done.

In fact, it’s really too simple, because a big outline will have hundreds of notes, maybe thousands of notes, but only a few dozen notes are going to be visible at any one time. Views are big, complicated things that take lots of work and lots of memory, and the views that are outside the scroll area aren’t doing us any good. So, we add some logic:

  1. if the note is offscreen, put its view into the recycling pool
  2. if the note is onscreen…
    1. if it has no view, get one for it (preferably a recycled view)
    2. if it’s changed, ask the system to redraw it when convenient

That’s simple, too. When do we need to do this? Well, obviously, we need this when we scroll. And when we press up-arrow or down-arrow, we’d better be sure that the note has a view before we select it and put it in charge of event handling.

Crime

And there’s our answer! At the bottom of the screen, we press down-arrow several times in a row, very quickly. The note we’ve now selected is, say, five notes below the bottom. It’s now in charge. And we press again, so it’s going to hand off to the next note.

BUT… scrolling is animated — jt plays out over time, on its own schedule. So now, perhaps, we scroll the screen a bit. And maybe we look around for any off-screen views we can recycle. We’re pressing down-arrow, so a bunch of views have scrolled off the top of the screen. Recycle them!

Oh — and there are some views beneath the bottom of the screen, too – because we’ve pressed the key so quickly. They’re offscreen. Recycle those, too!

And so the view that’s responsible for handling events goes into the recycling pool. Sure, before the note gets to the edge of the screen, we’ll make it a new view. But that view won’t be handling events. And the old view won’t be, either, because we’ve removed it from its window and that takes it off duty. So no one handles events, and we start beeping.

Investigator’s Report

I began with the usual suspects and routine probing, but got nowhere. This persisted through several attempts, concentrating on finding attempts to set the keyboard focus. Ultimately, every Tinderbox method that explicitly set the keyboard focus was examined, but none appeared to by setting it incorrectly.

Once I knew this investigation was at least a bear and possibly an epic, I concluded that the actual crime had to be that some unknown rogue object was covertly stealing the keyboard focus. To catch the thief, I eventually built all sorts of monitors, ultimately subclassing NSWindow so I could intercept every call to makeFirstResponder:, only to find that no one was stealing the keyboard focus. If no one was stealing the focus, why was firstResponder a note one minute and nil the next? Oh: someone is stealing the view, and that view was holding the keyboard focus. To steal the Torkington Tiara, they abducted Lady Torkington.

Verdict

Just don’t recycle a note that’s selected. Wait until it’s not selected, even if it’s offscreen.

Punishment

On the surface, this was a tiny UI glitch, one that’s barely an inconvenience. In practice, it might require an unnecessary mouse click for every 100-250 arrow key presses. Say a mouse click takes 3 seconds, and the average user makes $100,000/year. That’s about a nickel per click. But a lot of that scrolling isn’t really productive anyway: lots of scrolling is actually a displacement activity, something people do while they’re thinking or worrying or waiting to get off the phone. So making that scrolling a little slower or less fun isn’t good, but it’s not really costing anyone any money. How many unnecessary mouse clicks do we need to save to justify the twenty or thirty hours it took to solve this?

Of course, solving the crime is a good thing in itself. Now that it’s fixed, we understand the system more completely. The user experience is now more solid, and that reassures everyone. A byproduct of all that debugging is some refactoring that clarifies the code.

That wasn’t the case ten years ago, by the way: before refactoring, long debugging adventures tended to make the code worse, not better. You’d add instrumentation and sensors and loggers, you’d try experiments, and inevitably some of that scar tissue made its way into the final product.

The Official Party Line, of course, calls for infinite attention and polish and emphasizes the importance of a pristine user experience. This makes some sense on its own, and also because relentlessly solving this problem revealed a small but systematic problem in recycling. We have lots of separate processors performing their own tasks, we have animations going on all over the place, and any of these might at any moment need to make sure that some note it’s working on has a view – any might recycle our offscreen view and foul up event handling.

But it’s not always that simple. Lots of small UI glitches turn out to be small, esoteric bugs that don’t matter. Lots of outright crashes turn out to be small, esoteric bugs that will matter only to the four of people who will ever experience them. This particular bug had a one-line fix, but that one line probably cost a few thousand dollars. For a few thousand dollars, you might be willing to put up with some visual artifacts.

Policy Implications

Would better testing have caught this? Probably not, because the critical factor here is that scrolling is animated and asynchronous. Asynchronous tests are difficult to write, slow to run, and therefore costly. There was no particular reason to expect this Spanish Inquisition.

Would better debugging practice have solved this faster? I’m not sure, even in hindsight. The firstResponder was correct here and wrong there; the natural assumption was to ask “who is changing the first responder?”

Would better design have prevented this? I’m not wild about the view recycling, which smells of premature optimization. But Apple does it conspicuously in NSTableView, which suggests (a) it’s desirable and (b) the rest of the system expects it. Tinderbox users build much larger documents than you’d expect, and that means we could wind up with a ton of views and that will bog down your computer. But we’re not building this for your computer: we’re also building this for your computer in 2024. And remember, Moore’s Law says that your 2024 computer is going to have 64GB of memory, 4TB of hard drive, and 64 cores.

At one of the first computer science conferences I attended, someone asked markup language pioneer Brian Reid about the prospects for WYSIWYG editors. Reid pointed out that paragraph formatting was just too CPU-intensive, observing that it could “bring a dedicated 370 to its knees.” Now, of course, we do that on our pocket phones.

Avoiding premature optimization sometimes means, “keep the software slow and simple, and let the computers catch up.”

I think fixing this was right, but it’s a near-run thing. We never talk about the bugs we should let be.

by Jennifer Egan

Second reading of this marvelous, strange book. My original notes stand up well, I think.


In this fascinating and compelling novel, every chapter begins with a timeshift and a new point of view. What might seem a tedious experiment in late postmodernism becomes, in Egan’s hands, a natural way to tell a complex story about the intersecting lives of a group of friends and acquaintances over the span of many years.

At one point, a successful music industry pro is taking his kids and his (very) personal assistant on an African safari. His sulky daughter Charlie, one night, joins in a dance around the fire and launches us through time:

Lou lets go of Mindy’s hand and sits up straight. He wants to grab his daughter’s skinny arm and yank her away from these black men, but does no such thing, of course. That would be letting her win. The warrior smiles at Charlie. He’s nineteen, only five years older than she is, and has lived away from his village since he was ten. But he’s sung for enough American tourists to recognize that in her world, Charlie is a child. Thirty-five years from now, in 2008, this warrior will be caught in the tribal violence between the Kikuyu and the Luo and will die in a fire. He’ll have had four wives and sixty-three grandchildren by then, one of whom, a boy named Joe, will inherit his lalema: the iron hunting dagger in a leather scabbard now hanging at his side. Joe will go to college at Columbia and study engineering, becoming an expert in visual robotic technology that detects the slightest hint of irregular movement (the legacy of a childhood spent scanning the grass for lions). He’ll marry an American named Lulu and remain in New York, where he’ll invent a scanning device that becomes standard issue for crowd security. He and Lulu will buy a loft in Tribeca, where his grandfather’s hunting dagger will be displayed inside a cube of Plexiglas, directly under a skylight.

It should not come as a surprise that, much later, we will meet Lulu once more, or that she will play an important (if unconscious) part in resolving an injustice that appears in the book’s earliest chapter (though not its first) and which no one seems to have noticed.

Mar 14 23 2014

Divergent

I wasn’t expecting great things from Divergent, although the book was a lark. It’s a well made movie, about as good as it could possibly be.

The director lost his nerve (or feared for his PG-13 rating) in the boot camp assault, and that’s politically unfortunate, but perhaps the plot can’t really bear that additional weight. It certainly keeps moving.

Ruined Chicago never looked better.

Brent Simmons had a monster class – in his case a 2500-line view controller – that he wanted to break up into smaller classes. He describes this as “creating a basketful of bunny objects.”

Refactoring: Taming The Bunnies

We used to have one big mother class that was complicated and hard to understand. Now we have a smaller mother class and a bunch of very simple new bunny classes.

This is the way one hopes things will work. But, as Brent notes, it doesn’t always work that way.

The separation into separate objects wasn’t nearly clean, in other words. I had to expose a bunch of internal methods and properties of the view controller to its bunnies. Way more than I felt comfortable with. (And there’s no @bunnies keyword to protect those.)

And some of the bunnies had to know about each other: the drag controller delegate needed to know about the table view delegate and datasource. The timeline cell delegate needed to know about the datasource. Etc.

Refactoring: Taming The Bunnies

We have a basket of bunnies and a ball of yarn: the bunnies are cute, but the tangle isn’t. The new objects seem simple, but they all know too much about each other and they all communicate in complicated ways – ways so complicated that life was better when everything was in one monster mother class.

Sometimes, that’s the answer. But sometimes, refactoring further can drive you to a new design. Test-driven design throughout will help prevent errors from creeping in – and that’s important because we’re going to be yanking code all over the place.

Push Data Down

First, you may be able to simplify things in the old mother class by pushing properties and instance values down from the old class to the bunny class that is its primary user. This can eliminate a lot of communication between the bunnies and the mother class. Ideally, only one bunny needs this data. If a few bunnies need to share, that might be OK.

Herding Bunnies

When possible, it’s better for the mother to tell the bunnies what to do than to ask them about their internal state. This can often simplify coordination and improve encapsulation.

If bunny methods repeatedly need to get stuff from the mother object, consider passing the information they need as arguments. If you have too many arguments, make an argument object. If a method on bunny A needs to talk to some other bunny, pass the bunny as an argument.The point here is to unravel the tangled strands of yarn and to knit up your raveled sleeve of care.

Pull Methods Up

When bunnies need to talk to each other, you wind up with lots of inter-bunny murmuring.

self.depth = [self.controller.driller depth];

Get rid of this by adding convenience methods in the mother class. (Yes: this makes the mother class bigger, and yes, the whole point of the exercise was to make the mother class smaller. Trust me on this.) The extra convenience methods are trivial, they’re easy to write, and they’re unlikely to break. At the same time, you:

  • avoid violating the Law of Demeter
  • reduce inter-bunny murmuring

In fact, you may soon be able to remove a bunch of dependencies between bunnies at the cost of a few tiny methods in the mother class.

Continue this refactoring until the bunnies no longer need to know about each other, and talk only to their mother.

Extract A Nanny Class

The last refactoring round made the bunnies better, but now we’ve made the mother class worse. No worries! Take all those little methods you just made in the mother and sprout a Nanny class.

Refactoring: Taming The Bunnies

Now, when the bunnies want something from the mother or from another bunny, they talk to the Nanny. When the mother class wants a bunny to do something, it tells the Nanny.

The Nanny knows where to find each bunny and the mother, but otherwise it has no state. It’s got lots of intimate knowledge – it #include’s each bunny – but that’s OK because it doesn’t really do very much with that knowledge. It just relays messages between the bunnies, and passes messages from the bunnies to the mother and from the mother to the bunnies.

The nanny, in short, is a new class that abstracts that tangle of yarn. In trade school lingo, it’s a multiple Facade, an interface between bunnies and the mother class and also an interface amongst in homogenous bunny classes.

Special Friends

Often, you may find that the Nanny has a bunch of methods that talk to the same two or three bunny classes. If the Nanny starts to get complicated, you can hare off the parts that deal with that group of bunnies into its own Nanny.

Refactoring: Taming The Bunnies

Small Bunnies Really Are Better

I mistrust box-and-line diagrams; they’re often an indication of architectural astronautics. Is all this refactoring getting us anywhere? We started with a 2500-line mother class. Perhaps we end up with 8 classes. The mother’s still 1000 lines, and the nannies and bunnies are 200-400 lines. Are we better off?

Yes, we probably are.

First, everything is much simpler. Five years from now, you get a crash report right in the middle of Driller, because it’s being passed a WarpDrive and those hadn’t even been invented back in 2014. With only a handful of methods, fixing Driller to work with a WarpDrive won’t be hard. You probably won’t even need to glance at the other bunnies.

But even if you need to look through every single bunny and every nanny, you’re still better off. Small classes are easy to understand. 2500-line classes make you nervous now, and they’ll make you nervous in 2019.

Testing bunnies is likely to be straightforward. To test the old mother class, you probably need to build a model and then mock a view, and you’re going to need to plant sensors or breakpoints to get internal state. Trust me, you don’t want that.

Just this morning, Tinderbox was crashing when a table inside a popover called reloadData, thanks to some asynchronous code that was bashing the model just as we were reloading. In a five-method bunny that was so simple it couldn’t possibly crash, a concurrency error was an obvious place to look and the fix took twenty minutes. In a fifty-method mother, especially one you don’t really trust, you could spend days hunting that crash.

I’m pretty sure that the advantage of bunny classes can, in fact, be quantified. And perhaps it has! Let me know.


This recent series has been getting a lot of traffic from colleagues, and also at least one college class. (Hi, all you Manitobans!) I’ve not been seeing much email. Have something I should know about? Email me.

by Sam Miller, Jason Wojciechowski

This book is the heir to the old Bill James Baseball Abstract. I used to rush out and devour Baseball Abstract as soon as it arrived. Today, we have far more knowledge and far better tools, and where Baseball Abstract was always tinged by the derision of the baseball world, many modern Sabremetricians are honored (and employed) throughout the major leagues.

But it’s a lot less interesting and a lot less fun.

Why? First, I think I watch less baseball now. I miss it, sometimes, but there’s never time and you can always tell yourself you’ll catch a game tomorrow. I used to go to Fenway or Wrigley six or eight times a year, usually on the spur of the moment; now, it’s just too expensive. (Funny, isn’t it, how back when you didn’t have any money you could afford things that are too damn expensive nowadays?)

But when Bill James wrote about Rickey Henderson’s place in history, he was writing first about history and only incidentally about Henderson. Today’s Baseball Prospectus comments are focused entirely on the player and his immediate prospects, mostly with an eye to fantasy drafts. I understand: I buy the book for my own fantasy draft. I’ve been part of the Eddie Plank League since 1993. But I’d much rather read about the game than whether this scrub might help my team a bit.

Anyway, I just fouled up my whole season by writing a “10” next to the name of Anibal Sanchez. Or, rather, I intended to write a “10” but actually wrote a “0”. So welcome my new ace starter for his third stint with the Mallards (sigh), Anibal Sanchez. Nobody knows the trouble I’ve seen.

James used to write about topics that were fascinating even if they didn’t help with your Rotisseries league. What would Mike Schmidt hit if he always batted against the Cubs? Is taking the Cubs to win the series at 100-1 a reasonable proposition? Was it going to harm the characters of promising rookies Mark McGwire and Jose Canseco to be stuck on the hapless A’s?

That was an interesting question, before we knew the answer. Cobb would’ve caught it.

by Gerald Elias

Old, blind violinist Max Jacobus makes an unlikely mystery detective, and the dense and unlikely plot does not make his efforts easier. Yet there are some very good scenes here, and some fine ideas about music and some musicians.

Mar 14 18 2014

Lamport

Congratulations to Leslie Lamport, winner of the Turing Award.

Mar 14 16 2014

Subclassing

Brent Simmons poses an interesting puzzle about subclassing, and finds a nice solution.

Yes, novices subclass too often; they have learned about inheritance and, having overcome the obstacles, want to use it everywhere. But that’s not what we’re talking about here. Are subclasses a code smell?

I think that’s a mistake. I use (shallow) inheritance all over Tinderbox, and it’s essential.

Here’s one example, the Get Info popover in Tinderbox Six. It gives you information about the selected note.

Subclassing

At the left, we have a source list of various types of information we might find about a note. “Book” has the ISBN, the publisher, and tools for getting more information from libraries and other Web services. “Map” takes the address or the latitude and longitude and shows it to you on a map. “Similar” finds notes in this document with similar text.

Each of these panes is managed by its own class of view controller. We have TbxBookInfoController for books, and TbxMapInfoController for maps. The BookInfo controller knows how to talks to GoodReads and it knows how to validate ISBNs; that’s not stuff the MapInfo controller needs to know about. The MapInfo controller knows about geocoding, which isn’t very useful for the BookInfo controller.

But both kinds of controller have something in common: their views fit into the right panel of the GetInfo popover. So there’s lots of stuff that they share in order to manage the view and in order to talk to the rest of the system. The common stuff – the stuff about being a swappable Get Info pane – belongs to the superclass. The specialized stuff – books, maps, texts, tf-idf similarity measuring – belongs in the individual pane controller.

We could do this by delegation, but we don’t want to! After all, the first thing that a Get Info pane needs to know is, “what UI elements do I control?” We don’t want to discover them through some narrow delegation API: we want them to be our properties. They’re bound to be different for each kind of pane. New panes will come fairly often; we don’t want to expand the delegate protocol every time a new flavor of pane needs some new detail.

Over in the test lab, we’ve got another little inheritance hierarchy. Some tests inherit directly from XCTestCase, but lots of tests inherit from TbxTestCase, a subclass that provides a bunch of convenience functions for making and validating test documents. A few tests inherit from another subclass, AcceptanceTestCase, which builds a really complex text fixture that’s essentially a functional Tinderbox window; this is far too cumbersome for most testing but it provides a full text fixture for functional tests.

A few weeks ago, I wrote about another example. TbxMapViewController used to have 82 different methods that performed actions in response to menus or other user interface actions. That was a mess. Instead, we have TbxMapViewControllerAction, a superclass that manages a small mountain of tiny little classes that perform one action apiece. Each subclass knows one thing and only one thing; the superclass provides lots of convenience functions so they can concentrate on what they want to do. And the superclass provides a factory so TbxMapViewController doesn’t need to know about any of the subclasses:

- (TbxMapViewControllerAction*) actionFor: (SEL) selector;

The C++ world long ago came to grips with excessive reliance on inheritance and instituted a convention: public inheritance means that the subclass is a kind of its superclass. If you inherit, you promise to do everything the superclass does, and more. If you inherit, anyone that expects the superclass should be happy to receive you. That’s restrictive – Java is far more relaxed about inheritance – but it does rein in novice excesses.

What gets confused here is a different (and still recently-discovered) code smell: subclassing framework classes is undesirable. Inheritance is intimate, and requires extensive understanding; frameworks want to keep things more distant and formal so they can hide implementation details. As the undesirability of framework inheritance has become clearer, frameworks have begun to move away from requiring applications to do this: Cocoa, with its reliance on delegation, was an early leader in this movement. But this is a separate issue concerning proper relations between framework and application; application design itself is a separate issue entirely.

You don’t need inheritance every day, but when you need it, you really do need it.