Follow me on Twitter

Fork me on Github

Icons that have lost their meaning

I love this: Icons that don’t make sense anymore.

Icons that long ago lost their graphic meaning. My favorite is the phono logo that appears even now on my Android handset:

Wow - dependency injection in PHP is a really bad idea

I’m not a huge fan of dependency injection. Anytime you move logic out of code and into some XML file you’re making your application harder to understand. 

The argument for dependency injection is that it makes your application more flexible by creating a loose coupling between components. So rather than having a hard-coded line of code to instantiate a concrete instance of some logger class, instead you move the type choice out into some configuration file.

Dependency injection was popularized by the Spring framework in Java. Now I can almost, sort of, see the benefit of DI when using Java, where the compile-jar-startup cycle can be quite long. (Although I think most cases are probably better handled by a basic factory pattern.) When you’re using a static-typed language like Java, then DI can introduce some late binding where types don’t have to be resolved until runtime.

But recently I’ve gotten the peculiar pleasure of getting to work on a PHP application using the Symfony 2 framework. Symfony includes a DI system taking inspiration from Spring. They even have a really nice web page describing the system, which includes this great feature: “comes bundled with a Graphviz dumper, allowing you to visualize the graph of your objects and ease the debugging of your container”. 

The only problem is that dependency injection is a terrible idea in PHP. After all, PHP is a loosely typed, dynamic language. If you want to use a different class for your logger, well then you just assign your “logger” variable to some other object. Objects are duck-typed in PHP, you can call “logMessage” on any old object you like. There’s no compile-link-debug cycle to avoid by moving type resolution into some XML file!!

You want to choose a different logger at runtime? Just set some config option (say in php.ini or your own config system or in an env variable) and choose your logger class at runtime based on the config value. You can even put the logger class name in your config, and use: “$logger = new $loggerClassName;”. Please, please, do not start littering your code with XML files, and forcing yourself to “visualize the graph of your objects to ease debugging of your container”!! 

Dependency injection is a crummy solution to a problem specific to the limitations of complex, statically-typed systems. It really has no benefit in a dynamic language like PHP.

Engineering experience - the importance of breadth

David Heinemeier Hansson recently tweeted a link to a great, older blog post he wrote about how developer’s need about 6 months of experience to be effective on a new platform. His point was that beyond those 6 months there are diminishing returns in terms of new expertise gained on any given platform, and so recruiting for an engineer and asking for “5 years experience with XX” as a requirement is a poor tactic for finding a good developer.

I believe a corollary to to his point is that breadth of development experience can often be more important than depth. Certain fields or tasks are naturally going to reward deep experience - say artificial intelligence or network security. But many jobs are better served by someone with a great variety of development experience. 

This is because software development is a field built on patterns. Developers learn from one another, and good ideas naturally get recycled across many different platforms and contexts. And thus developers with a wide range of experience (different languages, different platforms, different problems) experience more of these patterns in more varied forms. And as you see the patterns in use across different contexts, you come to a deeper understanding of that pattern: its purpose, what it’s good for, and what it’s not. 

The results of this experience are shorter learning curves and greater ability to effectively exploit a platform. If you’ve used the Model-View-Controller architecture before, then understanding how it’s used in iOS programming is easier. And if you’ve used 3 different flavors off MVC on different platforms, then it becomes really easy. Having lots of experience in dynamic vs. static languages is key to understanding when one is the better tool for a certain job (example: the most talented web developers I know use dynamic languages - not Java - to program web pages).

When I’m looking to hire a developer, I look for breadth first. Have they used a majority of the popular programming languages? Have they worked with lots of web frameworks, or specialized in only one or two? I also look for side projects. Not necessarily just as a sign that “this person likes to code”, but rather to see if they’ve pushed themselves to learn more tools and languages. Breadth of experience turns out to be a much better “experience” proxy than “years on the job”.

Mobile app development is a two horse race - and Opera isn’t running

The jQuery Mobile team has been pushing this notion for a while that mobile apps need to target more than just WebKit browsers. Their biggest defense of this is the statement that “Opera is the #1 mobile browser in the world”. This notion goes way back. Here’s John Resig from a Hacker News thread a year and a half ago:

 What about Opera (the most popular mobile browser)?

And just recently the jQuery Mobile team was trumpeting the latest report from StatsCounter on mobile browser usage:

(From the slides for the jQuery Mobile State of the Framework)

Wow, look at Opera hanging tough in there at 22%! And indeed, if we look at the full graph from StatCounter we see this:

(Opera - red, Android - magenta, iPhone - dark blue, Nokia - light blue)

 

So Opera is a little up and down, but clearly holding the top spot. (Im going to ignore the question of whether StatCounter’s measurements are a good measure of mobile web usage. For sake of argument, let’s just assume that they are.)

The problem is, these are global numbers, counting all regions. Now let’s break down these numbers by region:

(Opera - red, Android - magenta, iPhone - dark blue, Nokia - light blue)

North America

Europe

South America

Asia

Africa

So what we see is that in the most developed markets, Android and iPhone dominate. Opera makes up ALL of its market share in South America, Africa, and Asia. And even if we look at the richest market in Asia, namely Japan, iPhone and Android have an 86% share.

Now I don’t want to put down the importance of serving the developing world. Obviously that is a huge and growing market. But if you live in Europe or North America, which regions do you realistically think you’re going to target with your app? Do you really think you understand the consumer needs in the developing markets well enough to serve them?

And now look at the trends. In Asia, Opera has lost 6% share in one year. In South America it lost 10% share. Only in Africa did Opera gain, growing 10%. Now look at the trend lines for WebKit, especially Android.

Opera is the browser of feature phones, and WebKit is the browser of smart phones. Do we really think the developing world is going to stick with feature phones, or will cheaper Android handsets prove incredibly popular in those markets as they have in the most developed countries?

Why does this matter?

I know, cross browser sounds great. Why not support older mobile browsers if we can? This is the open web after all. The problem is that supporting older browsers is a lot of work. If a browser comes along with the same HTML5 support as WebKit (IE9 perhaps?), then support should be easy. But supporting earlier generation browsers is a lot of work - work that is 90% wasted in the smart phone world. Just look at the effort that jQuey Mobile has put into supporting these other browsers, while mean time it provides zero touch scrolling support, a feature used by all of the best mobile web apps (Gmail, Yahoo Mail, LinkedIn, Twitter).

The real problem is that the mobile web is in a fight for its life as a viable platform for mobile application development. Android and iOS native platforms are killing the mobile web and garnering a huge amount of developer attention and resources. Joe Hewitt has written passionately about the need for the mobile web to better compete with native platforms. He rightly points out that if the mobile web continues to lag native platforms in capabilities then we may see a world eventually where most app development happens on native mobile platforms.

I happen to think that a big obstacle to the success of the mobile web right now is that there is very little support for building great mobile web apps. Efforts like jQuery Mobile should be key parts of improving the situation. But spending lots of time building a framework to support Opera, and pushing the idea that Opera is somehow an important target for development, is not the way to get that done.

The right approach is to recognize that mobile web apps need to compete with native apps. And the way to do that is to provide the best possible app on the most powerful devices. And given limited developer resources (since no one owns “the web platform”), and the fast rate of handset advancement, we need to stop wasting time trying to support old browsers and old handsets. 

I would go even further and suggest that we need leverage the unique capabilities of the web. To me this means the ability to easily link between apps (think of something like Twitter oauth), and the discoverability and zero-install of getting apps from the open web. I think solutions such as PhoneGap are a mistake. They are taking your great open web app and putting it inside a native straightjacket. It also means perpetuating the notion for users that you can only get great apps from someone’s app store. If you need special device capabilities, then you should just build a native app.

The future of the mobile web

I am a big fan of Joe Hewitt, but I think he’s just wrong that the web needs an owner. Joe’s argument is that because mobile browsers are failing to deliver the level of capabilities that you get from native mobile platforms, that in the future the open web may drastically decline as an app platform in favor of native platforms. And that the solution to this problem is that the web needs an “owner” to push it as a platform.

At root Joe’s complaint is about the inability to create mobile web apps that are as good as native apps. The problem with this argument is that people said the exact same thing about the desktop. Remember when Google Apps first launched, and MSFT and others went around pointing out how degraded the browser-based office app experience was compared to native Office? And yet Google Apps continues to improve and continues to acquire new users. I think what’s most instructive about the Google Apps example is that the core user interaction experience is still not as good as native (especially in spreadsheets). But it doesn’t matter, for many, many people. It’s good enough, and the web-integrated advantages of Google Apps often outweigh any perceived disadvantage in the user interface.

This will always be the case - native apps will always run better on any given device, whether its a desktop, tablet, or mobile phone, than web apps will. Games are another great example. Here’s an application type where even native desktop isn’t good enough, to the point that dedicated consoles are built to run the highest-end games. Native desktop games likes WOW are hugely popular too. And yet web based social games are the fastest growing category in gaming.

As an application platform, the web has always been a “good enough” technology. As web technology becomes “good enough” for any particular application, the advantages of the open web as an application platform (not the least the distribution advantage) come to be leveraged to create applications which displace many native apps. This will happen in mobile just as it did on the desktop. This doesn’t mean that native apps will go away, just like Office and Photoshop haven’t gone away. Joe mentions the lack of camera access for the mobile web. Guess what? Desktop-based photo tools like iPhoto and Picasa are some of the few native apps that many people still use, for exactly the same reason. But no one is saying that desktop web apps have no future because they can’t access your Twain driver to download photos.

Joe’s prescription is that the web needs an owner - someone to push the platform so it can better compete with the native mobile platforms. This is a terrible idea. It wouldn’t really be the open web if it had one owner, would it? This is the fundamental trade-off of the web: you can’t use a feature until most of the browsers implement it, but in exchange your code runs on multiple platforms. There is no way around this tradeoff. All you can do is hope that browser makers move faster. 

My own feeling is that many, many apps could be reasonably implemented as mobile web apps, today. Just look at Gmail, Yahoo Mail, Twitter mobile, or LinkedIn mobile. All of these are great mobile web apps. For the last month I’ve been using Twitter mobile exclusively instead of the native app on my iPhone, and it’s great. I’d say it works 90% as well, to the point where I don’t miss the native app. I think the problem is that very few developers know how to build mobile apps that work that well. There is a knowledge gap. And I think that knowledge and accumulated experience gap is the more pressing issue in mobile web than the lack of capabilities of the mobile browsers (although there are still plenty of those). 

iPad fluid layout prototype

Moritz Haarman put together a great proof-of-concept of an application using a fluid iPad layout. It’s super cool. The general idea is that as you browse around elements on the screen resize to take up more or less space depending on their relative importance to your current context.

I think the idea is very cool, but as he eludes to in his post, there is very little in the standard iOS UIKit that supports this kind of approach. Generally speaking UIViews are designed to have fixed sizes. There’s lots of torturous code hiding inside iOS apps dealing with resizing views. It’s one of the things I really hate dealing with UIKit, and something where I believe HTML5 has a big advantage.

If you’re building an app for the phone, these are mostly non-issues because it makes more sense to have fixed sizes on the small screen. But developing for the iPad really is a different task with much more complex requirements.

Android browser reflow issue

I’ve been testing a mobile app using jQuery Mobile on my old Droid, running Android 2.2.2. There’s a really bad reflow issue on any animated page transition, where the “from” page redraws either right before the transition or in the middle of it.

I’ve noticed that jQTouch has this same issue, perhaps because the CSS-animation based transition code is the same? I couldn’t really find any good Sencha Touch demos to test. The ones I found seemed a little better, but not too much.

I also noticed that Twitter mobile doesn’t use any page transition on that browser - I assume they tested it and figured it didn’t work. I’m gonna test on some later Android versions and see what happens, assuming the Android simulator will give me realistic behavior. Seems like jQuery Mobile should probably disable animated transitions on at least some versions of Android.

HTML5 web database - get the last insert ID

The HTML5 web database (sqlite) is super cool when building apps that store info offline. One trick without too much documentation is how you get the “last insert id” of a row you just inserted into the database.

Most db tables with have an auto-generated id column to identify each row. It’s nice after you perform an insert to get this value back so you can assign it to your object in memory. Turns out it’s super easy:

db = openDatabase(db_name, ‘1.0’, options.description, size);

db.transaction(function(tx) {
  tx.executeSql(“insert into posts (title) VALUES (‘Hear the news’)”, [], function(tx, sql_res) {
    var lastInsertId = sql_res.insertId;
  });
});

That’s it. Just access the “insertId” field on the result object passed back to your callback function you passed to the executeSql function. 

Learn Python in 5 minutes

After a long period of procastination (…15 years?) I’m finally learning Python. Having done tons of Ruby, learning Python is pretty easy. In fact, if you’re a Ruby developer, I can teach you most of what you need to know about Python in 5 minutes.

First, let me just say that Python is an awesome language. As fun as it would be to start a Ruby vs. Python flame war, I’m not gonna do that. That’ll have to wait for next week after I become a Python expert!

Feel the indentation my friends

Where Ruby uses begin/if/while…end for blocks of code, Python starts a block by ending a line with ‘:’ and indenting the block:

Ruby:

while true do
  puts “Hello world”
end

Python:

while True: 
   print “Hello world”

Simple enough - the dangling last line of a block just takes a little getting used to.

Use “import” like “require”

To include code from other modules, use the ‘import’ statement. Just saying “import os” makes the “os” module’s code available, but you still have to prefix all references with the ‘os’ module name. So Python lets you go further and say “from os import *” to make all the names available without prefix.

You have to specify ‘self’ all over the (damn) place

Classes in Python work generally similarly to Ruby, except Ruby has a lot of scoping rules for resolving variable/function references. So if you see something like this in Ruby:

puts foo

then that ‘foo’ could resolve to a local var, function parameter, an instance var, an instance method, an inherited method, and on it goes.

With Python, you have to specify “self” when you want to refer to an instance var or method of a class. So when you your Widget class needs to define its paint method, you write it like this:

class Widget:
    def paint(self, erase_background):
         # paint the widget

and if you need to call other instance methods inside Widget, or if you need the value of an instance var, then again you have to use “self”:

class Widget:
     def draw_background(self):
         drawRect(self.background_color)

     def paint(self, erase_background):
         if erase_background:
             self.background_color = “#ffffff”
             self.draw_background()

 I find this the hardest change coming over from Ruby, because I’m forever forgetting to specify “self” in the right places.  And if you forget “self” on something like an instance method declaration, then the error messages tend to read like runit() takes exactly one argument (2 given), which is technically correct but not very helpful for the beginner.

Arrays are called Lists, and Hashes are called Dictionaries

Easy enough. The structures work quite similarly.

a = [‘one’, ‘two’, ‘three’]

  -> makes an array

h = {‘foo’ : ‘bar’, ‘python’ : ‘is cool’}

  -> makes a hash. Sorry, no symbols.

Python gets “function-y” on occasion

Ruby tends to be pretty strictly object-oriented, so that every function or operator is a method on some class. Python has some exceptions where you just use a global or module-level function to get what you want:

len(mylist)

   -> ‘len’ returns the length of its argument, which could be of varying type like a String or a List.

del a[n]

  -> Removes the Nth element from the list ‘a’. That one really freaks me out.

a = [{‘name’:’neil’}, {‘name’:’alex’}]
map(lambda user:user[‘name’], a)

  -> Returns [‘neil’,’alex’] by mapping over collection ‘a’ and returning the result of the lambda function evaluated on each element.

Sorry player, no blocks

I know, I know, no blocks?!?! But as you saw right above, Python does have “lambdas” which are pretty close. Lambda defines an anonymous function that you can pass around as an argument (as you can any other function). Here’s an example equivalent to Ruby’s “enumeration.select_if {|item| … }”:

a = [{‘name’:’tom’,’salary’:20000}, {‘name’:’alex’, ‘salary’:60000}]
filter(lambda user:user[‘salary’] > 50000, a)

  -> returns [{‘name’:’alex’,’salary’:60000}]

Use ‘or’, ‘and’ instead of ‘||’, ‘&&’, and capitalize True and False

Python doesn’t have a C-style ternary operator, but you can use this syntax:

“320px” if mobile_agent else “980px” 

or the venerable:

mobile_agent and “320px” or “980px”

and remember to use None instead of nil.

Python doesn’t have string interpolation

Python doesn’t have Ruby-style string interpolation, but it does have a sprintf style operator which works pretty well:

year = 2112

print “%d Overture” % year

—> ‘2112 Overture’

To end this tutorial, I’ll just show a super naive grep program written in both Ruby and Python.

Ruby

pattern = ARGV[0]
f = open(ARGV[1])
matches = 0
f.each_line do |line|
  if line =~ /#{pattern}/
    puts line
    matches += 1
  end
end
puts “Found #{matches} matches”

Python

import sys
import re

pattern = sys.argv[1]
f = open(sys.argv[2])
matches = 0
for line in f:
  if re.search(pattern, line):
    print line,
    matches += 1
print “\nFound %d matches” % matches

See, no more procrastinating needed, you’re most of the way to learning Python already!