Friday, July 31, 2009

War and Decision

Recently I started reading Doug Feith's War and Decision.

I say "started reading" because I have not finished it yet. The book is about how the Bush Administration and in particular the Defense Department reacted to 9/11 and managed the wars in Afghanistan and Iraq. I have read most of the material on 9/11 and Afghanistan, but have not gone into the deeper material on Iraq.

I would highly recommend the book. Feith takes a very analytical approach that is full of insight and is though provoking. However, the book certainly has its faults. If you take the book as an extended position paper, then I would view these faults as fatal. If you take the book as a memoir, then these faults are perhaps the most valuable aspects of the narrative.

First off, Feith devotes a lot of the book to calling out statements by journalists and political opponents, and completely disproving these statements. From a literary perspective, this is easily the greatest weakness of the book. It is really beneath Feith to so painstakingly thumb his nose at detractors. How much joy can we really take in disproving pundits? This just in, journalists exaggerate and twist the truth in the quest for sensationalism...

I guess you can forgive Feith for all of this, as it must be frustrating to have to hear so many false claims in the press on a daily basis. Fine. However, the other mistake that Feith makes is not as annoying, but is in many was much worse. The funny part is that it is a mistake that, if we buy into Feith's characterizations, that his boss, Donald Rumsfeld, would have immediately pointed out. Feith claims to build up logical arguments for the decisions made by the Bush Administration, but he fails to point out the assumptions behind these decisions and their severe consequences. According to Feith, Rumsfeld was notorious for demanding to know the assumptions made by his analysts and advisors, hence the irony of Feith's prose.

The most basic and essential example of this is the reaction to the 9/11 attacks. Feith & co. immediately started thinking about how to broaden the response beyond just the perpetrators. This assumption, that the response needed to be broad, is hardly questioned. The only hand-waving given for it is that such a response would be more like a police action (punish the criminals) and thus ineffective. Justifications are only developed after the initial idea is pursued. For example, one justification is that a broad military action is the most likely way to prevent further attacks without negatively affecting the American way of life. Maybe this is true, the book is certainly thought provoking, but this justification is only developed ex post facto.

So more examples... Feith states that Iraq having WMDs was a given that everyone just accepted. He says that in late 2001 nobody would have argued that Iraq did not have WMDs. Feith also states that another given was that another 9/11-ish attack was imminent. It is not hard to see that if you start out assuming that the U.S. needed to make a broad military reaction, that Iraq had WMDs, and that devastating attacks were imminent, then you have to conclude the U.S. had to invade Iraq.

Anyways, I will reiterate that the book is good read, especially if you are an opponent of the war, as I am. Feith does admit early on that the Administration did not do a good job of communicating to the public. He underplays this (at least in the first third of the book or so, perhaps this changes.) Poor communication and an act of war have no place together in a democracy, at least in my opinion.

Sunday, July 19, 2009

My HTML in Scala Wishlist

One of my favorite features in Scala is its native support for XML(link warning, shameless plug.) I love the "projections DSL" (for lack of a better term) that is the scala.xml package. It is great for slicing up XML, and is almost like having native XPath and XQuery built into the language. Using XML in Scala for HTML generation is not as universally appealing to people. Some people think it encourages mixing presentation and business logic and is not "clean." I have even heard folks say that this is a critical flaw in Lift. I completely disagree. Of course I also think MVC is an anti-pattern, but anyways... HTML support in Scala is great in my opinion, but could be even better. Here is my wishlist.
  • Better understanding HTML semantics. For example, it is great that the compiler won't let me do something like this <div>Hello world</di>. However, I would not want it to even let me do <di>Hello world</di>. Similarly I should not be able to stick a thead outside of a table. If I have an anchor tag with an href attribute, then I'd like the compiler to do some validation on the value. Am I asking for too much? Well, that's I'm supposed to do, right? Is some/all of this possible with the help of XML schema support? Maybe so.
  • CSS. HTML without CSS ceased to exist a long time ago. With all of the DSL possibilities in Scala, is there some way to allow CSS literals and create some type safety for me. For example, I if I fat finger the name of a style on a class attribute, the compiler should catch this. Also I can say from experience that introducing an object-oriented model is really useful in CSS. Finally, the XPath/XQuery-like support in Scala XML makes me think that something similar could be done for CSS selectors.
  • JavaScript. Honestly I don't know what I would want here. I like JavaScript, but I know the idea of being able to write your web application in a single language is very appealing to a lot of people. If nothing else, it would once again be nice if the compiler would prevent me from doing something like <button onclick="foo()" ...> if there as no function called "foo" in scope.
  • Tooling. Most modern IDEs support things like syntax highlighting, code completion, error checking, code formatting for HTML and XML+schema. I expect at least this much for XML/HTML literals in Scala. I'd also like to be able to step through and debug literals. Refactoring on subtrees of XML (extract method for example) would be sweet. Oh, and large XML literals should not overwhelm my IDE :-)

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.