<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Mike West</title>
    <link rel="alternate"   type="text/html"            href="http://mikewest.org/" />
    <link rel="self"        type="application/atom+xml" href="http://feeds.mikewest.org/mikewest/" />
    <id>http://mikewest.org/</id>
    <updated>2009-03-22T20:37:07+00:00</updated>
    <author>
        <name>Mike West</name>
        <uri>http://mikewest.org/</uri>
        <email>mike@mikewest.org</email>
    </author>
    <entry>
        <title type='text'>Instapaper is Amazing</title>
        <link rel="alternate" href="http://mikewest.org/2009/03/Instapaper-is-amazing" />
        <id>http://mikewest.org/2009/03/Instapaper-is-amazing</id>
        <updated>2009-03-22T20:37:07+00:00</updated>
        <content type='html'>
&lt;p&gt;I'm subscribed to a slowly-expanding list of something like 230 RSS feeds (I
take the firehose approach to news-gathering, apparently), and for all
practical purposes, my internet experience centers around &lt;a href=&quot;http://www.newsgator.com/INDIVIDUALS/NETNEWSWIRE/&quot;&gt;NetNewsWire&lt;/a&gt;.
Most mornings, I sit down, skim through the headlines of some subset of my feeds,
and open tabs for all the the articles think I might find interesting.  Tabs
are NetNewsWire&amp;rsquo;s killer feature, so far as I'm concerned.  I can pop open a
few tabs and NNW happily keeps track of them across restarts so I don&amp;rsquo;t miss
out on whatever it was that I found interesting if I don&amp;rsquo;t read the article
immediately.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is sometimes as far as I get.  On Friday, I had 97 tabs
open; some had been sitting there since &lt;em&gt;January&lt;/em&gt;, which is a bit absurd.
These were articles that I'd almost certainly find interesting, but that I
hadn&amp;rsquo;t made time to actually &lt;em&gt;read&lt;/em&gt;.  Reading ought to be the entire point of
the tab-opening process, but here I was, opening tab after tab after tab,
regardless of the queue of content I'd already identified.  Obviously
something has gone seriously wrong with my workflow.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://carlo.zottmann.org/&quot;&gt;Carlo&lt;/a&gt; has been singing the praises of &lt;a href=&quot;http://instapaper.com/&quot;&gt;Instapaper&lt;/a&gt; for a while now, this
mountain of built up content seemed like a perfect test case.  After digging
around a bit, I came up with a script to &amp;ldquo;integrate&amp;rdquo; my Instapaper queue with
NNW (&lt;a href=&quot;http://protagonist.co.uk/nnwInstaPost/&quot;&gt;NNWInstaPost&lt;/a&gt;), and I started pushing articles to Instapaper, and
closing tabs.  This worked halfway decently (I'd like a &amp;lsquo;to Instapaper&amp;rsquo;
toolbar button in NNW.  Or a keyboard shortcut.  Or &lt;em&gt;anything&lt;/em&gt; other than
clicking through the &lt;code&gt;Scripts&lt;/code&gt; menu for each article individually).  After a
day or two, I've come to the conclusion that Carlo was right: Instapaper (in
particular, Instapaper.app on my iPhone) is &lt;em&gt;gobsmackingly brilliant&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I think I've &lt;em&gt;read&lt;/em&gt; more articles with Instapaper in the last two days than I
have in the last two weeks with NNW alone.  Walking around with a queued-up
list of content in my pocket is really quite wonderful.  I can read on the
bus.  I can read while waiting for the bus.  I can read while walking from
the bus to the subway.  I can read on the subway.  Etc, etc.&lt;/p&gt;

&lt;p&gt;I love it.  I think you will too, go &lt;a href=&quot;http://instapaper.com/&quot;&gt;try it out&lt;/a&gt;.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>Opera Web Standards Curriculum: The JavaScript Bits</title>
        <link rel="alternate" href="http://mikewest.org/2009/02/opera-web-standards-curriculum-javascript" />
        <id>http://mikewest.org/2009/02/opera-web-standards-curriculum-javascript</id>
        <updated>2009-02-08T12:19:27+00:00</updated>
        <content type='html'>
&lt;p&gt;Last year, I jumped on the opportunity to sit down and write some articles for Opera&amp;rsquo;s &lt;a href=&quot;http://www.opera.com/company/education/curriculum/&quot; title=&quot;The Opera Web Standards Curriculum&quot;&gt;Web Standards Curriculum&lt;/a&gt;.  I bit off a bit more than I could chew, and Chris Mills exhibited the patience of a saint as I finished the first quickly, the second slowly, the third &lt;em&gt;very&lt;/em&gt; slowly, and then completely failed to deal with the rest.  Regardless, those were released along with the rest of the JavaScript bits to complete the curriculum.&lt;/p&gt;

&lt;p&gt;I'm not particularly proud of my end of the &lt;em&gt;process&lt;/em&gt; of getting these articles released, but I'm happy to see them released, and happier still to see the company they keep.  Chris did a brilliant job organizing a brilliant group of authors;  Opera (and Chris in particular) have organized a great body of work, which I'm proud to have had a hand in.&lt;/p&gt;

&lt;p&gt;My articles are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.opera.com/articles/view/javascript-functions/&quot;&gt;JavaScript Functions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.opera.com/articles/view/objects-in-javascript/&quot;&gt;Objects in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.opera.com/articles/view/traversing-the-dom/&quot;&gt;Traversing the DOM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I hope you enjoy them.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>Centralized Bug Tracking</title>
        <link rel="alternate" href="http://mikewest.org/2009/01/centralized-bug-tracking" />
        <id>http://mikewest.org/2009/01/centralized-bug-tracking</id>
        <updated>2009-01-10T19:32:15+00:00</updated>
        <content type='html'>
&lt;p&gt;I liked many things about working at Yahoo.  I'm coming to realize that what I (in hindsight) like &lt;em&gt;most&lt;/em&gt; is probably the piece of software I thought about the &lt;em&gt;least&lt;/em&gt; positively, namely Yahoo&amp;rsquo;s mostly centralized and completely open bug tracking system: Bugzilla.  We abused it more than a bit, attempting to layer task and project management on top of a system that wasn&amp;rsquo;t really designed to support it, but all told, Bugzilla made my work life better.&lt;/p&gt;

&lt;p&gt;As a generic employee, the centralization of bug tracking meant that I was able to quickly and easily file bugs against any Yahoo property.  I didn&amp;rsquo;t have to know who was responsible for a project in order to raise bugs against it.  I didn&amp;rsquo;t need the group responsible for a project to know &lt;em&gt;me&lt;/em&gt;.  When I saw an issue on a Yahoo site, I filed a bug against the project, and knew &lt;em&gt;someone&lt;/em&gt; with the capability to fix the issue would be notified about it.  Bugzilla minimized the friction caused by unclear answers to the question &amp;ldquo;I found a bug, now what?&amp;rdquo;.  Instead of sending out a few emails, looking for someone to stick with a problem, it gave everyone in the company a clear &amp;ldquo;next step&amp;rdquo;, and (in the best cases) fostered a corporate culture of &lt;em&gt;reporting&lt;/em&gt; bugs rather than avoiding them.&lt;/p&gt;

&lt;p&gt;As a developer, Bugzilla meant that &lt;em&gt;I&lt;/em&gt; didn&amp;rsquo;t have to keep the list of bugs on my projects.  The bug database was maintained for me, triaged and prioritized by my managers, and brutally honest.  Every bug that was reported against News sat in my queue, staring at me pleadingly until I fixed it.  I made appropriate comments on each bug when necessary, which simple integration with CVS made trivial, with the cumulative effect that I didn&amp;rsquo;t worry about forgetting to fix something, or losing track of a bug&amp;rsquo;s status.  Everything was maintained for me, removing a burden from my shoulders.&lt;/p&gt;

&lt;p&gt;This isn&amp;rsquo;t to say Bugzilla was perfect.  It was a bit of a mess, honestly, often difficult to use, full of confusing forms and confused categorizations, and plagued by an understaffed team of developers who played with the UI far too often.  For these reasons and more, it probably annoyed me more than any piece of software at Yahoo, but it&amp;rsquo;s existence was hugely advantageous.  In hindsight, I'm coming to consider this a critical component of any development team; a central bug tracking system provides &lt;strong&gt;visibility&lt;/strong&gt; and &lt;strong&gt;accountability&lt;/strong&gt; in a way difficult (impossible) to replicate with personal to-do lists and email.&lt;/p&gt;

&lt;p&gt;Don&amp;rsquo;t read this as an endorsement of Bugzilla in particular, but as an endorsement of the concept of bug tracking.  Working without a centralized bug database makes your work life more difficult for no good reason.  It&amp;rsquo;s something I highly suggest that you avoid.&lt;/p&gt;

&lt;p&gt;If you'd like to get started quickly with an externally hosted bug tracking system, I've heard good things about &lt;a href=&quot;http://lighthouseapp.com/&quot;&gt;Lighthouse&lt;/a&gt; and &lt;a href=&quot;http://sifterapp.com/&quot;&gt;Sifter&lt;/a&gt;.  I'm still looking for a locally hosted system that I like, but I've been recommended &lt;a href=&quot;http://www.mantisbt.org/&quot;&gt;Mantis&lt;/a&gt;, &lt;a href=&quot;http://www.fogcreek.com/FogBUGZ/&quot;&gt;FogBugz&lt;/a&gt;, and, of course, &lt;a href=&quot;http://www.bugzilla.org/&quot;&gt;Bugzilla&lt;/a&gt;.  Honestly, even a hand-maintained text file in &lt;a href=&quot;http://github.com/henrik/tasks.tmbundle/tree/master&quot;&gt;Tasks&lt;/a&gt; format that you print out and pin to the wall for people to write on is better than nothing.  For the sake of your own sanity, use &lt;em&gt;something&lt;/em&gt;.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>Some Thoughts Regarding Caja</title>
        <link rel="alternate" href="http://mikewest.org/2008/12/some-thoughts-regarding-caja" />
        <id>http://mikewest.org/2008/12/some-thoughts-regarding-caja</id>
        <updated>2008-12-16T20:39:27+00:00</updated>
        <content type='html'>
&lt;p&gt;Yesterday, Yahoo! made some announcements regarding The Future™ of many of their high profile properties.  Specifically, they&amp;rsquo;re (slowly) opening up, enabling third-party developers to build applications that can be seen on and interact with your &lt;a href=&quot;http://my.yahoo.com/&quot;&gt;My Yahoo!&lt;/a&gt; page, or your &lt;a href=&quot;http://mail.yahoo.com/&quot;&gt;mailbox&lt;/a&gt;.  I think this is a great step, and one I wish they'd made &lt;em&gt;before&lt;/em&gt; they laid me off. &lt;/p&gt;

&lt;p&gt;Ah well.&lt;/p&gt;

&lt;p&gt;One of the core technologies that&amp;rsquo;s behind this set of features is called &lt;a href=&quot;http://code.google.com/p/google-caja/&quot;&gt;Caja&lt;/a&gt;.  Caja is a code sanitizer: it takes an HTML fragment, and JavaScript that operates on it, and &amp;ldquo;cajoles&amp;rdquo; it into a chunk that can be embedded into a page without the risk of maliciousness.  I'd like to ramble about that, briefly, at a very high level.  I'm still trying to wrap my head around it&amp;rsquo;s details&lt;/p&gt;

&lt;h2&gt;JavaScript is, simply, dangerous.&lt;/h2&gt;

&lt;p&gt;If you've paid attention to any of &lt;a href=&quot;http://developer.yahoo.com/yui/theater/&quot;&gt;Doug Crockford&amp;rsquo;s presentations&lt;/a&gt;, you&amp;rsquo;ll know that the browser security model is simply broken-as-designed.  The internet, therefore, is a place where one can barely trust &lt;em&gt;first-party&lt;/em&gt; code, much less code written by your neighbor.  You have to keep a constant eye out for new cross-site scripting vectors, and be very careful about how you filter third-party input before making it available as &amp;ldquo;user generated content.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;Seen in this light, Yahoo! has a massive problem to confront with it&amp;rsquo;s new &amp;ldquo;open&amp;rdquo; initiatives.  On the one hand, they &lt;em&gt;must&lt;/em&gt; protect the security of their sites.  On the other, they want to pull in content from their users, and not just &lt;em&gt;text&lt;/em&gt;, but &lt;em&gt;code&lt;/em&gt;.  Working applications, written outside of Yahoo!, running directly &lt;em&gt;on&lt;/em&gt; a Yahoo! site.  The project specification itself is basically a nightmare scenario for the security team.  They need to find a way to include third-party JavaScript safely and sanely onto Yahoo! pages.  This mechanism needs to be pretty automatic, as they can&amp;rsquo;t dedicate an engineering team to manually review (potentially) thousands of applications.&lt;/p&gt;

&lt;p&gt;There are two broad paths to take to this end:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Code sanitization, which reads unknown code, processes it, and outputs
a sandboxed version (if possible).  &lt;a href=&quot;http://code.google.com/p/google-caja/&quot;&gt;Caja&lt;/a&gt; is the best known example of
this tact.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Static analysis, which reads unknown code, parses it, and gives a
thumbs-up if it only does known-safe things.  &lt;a href=&quot;http://adsafe.org/&quot;&gt;AdSafe&lt;/a&gt; is a
work-in-progress along these lines.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Yahoo!&amp;rsquo;s running with the former, so let&amp;rsquo;s dive in.&lt;/p&gt;

&lt;h2&gt;Code Sanitization&lt;/h2&gt;

&lt;p&gt;Untrusted JavaScript must not be allowed access to the &lt;code&gt;document&lt;/code&gt; or &lt;code&gt;window&lt;/code&gt; objects.  This means that it must not gain direct access to any DOM node, as every DOM node enables you to crawl back up to &lt;code&gt;document&lt;/code&gt;.  &lt;code&gt;event&lt;/code&gt; objects are right out as well, as they contain dangerous references as well.  Really, when you get right down to it, you have to throw out practically everything of practical use.&lt;/p&gt;

&lt;p&gt;I mentioned that JavaScript was broken, right?&lt;/p&gt;

&lt;p&gt;Caja is an attempt to distill a safe subset of JavaScript out of this mess through server-side sanitization.  A third-party uploads an application, consisting of JavaScript, CSS, and HTML fragments, and Caja transforms it into something that can be guaranteed not to damage the page into which it&amp;rsquo;s embedded.  This is a good thing.&lt;/p&gt;

&lt;p&gt;Caja is a capability-based system, meaning in practice that it begins by defining an extremely restrictive sandbox in which code must run, and enabling well thought-out bits of functionality by selectively injecting access as needed.&lt;/p&gt;

&lt;p&gt;Think of it this way: when you hand your car to a valet, you would be better off if you gave them the valet key, which &lt;em&gt;only&lt;/em&gt; enables them to &lt;em&gt;drive&lt;/em&gt; the car.  You shouldn&amp;rsquo;t give them &lt;em&gt;your&lt;/em&gt; key, which would also let them rummage through your glove box, etc.  In the same way, you shouldn&amp;rsquo;t give a program access to &lt;em&gt;everything&lt;/em&gt; in the DOM if it&amp;rsquo;s only supposed to change a background colour in a particular location.  You'd be better off if you could restrict it&amp;rsquo;s scope of access.  Caja attempts to do this.&lt;/p&gt;

&lt;p&gt;The token you give the valet, the key, can be looked at as a set of &lt;em&gt;capabilities&lt;/em&gt;.  The valet key enables &amp;ldquo;drive the car&amp;rdquo;, your key enables much more.  Similarly, handing an object to a program &lt;em&gt;is&lt;/em&gt; handing it capabilities, enabling it to act in whatever ways are exposed by that object.  Since JavaScript&amp;rsquo;s default objects are &lt;em&gt;so&lt;/em&gt; overpowered, Caja exposes a new set of objects that completely wrap things like the DOM or the event model, and rewrites input programs to use these objects instead, severely limiting the damage they can do.  These wrapper objects contain a series of runtime checks to ensure that a malicious program hasn&amp;rsquo;t somehow broken out of their constraints, and the entire rewriting process fails if the program is written in such a way as to make it impossible to sandbox.&lt;/p&gt;

&lt;h2&gt;Big Drawback&lt;/h2&gt;

&lt;p&gt;Though I understand Caja&amp;rsquo;s practical necessity, I really don&amp;rsquo;t like the way it works.  In short: it breaks progressive enhancement completely, and introduces a hard dependency on JavaScript for functionality.&lt;/p&gt;

&lt;p&gt;As a quick demo, let&amp;rsquo;s look at the following code:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script src=&quot;searchbox.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;link rel=stylesheet href=&quot;searchbox.css&quot; /&amp;gt; 
&amp;lt;form&amp;gt; 
  &amp;lt;input type=&quot;text&quot; size=&quot;60&quot; name=&quot;q&quot;&amp;gt; 
  &amp;lt;input type=&quot;button&quot; value=&quot;Search&quot; onclick=&quot;doSearch(this)&quot;&amp;gt; 
&amp;lt;/form&amp;gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;After &amp;ldquo;cajoling&amp;rdquo;, it will look something more like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
IMPORTS___.htmlEmitter___.p('form') 
    .a('onsubmit', 'return false') 
    .ih('  &amp;lt;input type=&quot;text&quot; size=&quot;60&quot; name=&quot;q&quot;&amp;gt;\n' 
      + '  &amp;lt;input type=&quot;button&quot; value=&quot;Search&quot;' 
      + ' onclick=&quot;return plugin_dispatchEvent___(…)&quot;&amp;gt;\n') 
    .e('form'); 
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The HTML is transformed into a series of JavaScript method calls that &lt;em&gt;generate&lt;/em&gt; HTML.  This makes sense, as it enables Caja to retain complete control over what&amp;rsquo;s written to the page, but it has the side effect of making the form completely inaccessible to anyone who isn&amp;rsquo;t running JavaScript.&lt;/p&gt;

&lt;p&gt;I'd much prefer more thought to be put into &lt;a href=&quot;http://adsafe.org/&quot;&gt;AdSafe&lt;/a&gt;, which sets up the same sort of wrapped-object sandbox, as well as a series of rules which third-party developers must follow.  The system them simply &lt;em&gt;verifies&lt;/em&gt; that they have done so, rather than rewriting their code to ensure that they have.  If the rules are solid, the effect will be the same as can be achieved with Caja, but much more elegant, and with more respect for the fundamentals of the web.&lt;/p&gt;

&lt;p&gt;Crockford has (finally) put up some example code on the &lt;a href=&quot;http://adsafe.org/&quot;&gt;AdSafe site&lt;/a&gt;.  I'd suggest that you go take a look at it.  It looks like a very interesting way to program indeed.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>My job's value</title>
        <link rel="alternate" href="http://mikewest.org/2008/11/my-jobs-value" />
        <id>http://mikewest.org/2008/11/my-jobs-value</id>
        <updated>2008-11-30T15:50:24+00:00</updated>
        <content type='html'>
&lt;p&gt;Recently, I wrote a &lt;a href=&quot;/2008/11/the-inspiration-of-ownership&quot; title=&quot;Mike West: &amp;lsquo;The Inspiration of Ownership&amp;rsquo;&quot;&gt;short article&lt;/a&gt; on the effect a team&amp;rsquo;s sense of ownership in it&amp;rsquo;s projects can have on the finished product.  The &lt;a href=&quot;/2008/11/mike-has-been-laid-off&quot;&gt;surprising twist&lt;/a&gt; in my professional life last week has led me back onto the same train of thought, but I'm coming to it from a slightly different angle.  I discussed &amp;ldquo;ownership&amp;rdquo; in a narrow sense, relating to a team&amp;rsquo;s involvement with and responsibility for decisions made about a project&amp;rsquo;s vision and direction.  This isn&amp;rsquo;t the only way in which the word has impact; one also has &amp;ldquo;ownership&amp;rdquo; of a project in the broader sense of pure possession.&lt;/p&gt;

&lt;p&gt;A relatively famous study offered a representative sample of students a straight choice between a bar of chocolate and a coffee mug.  Opinions were split: neither bars nor mugs were substantially preferred.  If, however, a group was &lt;em&gt;given&lt;/em&gt; one, and then asked if they'd like to trade it for the other, surprisingly few would.  Even though the items were roughly equivalent in the abstract, &lt;em&gt;possession&lt;/em&gt; (however brief) seemed to imbue them with irrationally high value.  &lt;em&gt;My&lt;/em&gt; coffee mug is much more important &lt;em&gt;to me&lt;/em&gt; than some random bar of chocolate with which I have no relationship, even if I've only had &lt;em&gt;my&lt;/em&gt; mug for a few minutes.  Even if it&amp;rsquo;s a bit chipped and cracked, it&amp;rsquo;s &lt;em&gt;mine&lt;/em&gt;, and that counts for something.&lt;/p&gt;

&lt;p&gt;The economist &lt;a href=&quot;http://en.wikipedia.org/wiki/Richard_Thaler&quot; title=&quot;Wikipedia: &amp;lsquo;Richard Thaler&amp;rsquo;&quot;&gt;Richard Thaler&lt;/a&gt; coined the term &amp;ldquo;endowment effect&amp;rdquo; to describe this phenomenon, and I'm reminded very strongly of it as I start looking around for a new job.  Now that my projects at Yahoo! have been taken from me, I'm starting to wonder whether I perhaps I've been valuing them more than I rationally ought.  There are a lot of good jobs out there, and I'm relatively sure of finding one quite quickly.  Perhaps &lt;em&gt;my&lt;/em&gt; job wasn&amp;rsquo;t the best for me after all.  Perhaps that bar of chocolate across the room is significantly tastier than I expect.  Perhaps.&lt;/p&gt;

&lt;p&gt;This, of course, is nothing more than a thinly veiled attempt to rationalize to myself the thought that it&amp;rsquo;s really not all that bad to have my position yanked out from under me.  It&amp;rsquo;s not quite working.&lt;/p&gt;

&lt;p&gt;Yet.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>Has Mike been laid off?  Yes.  Yes he has.</title>
        <link rel="alternate" href="http://mikewest.org/2008/11/mike-has-been-laid-off" />
        <id>http://mikewest.org/2008/11/mike-has-been-laid-off</id>
        <updated>2008-11-21T17:13:13+00:00</updated>
        <content type='html'>
&lt;p&gt;Yahoo! has decided to close down the engineering team in it&amp;rsquo;s German office, of which I am (er&amp;hellip; &lt;a href=&quot;http://hasmikebeenlaidoffyet.info/&quot;&gt;was&lt;/a&gt;) a part.  I'm suddenly &lt;em&gt;incredibly&lt;/em&gt; motivated to look for new work.&lt;/p&gt;

&lt;p&gt;If you happen to know of an exciting web company somewhere in or around Munich that&amp;rsquo;s in need of a solid webdev, please &lt;a href=&quot;mailto:mike%40mikewest.org&quot;&gt;drop me an email (mike@mikewest.org)&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/mikewest&quot;&gt;ping me on twitter&lt;/a&gt;, &lt;a href=&quot;/resume&quot;&gt;take a look at my resume&lt;/a&gt; (or &lt;a href=&quot;http://www.linkedin.com/in/mikewestorg&quot;&gt;linkedin profile&lt;/a&gt;, if that&amp;rsquo;s your style), or give me a call ( +49 176 4854 6453 ).  I'd really &lt;em&gt;love&lt;/em&gt; to hear any and all leads you might have.  :)&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>I &hearts; GitHub</title>
        <link rel="alternate" href="http://mikewest.org/2008/11/i-love-github" />
        <id>http://mikewest.org/2008/11/i-love-github</id>
        <updated>2008-11-16T16:53:09+00:00</updated>
        <content type='html'>
&lt;p&gt;Over the last two or three weeks, a substantial subset of my friends and colleagues have started using &lt;a href=&quot;http://github.com/&quot;&gt;GitHub&lt;/a&gt; to host some of their personal projects.  I'm really enjoying this influx, and it&amp;rsquo;s inspiring in a way I didn&amp;rsquo;t really expect.  GitHub has done nothing less than to make my friend&amp;rsquo;s coding activity &lt;em&gt;visible&lt;/em&gt; to me, and mine visible to them.  This doesn&amp;rsquo;t sound like much, but it&amp;rsquo;s simply transformative; If this is how &amp;ldquo;normal&amp;rdquo; people feel about Facebook, then I can start to understand how it&amp;rsquo;s captured so much mindshare.&lt;/p&gt;

&lt;h3&gt;Coding in the Open&lt;/h3&gt;

&lt;p&gt;Visibility is inspiration and accountability.  Watching talented developers Get Things Done™ around me gives me impetus to start putting something together of my own.  &lt;a href=&quot;http://neilcrosby.com/&quot;&gt;Neil&lt;/a&gt; was creating a new repository every day at one point, and &lt;a href=&quot;http://marknormanfrancis.com/&quot;&gt;Norm&lt;/a&gt;&amp;rsquo;s potential set of projects is great to see.  The whole group of Londoners are setting an example I'd like to live up to, and at the same time generating gentle social pressure for me to build something exciting of my own.  Watching practically everyone I know fork &lt;a href=&quot;http://github.com/norm/homedir/tree/master&quot;&gt;Norm&amp;rsquo;s &lt;code&gt;homedir&lt;/code&gt;&lt;/a&gt; immediately after he put it online is simply brilliant.  I want that to happen to &lt;em&gt;my&lt;/em&gt; projects.  You couldn&amp;rsquo;t ask for better, more constructive peer pressure.&lt;/p&gt;

&lt;p&gt;To that end, I'm putting as much of my current code as possible out into the open.  I'm not generating a whole lot of code that I'd expect to be of use to anyone but myself at the moment, but even so, I &lt;em&gt;work harder&lt;/em&gt; when I know that people I respect will be seeing what I'm producing.  I'm coding for myself, but an audience changes the way I think about what I'm doing; The simple fact that my friends are following my progress on GitHub is reason enough to try to exceed their expectations.&lt;/p&gt;

&lt;p&gt;Moreover, I've been able to convince myself that even &lt;em&gt;robot&amp;rsquo;s&lt;/em&gt; opinions matter.  Just knowing that &lt;a href=&quot;http://calendaraboutnothing.com/&quot;&gt;CalendarAboutNothing&lt;/a&gt; is &lt;a href=&quot;http://calendaraboutnothing.com/%7Emikewest&quot;&gt;watching my every commit&lt;/a&gt; gives me reason to make sure that I make a little bit of time every day to sit down and write something resembling quality code.  It&amp;rsquo;s a simple thing, and has been much more effective than I thought it would be over the last ~2 weeks.  I highly recommend trying it out; soon you&amp;rsquo;ll be just as hooked on big red X&amp;rsquo;s as I've become.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>An Admonition Regarding Details</title>
        <link rel="alternate" href="http://mikewest.org/2008/11/an-admonition-regarding-details" />
        <id>http://mikewest.org/2008/11/an-admonition-regarding-details</id>
        <updated>2008-11-11T22:33:41+00:00</updated>
        <content type='html'>
&lt;p&gt;If Apple&amp;rsquo;s taught me anything about design, it&amp;rsquo;s that details are everything.  The overall product might be brilliant, but it&amp;rsquo;s the tiny bits of &lt;em&gt;perfection&lt;/em&gt; that really bring things together and imbue an experience with a sense of wonder and care.  When I noticed that &lt;a href=&quot;http://robgoodlatte.com/&quot;&gt;Rob Goodlatte&lt;/a&gt; (who has gone dark, apparently?) replaces the ampersands on his Lucida Grande dominated page with lovely, lovely Baskerville, I was thrilled.  The first time I saw the little bit of bounce-back at the end of an iPhone&amp;rsquo;s scrolled list, I was hooked.  These almost insignificant changes have an effect on the overall experience far out of proportion to their apparent importance.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s important, however, not to miss the forest for the trees.  Attention to details will often make or break a project, but first laying down a solid foundation of functionality in broad strokes is &lt;em&gt;critical&lt;/em&gt;.  If you haven&amp;rsquo;t yet &lt;em&gt;built&lt;/em&gt; a bit of your application, worrying about making it pixel-perfect cross-browser and subtly animated to amaze your users is nonsensical and counterproductive.&lt;/p&gt;

&lt;p&gt;Put (virtual) pen to (virtual) paper, and start working.  Details will fall into place naturally, either in the nooks and crannies of unconnected code you cleverly hack together to solve a problem, or in the long periods of iteration and polishing that you&amp;rsquo;ll start to go through near the middle of a project when things &lt;em&gt;mostly&lt;/em&gt; work.&lt;/p&gt;

&lt;p&gt;Test-Driven Development generally advocates that you should begin by ignoring (irrelevant) details and &amp;ldquo;Do the simplest thing that could possibly work.&amp;rdquo;  &lt;a href=&quot;http://neilcrosby.com/vcard/&quot;&gt;Neil Crosby&lt;/a&gt; similarly says &amp;ldquo;&lt;a href=&quot;http://thecodetrain.co.uk/2008/11/make-it-work-make-it-pretty-make-it-right/&quot;&gt;Make it work, Make it pretty, Make it right&lt;/a&gt;.&amp;rdquo;  My Dad (enthralled with the message while completely missing the commercial point of the Nike campaign) always told us &amp;ldquo;Just do it.&amp;rdquo;  These are starting to resonate with me, and I like the idea of the development process as a continual process of iteration, building something delightful&lt;/p&gt;

&lt;p&gt;This, of course, is a long-winded way of justifying the &lt;a href=&quot;http://github.com/mikewest/fallow/commit/9d9b4e69e56841fabe38eb4724caa8b629f40db3&quot;&gt;gaudy hack I've just put into Fallow&lt;/a&gt; to handle simple conditionals in templates.  It&amp;rsquo;s ugly, but functional, and I know I can make it cleaner tomorrow.  But right now, it works; That&amp;rsquo;s better than yesterday, and I can live with that.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>The Inspiration of Ownership</title>
        <link rel="alternate" href="http://mikewest.org/2008/11/the-inspiration-of-ownership" />
        <id>http://mikewest.org/2008/11/the-inspiration-of-ownership</id>
        <updated>2008-11-10T19:49:27+00:00</updated>
        <content type='html'>
&lt;p&gt;On the bus home from work, I was listening to this week&amp;rsquo;s &lt;a href=&quot;http://www.onthemedia.org/&quot;&gt;On the Media&lt;/a&gt;. In particular, I was struck by a &lt;a href=&quot;http://www.onthemedia.org/transcripts/2008/11/07/04&quot;&gt;great interview&lt;/a&gt; with the man who designed the field-organizer and volunteer training programs for Barack Obama&amp;rsquo;s campaign: &lt;a href=&quot;http://www.hks.harvard.edu/about/faculty-staff-directory/marshall-ganz&quot;&gt;Marshall Ganz&lt;/a&gt;.  If you&amp;rsquo;re at all interested in the political angle, I'd suggest you &lt;a href=&quot;http://www.onthemedia.org/transcripts/2008/11/07/04&quot;&gt;listen&lt;/a&gt;.  If you&amp;rsquo;re at all interested in how I'm planning to apply this seemingly unrelated topic to the technical field of web development (et al), keep reading.&lt;/p&gt;

&lt;p&gt;Ganz&amp;rsquo;s greatest accomplishment in this race was to empower a lower tier of volunteers to an extent that simply hadn&amp;rsquo;t been accomplished in previous elections.  By exposing a breadth of information and actionable intelligence that went beyond what campaigns in the past had been able or willing to share, his team was able to create a wide-reaching group of volunteer leadership that came to believe that Obama&amp;rsquo;s campaign was &lt;em&gt;their&lt;/em&gt; campaign too.  This self-identification enabled Obama&amp;rsquo;s volunteer staff to develop individual personal narratives that were far more compelling than anything the campaign could have come up with on it&amp;rsquo;s own.  Information lead to a feeling of ownership, which lead to acceptance of greater responsibility, and exhibition of greater creativity.&lt;/p&gt;

&lt;p&gt;The thing is, this isn&amp;rsquo;t at all limited to the political sphere: software projects work exactly the same way.  In particular, and regardless of the relative &amp;ldquo;objective&amp;rdquo; value, I&amp;rsquo;ll work harder on &lt;em&gt;my&lt;/em&gt; features or fixes than I will on &lt;em&gt;yours&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;Fostering Ownership&lt;/h3&gt;

&lt;p&gt;Especially in a large company working on large projects with many layers of indirection, the importance of a particular bug or task to a project&amp;rsquo;s leadership is almost guaranteed to diverge in some (hopefully small) way from the dreams and desires of the team actually implementing the changes.  Personal buy-in is simply hard to come by when tasks are handed down from on high, but that personal involvement is absolutely critical to a project&amp;rsquo;s success.  What to do?&lt;/p&gt;

&lt;p&gt;I have a few suggestions from my perspective, primarily as an implementor looking upwards:&lt;/p&gt;

&lt;h3&gt;Influence&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Reduce the distance between decision and implementation&lt;/strong&gt;. The more layers a task has to go through to reach it&amp;rsquo;s eventual executor, the less likely that it has any potential to inspire. Flattening the decision structure such that the implementing team feels like it has a hand in the project&amp;rsquo;s direction is one way to increase personal involvement, and to make the team feel that the project is somehow, for each of them, individually &amp;ldquo;&lt;em&gt;mine&lt;/em&gt;&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;Moreover, bringing the decisions about priorities, and the &lt;em&gt;rationale&lt;/em&gt; for the decisions, out from shadowy backrooms and into the harsh light of (probable) criticism is the single best way to make sure that the project is going in the right direction.  If the product vision can&amp;rsquo;t stand up solidly in front of the team that&amp;rsquo;s meant to implement it, it&amp;rsquo;s not going to go anywhere in the market, even if it&amp;rsquo;s perfect in every way.  The development team has to believe in what they&amp;rsquo;re building; they have to be in on decisions that they feel &lt;em&gt;they&lt;/em&gt; are making.&lt;/p&gt;

&lt;h3&gt;Information&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Share information, even if you don&amp;rsquo;t think it&amp;rsquo;s relevant&lt;/strong&gt;. You'd probably be surprised to learn exactly what your development team actually cares about.  Good (and bad) feedback from users or new data from Comscore isn&amp;rsquo;t something that you should talk about once a quarter in planning meetings, but could instead be a source of inspiration and innovation for the entire team, every day.&lt;/p&gt;

&lt;p&gt;Campaign volunteers are closer to the voters than the campaign leadership,    and look at the raw voter data differently.  Unforeseeable (or simply &lt;em&gt;unseen&lt;/em&gt;) trends might be easily explainable with the application of their  local expertise.  Likewise, engineers and web developers work right at the heart of a site or application.  Flood them with up-to-the-minute information you consider relevant &lt;em&gt;and&lt;/em&gt; irrelevant.  They will draw connections you couldn&amp;rsquo;t anticipate, and fill gaps you didn&amp;rsquo;t see, and that creates visible success that inspires.&lt;/p&gt;

&lt;h3&gt;Innovation&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Allow room for surprise and innovation&lt;/strong&gt;.  The products and applications that the development team builds are pure thought-stuff, forged and hammered through will alone. This has a few impacts on the project&amp;rsquo;s process, the most important of which is that the solution to a problem can almost never be specified at the same time the problem &lt;em&gt;itself&lt;/em&gt; is confronted and documented, because the statement of the problem is &lt;em&gt;never&lt;/em&gt; complete enough to illuminate a complete solution.  Experimentation and innovation, and the feeling that both are &lt;em&gt;allowed&lt;/em&gt; and &lt;em&gt;encouraged&lt;/em&gt; are critical.&lt;/p&gt;

&lt;p&gt;Obama probably didn&amp;rsquo;t tell each of his volunteers individually how they should campaign in their communities. He and his staff trusted in their ability to assess the general problem of increasing voter turnout, and turned them loose. In the same way, the development team shouldn&amp;rsquo;t be given detailed technical descriptions of solutions to implement, but instead detailed technical and nontechnical descriptions of &lt;em&gt;problems&lt;/em&gt; to  &lt;em&gt;solve&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The code written must be based on &lt;em&gt;their&lt;/em&gt; expertise, &lt;em&gt;their&lt;/em&gt; choices, and &lt;em&gt;their&lt;/em&gt; understanding of that problem. This personal involvement in the problem solving inspires a sense of ownership that can&amp;rsquo;t be created by mandate.  If the final solution that&amp;rsquo;s written doesn&amp;rsquo;t address the issue at hand in a way that&amp;rsquo;s &lt;em&gt;somehow&lt;/em&gt; surprising or innovative, then the development team is bored, uninspired, and &lt;em&gt;uninvolved&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;In a nutshell&amp;hellip;&lt;/h3&gt;

&lt;p&gt;If you make me &lt;em&gt;believe&lt;/em&gt; that a product, or a feature, or a fix is &lt;em&gt;mine&lt;/em&gt; by giving me &lt;strong&gt;influence&lt;/strong&gt;, &lt;strong&gt;information&lt;/strong&gt;, and &lt;strong&gt;room to innovate&lt;/strong&gt;, I&amp;rsquo;ll move mountains to accomplish more than you expect.  If, however, my paycheck alone is supposed to inspire me to greatness on &lt;em&gt;your&lt;/em&gt; project, then I&amp;rsquo;ll slowly stumble over every molehill on the path to mediocrity.&lt;/p&gt;

</content>
    </entry>    <entry>
        <title type='text'>Flickr's API is driving me nuts</title>
        <link rel="alternate" href="http://mikewest.org/2008/11/flickrs-api-is-driving-me-nuts" />
        <id>http://mikewest.org/2008/11/flickrs-api-is-driving-me-nuts</id>
        <updated>2008-11-09T17:00:13+00:00</updated>
        <content type='html'>
&lt;p&gt;I'm trying to do something with the Flickr API that I consider to be relatively trivial. I have the impression that the API is fighting me every step of the way. Why, oh why, can&amp;rsquo;t the wonderful people who designed Del.icio.us&amp;rsquo;s new API hop over to Flickr and slap together something that makes sense from the perspective of the end user?&lt;/p&gt;

&lt;h3&gt;Basics&lt;/h3&gt;

&lt;p&gt;I'd like to have a list of my flickr sets as a block on my homepage, displaying the most recent sets in the order they were published, along with some simple metainformation and a thumbnail.  I'd also like to display photosets in my &lt;a href=&quot;/archive&quot;&gt;archive pages&lt;/a&gt;, interspersed throughout the rest of the content at the proper point in the timeline.&lt;/p&gt;

&lt;p&gt;Most of this is easy to get with a single call to &lt;a href=&quot;http://www.flickr.com/services/api/flickr.photosets.getList.html&quot;&gt;&lt;code&gt;flickr.photosets.getList&lt;/code&gt;&lt;/a&gt;.  The XML that&amp;rsquo;s returned looks something like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&amp;gt;
&amp;lt;rsp stat=&quot;ok&quot;&amp;gt;
&amp;lt;photosets&amp;gt;
    &amp;lt;photoset id=&quot;[ID GOES HERE]&quot; primary=&quot;2914968443&quot; secret=&quot;[SECRET GOES HERE]&quot; server=&quot;3007&quot; farm=&quot;4&quot; photos=&quot;2&quot; videos=&quot;0&quot;&amp;gt;
        &amp;lt;title&amp;gt;2008-10 - Driving&amp;lt;/title&amp;gt;
        &amp;lt;description /&amp;gt;
    &amp;lt;/photoset&amp;gt;
    ...
&amp;lt;/photosets&amp;gt;
&amp;lt;/rsp&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Simple enough to parse, and in combination with Flickr&amp;rsquo;s &lt;a href=&quot;http://www.flickr.com/services/api/misc.urls.html&quot;&gt;standardized url structure&lt;/a&gt;, this gets me relatively close to the data that I'm looking for.  The small bit that&amp;rsquo;s missing is an actual publication date, which is significant for my plans.  Without it, I can&amp;rsquo;t correctly insert the photosets into my archive pages, and so far as I can tell, the data simply isn&amp;rsquo;t exposed via the API.  So let&amp;rsquo;s dig around a bit.&lt;/p&gt;

&lt;p&gt;Since I know what the primary photo is for the photoset, I can grab it via &lt;a href=&quot;http://www.flickr.com/services/api/flickr.photos.getInfo.html&quot;&gt;&lt;code&gt;flickr.photos.getInfo&lt;/code&gt;&lt;/a&gt;, which gets me the photo&amp;rsquo;s dates:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot; ?&amp;gt;
&amp;lt;rsp stat=&quot;ok&quot;&amp;gt;
&amp;lt;photo id=&quot;2914968443&quot; secret=&quot;[SECRET GOES HERE]&quot; server=&quot;3007&quot; farm=&quot;4&quot; dateuploaded=&quot;1223227911&quot; isfavorite=&quot;0&quot; license=&quot;3&quot; rotation=&quot;0&quot; originalsecret=&quot;c87ab26ef7&quot; originalformat=&quot;jpg&quot; media=&quot;photo&quot;&amp;gt;
    ...
    &amp;lt;dates posted=&quot;1223227911&quot; taken=&quot;2008-10-04 18:12:42&quot; takengranularity=&quot;0&quot; lastupdate=&quot;1223283362&quot; /&amp;gt;
    ...
&amp;lt;/photo&amp;gt;
&amp;lt;/rsp&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Leaving aside the strange change of &lt;a href=&quot;http://www.flickr.com/services/api/misc.dates.html&quot;&gt;timestamp format&lt;/a&gt;, and the nonsensical lack of timezone information, I can mash those into the photoset data to get an approximation of it&amp;rsquo;s creation date.  That works pretty well, actually.  It means, however, that I have to make an additional API request for &lt;em&gt;each&lt;/em&gt; photoset.  That&amp;rsquo;s more than a little annoying.&lt;/p&gt;

&lt;p&gt;But now I have all the information I need, so putting the code together is straightforward.  Straightforward, that is, until I start thinking about the necessity to automatically update this data periodically.&lt;/p&gt;

&lt;h3&gt;Updates&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;http://delicious.com/help/api&quot;&gt;Del.icio.us API&lt;/a&gt; is really good about handling this scenario:
&lt;a href=&quot;http://delicious.com/help/api#posts_all&quot;&gt;&lt;code&gt;posts/all&lt;/code&gt;&lt;/a&gt; returns all the your bookmarks, and allows you to &lt;em&gt;filter&lt;/em&gt; the list by tag or date range.  If I know, for instance, that I last polled for changes at 10:00 this morning, I can ask Del.icio.us to send me only the bookmarks that came in &lt;em&gt;after&lt;/em&gt; that point in time.  This makes the update-handling code on my end quite simple: I ask for all the updates since the last bookmark I've stored locally, and when I get a response, I treat the whole thing as new.&lt;/p&gt;

&lt;p&gt;Flickr doesn&amp;rsquo;t, so far as I can tell, support the same mechanisms.  This has the effect of pushing validation down to my layer: I grab a list of all my photosets and then walk through the list, checking locally to see if I've already got the information stored.  This is stupendously inefficient, and actually becomes &lt;em&gt;more&lt;/em&gt; inefficient as time goes on and I add more photosets.&lt;/p&gt;

&lt;p&gt;The closest Flickr comes to the Del.icio.us level of efficiency is &lt;a href=&quot;http://www.flickr.com/services/api/flickr.photos.getRecent.html&quot;&gt;&lt;code&gt;flickr.photos.getRecent&lt;/code&gt;&lt;/a&gt;, which returns a list of up to 500 recent photos.  It doesn&amp;rsquo;t, however, provide the same benefit as the Del.icio.us feed, as it doesn&amp;rsquo;t allow you to specify what &amp;ldquo;Recent&amp;rdquo; means.  It simply pulls a set number of photos off the top and throws them back over the wall.&lt;/p&gt;

&lt;p&gt;I would &lt;em&gt;love&lt;/em&gt; to see something like the Del.icio.us functionality added to the Flickr API. It would make my particular use case quite a bit simpler, and if applied across the board, it would make the entire Flickr API better suited to the polling-based tasks it&amp;rsquo;s being put to.&lt;/p&gt;

</content>
    </entry>
</feed>
<!-- Served uncached, via Fallow: 0.272015 seconds.  Probably 1 database query. -->