⇥ Goodbye from T·A·B

October 6, 2011
5 comments
⇥ Permalink

This is my last post on this blog. I have enjoyed having a place where I could write my thoughts more or less as they formed in my mind, and it seems that a fair number of people enjoyed reading what I had to say.

But times change. I own a company that deals almost exclusively with PHP knowledge, and it seems absurd that I should write about PHP here while php|a almost never gets to publish my pieces.

By the same token, various pieces that I write on Mac and on computing in general often make their way to a number of other publications, where they reach a broader audience and undergo the professional scrutiny that, for obvious reasons, cannot be part of a personal blog’s editorial process.

More than anything else, however, I’ve decided that I want to do fewer, but more meaningful, things with my life. In the past year or so, this blog has often had to take a backseat while other activities demanded, and usually received, my attention. I’m not a big fan of doing things halfway, so, instead of allowing it to sputter along with the occasional post, I’m going to let it fade gracefully into the twilight.

This Website will remain up, but from this point on only as an archive of words that I have written, and as a bibliography of words that I will write elsewhere.

If you have ever visited T·A·B, thank you. If you’ve ever found something here useful, you’re welcome.

⇥ Universal Save for iOS Apps

September 29, 2011

⇥ Permalink

Federico Viticci, commenting on a piece in which Ted Landau argues that iOS needs a “Universal Save” for iOS Apps:

Specifically, Landau notes that the lack of a “universal save” option for documents that can be read by third-party apps (PDFs, text files, images) leads to an annoying and pretty much useless duplication of content.

[…]

For Ted and me, yes, being able to avoid file duplication and tedious exporting processes would be nice. But I do wonder how much does Apple care about such functionalities considering the underlying paradigms of iOS and the upcoming iCloud functionalities of iOS 5. For one, Apple really cares about application sandboxing: each app has its own controlled data environment and only a few items can be shared between multiple apps.

I’m firmly with Federico on this point. The average iOS user has no use for filesystems, files, and the concept of “saving.” That’s probably one of the biggest innovations that iOS brought forth; of course, it’s going to be unpopular with us power users, because, having learned to live almost symbiotically with our computers, we have the hardest time letting go and learning this new paradigm.

This is also a problem for developers. I see tons of threads on mailing lists where folks are desperately asking how they can get out of supporting some of Lion’s new features and keep their app’s old functionality the way it was.

That’s not the right way to go about things. If you want your app to feel at home in a new operating system1, you have to embrace and implement the user-interface paradigms that the OS describes. This is probably the most fundamental step towards providing users with a consistent experience instead of a hodgepodge of half-baked ideas—and one step that, as a developer, you skip at your own risk.

What’s interesting is that, in my opinion, these “limitations” that we power users are complaining so much about matter very little to regular folks, as demonstrated by the great success of apps that have adopted Lion’s features in full. As sandboxing makes its way to OS X, this is going to be particularly important, because Apple gives its desktop apps much more freedom, and the addition of freedom to the ability to develop software results in a very flammable mixture.

Consider, for example, the case of 1Password. When Agile Bits released its popular software on the App Store, sandboxing forced them to introduce some seemingly arbitrary limitations on how it back its data up to DropBox. The reaction from power users was duly indignant that such limitations should be imposed on them.

The reaction from the public-at-large? 1Password quickly reached the number-two spot on the App Store. You do the math.

  1. And make no mistake about it, Lion *is* a new operating system.

⇥ You are not “Mr. X”

September 22, 2011
9 comments
⇥ Permalink

I keep coming across code like this (lifted, verbatim, from an OSS project I’ve been working with recently):

$a = $num * $coeff + $_SANITIZED_GET['val'];

What, in the name of all that is good and just, is “a?” Or, for that matter, what are “num” and “coeff?”

Computer manufacturers, OS vendors, and programming tool developers have worked for decades to give us the ability to create identifiers of arbitrary length. Personally, I’d much rather see someReallyLongNameThatLooksALittleRidiculous than a function or variable name that won’t tell me what it does at first sight.

The same goes for data. A “1” and “0” in a database don’t tell you as much as “Yes” or “No,” which are just as localizable, indexable, and searchable. Enumerations, as far as I’m concerned, should be verbose unless there are very compelling space or performance requirements that say otherwise.

I know that there are many people who disagree with this approach, but their arguments tend to fall in the “that’s the way I’ve been taught to do it” camp. The reality is, a numeric enumeration is just as arbitrary as a string-based one, but much harder for the human eye to make sense of—and we all know that, sooner or later, all data is looked at by a human eye. There are some circumstances in which performance and space constraints come into play, but otherwise the development tools at our disposal are mature enough to handle either type as easily as the other.

Besides, using numbers to identify non-numeric value is a domain violation. It used to be a necessity twenty years ago, but the vast majority of us work in environment that are well past that point. You wouldn’t want to be called “492829,” right1?

So, if you are writing a book or teaching a course on programming, please teach your readers and students to write descriptive code. They’ll be better for it, and we’ll be grateful that you did.

  1. Yes, I know. You probably have some kind of social security number assigned to you by your government. But that’s not your name—it’s an index (that is, a numeric value) in a table that *contains* your name. Big difference.

⇥ SEO for Non-dicks

September 21, 2011

⇥ Permalink

SEO for Non-dicks:

So, shockingly, you should try to make your site’s content trustworthy, genuine and relevant. All of the rules have come about due to their utility in detecting those three positive metrics. Good SEO is a by-product of not being a dick on the internet.

Really good piece by Matt Gemmell. In particular, I agree, with regret, on one point: descriptive titles are important.

And I hate them, because titles are like a secret trapdoor into your content—teasing you with one meaning and then springing a completely different one once you read through. Alas, the Internet has all but killed the often understated art of writing good headings.

(Via Lex Friedman).

⇥ Generations sideways

September 20, 2011

⇥ Permalink

Matthew Baxter-Reynolds on the various toolsets available to mobile developers:

The fact is that if your day job involves sitting in Visual Studio writing C# applications, or building Java applications in Eclipse (which will be most of you – albeit not necessarily in Eclipse), when you fire up Apple’s Xcode and start building CocoaTouch applications in Objective-C you’re going to come face-to-face with a toolset that has not had the sort of love put into it that the open source community has put into the Java toolset and associate platforms, or that Microsoft has put into VS and .NET over the past 10 years. Apple has been caught on the back foot by the popularity of its tools and is at least one, if not two, generations behind. For example, the iOS version of Objective-C does not have garbage collection.

Leaving aside the mistake at the end (which Baxter-Reynolds corrects at the bottom of the article), I’d say that Apple’s approach to its toolset is simply different, in some cases for the better, and in some for the worse.

Cocoa seems to be built on a simple premise: that developers know how to develop, but don’t know how to design interfaces; which, I am sorry to say, is probably not far off the mark.

Thus, Apple’s assumption is that developers don’t need fifteen ways to parse an XML file, because they already share enough common knowledge to do it on their own—and if they don’t, chances are that they will be smart enough to come up with their own solution and share it with the world.

The focus of Xcode is, instead, on creating an environment where even a person who is not well versed in user-experience design can still write an app that looks and feels good. Therefore, a lot of emphasis goes into good interface metrics, good look and feel, and so on.

In other words, Apple is counting on engineers commoditizing the aspects of software development with which they are most familiar, and focuses instead on filling the gaps in other disciplines that, traditionally, trip them up.

Case in point, Objective-C has lacked a public JSON framework for a really long time1. By all accounts, this should have made OS X and iOS very unsuccessful platforms for Web service-enabled apps; instead, developers simply built (and collaborated on) several JSON frameworks of their own. On the other hand, both of Apple’s operating systems present their users with an environment in which apps use a consistent design vocabulary that is well within the grasp of even the hard-core Luddite.

There are two reasons why this is important. The first is that a lot of development is still done without the benefit of a designer’s expertise. Even medium-size teams that build apps for large audiences place much more focus on engineering than on usability and ergonomics; thus, a toolset that promotes basic design principles can be beneficial from the get-go.

Second, even where designers are involved, developers are still responsible for implementing the code that makes design possible. Therefore, a development platform that emphasizes design creates a more collaborative environment for all involved.

That said, there are some aspects in which Apple’s toolset has dragged behind its competitors. Memory management, for example, has long been one, but Apple’s approach to solving the problem of managed memory has been a very deliberate one: they tried garbage collection, figured out that it didn’t quite work (particularly on iOS, where resources are relatively scarce), and moved to a different solution (ARC) that somehow manages to create a managed-memory environment with less overhead than its unmanaged predecessor.

All in all, my personal experience has been that every development environment has its flaws and benefits. Even Xcode’s focus on design doesn’t prevent the creation of plenty of really horrible apps. Still, that’s a far cry from saying that it’s generations behind—I’d rather say it’s generations sideways.

(Via Daring Fireball).

  1. Though that is getting resolved soon.

⇥ Right conclusion, wrong reasons

September 19, 2011
8 comments
⇥ Permalink

ORM is an anti-pattern:

The reason I call ORM an anti-pattern is because it matches the two criteria the author of AntiPatterns used to distinguish anti-patterns from mere bad habits, specifically:

  1. It initially appears to be beneficial, but in the long term has more bad consequences than good ones

  2. An alternative solution exists that is proven and repeatable

It is the first characteristic that has led to ORM’s maddening (to me) popularity: it seems like a good idea at first, and by the time the problems become apparent, it’s too late to switch away.

I agree that ORMs are, in general, to be treated with much suspicion. Their main shortcoming is that they are a square-peg solution for a round-hole problem: attempting to map a data model to another inevitably leads to conflicts and issues, or there wouldn’t be a need for the two different data models in the first place.

The real problem with this blog post, however, is that it uses an incomplete definition of anti-pattern (there’s Wikipedia for you). In his original article on anti-patterns, Andrew Koenig1 speaks specifically of anti-patterns as juxtaposing to patterns; like ying and yang, you can’t have anti-patterns without having patterns that they can be related to.

The significance of this is that an anti-pattern is not just something that is “bad on its own.” More often than not, it is more like “a pattern that has gone bad”—the right concept being applied under the wrong circumstances.

Thus, ORMs are not inherently bad. They are just inappropriate for a number of settings in which they are, admittedly, used. An ORM can be an excellent solution to scenarios in which a key-value store is not available, or in which a very simple schema is all you need. In those cases, the overhead of an ORM may be an acceptable tradeoff for the simplicity that it brings to an application.

This, in turn, brings me to another point: using an ORM does not excuse you from understanding the underlying data model and the way the ORM uses it. If you do, the ORM becomes almost inevitably an anti-pattern, because you’re resorting to magic and applying a solution without knowing the problem.

Thus, while it’s true that ORMs encourage (and mostly fail) the developer not to think in terms of SQL queries, there is no way to use an ORM well without understanding relational data mapping. Or, put another way, the ORM doesn’t replace your knowledge of SQL—it simply adds one more layer of indirection to it.

An argument could be made that ORMs do not scale well over time, because the relationship between the overhead they introduce and the complexity of the underlying data model is not linear. This, however, seems to me like a symptom of application design, rather than an inherent flaw in ORMs.

Let me give you an example; if you’re writing an application that you know you will only need to run once (for example, some sort of importer or data analysis function), an ORM can greatly simplify your job and bring immense benefits. Will you care if it doesn’t scale? No, because you’re writing a single-use application.

If, on the other hand, you’re writing a more complex application, then you need to evaluate how well an ORM will hold up over time. That’s as much an art as it is a science, but it doesn’t make ORMs inherently bad; it simply means that you need to learn to design software properly.

  1. The original article in JOOP is not available online, but it’s included in Linda Rising’s Patterns Handbook

⇥ A New and Improved Moore’s Law – Technology Review

September 15, 2011

⇥ Permalink

A New and Improved Moore’s Law – Technology Review:

Researchers have, for the first time, shown that the energy efficiency of computers doubles roughly every 18 months.

Dovetails nicely with something I wrote not long ago for TidBITS.

(Via Daring Fireball).

⇥ Dashes, spaces, and incompetence

September 14, 2011
8 comments
⇥ Permalink

Take, if you would, a look at your credit card. Unless you come from a different planet, chances are that it, like mine, has a series of digits separated by spaces. Depending on which kind of card you’re looking at, these numbers may be grouped in different ways, but, generally speaking, this is probably a valid statement for every kind of credit card in existence.

Those spaces are there for a very specific purpose: they break the visual flow of your credit card number, providing your brain with anchors that it can use to group the digits together in a way that makes them easy to process. Although the number as a whole is no easier to remember, it’s much simpler to copy and compare something like “123 457 789″ than “123457789.”

Why, then, do so many developers still insist on asking users to enter their credit card numbers “without dashes or spaces?”

The problem here is not just one of developer laziness. Sure—in the specific example of credit card numbers, all that needs to be done at the code level can be expressed with a regular expression that borders on the stupid:

$creditCardNumber = preg_replace('/\D/', '', $originalCardNumber);

In some other cases, building good heuristics that are flexible enough while providing the proper constraints can be a little trickier, but the real issue is that so many programmers don’t even try. And that, unless you’re writing your applications in assembler, is simply incompetence.

Learned helplessness

There is a beautiful concept in cognitive psychology called learned helplessness. The basic idea behind it is that people who repeatedly fail at a task will eventually blame themselves for the failure and give up trying to do it.

This, in a nutshell, describes perfectly the way I see most non-technical folk relate to computers. They’ve just been hit so many times by software that makes no sense to them that they approach every task with fear and uncertainty—instead of making users more productive (and, therefore, happier), software makes them more depressed.

Why does this happen? Because of a million little (and big) things like the credit card snafu. Every time the user encounters a scenario in which an application creates a disconnect between reality (spaces on my credit card) and its software representation (no spaces or dashes!), the sense of helplessness increases, and productivity decreases as a result.

Let me fix this for you

The good news is, this kind of problem is due entirely to developer incompetence, which makes it easy to fix—after all, there are far fewer of us than there are users, so education should be a far simpler task.

In the specific example of credit cards, the issue is usually related to the fact that the upstream credit card provider requires that numbers be passed to them without any extraneous character, and we simply transfer that constraint up to our downstream user.

However, the constraint is not transitive: it makes sense in one direction because the provider has created an interface built for engineers, who (at least in principle) should be able to deal with the resulting requirements. Our users possess no such ability, and expect an interface built for them.

From a more general perspective, solving this kind of problem is not that difficult: you simply need to look at the constraints you create from the user’s point of view. Credit cards numbers have spaces in them in real life, and that’s how users will want to input them. There. Simple as pie.

This doesn’t mean, however. that you need to take this too far in the other direction and create skeuomorphs that attempt to reproduce reality too closely. For example, making your credit card input form look like a credit card is dangerous because the various types of credit cards are different enough that it could create confusion instead of dispelling it. Besides, the user is probably capable of abstracting the underlying data model enough that such a skeuomorph would feel patronizing.

And, please, do not think that this is something that only designers should worry about. Developers are meant to solve problems, not churn out bytes. If you don’t want to be treated like a code monkey, stop acting like one.

⇥ Suggestions for a younger developer

September 13, 2011
5 comments
⇥ Permalink

Every now and then, I get asked by developers who are just getting started in the trade if I have any suggestions to help them out—favourite language, tips and tricks, and the like.

None of these things matter, really, but there are a few things I wish I had known when I started out that have nothing to do with the mechanics of software development.

1. Be humble

You just finished college with full marks. You know hundreds of algorithms backwards. You’ve read Don Knuth’s seminal programming series cover-to-cover (something that Professor Knuth himself would probably be disinclined to believe).

Alas, that does not a programmer make you. You’ll find out soon enough that being successful at writing software means quickly discarding options that are unlikely to lead nowhere, while zeroing in on those that will. And, more often than not, it means throwing away the book and violating every rule to get where you need to go.

2. There is no magic

Never assume that other developers are necessarily smarter than you. Remember that the people who write the tools you use have access to the same kinds of resources and techniques as you do.

Never accept the frameworks and APIs at your disposal as black boxes; understanding how they work internally will help you write better code against them.

3. Programming is a craft, not an art

Good code, like art, is many things to many people. Working code, however, is undisputedly code that performs its tasks properly and efficiently.

A good developer is like a good artisan, constantly balancing the needs of form and function, but always focused on making things work in the most practical way possible.

4. Software solves problem

Writing code is a crucial, but relatively minor, part of the software development process. You write code to solve problems, and can’t be good at one without being good at the other.

Strive to be part of the entire process that leads to the development of a system; insist on being treated not as a code monkey, but as an integral part of the overall team that contributes more than mere lines of code.

5. Code doesn’t leave sawdust

One of the best aspects of software development is the fact that it is a purely intellectual exercise. With a modicum of precaution, we can experiment knowing that our only waste is time; there is no wood to chop, pencils to sharpen, chemicals to react, or paper to crumple.

Sometimes, trying things out in practice leads to unexpectedly efficient solutions that all the planning in the world could not have anticipated. And, when it doesn’t, there’s always source control to take you back in time, ready for another try.

⇥ Maybe we should all be a little more intolerant

September 12, 2011
One comment
⇥ Permalink

Like most other people I know, I’ve been taught that the right way to respect other people is to tolerate them. Everyone is entitled to their opinion, beliefs, choice in religion, sexual orientation, and political ideology.

That might be true, but it’s not a productive way to lead our lives. Tolerance is but a feeble excuse that allows us to keep wallowing in our misogyny, racism, and homophobia while presenting a progressive, modern façade to the outside world.

Tolerance, when you think of it, is a mightily ugly world. You “tolerate” pests; the very dictionary definition of “to tolerate” includes words like “endure,” “put up,” and “stomach.” Is this the way you want to relate to other human beings? I certainly hope not.

More than anything else, tolerance doesn’t make us better human beings. It simply makes it possible to ignore the fact that someone around us could have a better outlook on life and close in on our own beliefs without ever needing to question them.

I grew up in a fairly conservative environment: Catholic upbringing, spent a lot of time around priests and nuns. And, despite what I keep hearing about the Catholic Church, I don’t regret one bit of it. But I also grew up in a progressive environment, in which my family and teachers always pushed to keep a critical eye on the world around me.

As a result, I have developed a somewhat eclectic system of beliefs in life. I am against organized religion, and very much pro-science1; I wholeheartedly support gay marriage, and look forward to the day when the words “who is openly gay” are going to sound as absurd as “who is openly human.” I am generally against abortion, and think that Affirmative Action is a bad idea. And so on, and so forth—many contradictions that make it difficult for me to say “I’m conservative” or “I’m liberal.”

This doesn’t, however, mean that I think that people on the other side of these (and many other) issues are stupid or evil. Wrong, maybe, but never beneath me, and always worthy of discussion and discovery. Some of my best friends and colleagues have outlooks on life that are far different from mine, and I enjoy nothing more than understanding why together with them.

I don’t expect that they will change my opinion, or that I will change theirs: dig enough into any person’s moral and ethical systems, and you’ll find that they are anchored in beliefs—which, by their very nature, resist logic. But, by understanding another’s point of view, you can learn more about them, and, most importantly, you can learn to empathize with them, transforming your society-enforced “tolerance” into respect.

This kind of intolerance—call it intolerance of tolerance—can be very beneficial to society. You can either be Richard Dawkins and proudly proclaim that the 75 percent of the world’s population that believes in some sort of divine presence is stupid, or you can ask them why and try to understand where their beliefs come from. In the first case, you’re simply peddling religion by another name; in the second, you might just enrich your life a little, and maybe the lives of others.

  1. Which is not the same as saying that I do not believe in the divine, mind you.