News for September 2004

Better Living Through Bigger Text

Today my office is an airplane. I’m visiting the home office in San Francisco for the week. I get to remind everyone that those of us in the Boston office are real people (insert your favorite joke here), and come back with enough to understand what’s behind the email and phone conferences for another month.

One of the geek games you can play on an airplane is stretching out the battery life of your computer. I have enough batteries to last me through a six-hour flight now, but old habits die hard.

Since I save my files every minute or two, spinning down the hard disk isn’t an option. (I tend to use programs that communicate use the file system to communicate. And I don’t want to be in a position to lose more than a few minutes of work anyway.) I don’t usually use a CD or DVD player, so I’m already optimizing there. The CPU that I’m using steps down to 800MHz when the plug is out, so that’s taken care of for me. That leaves screen brightness.

The problem with turning down the screen brightness is that this also turns down my reading speed. I’ve noticed that I read a lot faster when I’m reading higher-contrast text. Since I already use black text on a white background, the contrast is proportional to the screen brightness (as long as the overhead light is off).

This effect matters most when I’m reading English. When I’m reading math or code, or writing anything, my word recognition time, which is the part of the pipeline modulated by the contrast, isn’t the bottleneck anyway — in those cases I’m limited by comprehension time, or by other central abilities. So I used to turn the brightness up when I’m reading, and turn it down the rest of the time.

Let’s call this the contrast modulation strategy. It trades off reading speed against battery life, based on the current activity (reading versus other work). The contrast modulation strategy works if I’m spending long stretches of time reading, or not-reading. It’s a pain if I’m going back and forth — referring to one document while I’m writing another, for instance.

Here’s today’s discovery: my reading speed is also proportional to the text size. I just ran a few informal comparisons, and setting my document zoom to 200% at the lowest brightness works just as well as turning the brightness all the way up. (With a large font, it doesn’t seem to matter how bright the screen is, at least within the range that my screen adjusts to.)

With larger text (a larger font size, or a greater zoom), I have to scroll more, but when I’m reading English I don’t need to see more than a few paragraphs for continuity anyway. When I’m reading code I want to see as many lines as possible (this one reason I prefer concise programming languages, so I can see several different levels of structure without having commit as much to my mental buffers so that I can scroll) and technical documents always seem to refer to tables and figures a page away, which makes for a lot of scrolling, anyway. So I want big fonts for English that I’m reading, and small fonts for everything else. But font size, unlike screen brightness, is something you can associate with a specific document.

Let’s call this the text size modulation strategy. The text size modulation strategy trades reading speed off against the amount of the document that’s simultaneously visible. The text size modulation strategy takes decouples the trade-off between reading speed and battery life and, unlike the contrast modulation strategy, it’s automatic once you zoom your documents, no matter how many times you switch between them.

Posted: September 21st, 2004
Categories: General, Tips
Tags:
Comments: 1 Comment.

The Novell Virus

Miles told me about the computers at his elementary school:

They’re running anti-virus software, but they’ve installed a virus! It’s called Novell. It makes the computer boot slowly, it does a lot of stuff while it’s booting, and then you can’t log on.

Posted: September 12th, 2004
Categories: Amusements, Family
Tags:
Comments: No Comments.

Responsive Interfaces and Effective People

Patrick Roberts has written a fascinating post on Responsive User Interfaces. It’s easy to make a specific application responsive, through careful coding and by limiting what the user can do. An architecture for doing this, with arbitrary functionality, is one of the holy grails of GUI frameworks. Patrick’s post is a step towards this.

Patrick defines responsive as “the UI never locks up and provides at least partial results ASAP, not that every operation is completed instantaneously”. His design uses a UI thread that runs performs fast operations, and pushes slow operations onto a queue. A background thread runs these operations in priority order.

In his second post, Patrick refines the queue to handle superseded job items. This is important in a UI, where, for example, scrolling a list item out of the visible region of the list makes it unnecessary to figure out how to display it. It requires some finesse, because a naive implementation never gets around to displaying any of the items that the user is scrolling through. (A lot of work went into solving this particular case in the Laszlo implementation of lists.)

Patrick’s queue is just a step towards the responsiveness grail, and not the grail itself, because it still requires hand-coding to decide whether to perform each action immediately or place it on the queue, and to factor long-lasting tasks into subtasks that can display incremental progress — although maybe MVC usually takes care of the latter?

This design reminds me of David Allen’s Getting Things Done system. GTD is summarized here (PDF) and here. 43 Folders is an excellent site about how to use the system.

GTD can be thought of as a really sophisticated priority queue, and a decision procedure for deciding what to execute immediately and what to place in the queue. Each item in the queue has metadata: whether it has multiple steps, whether it requires additional information, its priority, external deadlines, and the context that the item requires: people, place, time, and energy. (GTD includes other storage structures too, and uses very different terms. I’m playing up the queue, and assimilating it to my own system, in order to make my point here.) When time is available, an item is selected from the queue according to the match between the current context and the item context, and then according to relative properties such as item priorities and external deadlines. For instance, I do my busywork tasks late in the day or when I’m otherwise feeling not at my sharpest; there’s some tasks I only do when I’m in California or when I’ve got a coworker on the phone; and there’s some that I’m only willing to start when I know that I’ve got a few uninterrupted hours in front of me. Beyond that, I choose according to whether there’s an external commitment and then by how important they are.

Here’s the idea I’m toying with: Use a queue like the GTD queue, and items with metadata, to schedule actions an application framework. The idea of matching task context with current context brings together some of the context-dependent actions that a computer performs. For example, indexing is a lower-priority task, but one that doesn’t require the user and doesn’t require an available time commitment to be worth starting; this is like my busywork. Synching, checking mail, and sending queued messages require a network connection; this is like my being in California or on the phone with a coworker. I also like the idea of adding metadata to an action, and using this to schedule it. In the GUI frameworks that I’m familiar with, the only metadata associated with an action is how to undo it (and what to call it in the Undo menu item). If the metadata also includes some of the same kinds of information that tasks in a project plan included, such as resources, dependencies, deadlines, and time estimates, then a GTD-style decision procedure can be used to move actions between a GUI thread, a background thread, and a Roberts-style queue.

There’s an obvious connection to blackboard systems and to AI planners such as Soar here. In fact, we can take a leaf from AI to solve the problem of how to supersede tasks, as in the scrolling case. The idea is that tasks have supertasks, and cancelling a supertask cancels its subtasks. (This is like a goal tree in planning; a process thread or child process in an operating system; and a project milestone or a milestone task in project management.) In the scrolling case, the task of rendering a list item is a subtask of displaying the visible content of the list. Once the list has scrolled again, the extension of the visible content has changed, and any subtasks of the task of displaying the content of the old position should be cancelled. (A smart system would pool the tasks, so that it could restart them or leave them running if they’re also subtasks of a new task — in the scrolling case, if the new position includes the same list item.)

Although the Roberts queue and the GTD system are similar, they serve different purposes. The Roberts queue was designed to optimize responsiveness — the time between the user event that initiates the action, and the initial feedback that the action is proceding. The GTD system was designed to optimize productivity — the throughput of the system, and the portion of that throughput dedicated to important items. Responsiveness and productivity are duals. A responsive application is easier to use productively, because it reduces input stuttering and it allows for tighter OODA cycles. And a productive person has an easier time being responsive, because (1) their backlog is smaller, and (2) they can tell you what their backlog is, and whether the task of responding to you is in it.

Posted: September 11th, 2004
Categories: Essays, Systems Thinking
Tags:
Comments: 2 Comments.

Becoming Lisp

Python really is becoming lisp. With the type/class unification, decorators, and generator expressions, it’s jumped from 80 percent of Common Lisp + CLOS to 90 percent1, and for web tasks the web programming libraries often make up the difference.

I’ve listed below some of the functional and metaprogramming recipes and packages that have shown up in PyPI and the Python Cookbook over the past few weeks. [As of Memorial Day weekend, when I first wrote this. I didn't post it until a week later. My"real job":http://laszlosystems.com is heating up :-]

The point is not that these recipes exist. There’s plenty of clever Perl preprocessor hacks; there’s some pretty amazing C++ template metaprogramming libraries ; and I bet if you scoured the web you could find this many recipes for Java reflection. (Well, I don’t bet very much on the Java part. I’ll buy you an ice cream at Bart’s. First taker only.)

The point is that these are flowing in fast and furious, and that they don’t take much code. The recipes below are from just two weeks. There’s half a dozen functional programming recipes, and a dozen MOP recipes; many of them are one-pagers. There were some real wizards in the Lisp community, but I don’t recall anything like this pace of development on top of the CLOS MOP.

Two weeks of MOP and reflection recipes:
* Overriding new for attribute initialization
* Named tuple items: here and here
* Cacheable value objects
* Thread-safe caching
* “Simpler super syntax”:http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/286195
* Constants
* Prolog syntax
* Named Singletons
* Handler design pattern
* Monostate design pattern
* Simplified Mutable Instances

Two weeks of functional programming recipes:
* izip inverse
* Batched iterables
* Windowed iterables
* Grouped iterables
* Coroutines
* Cartesian product

Web programming in August:
* The Whole Web in a Dictionary
* Webcleaner, a filtering HTTP proxy
* rxrdf, an RDF application stack
* milter, interface to sendmail milter API
* itools, uri, resources, handlers, i18n, and workflow tools
* libgmail, a binding for Google’s Gmail service
* naja, a download manager and a website grabber
* IRC bots: pyfibot and supybot
* linkchecker, not sure what this does :-)

And hotswap finally adds object evolution (what “live edit”).

1 Percentage gains are subjective and are based on simulated exploratory programming conditions. Actual productivity will vary with hardware speed, workplace environment, develpment habits, and problem complexity. Results reported to SEI indicate that the majority of projects with these estimates will achieve between 71% and 123% of Lisp productivity in single-person projects and between 83% and 159% in team projects.

Posted: September 10th, 2004
Categories: Programming Languages
Tags:
Comments: 9 Comments.

Refactoring for Fifth Graders

I gave Miles a set of Logo programming problems:
* sv 3 draws a square divided vertically into three columns
* sh 4 draws a square divided horizontally into four rows
* svn 3 4 draws a square with three columns and four rows

(These are going to build towards some work with fractions, but he won’t know that unless he reads my web site. Hi, Miles!)

The first thing he did was place a slider and a button on the screen. The slider ranges from 1 to 10, and the button calls sv@ with the value of the slider. He used these to test the program while he wrote @sv, to quickly try it on different arguments without typing. When he added sh@ he added another button, and so on for @svn.

This looked to me like some sort of hybrid between test-driven development (with a unit testing framework or FIT), and using the command line. It’s more parameterizable than unit tests, but easier to fit into a development cycle than the command line.

What was really interesting, though, was that Extract Method wasn’t a new concept. The initial implementation of sh@ was copy-pasted from @sv, and svn was copy-pasted from both of them. I started on my DRY lecture — “see how this part of sh@ is the same as this part of @sv” — and he jumped the gun. “Oh, cool, you can use aliases?!” he exclaimed, before I even modified any code.

The analogy is between files in a directory and callees in a method. If directory could transclude its contents — list one of its children’s contents as its own — then the analogy would be exact.

Posted: September 8th, 2004
Categories: Family, Programming
Tags:
Comments: No Comments.

Tablehood Watch

Tucker asked me if there was a name for the phenomenon where someone you don’t know asks you to watch over their possessions. I’m asked to do this a few times a day, for anything from books to laptops, at the ERC. (At the yuppie establishments that I also frequent, I’m not asked at all.)

If you’re worried that a total stranger might steal your belongings, why is it safe to ask a total stranger to guard them? There are at least two reasons.

The first reason is the asymmetry between your criteria, and those of a potential thief. Let’s assume some people are thieves, but not all. (If there aren’t any thieves present, it doesn’t hurt to recruit a guard, but you didn’t need to.) The chance of the person you chose being a thief is less than 1, but the chance of a thief choosing you (or your unattended belongings) is almost 1 — that’s our definition of “thief”: someone who is willing to steal from you. The chance of your picking a thief is therefore less than the chance of a thief picking you.

The second reason is social, not mathematical. Once you’ve made eye contact with someone and asked them for a favor — as long as you’re not obnoxious — then even if you did choose a potential thief, they’re less likely to steal from you. (This isn’t true for sociopaths, but even most thieves aren’t sociopaths.) Another way to put this is that interaction isn’t passive: asking someone for help changes the number of potential thieves in the room.

Posted: September 7th, 2004
Categories: Systems Thinking
Tags:
Comments: No Comments.

There They’re

(For Miles.)

_Possessives_Places_Contractions_Verbs
our..are
.here.hear
.wherewe’rewere
theirtherethey’re.
its.it’s.
your.you’re.
his, her, my...

Read across the rows to see words that are easily confused with each other. Read down the columns to see the patterns.

Things to note:
* All of the contractions have apostrophes ‘.
* Nothing in this table that isn’t a contraction has an apostrophe. “Its roof is red” doesn’t have an apostrophe even though “its” is a possessive. This makes “its” different from noun possessives (“The house’s roof is red”), but the same as “his”, “her”, and “their” (“Her hair is red”).
* The place words all have “here” in them: “here“, “there“, and “where“.
* Nothing that isn’t a place name has “here” in it: “Their hands are wet”, “They’re leaving”.

If you notice you’re using a word in this table, think about which kind of word it is (Possessive, Place, Contraction, or Verb), or which column it fits into. If you’re using “its”, would “his” also work? Or would you use a verb such as “we’re” — in which case you should be using “it’s” instead.

Once again, I’m sorry about English spelling — I would have done it differently. It’s not my fault.

Posted: September 5th, 2004
Categories: Words
Tags:
Comments: No Comments.