Links

pmuellr is Patrick Mueller

other pmuellr thangs: home page, twitter, flickr, github

Thursday, February 26, 2009

size matters

Fellow IBMer Bob Blainey recently posted a blog entry "Are you a Pakled?" which touched on software bloat. This is a subject near and dear to my heart, burned into me after spending a good five years or so in the embedded software space.

At the time, the devices that we were targeting would typically have something like 2MB ROM and 2MB RAM available. Think of the ROM like hard drive space, and the RAM is the memory in a computer today. We worked with devices that had less memory, sometimes, and near the end of my run, worked with devices that had much more memory available. But the 2/2 story was sort of the rule of thumb.

That's not a lot of space, so you worry about every byte. You worry about every new library that you need to add to your runtime. Not just in terms of it's disk footprint, which ate ROM, but the runtime footprint, which ate RAM. There were always hilarious situations where we'd be talking to product groups with no embedded experience, where they'd die laughing when we told them their library had to fit in 10K bytes; or it would be us laughing when they told us their runtime only required 1MB of RAM.

If you enjoy the "solving puzzles" aspect of software development, this is just an additional challenge on top of all the other challenges, which made it, for me, a terribly fun working experience.

You can imagine the "sticker shock" that hit me, when my first position after leaving the embedded world, involved J2EE. Whoa. And the sticker shock continues to this day, in every new piece of work I'm involved in. But it's not just me; most of my colleagues back in the embedded days seem to experience this sticker shock in their day-to-day jobs, which is something that I think most developers just don't think very much about. Like the kid in "The Sixth Sense", we see bloat - everywhere.

It's heartening to see the resurgence in interest in embedded development, in places like the iPhone and Android, since I hope this means we'll be seeing a lot more folks taking an interest in software bloat.

Aside: the Pakleds, referenced in Bob's post, were one of the most memorable races for me in the Star Trek series, but I wasn't able to find any video clips from the show. I did find a little audio clip though; this is Riker asking a Pakled what they need.

Wednesday, February 25, 2009

web ui progress

The hotness of the day (well, yesterday) appears to be video at 280atlas.com (permalink at Viddler here). It's technically very impressive. But I'm also a bit saddened. I worked on similar technology 15 years ago, for desktop applications. You know what I'm talkin' 'bout. I won't say the word.

Sad because, even 15 years ago, web browsers were around, in some state. Why has it taken this long for things to progress this far? It's nuts. Seems like a lost decade, to me. Of course, it's not like we were even really innovating in this space, back then, either. Interface Builder goes back even further.

Feh, always with the rock throwing. So let me shine a little brightness, as well.

First and foremost, hats off to the folks at 280north.com. Getting all this to work on the clumsy web browsers we use today is surely no small feat. It looks gorgeous. The layering is interesting, built on Cappuccino and Objective-J. Stuff to look into.

Two things I saw in the demo that I liked, in terms of UI constructs: "Layout Support" and "Split Views".

The "Layout Support" appears to be similar to what we used to call "Form attachments", back in the day, that allowed you to specify how widgets were attached to things - other widgets, parents, etc - and how they would resize. Ours were based on Motif's XmForm constraint resources. (Aside: isn't it hilarious that the first reference I found to XmForm was in the lesstif online doc?) Although kind of crazy complicated, and really easy to screw up when you were coding by hand, and requiring you implement a constraint solver IIRC, you could do some incredible stuff in terms of making windows full of widgets which responded in a nice way to resize requests. And even just doing (non-absolute) layout by specifying which things were next to other things, and letting the system figure everything out based on default sizes.

"Split Views" are similar to what we called "Split Panes" (think that's what we called them), that were a late edition to our product, but to me added the last little bit of UI goodness for users. Instead of providing either fixed width, or perhaps proportional width child windows inside a parent, Split Panes gave users the ability to resize those child windows as they saw fit. After they got added to the product, there was really not much else that I found I needed, to be able to whip up a nice little UI with intelligently resizable innards. Separate the top level bits of a window into Split Panes, and then layout those children using Form attachments, or perhaps recurse with another Split Pane.

Sure would be nice if these were native capabilities provided by our browsers. CSS (and Tables!!) and Framesets just don't cut the mustard. Ah, not to worry, we'll have a <video> element we can use in our applications soon, and that will more than make up for the lack of these other, much less interesting capabilities.

Thursday, February 19, 2009

on bespin

Could you have possibly missed the news on Bespin, a project from Mozilla Labs? Don't see how. But read up if you haven't.

Bunch of rambling thoughts here:

  • Also check out Sun's Lively Kernel. In particular, make sure you click on the "Development Tools" link (blue globe/basketball thing) after you "Enter the Lively Kernel" to see their take on Smalltalk-like browsers for JS.

  • Bespin works it's magic with HTML Canvas, Lively Kernel uses SVG. Interesting, because these are two completely different low-level programming models, though perhaps we'll end up seeing widget toolkits built with both.

  • Implementing text editors with HTML Canvas and SVG leads you into the Uncanny Valley, as such low-level things as clipboard operations, cursor movement, etc all have to be implemented with user-land code. Doesn't sound like a great proposition, it's at least a crap-load of work to get all the expected text editing behaviors implemented.

  • But you know what, I think Uncanny Valley may not really apply to text editors. I use a large number of text editors in my day-to-day computer usage, and almost none of them are using any kind of a common "text editor component". Eclipse, TextMate, Notes, vi, etc. You just have to get used to them. There are certainly programs I use that DO use a "system-level" common text editor - in my case, the one Mac OS X provides. Forms within Safari, Twitterific, other apps presenting text areas, etc, all use the baked in text editor control, which is nice, because I get the same kind of spell checking, cursor movement, etc. I think extending the usage out to "code" editing (eg, syntax highlighting) just isn't going to work though. Or let's say it hasn't happened yet.

  • Although most of the focus on Bespin is on the browser bits, the impacts/opportunities for server bits isn't lost on some people. In fact, this may well be a more interesting piece; if you imagine an interesting set of back-end "IDE services" being defined for Bespin, why couldn't desktop editors also take advantage of them?

May you live in exciting times.

Thursday, February 05, 2009

it's alive! JavaScript modules

Less than a month ago, I posted one of my long-winded blog entries, the subject being "JavaScript Modules". A week ago, Kevin Dangoor posted a blog entry titled "What Server Side JavaScript needs". One of the issues Kevin raised was:

JavaScript needs a standard way to include other modules and for those modules to live in discreet namespaces. There are easy ways to do namespaces, but there's no standard programmatic way to load a module (once!). This is really important, because server side apps can include a lot of code and will likely mix and match parts that meet those standard interfaces.

Kevin's post led to the creation of the serverjs Google group then a wiki and an IRC channel on freenode - #serverjs.

Well, yeeee haw!

While Kevin's post is really aimed at server-side JavaScript, a lot of the concepts he talks about are actually interesting to think about in the context of web browsers as well, as far as I'm concerned. And I'm not alone. There are also folks who don't give a flip about the browser and that's fine too.

With regards to "modules", there is a proposal for something that's pretty similar to what I blogged about, which I'm obvious partial to. And there are other alternatives. And spirited debate. Come join the fun!

Now there's talk of test cases. Good lord! In a week!

Saturday, January 10, 2009

spring break in canada?

My wife has this bizarre problem. She likes snow. Apparently, it's genetic, as my children suffer from this as well. Despite the fact that we sometimes get deluged with snow (per the included image), most of the time, we get nothing, or not enough to count.

I've suggested to my wife several times that we should take a vacation in Canada some time; I hear they got lots of the white stuff up there. She's taking me seriously now; desperation is setting in, it appears.

The current thought on time frame is spring break, which for us falls at the beginning of April. Seems pretty dicey to me as to whether they'll still be any snow around by then.

I've been to Mont Tremblant and the big log cabin at Montebello, for "work related meetings", both of which are the kind of thing I'm thinking about, though I'm guessing more expensive than I'd like.

Any suggestions from the lazy web?

Friday, January 09, 2009

JavaScript modules

When I see code like this, an example I pulled from YUI, I simply want to cry. Things need not be so ugly. I don't mean to callout Yahoo here, it's just an example I found. Most of the non-trivial 'package-ized' JavaScript I see is like this.

Issues:

  • Everyone of these files is a single anonymous top-level function that is invoked to execute it at the bottom of the file. Icky. Why do we need this?

    This is done because the method of compositing function into your application is done by including the source of that function into the big, single namespace known as your JavaScript environment. To keep from having source you are compositing into your app not "infect" it with additional global variables, you use the trick of putting all your code in a function body and executing it. The function can be (and should be) anonymous. No infection, or controlled infection, as long as you use var on all your variables (argh), as the variables at the top level of the function are local to the function, and not the "environment" (basically, globals).

  • We have functions defined in functions defined in functions here, two levels of which are asynchronous callbacks.

    I don't have a big beef with nested functions, except when it gets silly. Like, in this case. One of the big offenders is definition of the loader function, whose purpose is to load the code, pre-reqs, etc, defined as callbacks presumably because the loading of such files isn't necessarily provided as a synchronous capability from the browser.

  • I bet the folks that wrote this had editor macros set for the text YAHOO.example.app

    Frankly, there's no defense for this; the code should probably be using "shortcut" variables for the "package names", and even just some of the functions, like YAHOO.log.

    I assume there is some kind of taboo over using shortcut variables here; or are people depending on fully qualified function names for code completion or other source analysis tools? Yikes.

How can we make this nicer looking?

I think we need a better way of packaging up the pieces of our composite applications.

Packages. Modules. Bundles. Whatever.

Google Gears WorkerPools, again

I've previously blogged about using Google Gears Worker Pools to build service frameworks. For certain types of functionality, this makes a lot of sense. It certainly has the characteristic of compositing function into your application in a clean, infection-free manner. But it also has the following characteristics:

  • All message sense are asynchronous. While this sort of programming style might be comfortable to some people, and in fact might be the best way to program in the end, it's not terribly friendly for most programmers who have been using mostly/only synchronous function calls their entire programming life.

  • Out of the box, you're always going to be 'sending messages' instead of 'calling functions'.There's technically not much of a distinction between sending a message and a function invocation, you might say, besides the invocation style of the two. But again, for most programmers, function invocation is the norm. And probably requires less syntax per invocation. Shorter programs == good.

So while I don't have any problem with WorkerPools per se, and in fact, I think they are a great pattern for handling asynchronous, parallel work, they also aren't really going to provide the best pattern for modularity.

But I really love the cleanliness aspect.

So here is what I want

Python modules.

And here's the thing. I think we can add support for this fairly unobtrusively.

The basic idea is to define a new function, say loadModule() which is used to 'reference' another module by passing it's name as a parameter (URI to the name, prolly). A module is just a JavaScript file. Only instead of working the way <script src=""> does, it actually defines a new separate, empty namespace and loads the JavaScript into that namespace (just like the way Google Gears WorkPools does). The process of running loadModule() on a module the first time is that the JavaScript source is executed. The object returned is a 'module' object, whose propertes include all the global variables in the module's private namespace. For loadModule() calls with the same module beyond the first, the code is not executed again, but the same 'module' object is returned.

Or other varieties thereof. It's fairly simple to play with this kind of stuff from with Rhino, though your brain will be hurting after getting all the prototype and context linkages set up right. I assume you can do this sort of multi-environment stuff in other JavaScript implementations.

I want it in the browser.

This isn't the kind of code you can write in userland JavaScript, because JavaScript doesn't give you low-level access to it's innards. Needs to be yet another function the browser injects into the JavaScript environment, probably not even implemented in JavaScript, but in C, C++, Java, etc.

What changes

This makes individual JavaScript files a little cleaner by:

  • Not requiring the anonymous function wrapper.
  • Letting you get away with making your namespace a mess without worrying about infecting someone else's namespace.
  • Letting you use shorter names, because imports beyond the first are crazy cheap, so every module would probably just import everything they needed as one-level modules.

Sure would be nice if we could make that loadModule() function synchronous, otherwise loadModule() would really have to be a function which took the URI to the module and a callback, and invoked the callback after the module load. Back into some ickys-ville. Is <script src=""> synchronous?

It's not a lot. But it's a start.

Additional advantages

  • It's easy to imagine that the process of reloading a module which has changed (you just edited it while you were debugging) would be a little more straight-forward; largely only the module itself is affected, though presumably there are some imported object references that would also need to be fixed up (using short-cut variables causes issues here - is that one of the reason the Yahoo example used fully-qualified names?). Some lower-level VM help could get even those references fixed up, I'm thinking.

  • Better than eval(). Yeah, you could code something up to do this using eval(), I suppose. Or get close. The problem with eval() is the code becomes disassociated from it's source location. This makes it difficult/impossible to debug. Or save, after I make my changes in the debugger (some day). With an import story, the original location of the source can be associated with the code, just like all the files <script src="">'d into your page get associated with their source location.

  • You could imagine the keeping byte- or machine-code versions of those modules, in their pre-executed state, cached in memory for future interpreter invocations that imported the module. And cached on disk.

  • As a simple function, you can imagine have embellished versions that handled things like version numbering, pre-reqs, etc.

Example

I coded up an implementation of loadModule() for Rhino tonight, along with a simple example that uses four modules:

main.js:


print("loading module: " + __FILE__)

abc = loadModule("abc.js")
def = loadModule("def.js")

abc.sayHello()
def.sayHello()

abc.js:


print("loading module: " + __FILE__)

sayer = loadModule("sayer.js")

function sayHello() {
    sayer.say("hello")
}

def.js:


print("loading module: " + __FILE__)

sayer = loadModule("sayer.js")

function sayHello() {
    sayer.say("world")
}

sayer.js:


print("loading module: " + __FILE__)

function say(message) {
    print(message)
}

Each module prints a line indicating it's being loaded; the environment I set up defines the __FILE__ variable containing the module source file name (my C roots are showing), and a print() function which prints a line to stdout.

main.js loads two modules, abc.js and def.js. It then calls the sayHello() function in the abc module, followed by the sayHello() function in the def module.

abc.js and def.js are identical, except for the message printed from the sayHello() function at the bottom of the file. Both modules load the sayer.js module. They also both define a function with the same name - sayHello() - but that's ok because they live in separate namespaces and can be accessed separately by code that imports them, like main.js does above.

sayer.js defines a say() function prints a string (my REXX roots are showing).

Here's the output of running the main.js module:

loading module: main.js
loading module: abc.js
loading module: sayer.js
loading module: def.js
hello
world

The output shows that the code in sayer.js is only executed once, like with Python modules; subsequent imports just return the module reference which was built during the first import.

The source for the Java code to run this is available here: http://muellerware.org/hg/org.muellerware.jsml/; it's an Eclipse project stored in an hg repository.

There are really only two Java files used for this, if you just want to peek at the code: Main.java and ModuleLoader.java.

Why don't we have something like this in the browser?

Frankly, after spending a very small amount of time implementing the basic functionality, I have to wonder why we don't have something like this in the web browsers today? We have XMLHttpRequest to programmatically fetch data, why don't we have a way of programmatically fetching and executing code? <script src=""> is a sorry excuse of a version of this. Let me code it, dammit!

Tuesday, January 06, 2009

gpx and exif

Using a GPS

We got our first GPS last Christmas, in preparation for our trip to Ireland in the spring (awesome trip, BTW). That was a Garmin nüvi 270, which is the basic hardware device preloaded with maps of the US and Europe. Buying a device without the Europe maps, and then adding them back would have been a little more expensive. The device was quite useful on the trip.

As I'm a man, I've had more need for the device than my wife, and I had been leaving it in my car. So for my birthday this year, my wife got me a basic device, the Garmin nüvi 205. She wanted 'hers' back. When I started hiking a bit more this fall, I took it with me on the hikes, because it sucks to get lost. I could also kinda figure out where I was based on the shape of the track the device was generating, compared to maps showing trails.

The big problem with taking a nüvi hiking is that the battery only lasts 4-5 hours. It never ran out, but came close a few times. Another problem people may have with older devices is that they don't seem to have the nice tracking function that is really what you want in the device, to show you visibly where you've been on the map. Our one year old nüvi 270 doesn't do the tracking thing, near as I can tell. Lastly, it's not terribly convenient to slip into your pocket; it has a very sensitive touch screen and a easily switched on/off switch at the top. I found an old Palm Pilot leather case, with a hard 'front side' to prevent accidental touches through the case, that ended up being a perfect fit (saving $20 or on the Garmin case; I'm a pack-rat), but still a tight fit for the pocket, and you have to slip it in and out the case just so.

For Christmas, my wife ended up getting me a Garmin eTrex Venture HC, which is the basic GPS hiking model. The maps, compared to the nüvi suck, but that's ok, even the default Garmin maps don't include enough detail for hiking. This device handles track data much better than the nüvi, in that you can pre-load a bunch of tracks into the device and then display them while you're hiking. I've got a bit of a long-winded procedure to generate tracks from existing trail maps and Google Earth (see below), which then shows me something close to the actual trails while I'm hiking.

Besides being used for live tracking, the other thing I've been wanting to do is to correlate the pictures I've been taking while hiking with the GPS, so that I can associate a fairly precise location with the pictures. So that's how I spent a bit of my xmas break; writing that program.

What is GPX?

GPX is a XML file that your Garmin device will poop out giving you a braindump of what it knows; "favorites" you've set up, track logs for where you've been, etc. The file format is described pretty well on this site. The only thing I couldn't quickly figure out was the units for the elevation; meters.

The GPX file will contain a list of points, where each point has the following properties - latitude, longitude, elevation, and time - which it collects every so often (you can configure how often this happens). Here's the GPX file from my most recent hike to White Plains Nature Preserve - http://muellerware.org/kml/White-Pines-Nature-Preserve.gpx.

Actually, getting that GPX file can be a little tricky. You'll need to connect your GPS device to your computer, and for Garmin use the software they provide on a CD to pull the GPX file out, or for the Mac use RoadTrip. For RoadTrip, I always create a new folder for each GPX file I want to create, copy just the stuff I want from the "most recent import" (or whatever), and then export that folder, which exports it to a GPX file with the same name as the folder. A bit non-intuitive, but you'll figure it out.

Once you have the GPX file, you can open it directly in Google Earth. Google Maps doesn't appear to directly eat GPX files, but will eat KML files, and you can easily convert a GPX file to a KML file using the gpsbabel program.

What is EXIF?

EXIF is a standard for metadata embedded in image files. The site http://www.exif.org/ explains all, I guess. The spec is a bit dry. All sorts of metadata can get added to images by your camera, including all the camera settings used when the picture was takem, model information, and for this purpose, GPS information.

Here is an example of the sorts of information that gets stored as EXIF data for a photo.

Two great tastes ...

So, now that we have a bunch of images, and a GPX file, it's a SMOP to get the time of the photo, calculate the GPS coordinates given that time, and then stamp them back into the photo.

It looked to be a difficult slog to deal with the EXIF data myself, so some reading quickly led me to the exiftool program which can do all manner of slicing and dicing of EXIF data for your images.

The program I wrote reads in the GPX file, and then for every image pulls out the time the photo was taken with exiftool, and calculates the GPS coordinates for that photo, stamping that data back into the image with exiftool.

The program, gpx2exif, is housed here: http://muellerware.org/hg/gpx2exif/, is written in Python, may required version 2.5 or above, and also requires that you have exiftool installed.

In addition to stamping the images with GPS data (actually, creating new copies of the images with the GPS EXIF data), it also creates a KML file you can load into Google Earth to 'test' the locations that got stamped. In case your camera's clock is not synchronized to the GPS (hint, hint). If your times are off, read the exiftool help, there's a way to adjust the times of your photos in one swell foop.

Once you've got the GPS data stamped in your images, sites like Flickr and Picasa will show you "map" versions of your sets, and do other stuff with the geo data. The map view for my White Pines set at Flickr is here and the map view for the same set at Picasa is here.

What's next

Turns out you can do all sorts of interesting analysis of the data in the GPX file, like:

  • calculate distance travelled
  • calculate speed
  • figure out when you stopped for a break
  • plot data onto Google Maps or Google Earth
  • generate elevation maps

You should be able to do all this stuff in a web browser, in fact, by writing the analysis code in JavaScript. Given that you can access Flickr cross-site via their 'JSONP'-ish support, associating photos with the GPS data is something you can also probably do in the browser. We'll see. I'm a little worried that the number of data points and expensive math required will be a bit much for normal JavaScript processing; I may need to use a Google Gears worker to offload some of that processing.

Notes

  • exiftool rocks; I was was happy to not have to deal with reading/writing EXIF data myself.

  • My camera stores times in "local" format. Would have been nice if it used UTC. Do any cameras do this? I made an assumption that the camera, and computer you are running gpx2exif on, are running at the same local time. Again, use exiftool to "fix" this, if it's wrong.

  • I still can't figure out the secret to the findall() method ElementTree. bugger. Seems like a great API, I just can't use it. The XML processing wasn't that complex, so minidom, which I'm very familiar with, was fine.

  • Neither Flickr nor Picasa will do anything with your EXIF GPS data unless you specifically tell them to; presumably for privacy reasons. For Flickr, the setting is here; for Picasa, the setting is here.

  • The resulting map views from Flickr and Picasa aren't terribly pleasing to me; in fact, the KML "test" file I produce from gpx2exif is way more interesting. I think because you can see the actual trail, but also the markers I used (default ones) work better than thumbnails that Picasa uses, and the markers used by Flickr can't be disambiguated when they're too close, like they can in Google Earth.

  • On the Garmin eTrex device, if you "save" a track that you've made (hiked), it will strip the time values out. Make sure you export the track off the device before saving; the time values are (obviously) critical to determining the locations for your photos.

  • To pre-load a set of trails for a park onto the device, I do the following. Get a version of the trail maps (prolly from a PDF from the park site) and convert to a JPG file. Bring up Google Earth, find the park, and add an image overlay for the image file you created; set the transparency down so you can see the trails and Google Earth detail. Hopefully there's enough detail in the image, and Google Earth so that you can move/resize the image overlay close enough. Then create some new line segments in Google Earth, tracing over the trails. I couldn't figure out how to export those line segments directly out of Google Earth, but if you "mail" the folder they are in to yourself, you will get a KMZ file, which is just a zip file containing a KML file. Garmin tools like RoadMap don't eat KML, but you can convert the KML to a GPX using gpsbabel, and then import that. Voilà; trails to follow on my device.

  • When traveling long distances now, I've become completely dependent on the GPS, and it's very nice to have when you're not on the interstate. In fact, I've been actively avoiding interstates as much as I can now; traveling back roads through small towns is much more fun. You basically don't have to keep track of where you are, what roads you're on, where to turn, etc. As long as you got the destination plugged in right. And then I find myself racing against the ETA the GPS displays prominently. I called my wife at one point when I was coming home from hiking trip and the conversation went something like this:

    wife: So, where are you?
    me: I have no idea.
    wife: Well, which way are you coming home?
    me: I have no idea.
    wife: I don't suppose you know when you'll be getting home?
    me: 4:37

Tuesday, December 02, 2008

more android thoughts

I remember right when Android came out, I downloaded the SDK and tried playing with it, and there was some kind of silly show-stopping problem with it on the Mac. Thoughts from then, just a little under a year ago. IIRC, the bug got fixed fairly quickly, but not quick enough for me to get a chance to get back to looking at it in any depth. A long time goes by, and right before this Thanksgiving, I got the urge to look at it again, so I did. Here are some unorganized thoughts.

Note that I still didn't really spend a lot of time with it; the time I spent probably raised more questions than it answered, in a good way. I did the obligatory HelloWorld demo, the Notepad tutorial, and lots of browsing and reading in between.

Please comment if I misspeak about something; lots of guessing and incomplete research on my part here (this thing is big!).

Wow. Lots of stuff here.

Hats off to the team. This thing is huge, and seems fairly well put together, especially considering the size. The source takes up 1.4GB on disk; Linux and WebKit and on and on and on. It's fun just to troll around the source directories to see what's there. But I recommend downloading the wad and browsing with your usual editors/tools.

Rev 1

So sure, maybe it's not as sexy and polished as the iPhone, and sure the devices got shipped with a silly little bug, but I'm willing to forgive early releases. Given the scope of the effort, again, I think they've done a great job. It's early days.

But I'm also not willing to shell out my own pocket money for a rev 1 device or o/s. Just like I (no longer) buy rev 1 Apple products or immediately install new versions of OS X. Tired of playing pioneer.

I guess I'm most worried about the potential immaturity of the application and UI frameworks. Usually good frameworks require evolution, and I've used lots of "intelligently designed" frameworks over the years, so I'm a bit of a doubter when I see a new one pop up overnight. Might be interesting to get some background on them, kinda like Google has done with BigTable and some of their other technologies.

Here's an example worry: the Touch Mode blog post has me a bit confused. Touching the screen causes selection and focus to be lost? eh? I've been using my finger on PDA touch screens since the Palm. I'm used to touching the screen causing selection and focus events to occur, not to be lost. I'm either not understanding what's going on here, or this seems wrong. And here's a funny little note: "This is why some developers are confused when they create a custom view and start receiving key events only after moving the trackball once: their application is in touch mode, and they need to use the trackball to exit touch mode and resurrect the focus." Um, developers are confused? I think users will be confused by this also, won't they? I'll give them the benefit of the doubt here, I'd like to see how well this works on an actual device before passing judgement. Lastly, I'm glad to see that the wiggly mouse is back - it's been years! The referenced mail doesn't go into details, but I've been dealing with self-inflicted wiggly mouse problems since the Smalltalk days. Those were due to bugs though, not design.

Devices other than the T-Mobile G1?

I kinda hate to even provide the link the aurally offensive T-Mobile G1 site, but I'll let you feel my pain.

So what other devices are going to be available? More phones, I guess, but I wonder if anyone will do a non-phone version, like Apple's iPod Touch? I'm currently not willing to pay the data charges for presumably light bandwidth usage (over cell); I'm too much of a cheapskate and live fine with my cheapo phone. But I'm more than willing to carry a device I can connect to wifi.

I didn't see much (any?) information on any newer devices coming out, which is a bit worrisome. Before spending a significant amount of time playing with this, I'd like to know this thing has a future. It seems like a no-brainer to me that device manufacturers would take advantage of Android (many caveats apply), but I'm not willing to bet on common sense.

How would you do a port something like the Nokia N800?

In lieu of new devices, what about porting to existing devices, like (my) Nokia N800? Or say, a netbook?

Turns out folks have ported Android to the N800; see here and here.

It appears what these folks have done is ported the entire stack to the device, starting with Linux. Youch. More what I was thinking was porting the minimum number of things to be able to run Android apps on it somehow. Basically, get something like the emulator running as a native app on the device, as an application container. I don't really feel the need to either blow away my existing device, or run another Linux on top of (beside?) it. And I'd be willing to live with having to run Android apps in a container, instead of as native apps themselves.

We did this sort of thing back when we were working on embedded Java; we had a MIDP environment that could run on the native operating system, with the UI layer (for instance) implemented in SWT. In fact, I assumed this was probably how the emulator that ships with the Android SDK was implemented, but it slowly dawned on me that it's actually running the entire stack, from Linux up, in a virtualization environment of some kind. Wowsa. That's why it takes 23 seconds for the emulator to start up.

To implement an emulator for Android, you need to decide how low-level access you want to support. And the answer is obviously: the "Java" code that you use to write applications. All I'd want to do is run existing apps, which can only (?) access "Java" APIs, so all you have to do is have a matching set of Java APIs that do the right thing on the platform (note the 'all' is italicized).

In terms of implementation, since this is, really, Java source, you could (?) just run the apps in plain old Java. Alternatively, if you didn't have a Java available, you could port the Dalvik VM, and run it that way.

For the N800, there is a Java available (I've not tried it); it's a J2ME flavor, so may not be enough anyway. Might be better off porting the Dalvik VM, then porting the UI bits to Hildon/GTK/whatever; the N800 is already running Linux, so presumably other natively accessed things would have a bit of hope of running out of the box (but not camera, GPS, etc). Webkit's got me nervous.

Lots and lots of caveats here, and it's entirely possible that for some reason or another, you really, really need that Linux kernel to even run the plain ole "Java" applications.

Java

So I'll admit Java isn't my first choice for a language on a device like this. I like the option of Python on Maemo.

But I can live with Java on a constrained device like this; I wasn't unhappy doing embedded Java years ago. One of my pain points with Java is the sheer bulk of crap needed to get anything done, pulling in, eventually, loads of Apache and Eclipse projects to do some heavy lifting for you. The nice thing here, everything is included, or seems to be. But even we if end up needing more stuff (why do I even bother saying "if"), we're talking about a constrained device here, where you'll get laughed at if you want to install a 1MB library to pull in some function. People will have to learn how to write small code. Forced sanity.

Scripting?

Mark Murphy's blog post on using Java-based scripting languages on Android sums up the major points, especially as to language implementations that generate Java byte code directly; those will be a problem, and I think that affects a number of the interesting scripting languages. Presumably, someday you'll be able to generate and load Dalvik bytecode in Android. Maybe there will be a way to load Java bytecode and have it internally generate creamy Dalvik output automagically. Many possibilities.

But I wonder how appropriate scripting languages would be anyway? I've written about this before. If my option is to write Java code, or to write Java code in a Python dialect, I'll just stick to Java.

JavaScripting

Of course there's always JavaScript available, either in the native browser via web applications, or in some other way through the use of the WebView UI View class. And check out this interesting looking method, in that class: WebView.addJavascriptInterface(). hmmm ...

Dalvik docs

Some Dalvik docs like bytecode descriptions, file shapes, etc are available here. Of course, almost no one needs this info, but in case you just had to know ...

I was a little surprised the Java-ness of Dalvik went so far as to support JNI, but I guess that really makes a lot of sense.

Proprietary stuff

The licensing situation with maps is a little disconcerting, and at 11 pages, a bit long. But this feels a lot more like an application-level service than, say, core infrastructure, and I'm fine with people setting limits on application services like this. Of course, the core infrastructure / application service line is a bit fuzzy. I use Google Maps a lot; it's starting to feel like core infrastructure. Google's got us right where they want us!

How about a native desktop version?

Imagine something similar to Apple's Dashboard, only running Android applications. You know I just want to start using that WebView.addJavascriptInterface() API on the desktop ...

I had the same thoughts on MIDP, back in the day, of using it as a container for little useful desktop apps. But that was pretty silly, given the lameness of MIDP.

Again, I think the nice way to do this would be to run the apps "native" instead of in a virtualized Linux box. I think if you looked at some of the common componentry used in Android and Chrome, you might end up thinking that being able to run Android apps in Chrome would be an interesting idea.

Now, you might say "the UI capabilities of Android are too lame to be useful on a desktop!" Thing is, I hear that complicated GUIs are on the outs. Even on the internets! I generally agree with those thoughts, and I have to admit, one of the most interesting UI's I've seen recently was Muxtape (R.I.P.); simple.

Speaking of simple UIs, after watching this video discussing ListView, I couldn't help but to think of our old, dear friend Gopher (R.I.P.?). Once upon a time, I imagined having Gopher server interfaces on everything, so I could have a simple universal client that could talk to anything. Good times.

Friday, November 14, 2008

javascript service frameworks

In my "brainwashed" post, I managed to get a diss in for Yahoo!'s BrowserPlus™, calling it a band-aid. However, I carefully, pro-actively covered my arse with an earlier Twitter message "Y! BrowserPlus™ looks interesting; maybe the service framework moreso than the function provided".

The existing services provided by BrowserPlus™ seem like eye-candy. Not sure I really need an IRC client in my web apps, nor text to speech. And I'm worried about the kill switch. Mainly because the implication is that I'm somehow always tethered in an uncacheable way to Yahoo!. shiver

But I do like the service framework stuff. At this point, don't really care how useful it is, glad to see people playing in the space. Why?

The level of functionality we have today, provided by the browsers, for components/modularity of javascript code is <script src="">. Basically, all the power, flexibility, and functionality of the C preprocessor's #include statement (good and bad). But I'm looking at my calendar to see what year this is again. Doh!

The big JavaScript frameworks build their component stories on top of this, and the whole thing just gives me the willies looking at it. While I often wonder if JavaScript actually needs real structuring capabilities in the language, like a class statement, et al., I'm happy to try living without it, and try playing with some other mechanisms.

Java likewise has a crap component/modularity capabilities out of the box. Jar files and class loaders. OSGi plugs that hole. JavaScript likewise needs it's hole filled (that link is sfw, I swear).

So let's start experimenting! Go, go Yahoo! BrowserPlus™!

Could we do this with Google Gears WorkerPools?

In my "fun with WorkerPools" blog post from a while back, I wondered about building a service framework on top of the WorkerPool bits from Google Gears. Seems like building something similar to what BrowserPlus™ provides is pretty do-able.

The great thing about the WorkerPool stuff is that it brings another dimension to the JavaScript story - separate environments / contexts / spaces. The ability to have a bunch of code running, separated into protected object spaces, with very explicit communication channels open between these spaces. The best you can do with <script src=""> is namespacing via fixed name objects. Ugly and unsafe. I assume BrowserPlus™ is doing the multi-context thing as well, but I haven't looked close enough.

The other neat thing about Google Gears is that something like it has leaked into the WHATWG work, via a draft recommendation called Web Workers. Meaning we may be able to do this in a browser-independent way sometime around 2022. Or, our Chrome Overlords will render it moot, since Chrome already ships Google Gears. Or all the browsers will start shipping Gears. Whatever. Workers FTW!

So let's start experimenting! Go, go Google Gears WorkerPool-based service frameworks!

Thursday, November 13, 2008

hiking in the triangle

I've been doing a fair amount of hiking around the area lately, for some reason. Since it seems like there are a lot of folk unfamiliar with the fantastic parks available in the triangle area, and North Carolina in general, thought I'd dump some information here.

Local Hikes

For the hikes listed below, you won't need any special equipment to take a hike. Outdoors-y clothes, something you'll be comfortable walking in for a couple of miles (you're hiking!). And sweating in. Some kind of tennis shoes /sneakers. Bug spray if it's a buggy season. Sunscreen. A hat? And a bottle of water. You'll be outside, walking around for an hour or two; use your head.

  • Hemlock Bluffs Nature Preserve

    This park is maintained by the Town of Cary, and is a little bit of forest in the southern end of the city, right off of Kildaire Farm Road. Just a couple of short paths through the woods, along side Swift Creek, with some unexpected bluffs to overlook. I don't think any of the individual trails in the park are more than two miles.

    The Stevens Nature Center is co-located here which has some information on the park available in one of the buildings at the park entrance. They also hold occasional classes on various topics, through the Town of Cary.

  • Swift Creek bluffs

    A small park maintained by the Triangle Land Conservancy, off Holly Springs Road, between Cary Parkway and Penney Road. Admit it, you had no idea there was a park in that swampy-looking land, did you?

  • William B. Umstead State Park

    Oddly enough, I haven't been there in years. It's odd, because I drive by this park every day I drive to work; it's directly to the south of the airport, filling the area between I-40 on the west, and US-70 on the east. Joe Miller (see below) frequently writes about hiking, running, and biking in the park. Sounds great, and I feel like an idiot for not having visited in so long.

  • Raven Rock State Park [pix] [pix]

    This is one of the family favorites. The main attraction is Raven Rock itself, which is a rocky outcrop on the banks of the Cape Fear river. Fairly simple hike to the river, then a set of stair steps down to the river. Lots of rocks to climb on, for the kids. The Raven Rock Loop Trail is 2.6 miles.

  • Occoneechee Mountain State Natural Area [pix]

    A small park in Hillsborough, bordering the Eno River. While you can't get to the summit itself, you can walk up to the second highest point, and around an old abandoned quarry with some resultant man-made cliffs. You can both look out over the cliffs, from above, then walk down to the Eno River and get a view from below. The eastern section of the Loop Trail is about two miles.

Less Local Hikes

Listed here a couple of parks that aren't really local to the triangle, but close enough to make a day trip. I'm totally geared up when I go to one of these; boots, pack with bunch of crap in it, staff, GPS, etc. Though I've done some of the shorter hikes with the kids with just a bottle of water.

The paths marked on the trails as "strenuous" generally mean - lots of climbing - which usually also means great views. There will be lots of sweat.

Do some research before you go.

  • Hanging Rock State Park [pix] [pix]

    Hanging Rock is the main draw here, a fairly easy hike with great views and some rock scrambling when you get to the top. Lots of people.

    Moore's Wall Loop Trail takes you up a different mountain. At the top is an observation deck with fantastic views. You can do a bit of rock scrambling at the top, and some points along the ridge. Not many people.

  • Stone Mountain State Park [pix] [pix]

    A big mound of granite that's pretty breath taking. To see the view of the mountain, you'll have to venture on the trail to Hutchinson Homestead, which is a pretty easy hike. The hike up the mountain is a different story. There will be sweat. They now have steps that take you almost the entire way up the side of the mountain; not as fun as before they had the steps, but certainly a lot safer.

    When I was up there last week, I met a 70 year old couple from Charlotte who hit the mountain every year. I can only hope to be so lucky.

  • Crowders Mountain State Park [pix]

    The main draw is Crowders Mountain; lots of people. King's Pinnacle is just as nice, with much fewer people.

Web Sites

  • North Carolina State Parks by NC Division of Parks and Recreation

    This is a site maintained by the same folks who actually maintain the fantastic North Carolina state park system. Information on all the parks and natural areas (what's the difference?) is provided, including maps to the parks, maps of the facilities and trails in the parks, and other general information. The maps are quite detailed, and are PDF versions of the slightly better quality print versions of the maps available at the parks themselves. You'll want to use the maps provided at the park, while you're hiking, because they are a bit larger than the print version, printed on nice heavy paper, pre-folded, and have additional park information available on the flip side of the map. But print one of the PDF maps before you go, just in case they're out, or if you happen to go to part of a park which doesn't have a maps kiosk or park station nearby.

  • Triangle Land Conservancy

    You can read all about what the conservancy is about on their web site, but for purposes of this blog post, their web site contains links to a couple of hikable areas that they provide access to.

  • The Town Of Cary Cary Parks, Recreation & Cultural Resources Department

    Contains links to Cary's parks, trails and greenways.

  • North Carolina Parks - Google Maps by me

    This is a crude "mashup" I wrote a while back, recently refurbished to fix some broken links. It's a view of North Carolina in Google Maps, with a marker placed at all the state parks, and a few other random parks I've added. Clicking on a marker gives you a popup with a link to the park's web site, and the current weather and coupla day forecast, with links to more detailed weather information. A right click (if you're a righty) might bring up a context menu that offers to get directions to the park from somewhere else, like your house.

    You can also load the park data into Google Earth, by using the Add / Network Link menu item (on the Mac version anyway), and pasting the URL to the KML file into the Link field: http://www.muellerware.org/projects/ncParksMap/ncParksMap.kml. Once you've added it to your My Places list, you can use the context menu on the entry for the parks to refresh the data from the KML file (basically, the weather). Of course, Google Earth can show you the weather itself. It can also show you pictures taken from within the parks, links to Wikipedia entries, and so on. Google Earth is a great way to get familiar with the layout of the hilly parks, especially if you set "Elevation Exaggeration" to the maximum value of 3.

Blogs

  • Get Out! Get Fit! by Joe Miller

    Joe works for the Raleigh's News and Observer newspaper. He authors a print column "Take It Outside", which is also republished to the web. He usually references his print columns in his blog, so there's not much need to watch for the print columns. Just follow his blog instead.

    Joe covers all manner of outdoor activities, not just hiking, but he spends quite a bit of time covering hiking and biking in North Carolina. He has also written a few books, which I'll reference below.

Books

  • 100 Classic Hikes in North Carolina by Joe Miller - $16

    This is Joe's most recent book, and covers, as it claims, 100 hikes in North Carolina - east, west, north, south and in between. He covers a lot of the state parks, so provides addition information over what's available on the state park's web site. In the Introduction, he discusses clothing and gear, though as I mention above, for short hikes, you won't need much. It's a good introduction to other gear you might want to get though.

  • Take It Outside: Hiking in the the Triangle by Joe Miller - $13

    This is Joe's earlier book, which covers hikes in the Triangle area of North Carolina. Ten years old but still relevant. Simple hikes, places you should definitely check out because they're right in your backyard, if you live here.