Notes in Tinderbox Six can have captions — additional text that appears beneath the note and that can help explain or clarify the note.
Tinderbox Six comes with Mike Rhode’s wonderful Sketchnote font, used in the caption above, which gives you the informality of handwritten notes without sacrificing legibility and taste.
On May 21, 2012 – almost precisely two years ago, I created a new Tinderbox project to plan a new Tinderbox. The first journal note reads:
On the plane home from Hamburg, built a huge Tinderbox planning file by exploding the directory listing for the primary Tinderbox 5 source directories.
We have a surprising number of files, and some of those files contain a LOT of objects.
I may be in some trouble.
Tinderbox Six ships today. 101 development releases, 1704 commits, about 1600 files.
This morning, I woke a little before sunrise and didn't work on Tinderbox. Tinderbox 1.0 shipped yesterday. It's finished. Until yesterday, there was nothing much like it, anywhere. Yes, it's a little like Storyspace, VIKI, Blogger, Agenda, PageJockey, and a host of other systems old and new. But it's a very new kind of software, and until yesterday, if this is the kind of software you needed, you were in a bad place. Now, it's done.
One customer, a notable writer, was vexed with us. The writer wanted a hypertext, and she wanted it now. It’s a CD; mail takes two days to get from Boston to New York.
I was going to share the email with you without disclosing the writer’s identity, but as I recall the copyright of letters — even a letter like this — remains with the sender. So I’ll just give you some of the noun phrases:
…goddamn book … goddamn thing … fucking thing … you certainly aren't doing ___ any goddamn favors … I need a motherfucking key,… $25 for a fucking book that I should've just torrented … the fucking mail?…what the hell you're doing …. Consider this the last promotion you get from me. Jesus H. Christ. Furious furious furious plus I hate you right now,
I wish I could say this was unprecedented.
I wish I could say that, after years and years of toolsmithing and publishing for the hypertext community, this doesn’t bother me any more.
At least I’ve got a three day weekend coming up, so that means three days of mostly uninterrupted testing and debugging for Tinderbox Six.
by Robert Harris
An intriguing and engaging novelization of the Dreyfus Affair from the perspective of Colonel Georges Picquart, an honest, intellectual career officer who is asked to take chair of an intelligence outfit and does his best to discharge his unfamiliar and uncongenial duties. Unfortunately, his superiors neglected to explain to him that his best efforts were not what they desired. An Officer and A Spy is a thrilling police procedural and courtroom drama, even though everyone knows how things turn out.
I used to do a lot of coding after midnight, back in the day, but I used to stay up to all hours nearly all the time. Linda’s a big believer in sleep, though, so I don’t do it much any more.
But I think Brent is mistaken when he blames this mistake on the hour.
I would have realized this had I been fresher when I wrote that code. But it was late, and I thought I was being smart.
Brent is pretty sure he would have realized the problem. I might perhaps have seen it coming – especially after the first time I made this mistake.
Making this kind of mistake can make you a better programmer. Over the years, I’ve known a very few programmers who really didn’t make mistakes. They saved themselves a lot of time and bother. But somehow they also ended up working in software backwaters or working outside of software entirely.
Mistakes generally – and this kind of mistake specifically – have been the great driver of software progress in this generation. Just about every advance in practice is connected to this sort of logical error. The tiny-method style of object-oriented programming specifically addresses it. So, too, does the Template Method pattern, which we would write for Brent’s case:
- (void) removeThings
This is a catechism. Whenever we do something non-trivial, we ask:
- What needs to be done before we start?
- What needs to be done?
- What needs to be done after we finish?
Test-driven development or assertion-rich development or promises add some additional questions:
- What needs to be checked before we start?
- While we're working the problem, how might we know that something is amiss?
- What can we guarantee after we’re done?
Where once we would have done a lot of work in a big modular subroutine, now we break it up into a bunch of methods. Then we break those methods up into smaller template methods. And then we break those methods into little methods. Eventually, we have methods that can’t possibly fail.
Now, you might expect this to lead to disaster, to being swamped by thousands and thousands of little methods. It turns out, however, that a surprising number of the smallest, simplest, most numerous methods are likely to be used all over the place. Once you have them, these methods encapsulate abstractions that make the code cleaner and simpler, and that reduce clutter. In practice, things settle down.
But the driving force is always the fear of the third act: there was one thing they had forgotten. If you don’t make late night mistakes, I think there's a chance you never get there.
by Laini Taylor
Conclusion of the trilogy that began with Daughter of Smoke and Bone and Days of Blood and Starlight, the story of an art student in Prague who gradually discovers that she’s enmeshed in an ancient war between angels and chimera, and she’s not an angel. This conclusion adds a new player, a graduate student in biochemistry brought in to analyze DNA samples from some monsters discovered in the North Sahara, and who was raised by a Florida cult that believes itself descended from an angel. To everyone’s surprise, the cult has a point. The conclusion is a bit shaggy and shows some signs of haste; the hard work was done in Book I, a book that was propelled by the gradual unfolding of this strange world. Now the world is unfolded and the pieces are on the board and, oddly, there’s less propulsion beyond the gradual slide to the denouement. Nevertheless, a fierce and tiny delight.
Given a programmer who’s good at their job — who knows the language, frameworks, and runtime well — the dramatic nature of a bug is in inverse proportion to the difficulty of the fix as long as the bug is actually in that programmer’s code.
In my experience, drama doesn’t make bugs either easier or harder to solve. Brent identifies many of the sources of difficult bugs. Some others – often restatements of Brent’s principles:
- Inconsistent: bugs that sometimes occur and sometimes do not are much harder to fix than those that are predictable. Race conditions are one common source of inconsistent bugs, but unusual usage can be just as effective. (You clicked where?)
- Delayed: bugs whose effects are separated from their cause are challenging. For example, an error when writing a file might be apparent only when reading the file.
- Distant: debugging a system that uses multiple threads, processes, or computers is hard, especially when it’s unknown which system is mistaken. For example, fixing a sync problem is harder than fixing a problem when saving.
- Inconspicuous: today’s users have been trained to avoid tech support when possible, and in consequence they may not report problems you would normally expect to hear about. They may also assume that a bug is simply the way things ought to be; in WW2, the US Army printed and used millions of “Indentification Cards”, presumably because everyone involved assumed that someone else knew how to spell the word.
- Cumulative. Some bugs, such as memory leaks, are tolerable in small doses and only become noticeable after the error has been repeated over and over. In the worst cases, a side-effect of slow-acting bugs may remove some of the evidence; once the crime scene is discovered, the footprints have been trampled.
- Fragile. It’s hard to fix bugs in complex, fragile, and poorly-tested systems. Refactoring and test-driven development have given us powerful tools to cope, but of course that means writing tests and refactoring a legacy system before we can really tackle the bug.
- Infallible. Conversely, excessive cleanliness can also hide ghastly blunders. The
gotodisasters earlier this year was a classic example. We’ve all had cases where the code said “=” when it meant “==”, where we checked
if(ready)when we wanted
if(!ready). These blunders are especially hard to pick up in small, clean classes.
- Cloaked. Some bugs are tied to creating and dismantling the object or the system. These may be difficult to handle when they occur so early or so late in the process that your tools and instruments can’t see them. Related to these are bugs that appear only with specific and unusual system configurations or data, or bugs that appear only when the network connection goes haywire or only on Tuesdays. (Yes, I’ve had a bug that only happens on Tuesdays.)
by Rainbow Rowell
Less ambitious and less accomplished than Fangirl, this is still a fine story about two kids who meet cute under difficult circumstances.
One narrative spring that drives the story is a crucially withheld bit of information: something is terribly wrong in Eleanor’s household. Rowell dismisses the convention suspects – marital discord, money, sexual abuse – unconventionally: Eleanor has trouble with all these, yes, but they’re not the real problem. Her stepfather beats her mother, Eleanor daren’t bathe when her stepfather is home, at sixteen she’s been thrown out of her house at least once before. All five kids share one small room. Eleanor’s home has no phone, and she literally doesn’t own a toothbrush. But these, it’s clear, are but the trappings and the suits of woe: something else, something darker, is the real problem.
Indeed, the extent of the family’s poverty embedded in a 21st century suburban setting is itself a striking narrative choice. The trappings all read 2008 Omaha, but the circumstances sound like the lower East Side a century before. Indeed, the name “Eleanor” peaked in popularity around 1920, when it was about ten times more common than it was when our heroine was born.
In the end, the story is a love story for the mundane, troubled, old-fashioned American family. Eleanor’s boyfriend, Park, is the son of a Korean war veteran and his Korean wife. They don’t have much, but they have lots more than Eleanor. They don’t get along especially well – Park is convinced that his father loves him but doesn’t really like him, and Park is not wrong. From Eleanor’s perspective, it’s all pretty great.