Wednesday, July 15, 2009

Functional Paradigms on Android using Scala

I am slowly plugging away on my little side project. One of the fun things about "pimping" an API, is you can tweak the design of the API. For example, I was modifying TextView, a class used for creating text input boxes of various sorts in Android. One common use case in Android is to create an auto-complete text box. To do this, you need to subclass TextView. Then you can override various lifecycle methods like onEditorAction, onKeyUp, etc. However, I thought that it might be nice to do something like this:


val textView = new TextView
textView.keyUp = (code:Int, event:KeyEvent) => {
// do stuff to your TextView
}

As Debasish pointed out to me, this is a lot like you would do in JavaScript. Is it better? It's a little easier in certain cases. If you just need to change the behavior of a single TextView in a very specific way, then this would seem like the way to go. Subclassing TextView just to override a single method and then using that subclass exactly once definitely seems like overkill. Now if you really wanted to create a new kind of TextView that you could use in multiple places, then subclassing makes sense.

One thing worth mentioning is how this kind of thing is handled in Cocoa on the iPhone. The Cocoa way would be to create an untyped delegate. In the delegate you could override the lifecycle methods that you were interested in. It's untyped, so you have to know the right names. You still wind up defining a new class, even though you usually only want to customize the behavior of one particular instance. Also, it's a little clunky as the TextView instance would have to be passed in to each of the delegate methods, so that your delegate could actually do something to the TextView. I find this a little better than having to subclass as you do in Android, but once again I think using Scala can yield some nice results.

There was another interesting case that popped up while sugaring TextView. I wanted to sugar the setCompoundDrawablesWithIntrinsicBounds methods. This method is overloaded, taking either four integers or four Drawables. Here is what I first thought of doing:

def compoundDrawablesWithIntrinsicBounds_=(bounds:Tuple4[Int,Int,Int,Int]) {...}
def compoundDrawablesWithIntrinsicBounds_=(bounds:Tuple4[Drawable,Drawable,Drawable,Drawable]) {...}
// this allows
myTextView.compoundDrawablesWithIntrinsicBounds = (1,2,3,4)
// or
myTextView.compoundDrawablesWithIntrinsicBounds = (d1,d2,d3,d4)

Of course this won't work. The type parameters of Tuple4 are going to be erased by the compiler, and the two methods are indistinguishable. However, The Amazing Mr. Spiewak gave me a solution:

def compoundDrawablesWithIntrinsicBounds_=[T <% Either[Int, Drawable]](bounds:Tuple4[T,T,T,T]){
bounds._1 match {
case Left => baseTextView.setCompoundDrawablesWithIntrinsicBounds(bounds._1.left.get, bounds._2.left.get,
bounds._3.left.get, bounds._4.left.get)
case Right => baseTextView.setCompoundDrawablesWithIntrinsicBounds(bounds._1.right.get, bounds._2.right.get,
bounds._3.right.get, bounds._4.right.get)
}
}

In addition to this, you need implicits to convert an Int to a Left and a Drawable to a Right. The API looks a lot different, but it allows exactly the same usage that I wanted. Another case of how you need some non-trivial Scala (though I wouldn't be surprised if there is a more elegant way than the above) to create an API that is super simple to use.

Wednesday, July 08, 2009

WebOS'es, Big Oil, and The Nutty Professor

I'm not going to talk about it. However, it reminds me of some things from my past...

First, let me take you back to 2001. I was working for a start-up in the East Bay called RMX. We claimed to be the "Yahoo of convenience stores." In other words, we were a portal for owner/operators of convenience store/gasoline stations. We were backed by Chevron. All of their non-company stores used RMX to get data from Chevron, like when their next delivery of gas would be and how much it was going to cost them. They would also get promotional stuff from Chevron and other folks who sold lots of goods at convenience stores. Anyways, noticed I said non-company stores. Most gas stations selling Chevron gas are not owned by Chevron, they simply buy their gas from Chevron. Those stores were all required (by Chevron) to use RMX. Ch-ching. However, Chevron's so called "company owned, company operated" stores, or CoCos, did not use RMX :-( The reason? They did not have computers in these stores for fear that employees would waste time surfing the web and playing solitaire.

Being a savvy start-up whose income was tied to the number of stores using our service, we came up with a clever idea. We built the first WebOS. Ok, so not really, but close. We built a Windows program that would take over the Windows shell. So no explorer.exe for you. The new shell, would embed an IE control with the page automatically opened to the RMX portal. There was no navigation bar, or bookmarks, etc. If you tried to leave the RMX portal, we'd catch it and send you back. If you tried to close the shell, it would reboot the computer. There was no escape! WebOS FTW!

Anyways, many years later I would join another start-up called Sharefare (later renamed Ludi Labs.) Our goal was to build a WebOS! Our vision of a WebOS was a platform that handled all of your common tasks: email, bookmarks, photo/video/music management, blogging, etc. It was all through the web with all of your data stored in ... no not the cloud. We did not use that buzzword (maybe we should have.) Instead we had what we called a "cell architecture" and your data was stored in your cell. This was the brainchild of our founder/CEO, The Nutty Professor (Alan Bush, who is a great guy and brilliant to boot.) Our architecture was to have a UI layer on top of the WebOS. We called this the WebTop and that was my job. I wrote a programming language for the WebTop and implemented the language using a flammable combination of Java and JavaScript. It was a lot of fun, and probably the most academic exercise I will ever get to experience in my professional career. We never got to put it in the hands of customers, but at least I got a patent out of it.

So there, I've done the WebOS thing. Twice. Do people want this? I have no idea. In one case, we created a super-simplistic "OS", forced it on people, and did not care about their feedback (ok technically Chevron did the second two things.) In another case, we went for it all, but we never got the thing out the door, partially because it was a huge task.

Midseason Baseball Thoughts

It's the middle of the MLB season, and the All-Star Game is next week. This season has had its share of surprises so far. Since I live in the Bay Area, I must recognize the surprising season of the San Francisco Giants. They currently have the second best record in the National League. They are far back of the Dodgers, but would still be in the playoffs as the NL wildcard, if the season was over today. I have to admit that I keep wondering: are the Giants for real? The answer: Yes!

Based on the Giants runs scored vs. runs allowed, the Giants expected wins at this point is 46.9. Their actual wins are 46. So they have not been "lucky" in terms of wins and losses. Their 303 runs allowed is the best in baseball. The pitching has been awesome. The offense has been middle of the pack, but hey that is not as bad as many (including me) expected. So the Giants are for real because they have the best pitching in baseball. Will this continue to be true in the second half of the season?

It is not a slam dunk. Lincecum is even more dominating this year than he was last year when he won the Cy Young. Some people worry that he is pitching too many innings given his age, but I won't jump on that bandwagon. He is one of the Giants' two All-Stars. The other is Matt Cain. Now I love Matt Cain. He is from Dothan, Alabama. That is just two hours north of my hometown in Florida, and is where my brother lives. However, Cain has been a little lucky this year. On balls put in play, Cain's batting average against is a little. Plus he's been lucky with stranding base runners. If this luck does not continue, then you can expect his hits allowed and runs allowed to both jump up a bit. Cain's a flyball pitcher too, so a jump in home runs allowed is always possible. Randy Johnson has been ok, but more importantly healthy. He just suffered his first injury of the season, which does not look like it will be too bad. However, it's hard to expect him to stay healthy the rest of the season. Barry Zito has been better than last year (which is not saying much) but could actually do even better in the second half. The fifth spot in the rotation has been in flux, so things could really only get better for that spot.

Enough about the Giants... As for the rest of the NL. My favorite team, the Atlanta Braves, are mediocre and there's no reason to expect a lot different from them. The Phillies are better than their record, while the Marlins are a lot worse than their record. The Cardinals are also not quite as good as their record, but the rest of the NL Central is very mediocre. The Rockies have been a huge surprise, and they look a legitimate contender for the wildcard spot. They should be the strongest challenger to the Giants, and of course the two teams will get plenty of chances to play each other as they are both in the NL West.

As for the AL, arguably the four best teams are all in the AL East. The Yankees have a nice lead in the wildcard over Tampa Bay. Still, Tampa Bay has proven that last year was not a fluke. The Yankees are definitely getting a nice ROI on all the money they spent on pitching. They are only a game back of Boston. Both teams look to improve in the second half. The Yankees will get three months of Alex Rodriguez, and the Red Sox's David Ortiz seems to have finally regained his form. The AL Central is a mess, with three pretty good teams within 2 games of each other. It's easy to count out Minnesota, but statistically they have been the best of the three teams. Finally, the AL West is a two horse race, and the two teams, LA and Texas, are statistically very even.

Thursday, July 02, 2009

Hacking My iPhone 3GS

If you are a long time reader of this blog ... nevermind there are no long time readers of this blog. Anyways as it turns out, two of my most popular blog posts of all time have been about hacking my phone. First there was Hacking my A950. That was about enabling MP3 playback and Bluetooth dial-up-networking on my Samsung A950. A year later came Hacking my 8830. This was mostly about useful tips for the Blackberry, along with a failed attempt to get GPS working (thanks for nothing Verizon.)


Two weeks ago I deactivated my Blackberry after two years of excellent service, and bought the new iPhone 3GS. I have been working on iPhone apps (one app in particular) so this made sense. Oh and the iPhone is the best phone ever. The Exchange support is so good on it that it is an easy move for a Blackberry user, but I digress. Back to the point. As a rite of passage, it was time for me to write about hacking the iPhone.

There are two things that I will point you would-be hackers to. First up is ringtones. Just like with the Blackberry, there is no need to spend any money on ringtones for the iPhone. There are a few ways to create ringtones on the iPhone. This is the guide that got me going. If you don't want to read it (you should) the idea is simple. A ringtone for the iPhone is an AAC encoded, .m4r file. So clip a song down to less 40 seconds, convert it to AAC, and rename the file from .m4a to .m4r. It is a painless process. I created a half dozen or so ringtones in a few minutes, mostly Girl Talk songs...

The other tip is also pretty well known. The iPhone OS 3. 0 has support for tethering and MMS, but neither is currently supported by AT&T. However you can hack this at the software level, and pwn AT&T. Here is the best guide I have found for this. What is great is that it only involves going to a web page in Mobile Safari, and it is easy to undo. For me it works great for tethering, but MMS did not get enabled.

Thursday, June 25, 2009

iPhoto Faces Awesomeness

I've been using iLife '09 since it came out. I've made heavy use of its integration with Facebook and Flickr. One of the features that I've wanted to experiment with is Faces. This is face recognition technology. Using it is simple. You have to train it by taking a few pictures and telling iPhoto who are in those pictures. This is very easy. Look at a picture, click on the "Name" button, and iPhoto immediately recognizes the faces in the picture. There is a little text box next to each face, and you just type in the name. It remembers previously typed names or names from your Address Book, so there is usually very little typing to do. Obviously the more training you do, the better the results that iPhoto will have.

Despite this being so easy, I've been too lazy to use this. Until now. I was importing a handful of pictures taken with my iPhone. These were mostly pictures of my boys playing and being goofy. Here is a picture of Michael, Jr. (age 5):

And here is a picture of Raymond (age 3):

Now the reason that I show the pictures and mention the ages will become obvious momentarily. Back to the narrative. After tagging my kids in these pictures, iPhoto was ready to show me other pictures with the same faces. The very first one that it showed me nearly made me cry:

Yes that is my oldest son. He was just six months old in that picture. The pics I used to train iPhoto were all very recent. It was really cool that it recognized his face, even though he certainly looks a lot different today than he did four and a half years ago. Similarly, iPhoto served up this gem for Raymond:

Monday, June 22, 2009

Buyer Beware: ProFlowers

Last month I was in Israel for three weeks. These three weeks included the date of my anniversary. I still wanted to do something nice for my wife on our anniversary, so I decided to send her flowers. I used a company that I had seen an ad for ProFlowers. While I was checking out, they gave me an offer for $15 off my order. All I had to do was fill out a survey, which I did. As part of this process I agreed to sign up for a service called EasySaver. Joining was oh-so easy as ProFlowers shared my credit card information with EasySaver. Of course EasySaver then starts charging me $15 per month for membership.


Now I was clearly stupid for falling for something like this. I was quite embarassed when my wife noticed the charges on our credit card. Luckily we only got nailed for May and June. Anyways, clearly my fault. However, I really hate shady operations like this. I will never use ProFlowers again. As far as I can tell, EasySaver is completely worthless anyways. Hopefully other folks will be smarter than me and not fall for scams like this.

Thursday, June 18, 2009

Scala and Android

Recently I was working on an article for developerWorks about using Scala on Android. Stay tuned to developerWorks to see that article. Since then I have started a little side project to create a set of Scala libraries for working on Android. Now you may ask, why bother with this? Is this just a classic case of mental masturbation? Well, no, at least I hope not.


I think Scala is well suited as a programming language for mobile devices. I am not an expert on all mobile platforms, my experience is mainly around iPhone and Android development. For the iPhone you are developing in Objective-C, and for Android in Java. Now in general, I think the Android development environment is superior in almost every way to the iPhone. IDE is mostly a matter of taste, but Eclipse+ADT certainly has a lot more features than XCode. Debugging is definitely better on the Android. It is much easier to debug on a device, and the emulator gives you more ways to vary the environment (cpu/memory/network resources) for more realistic emulation. The only thing advantage I would give to iPhone is that XCode and the iPhone emulator both startup much faster than Eclipse and the Android emulator.

Programming in Java gives you a lot more options than Objective-C. There are just a lot more open source Java libraries out there to help you avoid reinventing wheels. In addition, I think the platform specific APIs added by Google are much better than the ones on the iPhone. A simple example is XML processing. Java and Objective-C both already have XML parsing APIs. However, Android adds extra APIs as they recognize this as a common task for mobile applications that leverage web services. They added convenience APIs for SAX based parsing. They also leveraged a StAX-style parser by leveraging an Apache project. There is nothing like this in iPhone, despite the fact that the iPhone has been around longer and should be more mature. It may be an oversimplification, but I think this comes back to the corporate cultures that produced these platforms. Apple has always been a company that uses software to sell hardware, and this continues with the iPhone. Google is much more of a software company, with strong ties to open source software. It should be no surprise that Android is a much more development friendly platform. And don't even get me started when it comes to garbage collection (Android has it, iPhone does not, despite the fact that Objective-C 2.0 has it.)

So Android is great, why do we need Scala? First there is verbosity. Actually both Objective-C and Java are quite verbose -- Objective-C is even more verbose than Java. Scala is a much more concise language than either. Objective-C can actually be more dynamically typed than Java/Scala, but this rarely makes the code any more concise or readable, and often makes it harder to debug. Next, neither Objective-C or Java have much support for functional programming. This is a bigger deal than you might think at first. UI frameworks are full of events that you must write code to handle. Writing a function to handle those events is so much easier than writing a class. On the iPhone you can often set any type of object as an event handler, and you just have to know the magic methods to implement. On Android, you usually have an interface to implement, and that interface has a single method. This is actually better than what you do on the iPhone, but the interface and its implementation class are both classic cases of boilerplate.

Thus it is my goal to make it possible to write Android applications in a much more concise way by using Scala. In general, you can replace Java code with Scala that is much easier to read and understand. I think this will be especially true on Android, and the contrast will be even more true.

The last reason that I think Scala is a great language for mobile development is threading. Both iPhone and Android support multi-threading, as any UI framework must. Any good UI will perform any non-trivial operations on a background thread, to keep the main UI thread responsive to the user. However, threads are tricky, especially this kind of multi-threading. Updating your UI from a background thread is a recipe for disaster. Android enforces this by using a Handler on the main thread that your background threads send messages to. If you are familiar with Scala then message passing as a way to implement multi-threading should ring a bell. This is exactly how actors work in Scala. I haven't tried using Actors on Android yet, but it sure seems like a good fit.

So there is some of the motivation. I think Scala on Android could be really compelling. My side project is pretty small so far: a handful of wrapper classes and implicit conversions to bring some syntactic sugar and functional programming into the mix on some common Android classes. The project also has a special build of the Scala library that I found necessary to get the library to work on Android and its compiler. I am hoping to add more sugar and to add the actors ideas listed above. I am also hoping to come up with a nice way to integrate something like Proguard to optimize the bytecodes that get compiled for Android.

Tuesday, June 16, 2009

HTML 5: Don't Believe The Hype

In case you haven't heard, HTML 5 is The New Hotness. I have been watching this tide rising for awhile. There have been many skirmishes between The Unite Emirates of JavaScript and The Kingdom of Flash over how plugin technologies were going to be made obsolete by HTML 5. To hear some folks talk about the future of HTML 5, it is a veritable morality play. HTML 5 is all about the nobleness of open source and open standards. It is democracy and freedom. Everything else is closed and tyrannical.


Things really took off a few weeks ago at Google's IO conference. GOOG officially put its chips in the HTML 5 pot. This should not have been a surprise, as Google has invested in improving browser technology first through Gears and then through its own browser, Chrome. Of course Chrome actually uses the now ubiquitous WebKit for its rendering engine. This is at the heart of not only Apple's Safari browser, but also the mobile browsers on the iPhone, Android, and Palm Pre. Google used the "standardization" of WebKit on mobile devices to deliver mobile versions of GMail and Calendar thus punting on native applications.

So HTML5 is the future, right? Not so fast. I know it seems this way to a lot of people, especially the emphatic fans of open standards. However, those guys live in a different world than I. In the world I live in, browser fragmentation is at an all-time high. In a world of fragmentation, standards are an amusing concept. If history has taught us anything, it is that standards are set by whoever has the most users.

This has long been a source of pain for Google and others. In all fairness, IE8 implements some of the HTML 5 features, but not all of them. Also, the IE family of browsers has been losing share for several years. However, it is going to be awhile before web developers can forget about IE6, not to mention IE7. Given the update cycle of IE in the past, we can expect the older versions to stick around a long time before IE8 finally becomes the king. Again it does not even implement all of the highly touted HTML 5 features. Maybe more will be supported in IE9? How long before that becomes the dominant browser?

My point is that if you want to hitch yourself to HTML 5, you are not hitching yourself to Firefox, Safari, and Chrome. Well ok, you can hitch yourself to those browsers (or IE+Gears), but you are saying go away to 60-70% of the world. So assuming you don't want to do that, then hitching your app to HTML5 means hitching your app to future IE adoption. That just seems like a scary proposition to me.

But what about mobile devices? Here things are clearly better. Again the standards are set by the dominant player. WebKit is the dominant technology in high-end mobile browsers. Still there is fragmentation. The exact same APIs do not work on Mobile Safari as on the Android browser (don't know about the Pre.) Thus you may have to do some abstractions to smooth over the differences. Oh wait, that is starting to sound a lot like the situation with desktop browsers... Anyways, many HTML 5 features are present on the iPhone and Android browsers, so you have much more latitude to use them. However, there is another, more important question to answer when considering going down the path of GMail/Calendar on the iPhone/Android. Can a browser based be as good as a native app? Probably not, but maybe it's "good enough." However, I have to wonder, how many GMail users use the GMail web app on their iPhone instead of using the native Mail application? The GMail web app gives you all of the features you are used to, like conversations, labels, stars, and awesome search. The native Mail app provides none (or at best much weaker implementations) of this, but yet I would guess that most people still prefer it over the web app.