Pink for boys

“The generally accepted rule is pink for the boys, and blue for the girls. The reason is that pink, being a more decided and stronger color, is more suitable for the boy, while blue, which is more delicate and dainty, is prettier for the girl.” —Ladies Home Journal, June 1918.

That’s from Smithsonian Magazine. Another interesting factoid: kids don’t realize gender is permanent until about age 6 or 7. So it’s perfectly normal that Ian likes to dress up like a princess from time to time. (Not that I ever thought his gender identity is unusual; he’s far more likely to dress as a firefighter.)

Mind vs. brain

Here’s an hour long video about the neurological basis for the mind from the Google Tech Talk series. I won’t say any more about it except that after watching it, I showed it to Jordan, and it inspired us to meditate every evening.

I have other thoughts on the subject, but I’ll save those for a later post.

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.)

MySQL has now been Oraclified

Anyone who has wondered what would happen to MySQL now that Oracle has purchased it need look no farther than www.mysql.com. The website has been remade in Larry Ellison’s image. My company stopped using MySQL a few years ago (we switched to PostgreSQL), but I saw a press release that there’s a new version of MySQL, so I went to look at the release notes. Problem is, there are no links to documentation from the website. None. So what is there?

  • Links in the heading for “Recommended servers for MySQL” (links to Sun/Oracle servers) and “Contact a MySQL Representative” (which has a login form)
  • A search form, which can’t find product documentation
  • A list of bullet points about the new version, if you click on the right rotating banner ad
  • A whitepaper about the new version, behind a login form
  • A full-page advertisement when you click on the home page link

But the coup de grâce is that a Google search for “MySQL Documentation” brings up an advertisement—with “MySQL Documentation” in its title—which leads to the whitepaper, login required.

(As a Java developer, I’m not actually surprised by any of this. For the last 15 years it’s been more convenient to use the online Java documentation than to download a local copy. Lately that’s changed. Oh, and for what it’s worth, the MySQL documentation website—it’s always been a separate site—has been Oraclified as well.)

Jordan Wood, Animal Rescuer

Diego and the Wonder Pets, move over. Just like those Nickelodeon characters, my wife has rescued baby animals twice this year. This summer it was a baby squirrel in our yard. This week it was a kitten that our neighbor found frozen to the stucco on another neighbor’s garage. Nobody along our alley claimed the kitten, and so despite Jordan and the kids having fallen in love with him, he’s now at the Humane Society. I have no doubt that with his good looks and winning personality, he won’t stay there for long.

Now at the Humane Society

"Smoky"

There are two types of programming…

…type 0 and type 1. (Laugh here.) Okay, so software engineering isn’t really binary. Still, I’ve found that the world of computer programmers makes a lot more sense if you divide it into two categories: engineered and improvised. If you think in this way, you’ll find that many of the holy wars among developers are a result of improvisers who don’t see engineering problems and vice versa.

Engineered programming is appropriate for problems with solutions that can be defined mathematically. People rely on these programs to act correctly. This includes wind tunnel simulators, machine controllers, pacemakers, and even tax preparation software. But it also includes software within a computer program for storing, retrieving, and interpreting data. For example, your web browser must follow many different protocols so a JPEG image will look like Justin Bieber and not random garble. Engineering problems need to be tested for correctness, because the end user may not be able to evaluate it. If your accounting software is buggy, and you’re not an accountant, you’re in trouble. Not only can they be tested, but the components of engineered software can be divided into sub-components, each of which can be tested independently. In fact, it’s possible to develop a test suite for every branch in the code. How much testing you do is limited only by how concerned you are about bugs. A pacemaker company hires 10 test engineers for every programmer, while an accounting company is considerably more relaxed, while the data loader for a video game may get fairly little testing. The tools of the trade for engineered software make testing quick and easy, and often automated. For example, when I’m writing Java code, my IDE highlights certain errors as I type them and offers corrections, just like a spell checker. As these tools get more sophisticated, bugs get harder to write.

Improvised programming is appropriate for problems where there’s no right or wrong answer, just better or worse solutions. And better or worse may be in the eye of the beholder. User interfaces are the most common situation, but there are others, such as special effects. Even things that ought to have well-specified requirements may require improvisation, particularly when the people providing the requirements keep changing their minds. When I write screen savers, I often find that my bugs are more interesting than what I’d planned to write. This is not a “no tests, just wing it” environment, though. The difference is in the kind of testing that’s appropriate. You can’t sub-divide a user interface into components and test each one separately; holistic tests are the rule. Usability tests tell you if the program works in a particular context for particular people. An iPhone widget that works great for kids may be completely unusable for fat-fingered football players. The tools of the trade for improvised programming make it easy to make changes, including throwing everything away and starting from scratch. This is often called rapid prototyping, even though the finished product is often the best prototype.

So there are two completely different types of programming, for which completely different types of tools–even different programming languages– are called for, and they are mingled together in most programs. What to do?

There’s a design pattern called Model-View-Controller, or MVC, which offers a solution. It’s enforced by Apple’s development tools, and Ruby on Rails is built around it. In MVC, the model is the engineered portion of your code. It describes the universe in which your game exists. If you can prove its correctness, it belongs in the model. The view is the pure UI portion, where user feedback rules. The controller is the in-between portion; it’s the logic of the program which isn’t as clearly defined as Model and isn’t as flexible as UI. The genius of MVC is that it cleanly separates the parts of the code that are best suited for test-driven design from those that require rapid prototyping.

Gifts of services

You hear a lot about how your Christmas shopping will help to save the economy. I’m not so sure; we got into this mess by overspending, after all. But let’s face it: buying trinkets that were made in China from a low-overhead retailer isn’t going to create many American jobs. If you want to help, give gifts of services this year. Massages, theater tickets, nights out, dance lessons, even babysitting. For the more practical and less romantic, how about gifts of oil changes, or legal or tax advice (to someone who grumbles that they need it). Anything that puts cash in the hands of someone local, who can then spend it again locally.

Being autistic

My good friend Seebs just wrote an excellent blog entry about autism. I should add that although he shares many quirks with Sheldon from Big Bang Theory, Seebs is by no means annoying or unsympathetic. Quite the opposite. He just doesn’t pick up on emotional cues easily, so you have to be direct with him. That’s not necessarily a bad thing. He’s also absolutely, completely non-judgmental, which makes it easy to be yourself around him. He’ll never consider you a bad person; there’s no such thing in his world. Though he’s discovered the hard way that there are people who shouldn’t be trusted to not steal, or who can’t be expected to be honest, or who otherwise aren’t good to have around for a particular activity for whatever reason. But he never holds a grudge or takes things personally.