Category Archives: Computers

Apple aims for the low end

John Gruber writes:

Another new pattern: the expansion of the iPhone product line down to free-with-a-contract pricing. Apple did this not by creating a new “low-end” model, but by keeping the 3GS around for another year. This move seems so obvious that I’m disappointed in myself for not having predicted it. Operations wise, the 3GS doesn’t just use cheaper components, but because Apple has been making it for two and a half years, they’ve surely streamlined the manufacturing process.

The most important cost savings is the value of simply keeping the factory doors open. For technology components manufacturers, costs break down into two categories: fixed and operational. The fixed costs can be huge. A new chip fab (factory) costs over a billion dollars. Companies like Intel spend the first several years just paying for the R&D and the factory. An Intel processor doesn’t actually start making them any money until they have a newer high-end chip, and the “obsolete” chip gets sold at discount prices. Without the fixed costs, the discount prices have a healthy profit margin.

Video game consoles are built around this model. They keep roughly the same price and the same specs over their lifetime. For the first few years, consoles are a huge bargain: the manufacturers actually loose money on them. Near the end of their lifetime, the components are laughably obsolete, but the price is justified by the huge library of video games they run. This drives their design. Hard disks were added only reluctantly, since their platters don’t get cheaper. Chips are good. And custom anything (processors, controllers, cases) is the best, as R&D is a pure front-end cost which keeps the console distinctive in later years.

Apple knows streamlined manufacturing, and it shows in the iPhone 4′s design. Using an antenna and two panes of glass for the case minimizes materials costs. As does a small battery. Small and thin, few buttons: it’s not just for looks, it’s to maximize the factory’s lifetime. The iPhone 4 was designed to be a third-world discount product. But for now, it’s cheaper to keep making the 3GS in an old factory than to put old components in an iPhone 4.

Steve Jobs: the Perfectionist who Shipped

In thinking back on Steve Jobs, I remember an insight I had years ago, while he was at NeXT. Most people in the computer industry are either perfectionists or pragmatists. The perfectionists do well in academia, where it doesn’t matter that their big ideas take years to turn into practical products (think Donald Knuth.) The pragmatists do well in the private sector, where a steady stream of adequate hacks trump elegant designs. Think Microsoft under Bill Gates: they had a reputation for shipping a laughable 1.0, followed by a nearly respectable 2.0, and then kill the competition with 3.0. Compare the Mozilla Foundation, which disappeared and left MS Internet Explorer with a monopoly while they perfected their browser. Or think of well-designed but expensive SCSI disks, which got eaten alive by the inconvenient, cost-cutting ATA format. Or BSD vs. Linux. (Or both vs. GNU Herd, which never shipped.) And on and on.

Of all the paradoxes of Steve Jobs, this is perhaps the most important. He was a perfectionist who didn’t miss deadlines.

RIP Michael S. Hart, E-books creator

Michael Hart is not exactly a celebrity. But as founder of Project Gutenberg, he’s an inspiration. He had a simple idea, digitizing and disseminating public-domain books. Perhaps it was inevitable that paper books would end up digitized, just as hand-copied ancient manuscripts were made into printed books. But he was the first. Often times the march of progress seems inevitable, especially in retrospect; just as often the appearance is misleading. When it comes to books online, the world doesn’t begin and end with Google and Amazon. Typically their source is Project Gutenberg, and it can be your source too. Thanks to Michael Hart.

A harbinger of things to come?

I just did a Google search for “Project Gutenberg.” Rather than finding the Project Gutenberg website, Google filled the results with entries from its own e-book catalog. A Bing search took me right to Project Gutenberg.

I filled out a complaint form (Google has a link at the bottom of the page.) A few minutes later, it was giving correct results. Questions: was this a broken server, or a normal result? Was my later search influenced by my complaint? If so, did it only affect my search results? No matter how well-intentioned the folks at Google are, there is too much incentive for bias, and it is too hard to detect* for bias not to creep in over time.

*See Appendix A of this academic paper for a discussion of the dangers of search engine bias.

Digital Archiving: paper is still best

The Internet Archive has announced a project to preserve physical copies of scanned books. There are two reasons for this. First, the original book is more authoritative than the scan. Second, books last longer than hard disks.

I find this interesting in the context of my Seventh Generation project. The letters I’m writing will be printed, but I’m planning to have electronic versions as well, hosted here at And I’m relying on the Internet Archive’s wayback machine to keep those available long since has gone away.


It occurred to me last year when the iPad was introduced that RAM may soon become a thing of the past, replaced by larger on-chip caches and super fast flash SSDs (solid-state disks.) Of course, something like this has been theorized for decades (consider Tom Baker’s endorsement of bubble memory in the 1981 Dr Who episode Logopolis.) But now it’s starting to look inevitable.

In the old days, chip speeds were so slow that RAM chips could be read almost as fast as processors could use the data. But as chips got faster, it became necessary to add more and more caches of memory between the processor and RAM. Today’s processor clocks are measured in gigahertz—meaning that a clock tick propagating at the speed of light can barely make it across the chip in time for the next tick. Traditional RAM chips, which might be a foot of wire away from the processor, have no chance of keeping up.

It’s hard to compare speeds between Serial ATA (for SSD) and memory buses, since SATA is measured in gigabits per second, whereas memory buses are measured in megahertz. The latter measures latency, or how long a bit takes to travel, which is the more important measure for replacing RAM with SSD. But my guess is that SATA 3 is within the “close enough” range, where a computer designer could start to consider throwing out the RAM and just having SSDs.

The iPad takes a step in that direction. The processor is designed to have its single RAM chip stacked on it like a layer cake, in a position which resembles an on-chip cache. (Desktop CPUs often have “on-chip” caches on a separate silicon chip, but packaged in the same plastic “chip.”) Future desktop processors may well have a similar configuration.

Indeed, there’s talk that down the road, supercomputers may need to have their “disks” (SSDs) on the processor chip simply to reduce their power requirements. That’s because if supercomputers continue to become more powerful without becoming more energy efficient, they’ll soon need dedicated nuclear power plants. But on-chip disks would also be useful in phones, tablets, and laptops.

Object extensions in database tables

At Vocalabs, we use a homebrew object-relational bridge, rather than more common ones like Spring Hibernate or ActiveRecord in Ruby on Rails. The reason is simple: when we first needed one in 2001, the others either didn’t exist, or weren’t mature. Object-relational (O/R) bridges, which map database tables to classes in an object oriented language, were pioneered by Enterprise Objects Framework (EOF) in NeXTStep. (NeXT was acquired by Apple, and EOF lives on in WebObjects.) Since I had used EOF in the 1990s, I had a good idea of what I needed, so homebrew was the way to go.

Many of the differences between the Vocalabs DBObject and other O/R bridges are a matter of laziness. It’s not worth my while to write a complete front end to SQL in Java, so my code is full of hand written SQL where auto-generated SQL would be too slow or hard to write. However, there are a few cases where I’m doing good stuff that I haven’t seen elsewhere.

One such case is DBObjectExtension. The idea is to have a generic way to store metadata that can be applied to any DBObject. Some uses might include: tagging, commenting, translation, or versioning. Each of these use cases would have a subclass of DBObjectExtension, and that class would have a separate table for each DBObject class that it extends.

For example, we do surveys, and surveys have questions which in turn have response options. Thus we have the Java classes Question and ResponseOption, each of which is a subclass of DBObject. Each of them has a table in the database. Most of the time that’s all we need. But this week we have a customer who needs to survey Spanish speakers, and we want to do it within an English-language survey, rather than creating a special Spanish survey.

Thus I’m working on DBObjectLocalization, a DBObjectExtension which lets you modify a DBObject with a translation. To enable DBObjectLocalization for ResponseOption, I created this table in the database:

create table response_option_localization (
response_option_localizationID serial primary key,
response_optionID int NOT NULL references response_option(response_optionID) on delete cascade,
language varchar(2),
property varchar(255), /* The Java property that gets overwritten */
translation text,
/* The last four columns are required by DBObject */
/* mainly because when you discover you need them, */
/* it's too late to add them. */
updated_by varchar(30),
updated_at timestamp,
created_by varchar(30),
created_at timestamp);

Now a ResponseOption gets translated when I call DBObjectLocalization.translate(myResponseOption, language) in Java. We’ve got a web-based front end to our database, and adding translation support was fairly simple. But the best part is that to add localization to Question, I’ll just have to create a question_localization table that looks just like response_option_localization. No new code required. And so on for every other DBObject.

Another nice feature is that because DBObjectLocalization is itself a DBObject, I can apply DBObjectExtensions to it. Our surveys are versioned: when a change is made to the text of a Question, a DBOBjectExtension keeps track of the old text so that we know who saw which wording. My next task will be to add versions to translations. In principle, all I need to do is create a response_option_localization_version table, but since I’ve got special rules for localization in the web-based editor, there’s a little more code needed to do this.

I’m not sure how you’d do this sort of stuff with other O/R software. Versioning can be done with a single version table, but for the other uses you lose referential integrity (when you delete a Question, the ResponseOptions and localizations are automatically deleted by the database), and joins become a nightmare.

Object extensions is one of these features that I think belongs in other O/R software. It’s the sort of thing that ought to be done with a database but you can’t naturally do in SQL.

Writing clean, testable code

A must watch for would-be programmers: Writing clean, testable code

Most of this stuff I’ve picked up through hard experience, though putting all of this stuff in one place is useful. Some of the most important code I work with is also some of the earliest I wrote at Vocalabs, and it’s nigh impossible to test. One thing he doesn’t mention is that when concerns are properly separated, it’s also easier to reuse and modify code, which I’m also bumping into. Unfortunately, the right way to separate concerns isn’t always obvious, and that same code includes some false attempts. (I.e. “dependency injection” means knowing your dependencies ahead of time, and getting it wrong is annoying.)