Thursday, October 30, 2008

2 Days with Google Gears

I had a chance to play with Google Gears on a mockup project recently. I was surprised to learn that my understanding of Gears was not the same as the reality of Gears. I had expected it to be a JS library to facilitate rich HTML applications to handle spotty network connections. It turned out that Gears is a browser plugin that adds useful tools that any rich web app developer would find useful, though they are all aligned to handle an app losing its network connection. In the two days that I spent playing with Gears, I was pretty much blown away by the power and simplicity of it.

Besides understanding what Gears is, it's important to also understand what Gears is not. Gears doesn't try to be a UI library, or a general "glue" library (see JQuery, Prototype, MochiKit, MooTools, or any other Javascript framework). It doesn't really force you to code in any particular way (this is a bit of a lie, but more on that later). Just as a sampling, Gears includes:

  • A cross-browser compatible XMLHttpRequest
  • Local database storage
  • A web resource cache, so that items can still be fetched even if the network connection goes down. This is nearly completely transparent to the developer, and works for resources loaded by Gears or by the browser itself.
  • A mechanism to run scripts in the background (for real).

In our little demo, we have a set of checkboxes that can be checked. Initially, these would perform an asynchronous post to the server, where they would update some server-side state. However, if the app goes offline, nothing will ever reach the server. We modified this to enqueue changes into a local database, with a background script pulling items out of the database and sending them to the server. If the server ever goes down, that thread simply stops pulling items out of the database. In addition, we set our app up so that its resources (HTML, Javascript, CSS, and images) were initially cached when the app is first loaded. A neat feature of Gears seems to be that it will monitor the apps that it knows about and will automatically update its cache if the cache ever gets stale. Unfortunately, it's not perfect. It depends on the developer updating a version string, which causes Gears to update its cache from the source.

One problem that we had is that the HTML that we served up would include information about what items were checked. That is to say, when you would load the page, we would serve up some <input type="checkbox" /> and <input type="checkbox" checked="checked" /> elements. This makes total sense in a traditional web app. The client requests the page, and you serve it, and everybody is happy. Every time the page is served, it is reconstructed with the current state of the data. As you might imagine, this caused all kinds of problems for us. Concretely, we noticed that every time the page was reloaded (whether the network connection is up or down), the browser would display the state of the page as it was when the cache first acquired it. In a real application, that could mean that you are seeing data that is several months out of date. Now you see how I lied earlier. Gears does influence the way you code your application, but its requirements are about the same as those of any Javascript-heavy web app. As long as you separate your application presentation from your data, you should be fine.

Another thing that surprised and greatly pleased me was Gears' WorkerPool implementation. As everybody knows, it is impossible to run Javascript in the background in a normal web browser. I think that's because multi-threaded programming is hard, and Javascript can be pretty hairy as it is. I think that the browser designers have held off on implementing a threading solution out of fear that multithreaded Javascript would cause the apocalypse. As it turns out, though, Gears' implementation is both simple and powerful. Gears uses a message-passing mechanism for communication, with absolutely no shared state. This is great news. As far as I can tell, just as your main JS code has an event loop, each worker also has an event loop. Whenever a message is sent from the main JS code to a worker, that message is copied and onMessage is invoked on by that worker's event loop. Likewise, when a worker sends a message back to the main JS, the message is copied and onMessage is invoked on the main event loop. This has some interesting implications. For one, none of the workers have access to the DOM, or to global variables defined on the page, and cannot participate in closures with mainline Javascript code. By placing a concrete wall between your page and your workers, Gears forces you to think about the interactions that the page and the worker will have, and that's a Good Thing. I'm sure that it's still possible for threading to ruin you, it's just a lot harder with a scheme like this.

And that's it. There's more to Gears that what I described (though not much more). It also includes some geolocation bits (presumably for Android, and maybe Safari Mobile, integration), desktop integration stuff, a standards-compliant timer, a file multi-chooser (yay!), and a binary data type (as opposed to String, which is for textual content). It's a shame that Gears is still in beta. I would really like to see some sites that use it. Of course, since I just recently installed Gears, there might be some sites that do and I never realized it.

Wednesday, October 29, 2008

User-Visible Permissions in Android

I picked up a T-Mobile G1 (danger: Flash-heavy site) at the local T-Mobile store. For those that don't know, the G1 is the first device to run Google's Android platform. So far I like it a lot, and I'll probably post a lot more about it in the near future.

Like the iPhone, Android has its own app store. Unlike the iPhone, nobody moderates apps submitted to the Android app store. If an app tries to do anything of consequence (i.e. anything that a user might want to know about), it must explicitly request that permission. When you start to download an app from the marketplace, it tells you what permissions that app will require. Most apps are well behaved, but some ask for way too much.

For example, I wanted a weather app. I saw that there is a Weather Channel app. When I went to download it, however, I was very surprised. Here is a list of the permissions that it requested.

Network communicationfull Internet access
Your locationcoarse (network-based) location, fine (GPS) location
System toolschange network communication, change your UI settings, modify global system settings
Your messagesedit SMS or MMS
Services that cost you moneysend SMS messages
Your personal informationread contact data

What? Why does this app need access to my contacts, or to send text messages? I hope that this was just a lazy developer who requested more permissions that he actually needed, but I'm suspicious. It's entirely possible that The Weather Channel intends to compile a list of all my contacts. Not cool. Especially since it makes no mention of that.

I think it's great that Android provides some ability for the end user to judge the software that they might install on their phone. I'll wait until The Weather Channel updates their app.

Tuesday, October 14, 2008

Scala's Model of Functions

I was a little dismayed to learn that Scala models functions with different numbers of parameters as instances of distinct function trait definitions. A practical upshot of this is that you can't really work with functions that take more than 22 parameters.

def crazy(a:Int, b:Int, c:Int, d:Int, e:Int, f:Int, g:Int, h:Int, i:Int, j:Int, 
k:Int, l:Int, m:Int, n:Int, o:Int, p:Int, q:Int, r:Int, s:Int, t:Int,
u:Int, v:Int) = 0
(crazy _).curry : (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) =>
(Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) => (Int) =>
(Int) => (Int) => Int = <function>

def crazier(a:Int, b:Int, c:Int, d:Int, e:Int, f:Int, g:Int, h:Int, i:Int, j:Int,
k:Int, l:Int, m:Int, n:Int, o:Int, p:Int, q:Int, r:Int, s:Int, t:Int,
u:Int, v:Int, w:Int) = 0
(crazier _).curry : <error>

The scala runtime apparently has traits Function0 through Function22 defined. I guess this is so that they can have call methods that take a statically known list of parameters (rather than, say, an array). That's all well and good, and probably necesary for proper Java interop, but it's still a little sad. Still, I don't expect to run into that limit any time soon. Oh wait, I have already worked on projects with functions that take more than 20 parameters. Maybe this was added just for me. Now I'm sad.

Monday, October 13, 2008

Partial Application in Haskell and Scala

This is an attempt to squeeze out a blog post while I wait for my laundry to finish.

Functional languages are fun. Fun in ways that Java (and, for that matter, Ruby) are not. Take Haskell. In that language, we can take any operator and turn it into a function. Normally, we use the symbol + to represent addition. If we enclose it in parentheses, we instead have a function.

(+) :: (Num a) => a -> a -> a

In this case, (+) is a function of 2 number parameters, which returns a number. Now that we have a function, we can apply all of the standard Haskell magic to it. Since Haskell is automatically curried (no function really ever takes more than one parameter), we chain calls to fully evaluate our (+) function.

(+) 2 3 => 5

We can also partially apply this operator.

add5 :: Integer -> Integer
add5 = (+) 5
add5 3 => 8

In this case, we have created an alias for the partially bound + operator. Rather than jump through so many hoops, we could specify add5 more directly.

add5 = (5+)

Finally, a slightly more complicated example.

simple :: Integer -> Integer -> Integer -> Integer
simple x y z = x * (y + z)

simpler :: Integer -> Integer -> Integer
simpler = simple 2

simplest :: Integer
simplest = simpler 3 4 => 14

All functions are also values in Haskell.

easy = simple
easy 2 3 4 => 14

As you can see, in Haskell, we can turn any operator into a function. Functions are curried, and can be partially evaluated from the left. Functions are also values that can be assigned and passed around as needed.

Scala takes a different approach. In Scala, operators are actually methods on values. There is no global + operator. Instead, you invoke the + method on the left hand parameter.

5 + 3 //is the same as...
(5).+(3)

If you want to refer to a function as a value in Scala, you must "partially apply" it to zero parameters.

val output = println //will result in a compilation error
val output = println _
output "Oh Hai, World!"

The underscore is the Scala placeholder operator. If used as we did with println, it stands in for the whole argument list, effectively turning the function into a function value. It is also the mechanism by which we can partially apply a function.

def simple(x:Int, y:Int, z:Int) = x * (y + z)
val simpler = simple(2, _:Int, _:Int)
simpler(3, 4) => 14

The underscores, when used this way, compel the result of the expression to itself be a function that takes n parameters, where n is the number of placeholders. Sometimes, it is possible to infer the type of the missing parameters; other times, it isn't. It depends on how the parameters are used.

It is very important to notice that, unlike Haskell, it is very easy to bind only the parameter in the middle of this expression.

val sample = simple(_:Int, 3, _:Int)
sample(2, 4) => 14

By combining placeholder syntax with operators, it is possible to turn an operator into a function, even a function that takes its left operand as a parameter.

List(1, 2, 3).map(_ + 2) => List(3, 4, 5)
List(1, 2, 3).reduceLeft(_ + _) => 6

As you can see, Haskell and Scala have a lot in common. Haskell's syntax is a bit more concise (and its inference rules much better), but Scala's ability to bind any parameter is pretty handy, too. There's something both cluttered and clean about Haskell's use of underscores, especially when types aren't required. Of course, I'm not an expert (or, in fact, experienced at all) with either language, so please correct me if I got any of my facts wrong.

Looks like I failed. My laundry was done 30 minutes ago.

Saturday, October 04, 2008

The Machine

Two weeks ago, I had the opportunity to see The Machine with my family. The Machine is a Pink Floyd tribute band. That is to say, at their shows, they play nothing but Pink Floyd music. All of the musicians are clearly extreme Floyd fans. I mean, why else would you spend 20 years of your life playing somebody else's music? Now, some people don't like tribute bands. I had a hard time getting people to see The Australian Pink Floyd Show when they came to New York (playing literally a few blocks from where we were staying). Who cares that these aren't the original musicians? Would you also refuse to go to a performance of Beethoven's 5th because it wasn't being conducted by the man himself? Of course not! The music is just as good, and the musicians are going to make it special and awesome anyway. But I digress...

It was interesting to see the variety in people in the theater. Obviously, many of the patrons were my parents' age, but there were also some college kids and folks whose heads were completely gray. What was perhaps more interesting to me is that the 50 year olds were more animated and crazy than the college kids. They had some smoke machines up on stage, but I don't think that was the source of all the smoke in the hall. It's fun to watch adults relive their youth.

The set was Dark Side of the Moon (with the Wizard of Oz projected onto their own version of Mr. Screen), followed by an intermission, followed by The Wall. Not a bad setlist at all. As they launched into the beginning songs from Dark Side, I was carefully listening for any variation from the album tracks that I know so well. I couldn't help it. These guys were playing well-known and well-loved music, so it's only natural to compare their performance to the original. By The Great Gig in the Sky, though, I was totally sold. The woman that belted out those notes was simply amazing. She absolutely hit every note. It was surreal. The keyboardist was younger than the rest and totally crazy, with a maniacal grin that was somehow larger than his actual face. The drummer hid behind the drums for most of the show, but did a very good job. The bassist seemed detached, standing apart from the others. I suspect that was completely intentional. The saxophone player was decent, but wasn't very memorable (after all, he only played on a few songs). Rounding out the group is the lead guitarist / lead singer. His ability to mimic both David Gilmour and Roger Waters was spooky. The man knew his guitar well, and made it sound just like the original.

By the time they were playing The Wall, people in the crowd were singing along. Performing Dark Side first was a good idea. People were more mellow when the entered the theater than when they left, and Dark Side is best appreciated without whoops and cheers. The Wall, on the other hand, is great with audience participation. In the end, they ended up getting 4 standing ovations (after Dark Side, after (I think) Comfortably Numb, after The Wall, and after their encore of Run Like Hell). They deserved each and every one of them. They probably played for 2.5 hours all told.

I never got a chance to see Pink Floyd live. As one of the people sitting next to us pointed it, this is the closest you can get at this point. While I agree with him, it is wrong to think of these guys as a facsimile of that famous band. These are all very talented musicians who love this music so much that they have dedicated a big chunk of their lives to it. As a fan, I'm grateful to them for doing that.