Lars Wirzenius: October, 2003
- October 29: DVD price comparison, Make your program easy to install
- October 28: Non-sensical clients, GUI code portability, Epigram 31
- October 27: Bad day, Nearing release
- October 26: Buffy the vampire slayer, third season, Log by category
- October 25: Thread programming is best done in a functional language
- October 24: Drilling machine, Blurb, Fame and fortune
- October 21: Language worth learning
- October 20: Ropecon pictures, Blurb being written, Search for a new editor
- October 15: Bug fixes, re-Buffy, Accuracy of manuals
- October 14: I'm using Lodju!
- October 13: New release: drag and drop
- October 12: Moment of absurdity
- October 11: The Art of Software Testint by Glenford J. Myers
- October 9: Programming language wishlist, Uncle
- October 8: Mobile phone wishlist
- October 2: LDP is 10 years
Wednesday, October 29, 2003
Spent a couple of hours tonight browsing various web stores and comparing prices for DVDs. To make comparisons and note keeping easier, I wrote a spreadsheet, and then added some additional stuff to make sure the prices were converted correctly to euros, and that postage and packaging costs and customs fees are included. Now I can easily see, for example, that at the moment the cheapest place to order season 6 of Buffy the vampire slayer is from Amazon.com, but it won't be available anytime soon, so if I want it now, I should order it from Ezydvd.com.au.
I only have a handful of stores and I look up and enter the data manually. If I was really serious about this, I'd write an application to fetch the data automatically and compare things properly. That's much too much work, however. Presumably someone else has done it already, but I'm happy enough with this simple thing.
If you're writing free software, you do yourself a big favor if you make your program easy to install. Programs that are difficult to install are harder to try out, and that limits the number of users you'll get. The absolutely easiest way to make your program easy to install, from my point of view, is to make sure the program is packaged for and included in Debian. Users of other Linux distributions and other operating systems want packaging for their favorite systems.
Note that packaging is more than just putting together a
tarball of compiled binaries. It includes integration to the
system the package is built. There are many subtle differences
even between Linux distributions. For example, for many years
the location of init scripts was
in Debian and
/etc/rc.d/init.d in Red Hat. The
way the init script was registered for different run levels
is still different. The meanings of different run levels
is different. Because of this, your program needs to be
flexible enough to not hard code such things into the code,
and must let the installer configure things easily.
Another issue is that your program shouldn't needlessly depend on unusual libraries or tools to work. For example, the first versions of bogofilter required a library that was not included in any Linux distribution at that time. It was also very difficult to install, because it did not follow any standard convention for configuration and installation. That's why I didn't install bogofilter until it was packaged for Debian.
By making your program easy to configure, and install, you make it easy to package it any platform. That makes it easy for people to try it. That means you get users more easily. Everyone is happy.
If, however, you make your program difficult to configure or install, it is tempting to assume you don't really care about getting any users. If you don't care about users, why are you releasing the software?
Tuesday, October 28, 2003
Sometimes I suspect some of our clients aren't quite as sensible as we would like. Like today: it is their responsibility to provide translations for the user interface. We have thoughtfully put all the user interface text in a single file, to make it easy to translate. We have e-mailed it to them. What they did, instead, was take a screenshot of each page in the web application, print it out, write translations out by hand, and fax it in to us. Our fax ran out of paper after ten or fifteen meters. Luckily, the boss is the assigned diplomat, and gets to explain the wonders of e-mail and editing text files to the customer.
For the most part, programming languages should be portable. One part that doesn't have to be portable is widget sets. Widget set portability is pointless.
The kind of portability I mean is where the same widget set works in several different graphical environments, such as both in Gnome and Windows. There seems to be two approaches for achieving this: either there is an abstraction API that is mapped into the native widget set on each platform, or the portable widgets are separate from the native ones and implemented for each platform separately.
The native widget sets on various platforms have much in common, but also there are huge differences. An abstraction API must be either so abstract, it prevents the programmer from doing anything fancy (and most interesting programs need fancy), or it must try to be a superset of all native widget sets, which makes it too complicated. Neither approach is good, but at least the widgets look like the native ones.
Writing non-native widgets for each platform is the approach of Tcl/Tk (and Python) and Java. The big problem is that the widgets aren't the native ones. They may try to look like the native ones, but they don't ever succeed completely. For example, GTK+ provides theming, and look-a-likes don't follow that. They also have subtle and not so subtle differences in how they react to keyboard and mouse input, which can be hugely annoying to the user.
I'm being provocative, of course. There are situations when portability is useful, but in general, it is better to write the user interface parts of each application for each platform, using native widgets for that platform. If you keep the UI code a thin layer over the actual application logic and data structures, the amount of effort to port to a new platform should reasonably small.
So why do I care? I'm on the lookout for a new programming language and most people seem to consider GUI programming as unimportant. They think it is enough to provide bindings to, say, Tk or WxWindows.
Another good quote from Alan Perlis' Epigrams in programming: 31. Simplicity does not precede complexity, but follows it.
Monday, October 27, 2003
Today was not the best day in my life. I forgot my gloves at home, and didn't have time to go back to get them. I fell on slippery ice and hurt my knee (though luckily not very badly). Tax people found yet another error in my data for last year: it is now official that every single piece of information they have of my finances for last year, except for the salaries paid by Oliotalo, were wrong. The deadline for complaining was last Friday (though luckily it was not a hard deadline, just the one for doing things the easy way). I've been boycotting CDs since I don't like the way record companies want to use copy protection, but today I bought an old (but unused) cheap one. It had read errors in the last track. The weather was windy, and my hat flew off my head, into a puddle, and in front of the wheels of a bus about to leave from a bus stop (but it waited and let me fetch my hat).
On the other hand, I met with some friends to celebrate Jiivonen's birthday, and that was fun and destressing. Also, the tax people graciously halved my tax percentage for the rest of the year, since it used to be quite high, due to having been calculated for a much higher income level than I really have (due, in turn, to the bad info they had on my last year's income). This means I will get some extra cash for the rest of this year.
Having now used Lodju for a while, I think the current development branch really is ready to be released. It should be about as useful as any previous version. The only big missing thing is a tool for converting old databases to the new format. No-one else has written one, so I guess I'll have to do it myself. Shouldn't be more than an evening's worth of work, but not exactly the kind of work I like.
After I have the conversion script, I'll make a beta release, and upload to Debian, possibly to experimental. After a week or two has passed without major complaints, I'll be ready to put out an official, stable release named 2.0. I don't know when that will happen: this development branch hasn't had very much use from other people than me, so probably a pile of bugs will be found as soon as someone else uses the program.
I have some plans for stuff that can be done after 2.0. There's all sorts of usability improvements, and also major new features. The TODO file in the release contains some of them. I don't have a roadmap. I tend to work on whatever annoys me most, or whatever I want most next.
Sunday, October 26, 2003
I've just finished watching the third season of Buffy the vampire slayer. I've seen it once before, but it is equally effective, emotionally, the second time around. I find that the third to last episode, The prom, has the mostest emotional impact for me, but the whole season is pretty impactful, and not just emotionally. The plots (per episode, and for the whole season) are excellent, and cut deeper than you'd expect from a critically acclaimed novel, never mind a fantasy TV series for teenage boys.
I don't actually think that teenage boys are the proper target audience for Buffy. At least not the stereotypical kind that only cares about amount of violence and skin tone. The series handles issues such as responsibility for other people, whether the common good is more important than personal good, and living with one's mistakes. A typical TV series (or movie, or novel) presents issues in monochromes, and simplifies things so that whatever point of view the author likes is clearly the best. While Buffy isn't quite immune to that, it does manage to make some of the bad guys be much less than pure evil, to be human even when they're monsters. Also, the good guys are not purely good, and have doubts, they feel the wrong things, and do things out of selfish motivations. And they do the wrong things, occasionally.
I don't claim that Buffy is the ultimate in storytelling, but it is far ahead from most stuff. I'm addicted not because of the many mini-skirts Sarah Michelle Gellar is wearing, but because the story bears being watched repeatedly. The skirts are just a bonus.
I wrote a small Python program to split the main log pages, written by hand in XHTML, into section specific ones. Perhaps it is useful for some people.
This is something that at least some of the fancy web applications for logs do automatically, but I'm still uninterested in using them.
Saturday, October 25, 2003
In a discussion with Cessu the other day, I formulated something that had been only half-formulated in my head before. It's about threads. I tend to dislike threads a lot. Threads are a rich source of problems, due to locking, memory management, and other things that are more complicated in a multithreading environment than in a single threading one. Cessu said something that I think I've also said: these are problems because data can be mutated. In a functional environment, the problems should be manageable. For example, there is no need to lock a data structure against modification, because a data structure cannot be modified. Garbage collection helps with memory management.
Threads can be a great abstraction. Program structure can be simpler if concurrent things can be expressed as a suitable number of threads, rather than as one complex thread. This simplicity doesn't help, of course, if using threads requires making each thread complex to handle all locking and memory management issues properly.
I have a gut feeling that thread programming is best done in a functional language, where the threads are abstractions much like functions, and where the language implementation maps them to operating system level threads in a suitable manner, and takes care of locking and such automatically.
Friday, October 24, 2003
One of the things that makes embedded software development different from, say, development of network servers is that embedded programmers get to dress in coveralls and play with real hardware.
We spent yesterday at the client hooking up to the machine above. It went like a charm. There was dirt, oil, and a noise so deafening ear protectors were mandatory. Not for us the calm, soothing whispers of computer fans or the serene tap-tap-tap of keyboards.
Cessu and I wrote a short blurb for Hedgehog, as a first step in the preparation for a release as free software. Don't hold your breath on the actual release, however, it might be months off. I need to restructure the code base, and such, before it can happen, and this needs to happen while I'm working full time on customer projects.
Hedgehog is a very concise implementation of a LISP-like language for low-end and embedded devices. It consists of a compiler to byte code and a corresponding interpreter. The byte code interpreter is written in standard conforming C, is efficient and easily portable, and can be compiled to a very small executable or library of only some 20 kilobytes.
The Hedgehog LISP dialect has proper support for local and lambda functions, lexical scoping, variable argument functions, garbage collection, exceptions, macros, and over a hundred predefined functions or special forms. The built-in types are lists, symbols, strings, 32-bit integers, AVL-trees, and tuples up to 16 elements wide. Proper 32-bit wide integers are necessary for various bit-level operations in embedded systems.
For a half-written tutorial and reference, see Oliotalo's site. If you have questions, feel free to mail me.
The Debian developers were discussing Nethack default key bindings and then suddenly turned around and started to talk mailing list software. My head spins when threads switch topics that fast. This time it's spinning faster than usual, since they mentioned Enemies of Carlotta. Fame! Fortune!
Tuesday, October 21, 2003
"Any language that does not change the way you think about programming is not worth learning." Bruce Lewis, comp.lang.scheme.
Update: It seems that Lewis was almost quoting Alan Perlis: "A language that doesn't affect the way you think about programming, is not worth knowing." (See epigrams.) Thanks to Antti-Juhani Kaijanaho and Chris Beggy for the link.
Monday, October 20, 2003
Yesterday I imported all the pictures from this year's Ropecon into a single folder in Lodju. At about 560 pictures, the process size was over 160 megabytes, which is quite big, but possibly not unreasonably big. Lodju was still quite fast enough. Happy thoughts.
About three weeks ago, I wanted to write a blurb for Hedgehog that could be put on a web page to describe it, and in the README for an eventual GPL release, and so on. About half a page of text. I had a difficulty writing keeping it short enough, and it is now 40 pages of text, plus front matter, with at least two chapters that have only a place keeper, no content. My megalomania strikes again.
As a result, Cessu wrote a new blurb, and we edited it for a few iterations. It really is short, and I think it mentions all the important features. As soon as the boss approves it, I'll put it on the web.
I'd like to see a GPL release of Hedgehog sometime early next year, but we'll see whether that happens for real. There's all these other things I need to do at work, which customers are actually paying for... (It's good to have customers, especially paying ones: I've had two employers go bankrupt on me, and it is not the most pleasant of experiences.)
It is beginning to be that time of the year again when I want to convert to using UTF-8 and switch to a new editor. The former requires the latter.
I've been using Simple editor for X (with the nice acronym SeX) for about a decade now, ever since I wrote it. It is small: the executable is only 108 kilobytes, and it links only to basic X libraries, plus the Athena widgets. It starts up in less than half a second. It can handle files of any size that fit into virtual memory. It is quite simple. It doesn't have undo, and there are a couple of other things I consider bugs, but haven't ever had the energy to fix. It is also getting old: it doesn't interact very well with Gnome programs (e.g., it doesn't support the clipboard), and, most importantly, it does not support UTF-8 at all.
During the weekend, I fooled around with Gnome's standard text editor, gedit. It supports UTF-8, and has undo and redo, and plays nicely on a Gnome desktop, but it fails to separate between tabs and indentation. I'm not going back to using tabs for indentation. It doesn't seem to support things like selecting everything from a parenthesis to its matching parenthesis, which I find quite useful, especially with Lisp. Or rectangular blocks. I can't even find a way to see the same editing buffer ("file") in two windows at the same time. These kinds of features are probably considered outside the needs of the target audience. Gedit is not, after all, meant to be a programmer's editor.
I guess I'll give GNU Emacs and XEmacs a try, later, though I'm not very enthusiastic about them. Big and complicated tools is not what I relish and I'm not sure they even support UTF-8 very well. Then there's a bunch of other editors for Gnome I could try, and if everything else fails, I could rewrite SeX using GTK+ widgets, I guess.
After the editor issue is resolved, I can probably start being serious about moving to UTF-8. The mailer, web browser, IRC client, and terminal emulator I use all claim to support it well already, and those are the crucial ones. I expect a number of other tools will have glitches, but mostly I expect the transition to be fairly smooth, since UTF-8 is, after all, not very new.
Wednesday, October 15, 2003
Spent a few moments making a release of Lodju with fixes for bad bugs. There's a bunch of more benign bugs, including some in display updating, but those can wait for later. I'm still happy with the current situation, though I'm now thinking I want more advanced user interface features, such as searching. Ah well, after I get 2.0 out, I'll start working on those.
I've decided to start watching Buffy the Vampire Slayer again. I have DVD boxes with seasons 1, 2, and 5, and I ordered season 3 from Amazon UK yesterday. Between the time I added it to the shopping basket and today, it went from being readily available to being probably available within a week. Sigh.
One of the boxes I'm supporting Hedgehog on has a built-in flash memory, and the operating system comes with an API for writing to it. So far so good. Unfortunately, the documentation does not specify things fully, and the technical support hasn't answered questions correctly, either.
For example, the flash memory can contain arbitrary user data, or an executable, and if it contains an executable, the functions for writing to the flash will change a checksum and other header information. That's not something you want happening to your data, unless it is an actual executable. The manual does not explain how these cases are differentiated. Technical support explained that the difference is that any write sessions that start at the beginning of the flash are assumed to be executable, others are not. Therefore, they said, I should start writing at offset 1.
It turns out that you must start writes at the beginning of a sector. There is a function for figuring out the size of a sector, but the documentation does not say what the unit is. Various parts of the manual and the API use different units: the size is reported in megabits, offsets into the flash are in bytes, and write operation lengths are in words of two bytes. So, exactly how long is a sector of length 4096? It could be 512, 4096 bytes, or 8196 bytes.
Tuesday, October 14, 2003
Spent half an evening organizing my photos with Lodju. Great fun. I should have been at this stage two years ago...
Fixed yet another small, but disastrous bug. Will have to make yet another release soon.
Monday, October 13, 2003
Made a new release yesterday. The primary focus was to fix the drag-and-drop behavior. I think it now works in all situations, unless the hard disk fills up. On the other hand, it is awkward, in that the program blocks until it has copied files (if it needs to copy), and this will have to be dealt with somehow.
Perhaps as importantly as a new release, I'm now ready to start trying to use Lodju for real, for myself. Let's see.
Well, I made a gallery of photos I took of a new client project at work, and only found one bug. Related to drag and drop, no less, which I thought I had tested thoroughly. Silly me. At least it was an easy one line fix. Otherwise, things are looking good.
Sunday, October 12, 2003
I had a moment of absurdity in a meeting with a potential client on Friday. We were discussing whether Hedgehog would fit in the embedded device they were building themselves. They said something like "We have 256 of memory". Hedgehog has so far been running on machines with at least 512 kilobytes of memory, although a smaller memory shouldn't be a problem, we're not using all of the 512 kilobytes either. Only a bit later did it occur to me that they were talking about megabytes. It feels weird to have that much memory in an embedded device, but hey, they're the ones paying for it.
Saturday, October 11, 2003
Glenford J. Myers starts his book The Art of Software Testing with a self-assessment test, which is a very good introduction to thinking about testing and test cases:
Before beginning the book, it is strongly recommended that you take the following short test. The problem is the testing of the following program:
The program reads three integer values from a card. The three values are interpreted as representing the lengths of the sides of a triangle. The program prints a message that states whether the triangle is scalene, isosceles, or equilatersl.
On a sheet of paper, write a set of test cases (i.e., specific sets of data) that you feel would adequately test this program. When you have completed this, turn the page to analyze your tests.
You can look at the sample pages of that book on Amazon (sorry about not giving direct links). Myers gives fourteen questions with which you can rate your test cases. If yours pass most of them, you're in pretty good shape, testing wise. Back a decade ago when I read the book, I only got a few correct.
Oh, by the way, the book is pretty old, published in 1979. I haven't got a copy (more's the pity), but it should still be relevant, even if it contains anachronisms like "reading cards".
Thursday, October 9, 2003
Yesterday I was thinking about what I want in a mobile phone. Today, I've been thinking about what I want in a programming language. Specifically, in a language for writing various kinds of hobby projects in.
- A good implementation as properly free software. Enough said.
- Expressive and powerful. I want to write only a little code. More power means less code to write. Lisp is better than C in this regard, since C requires dealing with all sorts of pesky details manually, which Lisp takes care for you.
- Fast execution. Most of the time speed is not an issue, but sometimes it is. I'd prefer not to have to switch to another language, such as C, even for the speed critical parts. Interfacing several languages is just the kind of detailed work I prefer not to do. Something less than four times slower than C would be nice.
- Bindings to important platform libraries. This implies general extensibility by linking in C code (or compiled code from other languages). The most important ones for me are the Gtk+ and Gnome libraries. These can't be re-implemented in the language itself. Libraries for XML parsing, network I/O, or whatever, should probably be written in the language itself: it should be powerful enough for them, after all.
- Garbage collected. Manual memory management a la C is excessively tiresome and error prone.
- Infrastructure for library creation and sharing. There doesn't have to be an existing library for every conceivable task, but there needs to be tools in the language and its community to build, share, and use libraries. This will ensure that the set of free libraries grows. CPAN for Perl is a wonderful example. Python's standard libraries are another.
- The paradigm should probably be functional, though I'm not married to that idea. I'm flexible enough to be happy with any reasonable paradigm, but functional is my current favorite.
- Static type checking using type inference. It should not be necessary to declare the types of everything, but the compiler should still be able to check types at compilation time and yell if there are obvious errors. While I've only read a few descriptions of how Haskell does this, it seemed nice.
- Stable specification. I'd like the language not to change every year or two. Changes to the standard libraries are OK, but the language itself should be stable.
My current favorite language for hobby projects is Python. It does not fill all the criteria above. For example, they keep changing the language - admittedly, mostly I'm happy about the changes, but it still annoys me when the language changes. I prefer the pace at which C changes: about once per decade. Python is also no speed daemon, even if fast enough for most stuff.
My favorite language for work projects is, of course, Hedgehog Lisp, but its scope is restricted enough that I'm not sure it is suitable for the kinds of programs I want to write in my free time. For example, it has no concept of packages or modules, which is bad for library generation.
Because of Hedgehog Lisp, I've been reading about other Lisps, such as Common Lisp and Scheme. Other languages I've read about include O'Caml and Haskell. Paul Graham's Arc might be interesting, eventually. I'm still looking, however, none of these have convinced me, at least yet.
I'm an uncle.
Wednesday, October 8, 2003
The new N-Gage phone and game platform from Nokia has inspired several discussions on new phones today. Even with all my experimentation with neophilia, I fail to be enthusiastic about new phones. They're too full of features useless for me. What I want is something much more simple.
- Most importantly, the phone must be a good phone. Calling someone must be easy, as should answering someone's call.
- As importantly, it should work well for sending and reading SMS messages. This requires an efficient way to enter text in Finnish, Swedish, and English. T-9 (or whatever it is called) is good enough.
- The user interface (software and hardware) needs to be fast enough and not get in the way. This means, for example, that it should not be overloaded with lots of features I don't use: games, Java, WAP, Bluetooth, music players, etc. Or buttons they need.
- Most of the time, the alarm should be a discreet beep (different ones for calls and text messages would be perfect), accompanied with vibration.
- The battery needs to last a couple of days of normal use without charging.
- No external antenna.
- Suitably sized and weighed for the inner pocket of a jacket. The Nokia 6210 is about perfect in this regard. Anything bigger gets in the way, anything much smaller is hard to dig out from the pocket.
- Everything needs to just work. I do not ever want to upgrade the phone software, for example, nor have the phone crash. My 1631 never crashed, and my needs have not grown much since, so I don't see why a new phone should crash either.
Those who have followed mobile phone developments in the past few years may note that my requirements are placed at around 1999 or 2000 in the development timeline. I have little interest in all the gadgets developed since. I'm not being a Luddite or neophobe, I'm just not interested in playing games on a phone, or using it as a PDA, or things like that. My phone is a tool; I'll seek thrills elsewhere.
Thursday, October 2, 2003
It is Thursday, and therefore time for a new issue of the best Linux publication, Linux Weekly News. One of the news items is that the Linux Documentation Project is celebrating its tenth birthday. As far as I can remember, the LDP was founded by myself, Matt Welsh, and Michael K. Johnson in the fall of 1992, so they should more appropriately be celebrating their eleventh birthday. (An earlier version of this entry used the date 2002 instead of 1992. Thanks to Oliver Maruhn for pointing this out.)
More importantly, this is yet another incident of the lack of historical record and a good historical document for Linux. Someone (else) should probably write one. This would be an excellent way for, say, someone with research and writing experience to contribute to Linux. A journalist, maybe.