<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Infrequently Noted &#187; programming</title>
	<atom:link href="http://infrequently.org/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://infrequently.org</link>
	<description></description>
	<lastBuildDate>Tue, 01 May 2012 11:30:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>For Dave and David</title>
		<link>http://infrequently.org/2012/04/one-for-dave-and-david/</link>
		<comments>http://infrequently.org/2012/04/one-for-dave-and-david/#comments</comments>
		<pubDate>Wed, 04 Apr 2012 14:49:16 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1819</guid>
		<description><![CDATA[Dave Herman jokingly accused me a couple of TC39 meetings ago of being an &#8220;advocate for JavaScript as we have it today&#8221;, and while he meant it in jest, I guess to an extent it&#8217;s true &#8212; I&#8217;m certainly not interested in solutions to problems I can&#8217;t observe in the wild. That tends to scope [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://calculist.org/">Dave Herman</a> jokingly accused me a couple of TC39 meetings ago of being an &#8220;advocate for JavaScript as we have it today&#8221;, and while he meant it in jest, I guess to an extent it&#8217;s true &#8212; I&#8217;m certainly not interested in solutions to problems I can&#8217;t observe in the wild. That tends to scope my thinking aggressively towards solutions that look like they&#8217;ll have good adoption characteristics. Fix things that are broken for real people in ways they can understand how to use.</p>
<p>This is why I get so exercised about <a href="http://www.w3.org/TR/WebIDL/">WebIDL</a> and the way it breaks the mental model of JS&#8217;s &#8220;it&#8217;s just extensible objects and callable functions&#8221;. It&#8217;s also why my discussions with folks at last year&#8217;s <a href="http://www.w3.org/2011/11/TPAC/">TPAC</a> were so bleakly depressing. I&#8217;ve been meaning to write about TPAC ever since it happened, but the time and context never presented themselves. Now that I got some of my words out about <a href="http://infrequently.org/2012/04/bedrock/">layering in the platform</a>, the time seems right.</p>
<p>Let me start by trying to present the argument I heard from multiple sources, most likely from (in my feeble memory) <strike><a href="http://annevankesteren.nl/">Anne van Kestern</a></strike> Jonas Sicking(?):</p>
<blockquote><p>
ECMAScript is not fully self-describing. <a href="http://es5.github.com/#x8.6.2">Chapter 8 drives a hole right through the semantics, allowing host objects to whatever they want</a> and more to the point, there&#8217;s no way in JS to describe e.g. list accessor semantics. You can&#8217;t subclass an Array in JS meaningfully. JS doesn&#8217;t follow it&#8217;s own rules, so why should we? DOM is just host objects and all of DOM, therefore, is Chapter 8 territory.
</p></blockquote>
<p>Brain <em>asploded</em>.</p>
<p>Consider the disconnect: they&#8217;re not saying &#8220;oh, it sure would be nice if our types played better with JS&#8221;, they&#8217;re saying &#8220;you and what army are gonna make us?&#8221; Remember, WebIDL isn&#8217;t just a shorthand for describing JavaScript classes, it&#8217;s an <a href="http://www.w3.org/TR/WebIDL/#idl-types">entirely parallel type hierarchy</a>.</p>
<p>Many of the Chapter 8 properties and operations are still in the realm of magic from JS today, and we&#8217;re working to open more of them up over time by giving them API &#8212; in particular I&#8217;m hopeful about Allen Wirfs-Brock&#8217;s work on making array accessors something that we can treat as a protocol &#8212; but it&#8217;s magic that DOM is appealing to and even <a href="http://www.w3.org/TR/WebIDL/#es-platform-objects">specifying itself in terms of</a>. Put this in the back of your brain: DOM&#8217;s authors have declared that they <em>can and will do magic</em>.</p>
<p>Ok, that&#8217;s regrettable, but you can sort of understand where it comes from. Browsers are largely C/C++ enterprises and DOM started in most of the successful runtimes as an FFI call <em>from</em> JS <em>to</em> an underlying set of objects which are owned by C/C++. The truth of the document&#8217;s state was not owned by the JS heap, meaning every API you expose is a conversation with a C++ object, not a call into a fellow JS traveler, and this has profound implications. While we have one type for strings in JS, your C++ side might have <code>bstr</code>, <code>cstring</code>, <code>wstring</code>, <code>std::string</code>, and/or some variant of <code>string16</code>. </p>
<p>JS, likewise, has <code>Number</code> while C++ has <code>char</code>, <code>short int</code>, <code>int</code>, <code>long int</code>, <code>float</code>, <code>double</code>, <code>long double</code>, <code>long long int</code>&#8230;you get the idea. If you&#8217;ve got storage, C++ has about 12 names for it. Don&#8217;t even get me started on <code>Array</code>.</p>
<p>It&#8217;s natural, then, for DOM to just make up it&#8217;s own types so long as its raison d&#8217;être is to front for C++ and not to be a standard library for JS. Not because it&#8217;s malicious, but because that&#8217;s just what one <em>does</em> in C++. Can&#8217;t count on a particular platform/endianness/compiler/stdlib? Macro that baby into submission. <a href="http://code.google.com/searchframe#OAMlx_jo-ck/src/third_party/WebKit/Source/WebCore/platform/">WTF</a>, indeed.</p>
<p>This is the same dynamic that gives rise to the tussle over <a href="http://infrequently.org/2011/10/real-constructors-webidl-last-call/">constructable constructors</a>. To recap, there is no way in JS to create a function which cannot have <code>new</code> on the left-hand-side. Yes, that might return something other than an instance of the function-object on the right-hand side. It might even throw an exception or do something entirely non-sensical, but because <code>function</code> is a JavaScript concept and because all JS classes are <em>just functions</em>, the idea of an unconstructable constructor is entirely alien. It&#8217;s not that you <em>shouldn&#8217;t</em> do it&#8230;the moment to have an opinion about that particular question never arises in JS. That&#8217;s not true if you&#8217;re using magic to front for a C/C++ object graph, though. You <em>can</em> have that moment of introspection, and you can choose to say &#8220;no, JS is wrong&#8221;. And they do, <a href="http://lists.w3.org/Archives/Public/public-script-coord/2011JulSep/thread.html#msg114">over and over</a>.</p>
<p>What we&#8217;re witnessing here isn&#8217;t &#8220;right&#8221; or &#8220;wrong&#8221;-ness. It&#8217;s entirely conflicting world views that wind up in tension because from the perspective of some implementations and all spec authors, the world looks like this:</p>
<p><img src="http://infrequently.org/wp-content/uploads/2012/04/today_small.png" alt="" title="The layers of today&#039;s platform." width="404" height="274" class="aligncenter size-full wp-image-1821"/></p>
<p>Not to go all Jeff Foxworthy on you, but if this looks reasonable to you, <em>you might be a browser developer</em>. In this worldview, JS is just a growth protruding from the side of an otherwise healthy platform. But that&#8217;s not how webdevs think of it. True or not, this is the mental model of someone scripting the browser:</p>
<p><img src="http://infrequently.org/wp-content/uploads/2012/04/a_choice_cut_of_well_marbled_platform.png" alt="" title="The Well-Marbled Platform" width="404" height="275" class="aligncenter size-full wp-image-1824" /></p>
<p>The parser, DOM, and rendering system are browser-provided, but they&#8217;re just JS libraries in some sense. With <code>&lt;canvas&gt;</code>&#8216;s 2D and 3D contexts, we&#8217;re even punching all the way up to the rendering stack with JS, and it gets ever-more awkward the more our implementations look like the first diagram and not the second.</p>
<p>To get from parser to DOM in the layered world, you have to describe your objects <em>as JS objects</em>. This is the disconnect. Today&#8217;s spec hackers don&#8217;t think of their task as the work of describing the imperative bits of the platform in the platform&#8217;s imperative language. Instead, their mental model (when it includes JS at all) pushes it to the side as a mere consumer in an ecosystem that it is not a coherent part of. No wonder they&#8217;re unwilling to deploy the magic they hold dear to help get to better platform layering; it&#8217;s just not something that would ever occur to them.</p>
<p>Luckily, at least on the implementation side, this is changing. Mozilla&#8217;s work on <a href="https://github.com/andreasgal/dom.js">dom.js</a> is but one of <a href="https://github.com/arv/JS-DOM-Test">several</a> projects looking to move the source of truth for the rendering system out of the C++ heap and into the JS heap. Practice is moving on. It&#8217;s time for us to get our ritual lined up with the new reality.</p>
<p>Which brings me too David Flanagan who last fall <a href="https://twitter.com/#!/__DavidFlanagan/status/109415801542557696">asked to read my manifesto on how the platform should be structured</a>. Here it is, then:</p>
<blockquote><p>
The network is our bottleneck and markup is our lingua-franca. To deny these facts is to design for failure. Because the network is our bottleneck, there is incredible power in growing the platform to cover our common use cases. To the extent possible, we should attempt to grow the platform through markup first, since markup provides the most value to the largest set of people and provides a coherent way to expose APIs via DOM.</p>
<p>Markup begets JS objects via a parser. DOM, therefore, is merely the largest built-in JS library.</p>
<p>Any place where you cannot draw a line from browser-provided behavior from a tag to the JS API which describes it is magical. The job of Web API designers is first to introduce new power through markup and second to banish magic, replacing it with understanding. There may continue to be things which exist outside of our understanding, but that is a challenge to be met by cataloging and describing them in our language, not an excuse for why we cannot or should not.
</p></blockquote>
<p>The ground below our feet is moving and alignment throughout the platform, while not inevitable, is clearly desirable and absolutely doable in a portable and interoperable way. Time, then, to start making Chapter 8 excuses in the service of being <em>more</em> idiomatic and <em>better</em> layered. Not less and worse.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2012/04/one-for-dave-and-david/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Misdirection</title>
		<link>http://infrequently.org/2012/02/misdirection/</link>
		<comments>http://infrequently.org/2012/02/misdirection/#comments</comments>
		<pubDate>Wed, 15 Feb 2012 23:04:26 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[chrome]]></category>
		<category><![CDATA[economics]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[licensing]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1724</guid>
		<description><![CDATA[As the over-heated CSS vendor prefix debate rages, I can&#8217;t help but note the mounting pile of logical fallacies and downright poor reasoning being deployed. Some context is in order. Your Moment Of Zen The backdrop to this debate is that CSS is absolutely the worst, least productive part of the web platform. Apps teams [...]]]></description>
			<content:encoded><![CDATA[<p>As the over-heated CSS vendor prefix debate rages, I can&#8217;t help but note the mounting pile of logical fallacies and downright poor reasoning being deployed. Some context is in order.</p>
<h3>Your Moment Of Zen</h3>
<p>The backdrop to this debate is that CSS is <em>absolutely</em> the worst, least productive part of the web platform. Apps teams at Google are fond of citing the meme that &#8220;CSS is good for documents, but not for apps&#8221;. I push back on this, noting the myriad ways in which CSS is <em>abysmal</em> for documents. That isn&#8217;t to minimize the pain it causes when building apps, it&#8217;s just that the common wisdom is that CSS surely must be <em>fantastic</em> for <em>somebody else</em>. Once we find that person, I&#8217;ll be sure to let you know. In the mean time we should contemplate how very, very far behind the web platform is in making it delightful to build the sorts of things that are work-a-day in native environments.</p>
<p>But it&#8217;s worse than simply being under-powered: CSS has the weakest escape hatches to imperative code and demands the most world-view contortion to understand its various layout modes and their interactions. Imagining a more congruent system isn&#8217;t hard &#8212; there are many in the literature, might I humbly suggest that now might be a good time to read <a href="http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.101.4819">Badros &#038; Borning</a>? &#8212; and even CSS could be repaired were we able to iterate quickly enough. Things have been moving faster lately, but fast enough to catch up with the yawning gap in platform capabilities? We&#8217;ll come back to the speed/scale of change later.</p>
<p>For now, consider that the debate (as <a href="http://folktrash.com/css-vendor-prefixes/">captured by Nate Vaughn</a>) is about the <em>retrospective</em> implications of the few things that have already gotten better for some set of developers in <em>some</em> situations. That this sort of meaningful progress (corners, gradients, animations, transitions, flexing boxes, etc.) is rare makes the debate all the more bone-chilling to me. We finally got a few of the long list of things we&#8217;ve been needing for a decade or more, and now because the future is unevenly distributed, we&#8217;re about to blow up the process that enabled even that modicum of progress? How is it we&#8217;re extrapolating causality about engine usage from this unevenness, anyhow? None of this is obvious to me. The credible possibility of losing prefixes as a way to launch-and-iterate is mind-exploding when you realize that the salient competition isn&#8217;t other browsers, it&#8217;s <em>other platforms</em>. Either the proponents of squatting other vendor&#8217;s prefixes haven&#8217;t thought this through very hard or they&#8217;re bad strategists on behalf of the web as a platform&#8230;not to mention their own products. The analysis that we&#8217;re being asked to accept rests on an entire series of poor arguments. Lets start with the&#8230;</p>
<h3>Uncomfortable Assumptions</h3>
<p>In an <a href="http://www.alistapart.com/articles/the-vendor-prefix-predicament-alas-eric-meyer-interviews-tantek-celik/">interview out yesterday with Eric Meyer</a>, <a href="http://tantek.com/">Tantek Çelik of Mozilla</a> tried to present this debate as a question of barriers to the adoption of non-WebKit based browsers, specifically <a href="http://www.mozilla.org/en-US/mobile/">Firefox Mobile</a>. Opera has made a similar case. What they ommit is that the only platforms where they can credibly ship such browsers are Android and S60 (a dead end). That&#8217;s <a href="http://en.wikipedia.org/wiki/File:World-Wide-Smartphone-Market-Share.png">a large (and growing) chunk</a> of the world&#8217;s handsets &#8212; good news for me, as I now work on Chrome for Android here in London &#8212; but for whatever reason it appears that <a href="http://marketshare.hitslink.com/browser-market-share.aspx?qprid=0&#038;qpcustomd=1">iOS users surf a whole lot more</a>.</p>
<p>Let that sink in: on the devices that are the source of most mobile web traffic today, it&#8217;s not <em>even possible</em> to install a browser based on a different engine, at least not without a proxy architecture like the one used in the excellent <a href="https://market.android.com/details?id=com.opera.mini.android&#038;hl=en">Opera Mini</a> or <a href="http://amazonsilk.wordpress.com/">Amazon&#8217;s Silk</a>. iOS and Windows Phone are both locked-down platforms that come with only one choice of engine (if not browser shell). When folks from the vendors who want to appropriate others&#8217; prefixes talk about &#8220;not being able to compete&#8221;, remember that competition <em>isn&#8217;t even an option</em> for the most active users of mobile browsers. And it&#8217;s prefixes that are keeping us down? We must go deeper.</p>
<p>The tension comes into focus when we talk in terms of <b>conversion</b>, <b>retention</b>, and <b>attrition</b>. Conversions are users who, if able, <em>switch</em> to a new product from an old one. Retention is a measure of how many of those users <em>continue to use</em> the product after some period of time. Today (and since Windows first included a browser), the <em>single largest factor</em> in the conversion of users to new browsers is <em>distribution with an OS</em>. This is the entire rationale behind the <a href="http://arstechnica.com/microsoft/news/2010/02/microsofts-eu-browser-ballot-approved-arrives-march-1.ars">EU&#8217;s browser choice UI, mandated on first start of new Windows installs</a>. Attrition is the rate at which users stop choosing to use your product day after day, and for most desktop installed software, attrition is <em>shockingly</em> high after 3 to 6 months. The attrition rate is usually measured by cohorts over time; users who installed on the same day/week/month to measure what % of that group continue to use the product over increasingly long periods of time. The rate of decay falls, but the overall attrition invariably continues to rise. You might not get un-installed, but that doesn&#8217;t mean you&#8217;ll still be the go-to icon on the user&#8217;s home screen or desktop. Eventually every device is recycled, wiped, or left for history in a drafty warehouse and along with it, your software. A key factor in getting attrition under control for Chrome has been evangelism to improve site compatibility, e.g. &#8220;I&#8217;m not using your browser because my bank website doesn&#8217;t work with it&#8221;. That argument &#8212; that site compatibility is key to ensuring a competitive landscape for what otherwise are substitutes &#8212; puts the entire thing in some perspective. Attrition isn&#8217;t the same thing as conversion, and conversion is driven primarily by integrations and advertising. Implicit in the arguments by Tantek and others is a sub-argument of the form:</p>
<blockquote><p>Our product would have measurably more users if sites were more compatible.</p></blockquote>
<p>Thanks to what we know about what drives conversions, in the short run this is simply false. Long term, what invariably gives you more users is <em>starting with more users</em>. The set of things that are most effective at convincing users to swap browsers, even for a day, include: advertising, word-of-mouth, a superior product, distribution/bundling, and developer advocacy. Depressingly, only one of those involves <em>actually being a better product</em>, and the prerequisite for all of them is the ability to switch (thanks, Android team!). There&#8217;s a similar dynamic at work when doing advocacy to web developers: if you&#8217;re nowhere in their browser stats, they&#8217;re adding support for a standard or worse a second prefix in order to do service to a cause, not because it&#8217;s <em>measurably good for them</em>. Clearly, that&#8217;s going to be somewhat less effective. Where, then, is the multi-million dollar advertising campaign for Fennec? The carrier and OEM rev-share deals for bundling on new Android phones? Hmm. To hear Tantek et. al. tell it, non-WebKit-based browsers would be prevalent on mobile if only it weren&#8217;t for those damned browser prefixes causing users of other browsers to receive different experiences! Also, those kids and that damned dog.</p>
<p>Over the long haul compatibility can have a dramatic effect on the rate of attrition by changing the slope of the curve &#8212; which, remember, is a rate with decay and not a single % &#8212; but it begs the next uncomfortable question: what do we mean by &#8220;compatibility&#8221; here? What sorts of incompatibility <em>cause</em> attrition? Is it content that looks <em>slightly worse</em> but still essentially works (think grey PNG backgrounds on IE6) or does it simply turn you away, not allow you to play in any way, and generally fails (think the ActiveX dependencies of yore)?</p>
<h3>Inaccessible or Ugly?</h3>
<p>Eric was good enough to call out what I view as a key point in this debate: what sort of &#8220;broken&#8221; are we talking about? Tantek responded with a link to side-by-side screenshots of various properties rendered on <a href="http://people.mozilla.com/~atrain/mobile/Evangelism/chrome-compare/chrome-compare.html">Chrome for Android&#8217;s Beta and current Fennec</a>. In some of these cases we may be looking at Fennec bugs. <a href="http://wordpress.com">WordPress.com</a> serves the same content to Fennec which seems to bork what <code>float: left;</code> means. That, or some media query is preventing the main blocks from being floated; it&#8217;s hard to tell which from a quick <code>view-source:</code>. For the versions of google.* included in the list, the front end is simply serving the desktop version to Fennec which makes the wonky button rendering even stranger. Is there room to improve what gets sent to Fennec? You bet, but that&#8217;s not what&#8217;s being argued in the main. Ask yourself this: is what you see on that page worth destroying the prefix system for? &#8216;Cause that&#8217;s what the advocates of prefix-squatting would have you believe. In effect, they&#8217;re suggesting that <em>nothing</em> will cause developers to test on non-pervasive engines, a deeply fascinating assertion. Even if we accept it, it doesn&#8217;t point clearly to a single tactic to resolve the tension. It certainly doesn&#8217;t argue most strongly for prefix-squatting.</p>
<p>An important point Eric failed to follow up on was Tantek&#8217;s assertion that Mozilla will be cloaking user-agent strings. Does he imagine that the only thing that might be cause someone to send different content is CSS support? API support for things like touch events differs, the performance characteristics of device classes and browsers vary wildly, and application developers are keen to deliver known-good, focused experiences. The <a href="http://code.google.com/mobile/articles/webapp_fixed_ui.html">endless saga of <code>position: fixed;</code> as plumbed by Google teams</a> and others is a story of competing constraints: browser vendors optimize for content, content fights back. Repeat. What does Mozilla imagine is going to happen here? Maintained content will react to the browser usage of end-users (and as we&#8217;ve covered, compat != conversions). Unmaintained content, well, that&#8217;s what fallback is all about. And bad things deserve to lose. Assuming that your browser is 100% compatible with developer expectations and testing if you only switch the UA and implement a few prefixes is NPAPI-level crazy all over again, and it&#8217;s entirely avoidable. Tantek and Brendan, of all people, should be able to reason that far. I guess they&#8217;ll find out soon enough &#8212; although we will have all been made poorer for it.</p>
<p>Now, what about the related argument that Mozilla &#038; Co. are only going to be doing this for properties which are &#8220;stable&#8221; (nevermind their actual <a href="http://www.w3.org/Style/CSS/current-work">standardization status</a>)? The argument says that because something hasn&#8217;t changed in another vendor&#8217;s prefixed version in a while, it must be safe to squat on. Not only is this (again) incredibly short-sighted, it says that instead of forcing a standard over the line and clobbering both developers and other vendors with the dreaded label of &#8220;proprietary&#8221; (the usual and effective tactic in this situation), they&#8217;re instead willing to <em>claim ownership and therefore blame</em> for the spread of this soon-to-be-proprietary stuff, all the while punting on having an independent opinion about how the features should be structured and giving up on the standards process&#8230;and all for what?</p>
<h3>Product vs. Platform</h3>
<p>Perhaps there wasn&#8217;t space in Tantek&#8217;s interview with Eric, but both of them chose not to be introspective about the causes of WebKits use in so many mobile browsers, with Tantek merely flagging the use of a single engine by multiple products as &#8220;a warning sign.&#8221; But a warning of what, exactly? Eric didn&#8217;t challenge him on this point, but I sorely wish he had. Why did Safari, the Android Browser, Chrome, Silk, Black Berry, and many others all pick WebKit as the basis for their mobile browsers?</p>
<p>WebKit <em>isn&#8217;t a browser</em>. It&#8217;s just not. To make a browser <em>based</em> on WebKit, one might bring along <em>at least</em> the following bits of infrastructure which WebKit treats as bits to be plugged in:</p>
<ul>
<li>Networking</li>
<li>Caches of some sort</li>
<li>Graphics rendering</li>
<li>A build system</li>
<li>POSIX or other platform plumbing</li>
</ul>
<p>And that&#8217;s a <em>minimum</em>. Competitive ports tend to include WebSQL, LocalStorage, and Indexed DB back-ends, video codecs, 3D infrastructure (deeply non-trivial), perhaps an alternative JavaScript engine (V8 or other), and alternative/additional image decoders (e.g., <a href="http://code.google.com/speed/webp/">WebP</a>). All of that is in addition to needing to create your own UI for bookmarking, navigation, etc. WebKit is an <em>engine</em>, not a fully-functioning vehicle. Therein may lay some of the difference in the relative success of the WebKit and Gecko on mobile to date. Want to build a Gecko-based browser? Great, first clone <a href="https://wiki.mozilla.org/Mobile/Build/Fennec#Install_build_dependencies_.28non-Maemo.29">the <em>entire Firefox codebase</em> from Mercurial</a>, then layer your stuff on top/around. Oh, wait, things might not cleanly be factored to allow you to plug in your own X, Y, or Z? Your builds take forever? Welcome to life in the Mozilla universe where your product is always second fiddle to Firefox. Now, that&#8217;s not by way of criticism, mind you. <em>It is entirely reasonable</em> for a product like Firefox not to pay coordination costs with other vendors/users of their code. God knows the overhead over here in WebKit land of trying to keep the menagerie of ports building against all changes is downright daunting. Mozilla (the organization) has made choices that prioritized the success of their <em>product</em> (Firefox) over their <em>codebase</em> (Gecko). WebKit was structured as platform only (no product), both forcing enormous costs onto every port while also freeing them from swimming upstream against a single product&#8217;s imperatives in the codebase.</p>
<p>What we&#8217;re witnessing isn&#8217;t open vs. closed, it&#8217;s differences in initial cost of adoption. In JS terms, it&#8217;s jQuery (focused core, plugins for everything else) vs. Sencha or Dojo (kitchen sink). Entirely different target users, and both will find their place. Nobody should be shocked to see smaller, more focused bits of code with good plugin characteristics spreading as the basis for new projects. The Mozilla Foundation wants to help prevent monoculture? In addition to making the Firefox product a success, there are concrete engineering things they can do to make Gecko more attractive to the next embedder, Firefox-branded or not. I haven&#8217;t heard of progress or prioritization along those lines, but I&#8217;m out of the loop. Perhaps such an effort is underway, if so, I applaud it. Whatever the future for Gecko, Product success isn&#8217;t related to platform success as a first approximation. Having a good, portable, pluggable core increases the odds of success in evolutionary terms, but it&#8217;s absolutely not determinant; see MSIE.</p>
<p>Speaking of IE&#8230;I respect those guys a lot, but the logical leap they&#8217;re asking us to swallow is that <em>the reason people return Windows Mobile phones is that some CSS doesn&#8217;t work</em>. That&#8217;s what attrition means on a platform where they&#8217;re the only native runtime. Data would change my mind, but it&#8217;s a hell of a lot to accept without proof.</p>
<h3>The Time Component</h3>
<p>Lets take a step back and consider Tantek&#8217;s claim that Mozilla has gotten very little traction in evangelizing multi-prefix or prefix-free development for the past year: Firefox for Android has been available since Oct. 2010 and stable for just 6 months. Opera Mobile on Android has been stable for just over a year. IE 9 (the only IE for mobile you could ever seriously consider not serving fallback experiences to) only appeared with Windows Phone 7.5 (aka &#8220;Mango&#8221;), shipped to users an <em>entire</em> 6 months ago.</p>
<p>And we expect webdevs to have updated all their (maintained) content? Never mind the tenuous correlation between the sorts of soft incompatibilities we&#8217;re seeing at the hands of CSS and user attrition; the argument that even this lesser form of harm hasn&#8217;t been blunted by evangelism appears suspect. Taking the incompatibilities seriously, I can quickly think of several other measures which are preferable to destroying the positive incentives towards standardization the prefix system creates (from least to most drastic):</p>
<ul>
<li>Continued evangelism to web developers with particular focus on major sites</li>
<li>Political pressure on browser vendors to start dropping prefixes (i.e., we&#8217;d all be <em>equally</em> disadvantaged until users pick up the standard version)</li>
<li>UA spoofing <em>without</em> prefix squatting</li>
<li>Blacklists to trigger alternative identity (UA/prefixes) on a subset of sites</li>
</ul>
<p>All of these are less blow-up-the-world than what MSFT, Mozilla, and Opera are proposing. It&#8217;s not even an exhaustive list. I&#8217;m sure you can think of more. Why these have either been not considered or dismissed remains a mystery.</p>
<h3>It&#8217;s More Complicated Than That</h3>
<p>In all of this, we&#8217;re faced with an existential question: what right do web developers have to shoot themselves in the foot? Is there a limit to that right? What sort of damage do we allow when some aspect of the system fails or falls out of kilter for some period of time? It&#8217;s a question with interesting parallels in other walks of life (for a flavor, substitute &#8220;web developers&#8221; with &#8220;banks&#8221;).</p>
<p>Can we show active harm to other browsers from the use of prefixes? The data is at best unclear. Arguing that any harm rises to a level that would justifies destroying the prefixes system entirely is rash. I argued many of the reasons for this in my <a href="http://infrequently.org/2011/11/vendor-prefixes-are-a-rousing-success/">last post</a>, but lets assume in our mental model that developers respond to incentives in <em>some</em> measure. If, concurrently with achieving as-yet un-managed distribution, Mozilla et. al. implement others&#8217; prefixes, what should we expect developers to do in response? After all, they will have reduced whatever tension might have been created by content that &#8220;looked wonky&#8221; and, where standards exist, will have reduced the incentive to switch to the standard version.</p>
<p>Now lets play the model one more turn of the wheel forward too: assume that Chrome or Safari (or both!) act in good faith and contemplate removing the <code>-webkit-*</code> prefix support for standardized features at a quick clip&#8230;and Mozilla doesn&#8217;t. You see how this quickly leads to a Mexican standoff: web developers won&#8217;t stop using prefixed versions because those are the way you get 100% support (thanks to Mozilla&#8217;s support for them); vendors won&#8217;t un-prefix things because <em>others</em> who squat their prefixes will then have a compatibility advantage; and nobody will be keen to add new things behind prefixes because they can no longer be assumed to be experiments that can change. Lose, lose, lose.</p>
<p>Some on the other side of the debate are keen to cite game theory as a support for their course of action, but the only conclusion I can draw is that their analysis must be predicated on a set of user and developer motivations that are entirely unlike the observable world we inhabit.</p>
<h3>A Call To Reason, Not Arms</h3>
<p>Based on a better understanding of the landscape, what should the various parties do to make the world better for themselves now and in the long run and for the web as a platform?</p>
<ul>
<li><b>Web Devs</b>: first, do no harm; test in multiple runtimes, pointedly including a &#8220;fallback&#8221;. Then enhance with prefixes. Do not apologize for giving some (or even many) of your users a better experience. That, after all, is your <em>job</em>. But know this: prefixed properties are not supported, <em>will</em> go away, and when something you didn&#8217;t test the fallback for falls over, it&#8217;s <em>your</em> fault.</li>
<li><b>Browser Vendors</b>: invest in advocacy and distribution enhancing moves for your product before threatening to blow up effective standards policies. If you&#8217;re going to implement a prefixed version, please have a different opinion or push to ram a standard through to Recommendation ASAP. Incompatible right-hand-sides help developers understand that things are still evolving. <em>DO NOT</em> squat on prefixes. It&#8217;s both relative ineffective and will make developer&#8217;s lives harder when they want to <em>legitimately</em> move to standard or support your prefixes.</li>
<li><b>Vendor CSS WG Reps</b>: get it through your heads, you&#8217;re <em>behind</em>. It&#8217;s not quaint and it&#8217;s not excusable. The platform needs more powerful CSS features, and stat. It&#8217;s long past time to start stealing good ideas from the pre-processors. Appeals to a lack of manpower to implement must never block others and shouldn&#8217;t block standardization, so please stop making them. If you care about the platform&#8217;s success, let those who are able and willing to take risks do so.</li>
<li><b>The CSS WG (as a whole)</b>: get the lead out. It&#8217;s not exclusively the W3C&#8217;s fault that things are slow, but the current MTTR (Mean Time To Recommendation) is still glacial. It is unreasonable to expect vendors to drop prefix support immediately upon standardization, but the W3C has a role here to advocate for quick sunsetting. Daniel Glazman is, as ever, right on most of this, but more can be done to streamline the process post CR.</li>
<li><b>The WebKit Project</b>: Add build flags to allow WebKit-based products to enable/disable vendor prefix support independently.</li>
<li><b>Chrome/Safari/Other-prefix-supporting-browsers</b>: Sunset prefixes as soon as is practicable post-standardization. Similarly, don&#8217;t ship prefixed features you&#8217;re not willing to be on the hook for via your reps to the CSS WG. Disabling them may be painful, but it&#8217;s the only good-faith thing to do.</li>
</ul>
<h3>Endnotes</h3>
<p>I&#8217;ve left a lot out of this post, but it&#8217;s too long already. I do truly hope it&#8217;s the last I write on prefixes because, as I said up front, we have <em>much</em> bigger fish to fry. Stat. Prefixes <em>do</em> work, they&#8217;re essential to delivering a future platform that can compete, and yes, they should be torn down at the same pace they&#8217;re erected.</p>
<p>A few things that folks have asked about as tangents to this debate:</p>
<ul>
<li>It&#8217;s never a good thing for there to be homogeneity in the experimentation phase. The <em>explicit goal</em> of the prefixes system is to enable diversity of early opinion and fast coalescing around the best answer, thereby enabling the writing of a standard which is likely to need less revising and iteration. Diversity provides some value, the market tests the alternatives, and we deliver the most value we can over time through the <em>standard</em> version. It has always been thus, but prefixes make it less risky&#8230;assuming we don&#8217;t start stepping on everyone else&#8217;s toes.</li>
<li>If the reasoning behind prefixes is to set up and tear down large-scale experiments, iterate, and collect feedback then Lea&#8217;s <a href="http://leaverou.github.com/prefixfree/">-prefix-free</a> approach and PPK&#8217;s <a href="http://www.quirksmode.org/blog/archives/2012/02/alpha_and_beta.html"><code>-alpha-*</code>/<code>-beta-*</code></a> proposals are equally counter-productive and should be avoided at all costs. Making prefixes less painful to use reduces the natural incentives for migrating to a standard while blindly assuming the same right-hand for a future standard version as we have for <em>some</em> prefixed versions is plainly idiotic. What were they thinking?</li>
<li><code><a href="http://felipe.wordpress.com/2012/02/02/a-proposal-to-drop-browser-vendor-prefixes/">@-vendor-unlock</a></code> is only slightly smarter, but in every possible way inferior to <a href="http://lists.w3.org/Archives/Public/www-style/2011Mar/0478.html">CSS Mixins</a>. Would that the WG spent as much time on Mixins as they have on this prefix kerfuffle.</li>
<li>Yes, I was in Paris when the CSS WG F2F was happening. No, I wasn&#8217;t at the meetings. Duty (Chrome for Android) called.</li>
<li>If you&#8217;ve read this far, congrats. You may be the only one. I&#8217;ve been assured by CSS WG delegates that nobody cares what I think, which statistically seems to just be rounding down by a tiny bit. Fair enough.</li>
</ul>
<p><em><b>Update</b>: <a href="http://infrequently.org/2012/02/misdirection/comment-page-1/#comment-239566">Michael Mullany of Sencha adds epicly good, epicly long context about what causes developers to target UAs and what the incentives that&#8217;ll change their minds about supporting a given browser really are.</a></em></p>
<p><em>Thanks to <a href="http://fberriman.com/">Frances Berriman</a>, <a href="http://jakearchibald.com/">Jake Archibald</a>, <a href="http://gent.ilcore.com/">Tony Gentilcore</a>, and <a href="http://www.xanthir.com/blog/">Tab Atkins</a> for reviewing earlier versions of this post. Errors of fact and form are all mine, however. Updated occasionally for clarity and to remove typos.</em></p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2012/02/misdirection/feed/</wfw:commentRss>
		<slash:comments>35</slash:comments>
		</item>
		<item>
		<title>Real Constructors &amp; WebIDL Last Call</title>
		<link>http://infrequently.org/2011/10/real-constructors-webidl-last-call/</link>
		<comments>http://infrequently.org/2011/10/real-constructors-webidl-last-call/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 14:10:03 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1693</guid>
		<description><![CDATA[For those who haven&#8217;t been following the progress of WebIDL &#8212; and really, how could you not? An IDL? For the web? I&#8217;d like to subscribe to your newsletter&#8230; &#8212; the standard is now in last call, which is W3C for &#8220;alllllllllllmost done&#8221;. Which it is not. Before I get to why, let me first [...]]]></description>
			<content:encoded><![CDATA[<p>For those who haven&#8217;t been following the progress of WebIDL &#8212; and really, how could you not? An IDL? For the web? I&#8217;d like to subscribe to your newsletter&#8230; &#8212; the standard is now in <a href="http://www.w3.org/TR/2011/WD-WebIDL-20110927/">last call</a>, which is W3C for &#8220;<em>alllllllllllmost</em> done&#8221;.</p>
<p>Which it is not.</p>
<p>Before I get to why, let me first say some nice, well-earned things about WebIDL: first, it has helped us out of the ad-hoc IDL sludge that used to be how APIs for JavaScript have been exposed in the past. It has shaved off many sharp edges and is giving spec authors a single dialect in which to write their API descriptions. From a browser perspective, this is a <em>Very</em> Good Thing (TM). Next, the draft in question contains some wonderful changes from the status quo, particularly the <a href="http://www.w3.org/TR/2011/WD-WebIDL-20110927/#interface-prototype-object">addition of a sane prototype to all WebIDL-specified objects</a>.</p>
<p>That all sounds good, so what&#8217;s missing?</p>
<p>In a word, constructors.</p>
<p>Well, a lot more than that, but I&#8217;d settle for constructors. Functionally speaking, it boils down to the fact that WebIDL makes spec authors do extra work to make something like this sane:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">new</span> HTMLDivElement<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Why doesn&#8217;t this work today? Funny story&#8230;see, HTML defines <a href="http://www.w3.org/TR/html5/grouping-content.html#htmldivelement">HTMLDivElement</a> as a regular WebIDL interface. WebIDL doesn&#8217;t really have the notion of concrete classes, just interfaces with and without constructors. Since the HTML spec is just doing what most specs will do &#8212; adding the smallest IDL you can get away with &#8212; the JS usability of this API is left in limbo; neither clearly HTML5&#8242;s responsibility nor WebIDL&#8217;s.</p>
<p>So what should a contentious version of HTML5 do? One answer is to specify a constructor, turning the IDL from this:</p>

<div class="wp_syntax"><div class="code"><pre class="idl" style="font-family:monospace;"><span style="color: #990078; font-weight: bold">interface</span> HTMLDivElement <span style="color: #66cc66;">:</span> HTMLElement <span style="color: #808080;">&#123;</span><span style="color: #808080;">&#125;</span><span style="color: #66cc66;">;</span></pre></div></div>

<p>to this:</p>

<div class="wp_syntax"><div class="code"><pre class="idl" style="font-family:monospace;"><span style="color: #808080;">&#91;</span>Constructor<span style="color: #808080;">&#93;</span>
<span style="color: #990078; font-weight: bold">interface</span> HTMLDivElement <span style="color: #66cc66;">:</span> HTMLElement <span style="color: #808080;">&#123;</span><span style="color: #808080;">&#125;</span><span style="color: #66cc66;">;</span></pre></div></div>

<p>Repeat ad-infinitum for each and every interface that <em>should</em> be constructable in every single spec that browser vendors ever implement. Don&#8217;t miss any! And please make sure that all your spec editors are on-board with good JS APIs as a goal! As it stands today, WebIDL doesn&#8217;t even force most spec authors to consider the question &#8220;do I need a constructor here?&#8221; &#8212; spoiler: <em>yes</em> &#8212; let alone the obvious follow-ups like &#8220;what arguments should one take?&#8221;.</p>
<p>The obvious better answer here is to flip the default on interfaces, causing them to generate constructors by default unless turned off with <code>[NoConstructor]</code> attributes or specified as <code>partial</code> interfaces (i.e., mixins or traits).</p>
<p>Cameron McCormack who is heading up the WebIDL effort <a href="http://twitter.com/#!/heycam/status/118784862164484096">tweeted in response to my exasperation</a> that:</p>
<blockquote><p>I think a &#8220;W3C Web API design guidelines&#8221; document would be a perfect place for such a recommendation.</p></blockquote>
<p>For serious? Such a document might be useful (and I&#8217;m working on something that might pass as a first draft), but what&#8217;s the argument against flipping the default here? This isn&#8217;t a dissent on the facts of the situation: most WebIDL &#8220;interfaces&#8221; that are exposed to JS are things that could be easily <code>new</code>&#8216;d up to useful ends. Most specs flub this in spectacular style. Most spec authors seem entirely ignorant of the problem and the design language of WebIDL continues to lead down a primrose copy-and-paste path that has little overlap with sanity. So why punt the decision? And why did it take and act of coordination with TC39 to get the prototype thing fixed?</p>
<h3>And Why Are We Having This Discussion Anyway?</h3>
<p>WebIDL, for all of its virtues, is deeply confused.</p>
<p>If you&#8217;re reading any of the stuff in the HTML5 spec that&#8217;s describing its API this way, it&#8217;s hard to see how it would have any sane relationship to JavaScript. Sure, you could argue that there might be other languages that matter, other languages for which you&#8217;d need to be able to generate some API, but none of them rise to anything like the importance of JavaScript. It <em>is</em> the programming language of the web, so if WebIDL has any animating force at all, it&#8217;s JS. Then there&#8217;s the &#8220;accident of history&#8221; aspect. Early DOM was specified as a form of IDL in part because there was some expectation that other languages would need to consume it and IDL was how C++ hackers (who still make up the entire set of people working on browser engines) are/were comfortable in describing their FFIs thanks to the legacy of COM/CORBA. <a href="http://www.w3.org/TR/2011/WD-WebIDL-20110927/#java-binding">Hilarious examples of multi-language-ism still persist in the WebIDL spec</a> for no apparent reason whatsoever, warping the entire design around the altar of an ideal that is either quixotic or vestigial depending on which argument you give more weight. </p>
<p><a href="http://lists.w3.org/Archives/Public/public-script-coord/2011JulSep/thread.html#msg114">Since the debate was re-kindled thanks to a debate at a TC39 meeting in July</a>, I&#8217;ve been on the receiving end of more than one webdev&#8217;s rant about DOM&#8217;s JS incoherence, generally taking the form:</p>
<blockquote><p>Why the *#!*?^@$ isn&#8217;t DOM just #@!*@ing specified in JavaScript?</p></blockquote>
<p>To be honest, I have no answer aside from pointing to the IDL history, the fact that browser hackers don&#8217;t tend to write JS so don&#8217;t feel the pain, and noting that WebIDL <em>is</em> better in some important ways. Certainly these interfaces <em>could</em> be specified in a subset of JS with annotations for where native behavior is required. But their larger lament has merit too: seamlessness with JS is the bar WebIDL should be judged by. I.e. does it help spec authors do the right thing by JS devs? Or does it lead them down paths that make their generated APIs stick out like sore thumbs, full of anti-social/alien behavior such that you can&#8217;t think of them as &#8220;regular&#8221; JS?</p>
<p>Yes, constructors are only one minor step toward reaching this aspiration, but the fact that WebIDL has gotten to last-call without a reasonable solution to them speak volumes. If WebIDL <em>isn&#8217;t</em> animated by the need of JS developers, it would be good if that could be loudly called out somewhere so that the community can have the spirited debate that this point demands. If it is, can we please get on discussing how best to ensure that most &#8220;interfaces&#8221; generate constructors and stop punting?</p>
<p>Either way, WebIDL isn&#8217;t done yet.</p>
<p><b>Update:</b> It occurred to me, as part of the discussion in the comments, that the provision against <code>new</code> with a class or type of any type is completely non-sensical in JS, as is the lack of <code>call()</code> and <code>apply()</code> methods on them. Idiomatic subclassing requires that the mixin-style be available, which uses <code>ClassName.call(this)</code>. This is what you&#8217;d do with things that are &#8220;virtual&#8221; or &#8220;partial&#8221; interfaces if you&#8217;re describing them in actual JS. And there&#8217;s no real problem with folks <code>new</code>-ing them up. Doesn&#8217;t happen, doesn&#8217;t matter. Strong restrictions against it are, to quote Andrew DuPont, anti-social. Long story short: <b><em>there is absolutely no reason whatsoever to disable construction on any WebIDL interface. It&#8217;s deeply non-sensical from the JavaScript perspective.</em></b></p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2011/10/real-constructors-webidl-last-call/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Half Lives</title>
		<link>http://infrequently.org/2011/03/half-lives/</link>
		<comments>http://infrequently.org/2011/03/half-lives/#comments</comments>
		<pubDate>Wed, 09 Mar 2011 16:04:02 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1616</guid>
		<description><![CDATA[I&#8217;m headed to Austin soon for spring break SxSWi, and this year I&#8217;m lucky and grateful to be representing Chrome on the always-packed browser panel (more usable Lanyrd talk page here). The context for this year&#8217;s panel is interesting to me &#8212; a couple of years into a renewed era of browser competition, users have [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m headed to Austin soon for <del>spring break</del> SxSWi, and this year I&#8217;m lucky and grateful to be <a href="http://schedule.sxsw.com/events/event_IAP7286">representing Chrome on the always-packed browser panel</a> (more usable <a href="http://lanyrd.com/">Lanyrd</a> talk page <a href="http://lanyrd.com/2011/sxsw/scrxm/">here</a>). The context for this year&#8217;s panel is interesting to me &#8212; a couple of years into a renewed era of browser competition, users have more choice but developers are still struggling with the same landscape, even as HTML5 starts to materialize as the platform of choice for <em>most</em> apps &#8212; even the ones wrapped up in native wrappers to jump the various app-store-form distribution hurdles.</p>
<p>It&#8217;s good to see <a href="http://ie6countdown.com/">MSFT belatedly trying to put IE6 out to pasture</a>, but what about IE 7? Or 8? Lets take stock of where we really are and where we&#8217;re likely to be in the next couple of years. First, remember that there&#8217;s no IE 9 for Windows XP &#8212; an OS that&#8217;s currently the most popular in the world &#8212; and no matter what happens with IE 6, IE 8 is the end of the upgrade road for XP. Unless you think half of the world&#8217;s computers will be replaced/upgraded in the next couple of years, it seems likely that IE 8 will be with us for the foreseeable future.</p>
<p>And what about the folks who <em>do</em> get IE 9? Well, so far, there&#8217;s nothing to make me believe that the uptake rate will be anything better than the IE 8 transition; a process which has taken 2 years to give ~30% of the market the latest version. If anything, we should expect that rate to be retarded somewhat by the XP hurdle.</p>
<p>MSFT&#8217;s browser replacement rates bear understanding because they&#8217;re the most popular and suffer from the longest half-lives. That is to say, the time it takes for an old version of IE to decay in the wild is much, much higher than for other browsers. Some part of this is surely due to sheer market share, but not all of it. The XP hurdle, for instance, is a form of structural drag on uptake rates &#8212; a flaw that browsers that aren&#8217;t tightly tied to OSes don&#8217;t suffer from. For web developers, I dare say that half-life of popular browsers matters much, much more than the current or trending market share since it&#8217;s predictive of our potential for browser improvement in the near future. It&#8217;s one thing to get the new shiny, but how long will it take you to install it? If the shiny is old and dingy by the time it&#8217;s in place, what good is that? It&#8217;s this lens that makes browser market share stats interesting to me; i.e., what percentage of the web&#8217;s users will get the new features soonest? &#8216;Cause those are the folks we can start building super compelling content for.</p>
<p>The average half-life of the majority of browsers in the wild also gates the rate of progress in standards. When the process is working well, bugs in browsers or pre-standards implementations of features aren&#8217;t a permanent features of the landscape. Instead, they&#8217;re the understandable and inevitable result of a process that prioritizes implementation experience and iteration over raw compliance with an academic spec that may or may not actually get it right on the first go &#8217;round. But that iterative, feedback-rich process only works when browsers iterate quickly and web developers can target the future without thinking so hard about the past, else progress simply turns into something to resent and distrust. That&#8217;s good for no one, and a shorter half-life is the key to making progress more than just a spec-tease.</p>
<p>I&#8217;m personally hopeful that when IE 9 is finally RTM&#8217;d, that it includes some provisions for shortening its life expectancy in the ways that Chrome and Firefox have through aggressive auto-updating. Getting IE 9 out to the world will be a good thing, but only if it happens quickly and if IE 10 can follow it even faster.</p>
<p>There&#8217;s obviously a lot more to talk about at the browser panel &#8212; <a href="http://chrome.blogspot.com/2011/03/speedier-simpler-and-safer-chromes.html">Chrome 10 just launched with Crankshaft</a>, for instance &#8212; but the fact that nearly every Chrome user will have those improvements <em>this week</em> and that if you&#8217;re building a Chrome Web Store app, you&#8217;ll get to target those improvements nearly instantly seems like the biggest, most interesting change from where we were just a couple of years ago.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2011/03/half-lives/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>&#8220;But IE 9 Is Just Around The Corner&#8230;&#8221;</title>
		<link>http://infrequently.org/2010/09/but-ie-9-is-just-around-the-corner/</link>
		<comments>http://infrequently.org/2010/09/but-ie-9-is-just-around-the-corner/#comments</comments>
		<pubDate>Fri, 24 Sep 2010 18:03:46 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[chrome]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[chromeframe]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1462</guid>
		<description><![CDATA[The single most frustrating thing for me as a web developer is the incredible disconnect between day-to-day development and the shiny, shiny stuff showing up in HTML5 and modern browsers. It&#8217;s made all the more frustrating by bold pronouncements from any (every?) vendor about how much more awesome the web will be thanks to the [...]]]></description>
			<content:encoded><![CDATA[<p>The single most frustrating thing for me as a web developer is the incredible disconnect between day-to-day development and the shiny, shiny stuff showing up in HTML5 and modern browsers. It&#8217;s made all the more frustrating by bold pronouncements from any (every?) vendor about how much more awesome the web will be thanks to the shiny stuff their upcoming release. The reality for web developers is that those features <em>won&#8217;t matter on a relevant time-scale</em>. Not your next project. Not your next 5 projects. No, the lag today between new features and when you can use them might as well be measured in geologic time.</p>
<p>How bad is it? The next time you read some tech journalist write about how some new browser version is just around the corner and how it&#8217;ll make everything better, remember that:</p>
<ul>
<li><a href="http://marketshare.hitslink.com/operating-system-market-share.aspx?qprid=10">50+% of Windows users are on XP</a> a <a href="http://en.wikipedia.org/wiki/Windows_7">year after Windows 7 shipped</a> and <a href="http://en.wikipedia.org/wiki/Windows_Vista">3.5 years since Vista shipped</a></li>
<li>Windows XP will be supported until <em>2014</em>, giving organizations on XP extra breathing room to limp along on IE 6-8</li>
<li><a href="http://www.msnbc.msn.com/id/39235363/ns/technology_and_science-tech_and_gadgets/">There will be no IE 9 for Windows XP</a></li>
<li>After something like 4 years of MSFT urging customers in the strongest possible language to get off of IE 6, it still has <a href="http://marketshare.hitslink.com/browser-market-share.aspx?qprid=3">16%</a> of the market, and it&#8217;s not falling nearly fast enough. At the current 0.75%/month dropoff, we&#8217;re looking at 20+ more months of IE 6. At this rate, kids born today will be walking and maybe even talking by the time we can write IE 6 into the history books.</li>
</ul>
<p>The goal here isn&#8217;t to drive you to drink, but to call out the dichotomy between when <em>users get features</em> and when <em>developers can address features</em>. For users, things tend to get better as soon as you pick up a new browser. Developers have to wait until <em>every user</em> makes that sort of choice. Said differently, users can benefit from the bleeding edge but developers are beholden to the late adopters.</p>
<p>We should cut tech journalists and users a <em>little</em> slack, though; in a world without adoption friction, the launch of a new feature would translate directly into the sort of &#8220;now you can build sites and apps with awesome thing X&#8221;. The instinct to believe that&#8217;s how it should be is spot on. But that&#8217;s observably not how the world works. Don&#8217;t believe the hype. New browsers alone haven&#8217;t fixed the problem so far, so what makes us think they will in future? No vendor wants to talk about their last version, but for web developers stuck in the trenches, that <em>all</em> there is to talk about. That&#8217;s where the pain is, after all, and counting on browser upgrades to fix the problem quickly isn&#8217;t working well enough. Chrome&#8217;s aggressive auto-update feature is changing the way things will work in future, but for now we&#8217;re still stuck in the slow-upgrade dynamic.</p>
<p>We need a <a href="http://code.google.com/chrome/chromeframe/">Plan B</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2010/09/but-ie-9-is-just-around-the-corner/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Whoa.</title>
		<link>http://infrequently.org/2009/01/whoa/</link>
		<comments>http://infrequently.org/2009/01/whoa/#comments</comments>
		<pubDate>Mon, 12 Jan 2009 23:38:00 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[dojo]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[palm]]></category>
		<category><![CDATA[pre]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=867</guid>
		<description><![CDATA[Via Dion, Palm&#8217;s new Mojo framework for the Pre is based on Dojo! As far as I know, it was a total surprise to the Dojo community (myself included). I can&#8217;t wait to get started writing apps for this thing and see what device APIs Palm has surfaced.]]></description>
			<content:encoded><![CDATA[<p><a href="http://ajaxian.com/archives/palm-mojo-uses-dojo-view-the-source">Via Dion</a>, Palm&#8217;s new <a href="http://developer.palm.com/">Mojo</a> framework for the <a href="http://www.palm.com/us/products/phones/pre/index.html">Pre</a> is based on Dojo!</p>
<p>As far as I know, it was a total surprise to the Dojo community (myself included). I can&#8217;t wait to get started writing apps for this thing and see what device APIs Palm has surfaced.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2009/01/whoa/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>OSCON 2009 Call For Papers Is Open!</title>
		<link>http://infrequently.org/2009/01/oscon-2009-call-for-papers-is-open/</link>
		<comments>http://infrequently.org/2009/01/oscon-2009-call-for-papers-is-open/#comments</comments>
		<pubDate>Sun, 11 Jan 2009 21:35:20 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[opensource]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[oscon]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=865</guid>
		<description><![CDATA[I&#8217;m a bit tardy on this, but the OSCON 2009 Call For Papers is now open. In the past couple of years the shift from desktop-centric to a more web-centric OSCON has continued to make the conference useful and engaging, and great work on topics like JavaScript/Ajax performance, Dojo, Comet, and many of the emerging [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a bit tardy on this, but the OSCON 2009 Call For Papers <a href="http://en.oreilly.com/oscon2009/public/cfp/57">is now open</a>.</p>
<p>In the past couple of years the shift from desktop-centric to a more web-centric OSCON has continued to make the conference useful and engaging, and great work on topics like JavaScript/Ajax performance, Dojo, Comet, and many of the emerging back-end bits of infrastructure that make it all go have made my yearly trip to Portland worthwhile.</p>
<p>Great talks have gotten lost from the JavaScript/web track in years past because they&#8217;ve missed the submission deadline, so if you&#8217;re hacking on something fascinating, now&#8217;s the time to get that proposal in.  Make sure you flag it with the right track when you submit (javascript, ajax, web, or whatever they&#8217;re calling it this year), and don&#8217;t hesitate to ping me if you&#8217;re unsure about whether or not your talk got slotted correctly for the review process.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2009/01/oscon-2009-call-for-papers-is-open/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Census 2: More Than Just A Pretty Graph</title>
		<link>http://infrequently.org/2008/12/census-2-more-than-just-a-pretty-graph/</link>
		<comments>http://infrequently.org/2008/12/census-2-more-than-just-a-pretty-graph/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 15:59:07 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dhtml]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[benchmarks]]></category>
		<category><![CDATA[flex]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=849</guid>
		<description><![CDATA[Numbers without context are lies waiting to be repeated.]]></description>
			<content:encoded><![CDATA[<p>Benchmarks are hard, particularly for complex systems. As a result, the most hotly contested benchmarks tend not to be representative of what makes systems faster for real users. Does another 10% on <a href="http://www.tpc.org/default.asp">TPC</a> really matter to most web developers? And should we really pay any attention to how <em>any</em> JS VM does on <a href="http://shootout.alioth.debian.org/">synthetic language benchmarks</a>?</p>
<p>Maybe.</p>
<p>These things matter only in regards to how well they represent end-user workloads and how trustworthy their findings are. The first is much harder than the second, and end-to-end benchmarking is pretty much the only way to get there. As a result, sites like <a href="http://www.tomshardware.com/">Tom&#8217;s Hardware</a> focus on application-level benchmarks while still publishing &#8220;low level&#8221; numbers. Venerable test suites like <a href="http://en.wikipedia.org/wiki/SPECint">SPECint</a> have even moved toward running &#8220;full stack&#8221; style benchmarks which may emphasize a particular workload but are broad enough to capture the wider system effects which matter in the real world.</p>
<p>Marketing departments also like small, easily digestible, whole numbers. Saying something like &#8220;200% Faster!&#8221; sure sounds a lot better than &#8220;on a particular test which is part of a larger suite of tests, our system ran in X time vs. Y time for the competitor&#8221;. Both may be true, but the second statement gives you some context. Preferably even that statement would occur above an actual table of numbers or graphs. Numbers without context are lies waiting to be repeated.</p>
<p>With all of this said, <a href="http://www.jamesward.com/blog/">James Ward&#8217;s</a> <a href="http://jamesward.com/census">Census</a> benchmark makes a valiant stab at a full-stack test of data loading and rendering performance for RIA technologies. Last month <a href="http://dojotoolkit.org/2008/11/05/flash-flex-versus-open-web-ajax">Jared</a> dug further into the numbers and found the methodology wanting, but given some IP issues couldn&#8217;t patch the sources himself. Since I wasn&#8217;t encumbered in the same way I thought I might as well try my hand at it, but after hours of attempting to get the <a href="http://sourceforge.net/projects/flexapps">sources to build</a>, I finally gave up and decided to re-write the tests. The result is <a href="http://textterm.com/census.html">Census 2</a>.</p>
<p><a href="http://textterm.com/census.html"><img src="http://alex.dojotoolkit.org/wp-content/uploads/2008/12/census2_main_small.png" style="border: 0px;"/></a></p>
<p>There are several goals of this re-write:</p>
<ul>
<li><b>Fairness.</b> Tests need to be run multiple times for them to be representative in any way. Likewise, systems not being directly tested need to be factored out as much as possible. C2 does this by reducing the number of dependencies and running tests (at least) 5 times and discarding outliers before reporting an average. I&#8217;ve also worked to make sure that the tests put the best foot forward for all of the tested technologies.</li>
<li><b>Hackability.</b> Benchmarks like Census serve first as a way for decision makers to understand options but second as a way for developers to know how they&#8217;re doing. Making it trivial to add tests helps both audiences.</li>
<li><b>Portability.</b> The test suite should run nearly everywhere with a minimum of setup and fuss. This ensures that the largest numbers of people can benefit from the fairness and hackability of the tests.</li>
</ul>
<p>The results so far have been instructive. On smaller data sets HTML wins hands-down for time-to-render, even despite its disadvantage in over-the-wire size. For massive data sets, pagination saves even the most feature-packed of RIA Grids, allowing the Dojo Grid to best even XSLT and a more compact JSON syntax. Of similar interest is the delta between page cycle times on modern browsers vs their predecessors. Flex can have a relatively even performance curve over host browsers, but the difference between browsers today is simply stunning.</p>
<p>Given the lack of an out-of-the-box paginating data store for Flex, RIAs built on that stack seem beholden to either Adobe&#8217;s <a href="http://www.adobe.com/products/livecycle/dataservices/">LCDS licensing</a> or are left to build ad-hoc pagination into apps by hand to get reasonable performance for data-rich business applications. James Ward has already exchanged some mail with me on this topic and it&#8217;s my hope that we can show how to do pagination in Flex without needing LCDS in the near future. </p>
<p>The tests aren&#8217;t complete. There&#8217;s still work to do to get some of the SOAP and AMF tests working again. If you have ideas about how to get this done w/o introducing a gigantic harball of a Java toolchain, I&#8217;m all ears. Also on the TODO list is an <a href="http://code.google.com/appengine/">AppEngine app</a> for recording and analyzing test runs so that we can say something interesting about performance on various browsers. </p>
<p>Census 2 is very much <a href="http://code.google.com/p/census2/">an open source project</a> and so if you&#8217;d like to get your library or technology tested, please don&#8217;t hesitate to send me mail or, better yet, attach patches to the <a href="http://code.google.com/p/census2/issues/list">Bug Tracker</a>.</p>
<p><b>Update:</b> I failed to mention earlier that one of the largest changes in C2 vs. Census is that we report <em>full page cycle times</em>. Instead of reporting just the &#8220;internal&#8221; timings of an RIA which has been fully boostrapped, the full page times report the full time from page loading to when the output is responsive to user action. This keeps JavaScript frameworks (or even Flex) from omitting from the reports the price that users pay to download their (often sizable) infrastructure. There&#8217;s more work to do in reporting overall sizes and times (&#8220;bandwidth&#8221; numbers don&#8217;t report gzipped sizes, e.g.), but if you want the skinny on real performance, scroll down to the red bars. That&#8217;s where the action is.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/12/census-2-more-than-just-a-pretty-graph/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Notes To A Future Self: Getting Productive On WinXP</title>
		<link>http://infrequently.org/2008/12/notes-to-a-future-self-on-de-sucking-xp/</link>
		<comments>http://infrequently.org/2008/12/notes-to-a-future-self-on-de-sucking-xp/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 21:15:20 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[work]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[vim]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=844</guid>
		<description><![CDATA[Windows XP is truly a horrid desktop OS, particularly if you&#8217;re a programmer. The default install contains roughly nothing useful, and even getting a development environment going requires grabbing the likes of cygwin, Visual Studio, and a zillion patches from Microsoft. The truly dispiriting thing, though, is how badly cmd.exe still sucks. I fully admit [...]]]></description>
			<content:encoded><![CDATA[<p>Windows XP is truly a horrid desktop OS, particularly if you&#8217;re a programmer. The default install contains roughly nothing useful, and even getting a development environment going requires grabbing the likes of cygwin, Visual Studio, and a zillion patches from Microsoft.</p>
<p>The truly dispiriting thing, though, is how badly cmd.exe still sucks. I fully admit that my personal programming proclivities are not normal, but to be reasonably productive I need a Unix-like shell, a terminal that works (can be resized, has reasonable VT100 emulation, etc.), and the ability to fix the &#8220;Caps Lock&#8221; key to do the right thing &ndash; namely, have it fire the &#8220;Ctrl&#8221; key instead. This is all relatively straightforward to do on Linux and OS X. Here&#8217;s how I got it done with Windows:</p>
<h4>Do the MSFT Patch Dance</h4>
<p>Make coffee?</p>
<h4>Install Cygwin</h4>
<p>We&#8217;ve all <a href="http://www.cygwin.com/">done it a thousand times</a>. This&#8217;ll make 1001. It&#8217;s kind of comforting that the Cygwin home page hasn&#8217;t changed perceptibly in nearly a decade.</p>
<h4>Get SharpKeys</h4>
<p>Instead of fugly registry hacks, <a href="http://www.randyrants.com/2006/07/sharpkeys_211.html">SharpKeys</a> allows you to map the dreaded and useless &#8220;Caps Lock&#8221; key to something actually useful. If your key-mapping preferences swing some other way, SharpKeys can likely handle that too. Not sure why it&#8217;s not built into Windows, frankly.</p>
<h4>Set Up Puttycyg</h4>
<p>Having cygwin is nice, but having a terrible shell with Cygwin? Not so nice. Enter <a href="http://code.google.com/p/puttycyg/">Puttycyg</a>, a small hack on the venerable <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/">Putty</a> SSH client for windows that provides an option to launch a local Cygwin session in lieu of connecting to another system. </p>
<p>Once I extracted it and ensured the Puttycyg directory was in my windows PATH, I created a desktop shortcut to the <code>putty.exe</code> included in the distribution and configured the shortcut (right-click) to read:</p>
<pre>
"C:\Documents and Settings\slightlyoff\Desktop\puttycyg\putty.exe" -cygterm -
</pre>
<p>And then set the &#8220;Shortcut key:&#8221; to be:</p>
<pre>
Ctrl + Alt + T
</pre>
<p>Now, whenever I want a fully functional shell from my desktop, I just hit that key combination and it All Works (TM).</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/12/notes-to-a-future-self-on-de-sucking-xp/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>delegate(), delegate(), delegate()</title>
		<link>http://infrequently.org/2008/10/delegate-delegate-delegate/</link>
		<comments>http://infrequently.org/2008/10/delegate-delegate-delegate/#comments</comments>
		<pubDate>Fri, 10 Oct 2008 23:50:01 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[dhtml]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[boodman]]></category>
		<category><![CDATA[crockford]]></category>
		<category><![CDATA[delegate]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=786</guid>
		<description><![CDATA[My MBP batteries keep dying after about a year (each). I usually have 2 that I tote around with me, and each tends to be good for 1.5-2hrs of actual work. This means that I tend not to be able to work through a cross-country flight, and particularly not if I need a VM for [...]]]></description>
			<content:encoded><![CDATA[<p>My MBP batteries keep dying after about a year (each). I usually have 2 that I tote around with me, and each tends to be good for 1.5-2hrs of actual work. This means that I tend not to be able to work through a cross-country flight, and particularly not if I need a VM for anything (which is most of the time). I think that if Apple <em>does</em> <a href="http://www.macrumors.com/2008/10/09/apple-invites-media-to-notebook-event-october-14th/">rev the MBP&#8217;s on the 14th</a>, the things I&#8217;d pay for boil down to &#8220;more memory and much longer battery life&#8221;. The 5+ hour flight to <a href="http://ajaxexperience.techtarget.com/html/index.html">TAE</a> then provided a short window to do work in before I retreated to watching episodes of <a href="http://www.colbertnation.com/">The Colbert Report</a> on my phone. Knowing that i wouldn&#8217;t be able to work the whole time, I brought a copy of <a href="http://www.iam.unibe.ch/~scg/Archive/Papers/Duca06bTOPLASTraits.pdf">a great paper on Traits</a>. The paper got me thinking a lot about <code><a href="http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.declare">dojo.declare()</a></code> and <code><a href="http://api.dojotoolkit.org/jsdoc/dojo/1.2/dojo.delegate">dojo.delegate()</a></code>.</p>
<p>Today, Dojo&#8217;s <code>delegate()</code> function is a straightforward implementation of the <a href="http://blog.youngpup.net/">Boodman</a>/<a href="http://www.crockford.com/">Crockford</a> delegation pattern which Doug calls &#8220;beget&#8221; and which ES 3.1 will refer to as <code>Object.create</code>:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">dojo.<span style="color: #660066;">delegate</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// boodman/crockford delegation w/ cornford optimization</span>
    <span style="color: #003366; font-weight: bold;">function</span> TMP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        TMP.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> obj<span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> TMP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>props<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            dojo._mixin<span style="color: #009900;">&#40;</span>tmp<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> tmp<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Object</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This function returns a new object which looks to the old object for things it does not itself have. Imagine an object <code>foo</code> which contains pithy truisms:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
  science<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rocks!&quot;</span><span style="color: #339933;">,</span>
  learning<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;is how you know you're alive&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>We now want to promigulate our opinions, so we can delegate the responsibility of forming them:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> bar <span style="color: #339933;">=</span> dojo.<span style="color: #660066;">delegate</span><span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
  testify<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    console.<span style="color: #660066;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;science &quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">science</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;and learning&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">learning</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now, our <code>bar</code> object can change its mind independently of <code>foo</code>, but until it does, it&#8217;ll behave as though <code>foo</code>&#8216;s views are its own:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">bar.<span style="color: #660066;">testify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// outputs: &quot;science rocks and learning is how you know you're alive&quot;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// bar refines its opinion</span>
bar.<span style="color: #660066;">science</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;is a process&quot;</span><span style="color: #339933;">;</span> 
bar.<span style="color: #660066;">learning</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;requires humility&quot;</span><span style="color: #339933;">;</span>
foo.<span style="color: #660066;">science</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;rocks!&quot;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// still true</span>
&nbsp;
bar.<span style="color: #660066;">testify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// outputs: &quot;science is a process and learning requires humility&quot;</span></pre></div></div>

<p>But what about when the chain gets deeper? The fact that <code>bar</code> can&#8217;t &#8220;see&#8221; <code>foo</code>&#8216;s values via <code>this</code> isn&#8217;t much of a problem when the hierarchy isn&#8217;t very long, but if you&#8217;re specializing a behavior or complex interaction, making it possible to get at the parent&#8217;s values for properties and methods becomes more pressing.</p>
<p>Neil has previously <a href="http://www.sitepen.com/blog/2008/03/16/are-you-sure-you-should-be-subclassing-that/">written about lightweight subclassing</a>, but for as good as it its, it doesn&#8217;t get us all the way there either. In regular OO-style languages, the inheritance system gives you an out via a &#8220;super&#8221; keyword or convention. This type of property shadowing-with-exceptions is a huge boon to composition in class-based languages, but it&#8217;s not the whole story. Indeed, the Traits paper was all about the shortcomings of this special-purpose mechanism. What we want for both long delegation chains and long inheritance hierarchies is a more general system; in essence a way to say &#8220;I want to control how things are shadowed and which ones an item points at in each level of the hierarchy&#8221;.</p>
<p>What if we could make <code>delegate()</code> savvy of this type of indirection? Here&#8217;s my quick prototype:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">delegate <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> tobj <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> TMP <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        TMP.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> obj<span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> TMP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>props<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> remaps <span style="color: #339933;">=</span> props<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>remaps<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">delete</span> props<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #000066; font-weight: bold;">in</span> remaps<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>tobj<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">===</span> undefined <span style="color: #339933;">||</span> tobj<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> remaps<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>remaps<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                            <span style="color: #006600; font-style: italic;">// support hiding via null assignment</span>
                            tmp<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
                            <span style="color: #006600; font-style: italic;">// alias the local version away</span>
                            tmp<span style="color: #009900;">&#91;</span>remaps<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> obj<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
            dojo.<span style="color: #660066;">mixin</span><span style="color: #009900;">&#40;</span>tmp<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">return</span> tmp<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Object</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>This new version of <code>delegate()</code> accepts a specially named &#8220;->&#8221; property in the list of items to add to the destination object. Items in this list can either &#8220;shadow null&#8221; (hide entirely) the parent&#8217;s property or can provide a new name for it, assuming of course that the new object will also have a property of that name. Here&#8217;s a quick example of &#8220;->&#8221; at work with our previous example. This time, <code>foo</code> also has a &#8220;testify&#8221; method that we&#8217;d like <code>bar</code> to be able to control without having to copy the implementation:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    science<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rocks!&quot;</span><span style="color: #339933;">,</span>
    learning<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;is how you know you're alive&quot;</span><span style="color: #339933;">,</span>
    testify<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;science &quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">science</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;and learning&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">learning</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> bar <span style="color: #339933;">=</span> delegate<span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;testify&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;grampsSays&quot;</span> <span style="color: #006600; font-style: italic;">// maps foo's &quot;testify&quot; to bar's &quot;grampsSays&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    testify<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">science</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">learning</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">grampsSays</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// call the re-named &quot;testify&quot;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
            console.<span style="color: #660066;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;this object is strikingly ignorant&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
bar.<span style="color: #660066;">testify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// outputs: &quot;science rocks and learning is how you know you're alive&quot;</span>
bar.<span style="color: #660066;">science</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
bar.<span style="color: #660066;">testify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// outputs: &quot;this object is strikingly ignorant&quot;</span></pre></div></div>

<h4>That New Object Smell</h4>
<p>The last missing piece of the hierarchy pie here is that there&#8217;s no initializer for the objects which come from a delegation. A simple addition of some property detection code to look for an initializer can easily handle that:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">delegate <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> tobj <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #003366; font-weight: bold;">var</span> TMP <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>obj<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// boodman/crockford delegation w/ cornford optimization. </span>
&nbsp;
        TMP.<span style="color: #660066;">prototype</span> <span style="color: #339933;">=</span> obj<span style="color: #339933;">;</span>
        <span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> TMP<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>props<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            <span style="color: #003366; font-weight: bold;">var</span> remaps <span style="color: #339933;">=</span> props<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>remaps<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                <span style="color: #000066; font-weight: bold;">delete</span> props<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                <span style="color: #006600; font-style: italic;">// like dojo.mixin(), except w/o key/key mapping</span>
                <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> x <span style="color: #000066; font-weight: bold;">in</span> remaps<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                    <span style="color: #006600; font-style: italic;">// &quot;safe&quot; copy properties</span>
                    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>tobj<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">===</span> undefined <span style="color: #339933;">||</span> tobj<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">!=</span> remaps<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>remaps<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                            <span style="color: #006600; font-style: italic;">// support hiding via null assignment</span>
                            tmp<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span><span style="color: #000066; font-weight: bold;">else</span><span style="color: #009900;">&#123;</span>
                            <span style="color: #006600; font-style: italic;">// alias the local version away</span>
                            tmp<span style="color: #009900;">&#91;</span>remaps<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> obj<span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                        <span style="color: #009900;">&#125;</span>
                    <span style="color: #009900;">&#125;</span>
                <span style="color: #009900;">&#125;</span>
            <span style="color: #009900;">&#125;</span>
            dojo.<span style="color: #660066;">mixin</span><span style="color: #009900;">&#40;</span>tmp<span style="color: #339933;">,</span> props<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #006600; font-style: italic;">// support for &quot;constructor&quot; functions. The name &quot;init&quot; is arbitrary.</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">typeof</span> tmp<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;init&quot;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;function&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
            tmp.<span style="color: #660066;">init</span>.<span style="color: #660066;">call</span><span style="color: #009900;">&#40;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
&nbsp;
        <span style="color: #000066; font-weight: bold;">return</span> tmp<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// Object</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>And there we have it. A style of delegation that easily supports both Trait-like name aliasing (and null shadowing) as well as internal initializers. Since our upgraded <code>delegate</code> can handle nulling out a parent&#8217;s value for a property, we also have a straightforward way to prevent parent initializers from being called (or being called/chained &#8211; at our discretion &#8211; by a new name):</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> foo <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span>
    science<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;rocks!&quot;</span><span style="color: #339933;">,</span>
    learning<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;is how you know you're alive&quot;</span><span style="color: #339933;">,</span>
    testify<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;science &quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">science</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;and learning&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">learning</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> bar <span style="color: #339933;">=</span> delegate<span style="color: #009900;">&#40;</span>foo<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">testify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// outputs: &quot;science rocks and learning is how you know you're alive&quot;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> baz <span style="color: #339933;">=</span> delegate<span style="color: #009900;">&#40;</span>bar<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">// map away the parent's constructor</span>
    <span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">&quot;init&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;superInit&quot;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    <span style="color: #006600; font-style: italic;">// provide our own constructor</span>
    init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        console.<span style="color: #660066;">debug</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;howdy!&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">superInit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// call the super-object ctor</span>
    <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// outputs: &quot;howdy&quot;, &quot;science rocks and learning is how you know you're alive&quot;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> thud <span style="color: #339933;">=</span> delegate<span style="color: #009900;">&#40;</span>baz<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #3366CC;">&quot;-&gt;&quot;</span><span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> <span style="color: #3366CC;">&quot;init&quot;</span><span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#125;</span> <span style="color: #006600; font-style: italic;">// hide the parent ctor</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// outputs: nothing</span></pre></div></div>

<p>This form of <code>delegate</code> is likely to appear in Dojo 1.3 along with similar improvements to <code>dojo.declare()</code> to help alleviate the composition problems associated with using complex sets of mixins.</p>
<p><b>Update</b>: corrected the null-out branch and updated the text with Doug&#8217;s note that beget/delegate will be called Object.create() in 3.1.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/10/delegate-delegate-delegate/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>&#8220;Action Oriented Programming&#8221;</title>
		<link>http://infrequently.org/2008/10/action-oriented-programming/</link>
		<comments>http://infrequently.org/2008/10/action-oriented-programming/#comments</comments>
		<pubDate>Thu, 09 Oct 2008 16:40:13 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[closures]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=783</guid>
		<description><![CDATA[It&#8217;s good to be back in SF after a pretty hectic week in Boston for Dojo Developer Days and The Ajax Experience. There&#8217;s a lot to say about them, which hopefully I&#8217;ll get to in a longer post. Our first DDD event under Pete&#8216;s excellent leadership was a success and Dojo and SitePen very well [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s good to be back in SF after a pretty hectic week in Boston for Dojo Developer Days and The Ajax Experience. There&#8217;s a lot to say about them, which hopefully I&#8217;ll get to in a longer post. Our first DDD event under <a href="http://higginsforpresident.net/">Pete</a>&#8216;s excellent leadership was a success and Dojo and SitePen very well represented at the conference.</p>
<p>While in Boston, <a href="http://blog.xdraw.org/">Gavin</a> and <a href="http://www.eyelevelpasadena.com/">Jill</a>  joined a gaggle of Dojo hackers at a dinner ostensibly to mourn my birthday (thanks to Dylan and Pete for organizing!) and in the course of conversation Jill asked something along the lines of:</p>
<blockquote><p>
So why do people get so excited about closures?
</p></blockquote>
<p>Which prompted a several of us to flail and flop gasping the salt flats of analogy like fish out of polite-conversation water. After about 10 minutes of this, Jill succinctly summed it all up in the form of a question:</p>
<blockquote><p>
Oh, so it&#8217;s like &#8220;action-oriented programming&#8221;?
</p></blockquote>
<p>This is perhaps the most insightful and succinct description I have ever heard of what JavaScript is all about.</p>
<p><b>Update:</b> <a href="http://tharpo.com">Jennifer</a> just played <a href="http://blogs.wnyc.org/radiolab/2008/07/29/tell-me-a-story/">this for me</a> and it gets right to the heart of this post: the important part of doing what we do with computers, and more importantly, with the web, is to give the power of Computer Science to real people&#8230;and it starts with insights like Jill&#8217;s that build a shared way of thinking and talking about the world. It makes me sad that many programmers miss that, but when non-programmers can share in the beauty and power of code, it does a lot to make it all seem worthwhile.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/10/action-oriented-programming/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Harmony Fallout</title>
		<link>http://infrequently.org/2008/08/harmony-fallout/</link>
		<comments>http://infrequently.org/2008/08/harmony-fallout/#comments</comments>
		<pubDate>Fri, 15 Aug 2008 08:33:17 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=731</guid>
		<description><![CDATA[Lets end the silly meme that "Adobe lost" or that "Microsoft won". The game has hardly begun and it won't be settled in a standards body anyway. ]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s a lot of weirdness going on around the Harmony announcement. <a href="http://whydoeseverythingsuck.com/2008/08/ru-roh-adobe-screwed-by-ecmascript.html">This post in particular</a> tries to dig into some of the wrangling that caused the ES4/3.1 split and what the Oslo resolution &#8220;means&#8221;, but I&#8217;m afraid that much of the analysis is being done without the benefit of an inside view of the WG process.</p>
<p>At the risk of talking too much out of school, I want to set the record straight in some ways. First, let me set some facts out:</p>
<ul>
<li>ES4, <a href="http://www.ecmascript.org/es4/spec/overview.pdf">as outlined last fall</a>, was <b>not</b> ActionScript 3. <em>Major</em> changes to the semantics of Adobe&#8217;s initial contribution ensured that any truly compliant ES4 implementation from Adobe would have required many concessions, including the inclusion of a client-side compiler. ES4 without <code>eval()</code> (ala AS3) would never have cut it as a &#8220;real&#8221; ES4.</li>
<li>Adobe had not donated &#8220;ActionScript 3&#8243; to Mozilla nor Open Sourced ActionScript 3. Adobe had donated a high-performance byte-code VM which a separate front-end compiler targeted. It is absolutely possible that the Tamarin VM can and will run <em>whatever</em> syntax for the next version of JavaScript is ratified. The design of the VM is, of course, predicated upon the language semantics but lets not confuse the front-end compiler and the language that it consumes with the VM and byte-code format which it executes. The front-end compiler was not donated to Mozilla (although something similar exists in the OSS&#8217;d Flex SDK) nor does it ship inside of the Flash player today. Adobe can continue to evolve their developer languages and byte-code VMs independently so long as they never ship an <code>eval()</code> feature. Even if they do, there are other (harder to swallow) options available, but no road is cut off to Adobe which was not already long-since abandoned in other ways by the ES4 process.</li>
<li>Like Adobe, Microsoft has jumped ahead in the evolution of JavaScript via the seemingly forgotten JScript.NET. Like Adobe, Microsoft has had to come back from that position to meet the web where it really is. Microsoft now ships 3 &ndash; yes, that&#8217;s right, <em>three</em> &ndash; JavaScript-ish languages which are capable of running in a browser:
<ul>
<li>JScript (via Windows Scripting Host)</li>
<li>JScript.NET</li>
<li>JScript for the DLR (via Silverlight)</li>
</ul>
<p>Make no mistake about it, these are all separate implementations which likely share little if any code. The DLR variant is even new in the last several years. Creating a new JavaScript compiler and runtime is not an overly onerous task for MSFT and clearly not one that will take a long time should the occasion arise. What&#8217;s confusing and can likely be tied to strategic wrangling is the puzzling lack of progress in the WSH version of JScript (the one everyone uses day-to-day). Any strategic discussion of JScript as a platform needs to start from this perspective.</li>
<li>Much in ES4 was new. The gradual typing system (which I&#8217;m a big supporter of) was something of a large-scale experiment coupled with as much rigor as I&#8217;ve ever seen in a standards body in proving things out in an RI. The Class system (which I wasn&#8217;t a big supporter of) needed to marry class-based inheritance to prototypal inheritance in ways which were new. ES4 contained many good features and syntactic forms which were borrowed from other places, but as Brendan Eich has said, it was a process of synthesis plus invention. In my opinion, much of the failure of ES4 as an initiative can be traced to significant failings of ActionScript 3 <em>as a language</em>. AS3 is a Java-like language with a Java-like execution model. JavaScript is a dynamic language with a dynamic execution model. The gulf in expectations between those camps turns up in every corner of the language design. For instance: what does it mean to load new code? Are classes forever &#8220;closed&#8221; or can they be re-opened? Do you <em>really</em> need the <code>static</code> and <code>final</code> keywords? Solving these issues in the context of the old is easy. In the context of the new, it&#8217;s hard. ES4 suffered because it had to do it in a new world which no one was yet writing code for.</li>
</ul>
<p>So, lets pop up and talk about strategy for a minute. Fundamentally, very little has changed in terms of available strategic options for any of the players:</p>
<ul>
<li>MSFT can still hold the web hostage to their ailing WSH VM by continuing to ignore its performance, regardless of bug fixes and syntactic updates. Doesn&#8217;t matter if it&#8217;s amputation or debilitating arthritis, crippled is crippled. For what it&#8217;s worth, my interactions with the MSFT reps on TC39 give me no reason to believe that they won&#8217;t be improving their VM.</li>
<li>Adobe can still chose to implement a language which implements an ECMA spec. They can do this any time they damn-well please. It may not align so cleanly with their current technology roadmap, but it&#8217;s absolutely feasible and when Mozilla ships a &#8220;regular JavaScript&#8221; front-end to the Tamarin back-end, it&#8217;ll be even easier. Note that this plan can be done in parallel with AS3 evolution since Tamarin (as a VM) need not be aware of any language semantics on its own.</li>
<li>Browser vendors can still wring large speedups out of ES3 and 3.1</li>
</ul>
<p>What died here wasn&#8217;t Adobe&#8217;s attempts to &#8220;own&#8221; a spec. If there were such hopes in play, they had been quietly put down one rational, backwards compatible decision after another in the year preceding the Oslo meeting. What died was an assumption that the web can evolve without implementations being out in front of the spec. AS3 was one implementation of a JavaScript-like language that might have been a contender for crown of &#8220;the next one&#8221;, but so was JScript.NET. That neither of them &#8220;won&#8221; simply because they had been built in good faith is as true a sign as I can find that the process is working. <a href="http://blogs.adobe.com/open/2008/08/blog_entry_dated_81408_715_pm.html">Adobe gets it</a>. Lets end the silly meme that &#8220;Adobe lost&#8221; or that &#8220;Microsoft won&#8221;. The game has hardly begun and it won&#8217;t be settled in a standards body anyway. What matters &ndash; and what we all need to keep our eyes keenly trained on &ndash; is what the big implementations do in the way of compatibility, performance, and feature set once ES3.1 arrives.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/08/harmony-fallout/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>A Lovely Box For Your Toolkit</title>
		<link>http://infrequently.org/2008/07/a-lovely-box-for-your-toolkit/</link>
		<comments>http://infrequently.org/2008/07/a-lovely-box-for-your-toolkit/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 18:15:13 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[sitepen]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=686</guid>
		<description><![CDATA[I&#8217;m incredibly excited about the SitePen Dojo Toolbox AIR app that just launched. I&#8217;ve been using early versions for a couple of weeks now, and in that time it has earned a privileged place on my desktop. Being able to make local builds without delving to the command line is something that I&#8217;ve wanted to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.sitepen.com/labs/toolbox/"><img src="http://www.sitepen.com/blog/wp-content/uploads/2008/07/launcherexpanded.png" style="width: 70px; padding-right: 15px; border: none;" align="left" /></a></p>
<p>I&#8217;m incredibly excited about the <a href="http://www.sitepen.com/blog/2008/07/08/dojo-toolbox-first-look/">SitePen Dojo Toolbox</a> <a href="http://www.adobe.com/products/air/">AIR</a> app that just launched. I&#8217;ve been using early versions for a couple of weeks now, and in that time it has earned a privileged place on my desktop. Being able to make local builds without delving to the command line is something that I&#8217;ve wanted to be able to show new Dojo users for <em>years</em> and this tool finally makes it easy. There&#8217;s more work to do around configuring the profiles themselves, but the new tool demystifies many of the build configuration options significantly. Having a searchable API viewer available is also a godsend. Huge props to the team that put it together!</p>
<p><b>Edit:</b> I forgot to note one of my favorite parts of the project, namely that because the Dojo build system is written in JavaScript (thanks to <a href="http://tagneto.blogspot.com/">James Burke</a>&#8216;s awesome work), the build system in the Toolbox doesn&#8217;t require Java. Instead, SitePen was able to port the few Rhino dependencies in the build tool to work with the native JavaScript engine in AIR. It&#8217;s a minor thing, but it speaks to the excellent engineering behind Dojo&#8217;s tooling and the power of having actual web-native technologies inside a desktop app.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/07/a-lovely-box-for-your-toolkit/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Zend + Dojo: More Than The Sum Of The Parts</title>
		<link>http://infrequently.org/2008/05/zend-dojo-more-than-the-sum-of-the-parts/</link>
		<comments>http://infrequently.org/2008/05/zend-dojo-more-than-the-sum-of-the-parts/#comments</comments>
		<pubDate>Thu, 22 May 2008 21:56:55 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[integrations]]></category>
		<category><![CDATA[zend]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=671</guid>
		<description><![CDATA[In the past several months, more and more integrations of Dojo with server frameworks have been shipping, and we couldn&#8217;t be happier about the Zend + Dojo integration that was announced yesterday. Fundamentally the Dojo and Zend teams really &#8220;get&#8221; each other. Both are deep packages that give you an opinion about how best to [...]]]></description>
			<content:encoded><![CDATA[<p>In the past several months, <a href="http://code.google.com/p/d-rails/">more</a> and <a href="http://ajaxian.com/archives/spring-webflow-20-javascript-module-released">more</a> integrations of Dojo with server frameworks have been shipping, and we couldn&#8217;t be happier about the <a href="http://andigutmans.blogspot.com/2008/05/dojo-and-zend-framework-partnership.html">Zend + Dojo integration that was</a> <a href="http://ajaxian.com/archives/dojo-and-zend-framework-integratation-released">announced yesterday</a>.</p>
<p>Fundamentally the Dojo and Zend teams really &#8220;get&#8221; each other. Both are deep packages that give you an opinion about how best to do something but also all of the tools you&#8217;ll need to make it work at scale. The &#8220;use at will&#8221; term that the Zend folks use made immediate sense to us. Like Dojo, Zend doesn&#8217;t saddle you with more than you&#8217;re <em>really going to need</em> up-front, but at the same time, when you need something awesome which is well tested and integrated, it&#8217;s right there. No digging around on google to find a &#8220;plug in&#8221; that will get you where you want to go&#8230;both Zend and Dojo give you a full stack of great components to work with out of the box.</p>
<p>There have been some questions on IRC today about why Dojo and not something else, and we know that the Zend folks are committed to continuing to allow Zend to work with other frameworks as well and we fully support them in that. There <em>seem</em> to be lots of choices of Ajax frameworks which Zend could have integrated, but when you look at the requirements of serious products which need to ship tested solutions to really hard problems, the field whittles down very fast. In response to the needs of our users, both Zend and Dojo take seriously our responsibilities to provide integrated, high-quality, unambiguously licensed products that will let user scale both up <em>and</em> down. Key to this is understanding the full spectrum of use-cases, informed by past experience, and striking a balance between enterprise-ready features and close-to-the-metal primitives. The Zend Framework has a larger view of the server-side than Dojo can, and as a result there are new opportunities to optimize and improve the user experience for all classes of users through this integration. This isn&#8217;t just about including some scripts on a page, this integration is about improving user and developer experiences, and both Dojo and Zend bring a lot to the table which can compliment the other. Dojo&#8217;s strengths in progressive enhancement, packaging, localization, and accessibility all have obvious allegories in the ZF world where a complete integration can more value <em>based on what developers are already doing</em>. All of those features of Dojo will work better when the server-side knows how to &#8220;hint&#8221; things for the client and work with, not against, the client to deliver better experiences.</p>
<p>I&#8217;m perhaps most excited about the data-driven opportunities in the Zend/Dojo integration. Dojo&#8217;s data infrastructure is second-to-none, and the design of the <code>dojo.data</code> and <code>dojo.rpc</code> layers provide Zend Framework integration the ability to take advantage of systems like the incredible Dojo Grid and the client-side charting package. There&#8217;s more to look forward to, and figuring it out together with the folks at Zend is a great opportunity for the Dojo community.</p>
<p>Pete Higgins and I will be participating in <a href="http://www.zend.com/en/company/news/event/webinar-zend-framework-project-partners-with-the-dojo-ajax-toolkit">next Tuesday&#8217;s</a> discussion with a broader chunk of the Zend Framework world, but until then (and long after) we&#8217;ll be hanging out in the <code>#dojo</code> and <code>#zftalk</code> channels on <code>irc.freenode.net</code>. We&#8217;re looking forward to working more with the ZF community to build great experiences, and are hugely excited about the direction things are already taking!</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/05/zend-dojo-more-than-the-sum-of-the-parts/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>App Engine: Most Of The Stuff I Want, None Of The Stuff I Don&#8217;t</title>
		<link>http://infrequently.org/2008/04/app-engine-most-of-the-stuff-i-want-none-of-the-stuff-i-dont/</link>
		<comments>http://infrequently.org/2008/04/app-engine-most-of-the-stuff-i-want-none-of-the-stuff-i-dont/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 22:51:34 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=665</guid>
		<description><![CDATA[I&#8217;m not sure who or how, but I got an invite to yesterday&#8217;s Camp Fire One event at Google where they announced their new App Engine platform. The event itself was small-ish, with lots of interesting people invited (both from Google and not). I had no idea ahead of time what the announcement would be, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not sure who or how, but I got an invite to yesterday&#8217;s Camp Fire One event at Google where they announced their new <a href="http://code.google.com/appengine/">App Engine</a> platform. The event itself was small-ish, with lots of interesting people invited (both from Google and not). I had no idea ahead of time what the announcement would be, and frankly I forgot all about the event until the day of. I&#8217;m glad I remembered (note to future self: next time, pack gloves and a hat).</p>
<p>As they started talking about the platform and what&#8217;s part of it (and what&#8217;s not), I couldn&#8217;t escape escape the feeling that they&#8217;d gotten it right. It is <em>absolutely</em> the case that for most apps, scaling requires some amount of re-architecting. Systems like Rails are built with such a dependence (intentional or not) on the features of relational data stores that they quickly hit bottlenecks because <em>frameworks aren&#8217;t keeping developers out of the gutter</em>. This is nearly the same lesson that the security community collectively came to when it started to beat the average developer about the head regarding the awesome power of defaults. What systems do and don&#8217;t do for you &#8220;cheaply&#8221; defines their character, and in many systems those choices aren&#8217;t made consciously, or if they are, they don&#8217;t have the benefit of a different perspective which might de-emphasize certain traits. Call it libertarian paternalism, choice architecture, or pure condescension, but whatever it is, systems and platforms today are in the explicit business of making some things easier than others.</p>
<p>As the presenters showed how to make an app quickly, I knew I was looking at something I hadn&#8217;t seen the likes of since Jot. We all know that Big Table is a column-oriented data-store, but since most people are still stuck on the likes of MySQL, it&#8217;s hard to appreciate how liberating it is not having to think about how adding properties to models will affect a schema. The way App Engine is constructed lets the data store layer provide something called <a href="http://code.google.com/appengine/docs/datastore/entitiesandmodels.html">expando models</a>. These models give us the kind of flexibility that I&#8217;ve only ever enjoyed before inside of Jot. Want a property? Just add it. No migration, no schema version&#8230;just data finding a happy home, and as your app&#8217;s skeleton &#8220;solidifies&#8221; and you figure out which properties really do need to be faster, you can migrate that data into fixed properties with indexes and types and all that jazz. It&#8217;s like a gradual type system, only for data stores. It&#8217;s agility nirvana for application development.</p>
<p>Speaking of application development nirvana, they also had the good sense to start with a great language (Python) and a great webapp framework (Django) as the basis for the new system. For all the Rubyists and Java heads out there who are surely crying bloody murder, I suggest that they just try it. Seriously. Django&#8217;s template system is freaking sweet, and Python (despite it&#8217;s lambda-related warts) is close enough to being executable pseudo-code as to still hold the second place in my toolbox of languages.</p>
<p>There&#8217;s a lot which I&#8217;m sure others will (and have) covered about how App Engine is going to change the game for startups and players like Amazon, but I think that if someone else had launched this system it would still survive on its merits alone. The only wrinkle in the whole thing will be seeing what&#8217;s done about pricing over the long haul. It really shouldn&#8217;t be hard for Google to beat S3 on price, and I&#8217;m sure there will still be a market for EC2 for non-traditional tasks, but fundamentally I think App Engine has all the makings of something really, truly <em>better</em> than the current (assumed) stack.</p>
<p>After more than a year of mourning the effective loss of Jot as a platform, writing apps on the server just got interesting for me again, and that may be the highest praise I can offer and framework or platform.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/04/app-engine-most-of-the-stuff-i-want-none-of-the-stuff-i-dont/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

