2009-03-30
There are three entry states for feed readers
In making yet another small mistake with my feed reader of choice, I have come to the realization that there are actually three states that I want entries to be in, in addition to the basic 'read' one. I want to have all of unread entries, entries flagged for later attention, and marked (saved) entries. In fact, I think that this also holds true for email readers, since they are dealing with the same sort of issues.
In theory, I shouldn't need the 'flagged for later attention' state, because I should be completely reading and dealing with each entry and all of its links when I read it for the first time. In practice, this doesn't work out; there are often entries that I can't completely read or deal with at the moment. I don't want to permanently save these entries, but I do need some way to find them later. Right now my solution is to reset these entries to be unread, but this periodically leads to accidents with 'read next unread entry' and other similar things.
(Naturally, there should be a 'read next flagged entry' operation in your UI, and I feel that you should have to explicitly clear the flag instead of having it fall off if you just look at the entry.)
In thinking about it, this is more or less what I do with email too, but with email I have two luxuries not really available in feed readers; I can delete messages outright (and they won't reappear) and I can move messages to other folders. Both of these can be used to turn 'read but not deleted' into effectively 'flagged for later attention', although I think that they're not quite as good as having an explicit state for it.
2009-03-23
How libraries should handle internal warning messages
The GTK libraries have a problem; using them is evidently complicated enough that programmers can commit errors that don't crash the program (partly because GTK can detect them). The people writing the GTK libraries decided that they wanted programmers to be aware of these problems, so they'd print warning messages every time they happened.
I sympathize with the GTK people, because this is a hard problem. You can't detect these problems at compile time or link time, and they're not severe enough to crash the program but at the same time you want and possibly even need the programmers to fix them. But printing warning messages all the time is still the wrong answer; the net effect is that many GTK-based applications that I use dump various 'warning' messages all over my terminal windows (if I'm foolish enough to run them without throwing away standard output and standard error). The right solution is to make printing warning messages from your library be conditional on some (non-default) environment variable.
(If you already have a logging and configuration system for your library set up, you should of course use it instead.)
I expect that the objection from library authors will be that programmers using the library won't actually turn the environment variable on, so problems in their code will go un-warned-about. However, this assumes that the programmers who don't bother to turn on the environment variable will never the less bother to notice and do something about warning messages, and I suspect that the odds of that are relatively low.
The exception to this is programmers who don't know about the existence of the environment variable. If you think that there are significant number of them, I have two suggestions. First, you should improve your documentation because clearly it is falling down on the job of educating people about the best way to develop with your library. Second, only print one or two messages from your library; one warning message, and a subsequent message about 'further warnings suppressed, set this environment variable to enable them'.
(My personal and cynical belief is that either you care about such library usage problems or you don't. If you do care you'll read the documentation and find the environment variable; if you don't you'll ignore the warnings. I may be under-estimating the number of ignorant programmers.)
2009-03-16
Complex data structures and the two sorts of languages
I've written before about the two sorts of languages, namely the ones where you can write code that runs as fast as the builtin features, and ones where you can't. For now, let me call these 'fast' and 'slow' languages, on the grounds that it is a slightly less loaded set of terms than other possible ones.
It's recently struck me that one of the effects of this language gap on the 'slow' languages is that it basically cuts off your ability to write new implementations of interesting data structures that are speedy and efficient. I think that this is important because it is my sense that it is usually exactly when time and space are at a premium that you want to write such a new data structure; otherwise, you might as well just use the built in ones.
(There are cases where an algorithm is most clearly and compactly expressed by using a specific data structure, so it is worth using it even when it is not the 'best' from a performance perspective.)
In turn this may mean that you just can't such languages to tackle problems that call for such specific, specialized data structures because your implementation will wind up too slow to be usable. (This is different from the language being slow in general; in the sort of case I am thinking of, the problem would be perfectly feasible in the language if only you had a fast implementation of the underlying data structure.)
As someone who likes playing around with programming, I find this regrettable for more than the obvious reason. For example, it means that there really is not much point in implementing, say, splay trees in Python (normally my preferred language), because while the result will work it probably won't run fast enough to be useful for any real code I write.