<?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; webdev</title>
	<atom:link href="http://infrequently.org/category/webdev/feed/" rel="self" type="application/rss+xml" />
	<link>http://infrequently.org</link>
	<description></description>
	<lastBuildDate>Fri, 18 Nov 2011 16:25:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Vendor Prefixes Are A Rousing Success</title>
		<link>http://infrequently.org/2011/11/vendor-prefixes-are-a-rousing-success/</link>
		<comments>http://infrequently.org/2011/11/vendor-prefixes-are-a-rousing-success/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 14:36:27 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[openweb]]></category>
		<category><![CDATA[politics]]></category>
		<category><![CDATA[standards]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1715</guid>
		<description><![CDATA[tl;dr version: Henri Sivonen&#8217;s arguments against vendor prefixing for CSS properties focus on harm without considering value, which in turn has caused him to come to a non-sensical set of conclusions and recommendations. Progress is a process, and vendor prefixes have been critical in accelerating that process for CSS. For a while now I&#8217;ve been [...]]]></description>
			<content:encoded><![CDATA[<p><em>tl;dr version: Henri Sivonen&#8217;s arguments against vendor prefixing for CSS properties focus on harm without considering value, which in turn has caused him to come to a non-sensical set of conclusions and recommendations. Progress is a process, and vendor prefixes have been critical in accelerating that process for CSS.</em></p>
<p>For a while now I&#8217;ve been hearing the meme resurface from CSS standards folks and a few implementers that &#8220;vendor prefixes have failed&#8221;. I&#8217;d assumed this was either a (bad) joke or that it was one of those things that web developers would scoff at loudly enough to turn the meme recessive. I was wrong.</p>
<p>Henri Sivonen, Mozilla hacker extrordinare, <a href="http://hsivonen.iki.fi/vendor-prefixes/">has made the case directly and at length</a>. Daniel Glazman, co-chair of the CSS WG posted a <a href="http://www.glazman.org/weblog/dotclear/index.php?post/2011/11/16/CSS-vendor-prefixes-an-answer-to-Henri-Sivonen">point-by-point response.</a> If you have the patience, you should read both.</p>
<p>Lost in the debate between &#8220;browser people&#8221; and &#8220;spec people&#8221; is the the essential nature of what has happened with prefixes: they <em>worked</em>. From the perspective of a web developer, any first approximation of the history of vendor prefixes are <em>pure win</em>, even if only a fraction of the value that has been delivered behind them is attributable to prefixes un-blocking vendors from taking risks and shipping early.</p>
<p>Daniel&#8217;s rebuttal to Henri gets a lot of things right, but he gives in on an essential point; by agreeing with Henri that vendor prefixes are &#8220;hurting web authors&#8221; he wites off the benefits that they&#8217;ve delivered &#8212; namely the ability of vendors to get things out to devs in a provisional way that has good fallback and future-proofing properties and the ability for devs to build with/for the future in an opt-in, degradable way.</p>
<p>Rounded corners, gradients, animations, flex box, etc. are all design and experience enablers that developers have been able to take advantage of while waiting for the standards dust to settle, and thanks to W3C process, it takes a LONG time to to settle. Yes, that has some costs associated with it. Henri is very worried that browsers that aren&#8217;t keeping up quickly will be &#8220;left behind&#8221; by webdevs who use only one vendor&#8217;s prefix. But surely that&#8217;s a lesser harm than not getting new features and not having the ability to iterate. And it provides incentive for following browsers to try to make a standard happen. What&#8217;s not to love? More to the point, I just don&#8217;t believe that this is a serious problem in practice. What front-ender in 2011 doesn&#8217;t test on <em>at least</em> two browsers? Yes, yes, i&#8217;m sure such a retrograde creature exists, but they were going to be making non-portable content <em>regardless of prefixes</em>. Assuming you&#8217;re testing fallback <em>at all</em> (e.g., by testing on more than one browser), prefixes not appearing on some browser are just the fallback case. CSS FTW! Webdevs who don&#8217;t test on more than one browser&#8230;well, they&#8217;re the ones hanging the noose around the neck of their own apps. Vendor prefixes no more enable this stupidity than the existence of the <code>User-Agent</code> header. Compatibility is a joint responsibility and the best each side (browser, webdev) can hope of the other is some respect and some competence. Cherry picking egregious examples and claiming &#8220;it&#8217;s hurting the web&#8221; seems, at a minimum, premature.</p>
<p>And how did we think we&#8217;d get a good standard, anyway? By sitting in a room in a conference center more often and thinking about it harder? Waiting on a handfull of early adopters to try something out in a tech demo and never stress it in practice? That&#8217;s not a market test (see: XHTML2), it doesn&#8217;t expose developers to the opportunities and tradeoffs that come with a new feature, and doesn&#8217;t do anything to address the inevitable need to integrate feedback at <em>some</em> point.</p>
<p>Yes, we could go with Henri&#8217;s suggestion that the first person to ship wins by default, never iterate on any designs, and avoid any/all first-mover disadvantage situations, but who among the browser vendors is perfect? And what would the predictable consequences be? I can only assume that Henri thinks that we&#8217;ll end up in a situation where vendors coordinate with the CSS WG early to add new stuff, will design things more-or-less in the open, and will only ship features to stable (no flag) when they&#8217;re sure of their design. That could happen at the limit, but I doubt it. Instead, the already fraught process of adding new features to the platform will be attempted by even fewer engineers. Who wants the responsibility for having to be perfect lest you screw the web over entirely? Fuck that noise, I&#8217;m gonna go work on a new database back-end or tune something to go faster. Browsers are made by smart people who have a choice of things to be working on, and any time you see a new platform feature, it probably came about as the result of an engineer taking a risk. Many times the engineers in a position to take those risks don&#8217;t have a great sense for what good, idiomatic web platform features might be designed, so they&#8217;ll need to tweak/iterate based on feedback. And feedback is painfully hard to extract from webdevs unless you&#8217;ve made something available in a tangible way such that they can use it and discover the limitations.  Shipping things only to dev is perhaps a good idea for other aspects of the platform where we can&#8217;t count on CSS&#8217;s forgiving parsing behavior (the basis for prefixes). Syntax changes for JS and CSS seem like good examples. But for features that are primarily new CSS properties? Oy. Making the stakes even higher, reducing the ability to get feedback and iterate isn&#8217;t going to lead to a harmonious world of good, fast standards creation. It&#8217;s going to predictably reduce the amount of new awesome that shows up in the platform.</p>
<p>Prefixes are an enabler in allowing the <em>necessary</em> process of use, iteration, and consensus building to take place. Want fewer messes? There&#8217;s an easy way to achieve that: try less stuff, add fewer features, and make each one more risky to add. That&#8217;s Henri&#8217;s prescription, wether or not he knows it, and the predictable result is a lower rate of progress &#8212; advocating this sort of thing is <em>much</em> worse for the web and for developers than any of the harm that either Henri or Daniel perceive.</p>
<p>Which brings me to Henri&#8217;s undifferentiated view of harm. His post doesn&#8217;t acknowledge the good being done by prefixed implementations &#8212; I get the sense he doesn&#8217;t build apps with this stuff or it&#8217;d be obvious how valuable prefixed implementations are for work-a-day web app building &#8212; instead focusing on how various aspects of the process of prefixed competition can be negative. So what? Everything worth having costs <em>something</em>. Saying that things &#8220;hurt the web&#8221; or &#8220;hurt web developers&#8221; without talking in terms of <em>relative harm</em> is just throwing up a rhetorical smoke screen to hide behind. If you focus only on the costs but write the benefits out of the story of <em>course</em> the conclusion will be negative. In many cases, the costs that Henri points out are <em>correctly aligned</em> with getting to a better world: having to type things out many times sucks, creating demand among webdevs for there to be a single, standardized winner. Having multiple implementations in your engine sucks, creating demand from vendors to settle the question and get the standards-based solution out to users quickly. Those are good incentives, driven by prices that are low but add up over time in ways that encourage a good outcome:  a single standard implemented widely.</p>
<p>And as Sylvain Galineau pointed out, what looks like pure cost to one party might be huge value to another. I think there&#8217;s a lot of that going on here, and we shouldn&#8217;t let it go un-contextualized. The things that Henri sees as down-sides are the predictable, relatively minor, costs inherent in a process that allows us to make progress faster and distribute the benefits quickly, all while <em>minimizing</em> the harm. That he&#8217;s not paying the price for not having features available to build with doesn&#8217;t mean those opportunity costs aren&#8217;t real and aren&#8217;t being borne by webdevs every day. Being able to kill table and image based hacks for rounded corners is providing HUGE value, well ahead of the spec. Same for gradients, transitions, and all the rest. Calling prefixed implementations in the wild a bad thing needs to argue that the harm is greater than all of that value. I don&#8217;t think Henri could make that case, nor has he tried.</p>
<p>I think the thing that most shocks me about Henri&#8217;s point of view is that he&#8217;s arguing against a process when in fact the motivating examples (transforms, gradients) have been sub-optimal in <em>exactly</em> the better-than-before ways we might have hoped for! Gradients, for example, saw a lot of changes and browsers had different ideas about what the syntax should be. Yes, it&#8217;s harder to get a consistent result when you&#8217;re trying to triangulate multiple competing syntaxes, but we got to <em>use</em> this stuff, get our hands dirty, and get most of the benefits of the feature while the dust settled. Huzzah! This is <em>exactly</em>> the way a functioning market figures out what&#8217;s good! Prefixes help developers understand that stuff can and will change, and they clear the way for competition of ideas without burdening the eventual feature&#8217;s users with legacy bagage tied to a single identifier.</p>
<p>So what about the argument that there might be content that doesn&#8217;t (quickly?) adopt the non-prefixed version, or that vendors can&#8217;t remove their prefixed implementations because content depends on it?</p>
<p>To the first, I say: show me a world where 90+% of users have browsers support the standard feature and I&#8217;ll show you a world in which nobody (functionally) continues to include prefixes. That process is gated in part by the WG&#8217;s ability to agree to a spec, and here I think there&#8217;s real opportunity for the CSS WG to go faster. The glacial pace of CSS WG in getting things to a final, ratified spec is in part due to amazingly drawn-out W3C process, and in part a cultural decision on the part of the WG members to go slow. My view is that they should be questioning both of these and working to change them, not blaming prefixes for whatever messes are created in the interim.</p>
<p>As for removing prefixes, this is about vendors just doing it, and quickly. But the definition of &#8220;quickly&#8221; matters here. My view is that vendors should be given <em>at least</em> as long as it took to get a standard finalized from the introduction of their prefixed version for the removal process to be complete. So if Opera adds an amazing feature behind a <code>-o-</code> prefix in early 2012 and the standard is finalized in 2014, the deprecation and eventual removal should be expected to take 2 years (2016). This has the nice symmetry of incentives that punish the WG for going slow (want to kill prefix impls? get the standard done) while allowing the vendors who took the biggest risks to provide the softest landings for their users. And it doesn&#8217;t require that we simply go all-in on the first person&#8217;s design to ship. Yes, there will be mounting pressure to get <em>something</em> done, but that&#8217;s good too!</p>
<p>The standards process needs to lag implementations, which means that we need spaces for implementations to lead in. CSS vendor prefixes are one of the few shining examples of this working in practice. It&#8217;s short-term thinking in the extreme to either flag the costs associated with them as either justifying their removal or even suggesting that the costs are too high.</p>
<p>And webdevs, always be skeptical when someone working on an implementation or a spec tells you that something is &#8220;hurting the web&#8221; when your experience tells you otherwise. The process of progress needs more ways to effectively gauge webdev interest, collect feedback, and test ideas. Not fewer or narrower channels.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2011/11/vendor-prefixes-are-a-rousing-success/feed/</wfw:commentRss>
		<slash:comments>25</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>Google &amp; the Future of JavaScript</title>
		<link>http://infrequently.org/2011/09/google-the-future-of-javascript/</link>
		<comments>http://infrequently.org/2011/09/google-the-future-of-javascript/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 00:36:54 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[openweb]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1657</guid>
		<description><![CDATA[Simply stated, Google is absolutely committed to making JavaScript better, and we're pushing hard to make it happen.]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s very little public information yet about Dart (nee, Dash), and as I&#8217;m not on Lars&#8217; team I can&#8217;t comment about it. More details will be forthcoming at the <a href="http://gotocon.com/aarhus-2011/presentation/Opening%20Keynote:%20Dart,%20a%20new%20programming%20language%20for%20structured%20web%20programming">GOTO session next month</a>. I&#8217;ll also be at GOTO, <a href="http://gotocon.com/aarhus-2011/presentation/Send%20Less,%20Do%20More,%20Go%20Faster:%20The%20Future%20of%20Front%20End%20Development">speaking on JavaScript and the state of the web platform</a>.</p>
<p>Making the rounds is an accidentally leaked early draft of notes from a meeting last year that discusses both Dart and JavaScript. I work on many web platform-related things at Google, including serving as a representative to TC39, the body that standardizes the JavaScript language. I wasn&#8217;t at the meetings having previously committed to <a href="http://2010.full-frontal.org/">presenting at FFJS</a>, but my views were represented by others and my name is on the document. As I said, though, it was a draft and doesn&#8217;t reflect either the reality of what has happened in the meantime or even the decisions that were taken as a result. And it certainly doesn’t reflect my personal views.</p>
<p>So what&#8217;s the deal with Google and JavaScript?</p>
<p>Simply stated, Google is absolutely committed to making JavaScript better, and we&#8217;re pushing hard to make it happen.</p>
<p>Erik Arvidsson, Mark Miller, Waldemar Horwat, Andreas Rossberg, Nebojša Ćirić, Mark Davis, Jungshik Shin and I attend TC39 meetings, work on implementations, and try to push JS forward in good faith. And boy, does it need a push.</p>
<p>Erik and I have specifically been working to focus the TC39 agenda away from syntax-free, semantics-only APIs (Object.defineProperty, anyone?) which might be good for tools, compilers, and frameworks but which are hard for day-to-day use.</p>
<p>Through <a href="http://code.google.com/p/traceur-compiler/">Traceur</a> and other efforts we&#8217;ve been socializing the idea that the one thing the committee can exclusively do &#8212; and should do more of &#8212; is to carve out syntax for commonly exercised semantics. Seemingly small things like the <a href="http://wiki.ecmascript.org/doku.php?id=harmony:classes"><code>class</code> keyword as sugar</a> for the constructor function pattern, or a <a href="http://wiki.ecmascript.org/doku.php?id=strawman:arrow_function_syntax&#038;s=short+function">shorter syntax for functions</a> are big improvements, if only because it&#8217;s TC39 that&#8217;s making them. Syntax can end battles over common patterns and help you say what you mean, and JS is overdue for some of this. Larger but more subtle things, like agreement to use pragmas as a way to enable the process of progress in a compatible web, are even more exciting to me. Even proposals that haven&#8217;t made it through like <a href="http://wiki.ecmascript.org/doku.php?id=strawman:scoped_object_extensions">Scoped Object Extensions</a> and <a href="http://wiki.ecmascript.org/doku.php?id=strawman:deferred_functions">deferred functions</a> have been fought for by us because we desperately want JavaScript to get better. We&#8217;re big fans of much of the work coming out of Mozilla for the same reason &#8212; in particular Dave Hermann&#8217;s excellent <a href="http://wiki.ecmascript.org/doku.php?id=harmony:modules">modules proposal</a>. Together, these are going to do much to help give modern JS some &#8220;backbone&#8221; in the near term. I’m proud of what we’ve accomplished in TC39 over the last year, and while I hoped for more, the result is an ES.next that looks like it’ll embody many of the things I feel are currently missing. The day-to-day practice of writing JS is going to change dramatically for the better when ES.next arrives.</p>
<p>But it&#8217;s not the end &#8212; not by a long shot. Classes will give us a humane, interoperable inheritance syntax, but it leaves composition unaddressed by syntax. I&#8217;m hopeful that we bless traits in future versions, removing the use of inheritance in most cases. Similarly, I think we can find a way to repair &#8220;this&#8221; binding foot-guns with softly-bound &#8220;this&#8221;. Repairing the shared-prototypes issue, either through DOM or through something like Scoped Object Extensions, can and should be done. And once we have all of this, the stage will be set for a flexible, advanced type system that does not need to be all-or nothing and does not need to be hobbled by the ghost of C++/Java&#8217;s inflexible nominal-only types. That&#8217;s the dream, and we&#8217;re not shying away from it.</p>
<p>It&#8217;s hard to square this sort of wild enthusiasm for &#8220;raw&#8221; JavaScript with what&#8217;s in the leaked memo, and I can only beg for some amount of understanding. As committed and enthusiastic as I am about the prospects for JavaScript, others are just as enthused about Dart. Google is big, can do many things at once, and often isn&#8217;t of one mind. What we do agree on is that we&#8217;re trying to make things better the best we know how. Anyone who watches Google long enough should anticipate that we often have different ideas about what that means. For my part, then, consider me and my team to be committed JS partisans for as long as we think we can make a difference.</p>
<h3>Reality Check</h3>
<p>There are risks, of course. TC39 is long on seasoned language design skill and short on webdev experience, meaning that many things that Erik and I may take for granted as pressing problems need to be explained, sometimes to an incredulous audience. The flip side risk is that naïve solutions may have better alternatives that seasoned language hands can quickly spot and that simple answers have non-obvious risks or preclude movement in other important areas later. It&#8217;s good, then, that the committee is working well and is taking appeals to developer productivity seriously.</p>
<p>Whatever you might think about programming languages for the browser, let me assure you of one thing: your problem isn&#8217;t the language. Not really, anyway. We&#8217;ve made good progress in the last year repairing some of the seams between JS and DOM, and Cameron McCormack has helped us drive a new version of WebIDL that correctly explains DOM as a reasonable prototype chain. But it&#8217;s only the beginning. The DOM is in terrible shape, and not due to implementation differences. The malign neglect of IDL-addled designs, the ghosts of dead-end XML experiments, and endless cruft will plague any language that sidles up to it. Until we get a real <a href="http://wiki.whatwg.org/wiki/Component_Model">Component Model</a>, a better CSS OM, and some sort of a pragma for DOM that allows us to fix DOM&#8217;s abhorrent JS bindings, we&#8217;ll continue to be hostage to C++ APIs inartfully wired up to an incredibly dynamic language. And that’s to say nothing of the pressing need for <a href="http://code.google.com/p/experimental-css/">better CSS</a>, animations, and <a href="http://code.google.com/p/mdv/">a built-in data-binding/templating system</a>. When the platform doesn’t provide it, today, we get it from JavaScript. But that’s not where the solutions always belong.</p>
<p>Let me put it another way: when you find yourself thinking &#8220;man, JavaScript sucks,&#8221; remember that it&#8217;s only painful in large quantities. And why do you need so much of it? &#8216;Cause the DOM, CSS, and HTML standards are letting you down. Any language wired up to the browser today is subject to the same fate, and the insane reality that these things are specified under different roofs in processes that aren&#8217;t subject to the popular will of web developers. Python doesn’t have it’s DOM APIs decided by the W3C, they borrow the idiomatic <a href="http://docs.python.org/library/xml.etree.elementtree.html">ElementTree API</a> from within their own community. WebIDL is an artifact of a different time that has a tenuous relationship to idiomatic JavaScript, the CSS-OM barely exists, and DOM apologists are doing more harm than any of JavaScript&#8217;s warts ever have. We can fix these things, of course, and here at Google we&#8217;re trying – in good faith – to work in standards to make them better. But the bottom line is that the language isn’t the problem. I repeat: the language isn’t the problem, the platform is.</p>
<p>The only thing that&#8217;s going to replace the web as universal platform is the next version of the web. Those of us working on Chrome believe that to the core and feel a deep urge to make things better faster. We might not always agree on the &#8220;how,” but we all believe that we can’t do it alone.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2011/09/google-the-future-of-javascript/feed/</wfw:commentRss>
		<slash:comments>36</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>Cutting The Interrogation Short</title>
		<link>http://infrequently.org/2011/01/cutting-the-interrogation-short/</link>
		<comments>http://infrequently.org/2011/01/cutting-the-interrogation-short/#comments</comments>
		<pubDate>Sun, 30 Jan 2011 22:21:04 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://infrequently.org/?p=1560</guid>
		<description><![CDATA[I&#8217;ve been having a several-day mail, IRC, and twitter discussion with various folks about performance and the feature detection religion technique, particularly on mobile where CPU ain&#8217;t free. So what&#8217;s the debate? I say you shouldn&#8217;t be running tests in UA&#8217;s where you can dependably know the answer a-priori. Wait, what? Why does Alex Russell [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been having a several-day mail, IRC, and twitter discussion with various folks about performance and the feature detection <strike>religion</strike> technique, particularly on mobile where CPU ain&#8217;t free. So what&#8217;s the debate? I say you shouldn&#8217;t be running tests in UA&#8217;s where you can dependably know the answer a-priori.</p>
<p>Wait, what? Why does Alex Russell hate feature testing, kittens, and cute fuzzy ducklings?</p>
<p>I don&#8217;t. <a href="http://paulirish.com/">Paul</a> warned me that my approach isn&#8217;t going to be popular at first glance, but hear me out. My assumptions are as follows:</p>
<ul>
<li>Working is better than busted</li>
<li>Fast is better than slow</li>
<li>No browser vendor changes the web-facing features in a given version. Evar. Does not happen</li>
</ul>
<p>If you buy those, then I think we can all get some satisfaction by retracing our steps and asking, seriously, what <em>is</em> the point of feature testing?</p>
<p>Ok, I&#8217;ll go first: feature testing is motivated by a desire not to be busted, particularly in the face of new versions of UA&#8217;s which will (hopefully) improve standards support and reduce the need for hacks in the first place. Sensible enough. Why should users wait for a new version of your library just &#8217;cause a new browser was released or because you didn&#8217;t test on some version of something.</p>
<p>Extra bonus: if you don&#8217;t mind running them every time, you can write just the feature test and your work is done now and in the future! Awesome! Except some of us do mind. Yes, things are now resilient in the face of new UA&#8217;s and new versions of old ones, but only on the back of testing for everything you need ever time you load a library on a page. Slowly. Veeerrrrry slooowly.</p>
<p>Paul suggested that some library could use something like Local Storage to cache the results of these tests locally, but this hardly seems like an answer. First, what if the user upgrades their browser? Guess you have to cache and check against the UA string anyway. And what about the cost of going to storage? Paul reported that these tests can be <em>wicked</em> expensive to run at all, on the order of 30ms for the full suite (which you hopefully won&#8217;t hit&#8230;but sheesh). Reported worst-case for <a href="https://github.com/phiggins42/has.js/">has.js</a> is even worse. But apparently going to Local Storage is <em>also</em> expensive. And we&#8217;re still running all these tests in the fast path the first time anyway. If we think that they&#8217;re so expensive that we want to cache the results, why don&#8217;t we think they&#8217;re so expensive that we don&#8217;t want to run them in the common case?</p>
<p>Now for a modest proposal: <b>feature tests should only ever be run <em>when you don&#8217;t know what UA you&#8217;re running in</em></b>.</p>
<p>Feature testing libraries should contain pre-built caches &#8212; the kind that come with the library, not the kind that get built on the client &#8212; but they should only be consulted for UA versions that you <em>know</em> you know. If we assume that behavior for UA/version combination never changes, we&#8217;ve got ourselves a get-out-of-jail free card. Libraries can have <code>O(1)</code> behavior in the common case and in the situations where feature testing would keep you from being busted, you&#8217;re still not busted.</p>
<p>So what&#8217;s the cost to this? Frankly, given the size of some of the feature tests I&#8217;ve seen, it&#8217;s going to be pretty minimal vs. the bloat the feature tests add. All performance work is always a tradeoff, but if your library thinks it&#8217;s important not to break <em>and</em> to be fast, then I don&#8217;t see many alternatives. New versions of libraries can continue to update the caches and tests as necessary, keeping the majority of users fast, while at the same time keeping things working in hostile or unknown environments.</p>
<p>Anyhow, if you&#8217;re a library author or maintainer, please please <em>please</em> consider the costs of feature tests, particularly the sort that mangle DOM and or read-back computed layout values. Going slow hurts users, hurts the web, and hurts the culture of performance that&#8217;s so critical to keeping the platform a viable contender for the next generation of apps. We owe it to users to go faster.</p>
<p><b>A quick aside</b>: I hesitated writing this for the same reasons that Paul cautioned me about how unpopular this was going to be: there&#8217;s a whole lot of know-nothing advocacy that&#8217;s still happening in the JS/webdev/design world these days, and it annoys me to no end. I&#8217;m not sure how our community got so religious and fact-disoriented, but it has got to stop. If you read this and your takeaway was &#8220;Alex Russell is against feature testing&#8221;, then you&#8217;re part of the problem. Think of it like a feature test for bogosity. Did you pass? If so, congrats, and thanks for being part of the bits of the JavaScript universe that I like.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2011/01/cutting-the-interrogation-short/feed/</wfw:commentRss>
		<slash:comments>51</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>View-Source Is Good? Discuss.</title>
		<link>http://infrequently.org/2010/01/view-source-is-good-discuss/</link>
		<comments>http://infrequently.org/2010/01/view-source-is-good-discuss/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 03:36:22 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[webdev]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[flex]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[silverlight]]></category>
		<category><![CDATA[viewsource]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=1241</guid>
		<description><![CDATA[I&#8217;ve been invited by Chris Messina and some kindly folks at MSFT to participate in a panel at this year&#8217;s SxSW regarding the value and/or necessity of view-source, and so with apologies to my fellow panelists, I want to get the conversation started early. First, my position: ceteris paribus, view-source was necessary (but not sufficient) [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been invited by <a href="http://factoryjoe.com/blog/">Chris Messina</a> and some <a href="http://chrisbernard.blogs.com/">kindly folks</a> at MSFT to participate in a panel at this year&#8217;s SxSW regarding the value and/or necessity of view-source, and so with apologies to my fellow panelists, I want to get the conversation started early.</p>
<p>First, my position: <em><a href="http://en.wikipedia.org/wiki/Ceteris_paribus">ceteris paribus</a></em>, view-source was necessary (but not sufficient) to make HTML the dominant application platform of our times. I also hold that it is under attack &mdash; not least of all from within &mdash; and that losing view-source poses a significant danger to the overall health of the web.</p>
<p>That&#8217;s a lot to hang on the shoulders of a relatively innocent design decision, and I don&#8217;t mean to imply that any system that has a view-source like feature will become dominant. But I do argue that it helps, particularly when coupled with complementary features like reliable parsing, semantic-ish markup, and plain-text content. Perhaps it&#8217;s moving the goal line a bit, but when I talk about the importance of view-source, I&#8217;m more often than not discussing these properties together.</p>
<p>To understand the importance of view-source, consider how people learn. <a href="http://vis.berkeley.edu/papers/prefuse/2005-prefuse-CHI.pdf">Some evidence exists</a> that even trained software engineers chose to work with copy-and-pasted example code. Participants in the linked study even expressed guilt over the copy-paste-tweak method of learning, but guilt didn&#8217;t change the dynamic: a blank slate and abstract documentation doesn&#8217;t facilitate learning nearly as well as poking at an example and feeling out the edges by doing. View-source provides a powerful catalyst to creating a culture of shared learning and learning-by-doing, which in turn helps formulate a mental model of the relationship between input and output faster. Web developers get started by taking some code, pasting it into a file, saving, loading it in a browser and hitting <code>ctrl-r</code>. Web developers switch between editor and browser between even the most minor changes. This is a stark contrast with technologies that impose a compilation step where the process of seeing what was done requires an intermediate step. In other words, immediacy of output helps build an understanding of how the system will behave, and <code>ctrl-r</code> becomes a seductive and productive way for developers to accelerate their learning in the copy-paste-tweak loop. The only required equipment is a text editor and a web browser, tools that are free and work together instantly. That is to say, there&#8217;s no waiting between when you save the file to disk and when you can view the results. It&#8217;s just a <code>ctrl-r</code> away.</p>
<p>With that hyper-productive workflow as the background, view-source helps turn the entire web into a giant learning lab, and one that&#8217;s remarkably resilient to error and experimentation. See an interesting technique or layout? No one can tell you &#8220;no&#8221; to figuring out how it was done. Copy some of it, paste it into your document, and you&#8217;ll get <em>something</em> out the other side. Browsers recovering from errors gracefully create a welcome learning environment, free of the inadequacy that a compile failure tends to evoke. You can <em>see</em> what went wrong as often as not. The evolutionary advantages of reliable parsing have helped to ensure that strict XML content comprises roughly none of the web, a decade after it was recognized as &#8220;better&#8221; by world+dog. Even the most sophisticated (or broken) content is inspectable at the layout level and tools like <a href="http://getfirebug.com/">Firebug</a> and the <a href="http://webkit.org/blog/829/web-inspector-updates/">Web Inspector</a> accelerate the copy-paste-tweak cycle by inspecting dynamic content and allowing live changes without reloads, even on pages you don&#8217;t &#8220;own&#8221;. The predicate to these incredibly powerful tools is the textual, interpreted nature of HTML. There&#8217;s much more to say about this, but lets instead turn to the platform&#8217;s relative weaknesses as a way of understanding how view-source is easily omitted from competing technologies.</p>
<p>The first, and most obvious, downside to the open-by-default nature of the web is that it encourages multiple renderers. Combined with the ambiguities of reliable parsing and semantics that leave room for interpretation, it&#8217;s no wonder that web developers struggle through incompatibilities. In a world where individual users each need to be convinced to upgrade to the newest version of even a single renderer, differences only in version can wreak havoc in the development process. Things that work in one place may not look exactly the same in another. This is both a strength and a weakness for the platform, but at the level of sophisticated applications, it&#8217;s squarely a liability. Next, ambiguities in interpretation and semantics mean that the project of creating tooling for the platform is significantly more complex. If only one viewer is prevalent (for whatever reason), then tools only need to consume and generate code that understands the constraints, quirks, and performance of a single runtime. Alternate forms of this simplification include only allowing code (not markup) so as to eliminate parsing ambiguity. The code-not-markup approach yields a potentially more flexible platform and one that can begin to execute content more quickly (as Flash does). These advantages, taken together, can create an incredibly productive environment for experts in the tools that generate content: no output ambiguity, better performance, and tools that can deliver true WYSIWYG authoring. These tools can sidestep the <code>ctrl-r</code> cycle entirely.</p>
<p>But wait, I hear you shout, It&#8217;s possible to do code-only, toolable, full fidelity development in JavaScript! Tools like GWT and Cappuccino generate code that generates UI, ensuring that only those who can write code or have tools that can will participate; removing the potential value of view-source for those apps. But lets be honest: view source is nearly never locally beneficial. I can hardly count the number of times I&#8217;ve seen the &#8220;how do I hide my code?&#8221; question from a web n00b who (rightly or wrongly) imagines there&#8217;s value in it. For GWT the fact that the output is an HTML DOM that&#8217;s styled with CSS is as much annoyance as benefit. The big upside is that browsers are the dominant platform and you don&#8217;t have to convince users to install some new runtime.</p>
<p>Similarly Flex, Laszlo, GWT&#8217;s UI Binder, and Silverlight have discovered the value in markup as a simple declarative way for developers to understand the hierarchical relationships between components, but they correspond to completely unambiguous definitions of components they rely on compiled code &mdash; not reliably parsed markup &mdash; for final delivery of the UI. These tight contracts turn into an evolutionary straightjacket. Great if you&#8217;re shipping compiled code down the wire that can meet the contract, but death if those tags and attributes are designed to live for long periods of time or across multiple implementations. You might be able to bolt view-source into the output, but it&#8217;ll always be optional and ad-hoc, features that work against it being pervasive. Put another way, the markup versions of these systems are leaky abstractions on the precise, code-centric system that under-girds both the authoring and runtime environments. This code-centric bias is incredibly powerful for toolmakers and &#8220;real&#8221; developers, but it cuts out others entirely; namely those who won&#8217;t &#8220;learn to program&#8221; or who want to build tools that inject content into the delivery format.</p>
<p>Whatever the strengths of code-based UI systems, they throw web crawlers for a loop. Today, most search engines deal best with text-based formats, and those search engines help make content more valuable in aggregate than it is on its own. Perhaps it&#8217;s inevitable that crawlers and search engines will need to execute code in order to understand the value of content, but I remain unconvinced. As a thought experiment, consider a web constructed entirely of Flash content. Given that Flash bytecode lacks a standard, semantic way to denote a relationship between bits of Flash content, what parts of the web wouldn&#8217;t have been built? What bits of your work would you do differently? What would the process be? There&#8217;s an alternate path forward that suggests that we can upgrade the coarse semantics of the web to deal with ever-more-sophisticated content requirements. Or put another way, use the features of today&#8217;s toolkits and code generators as a TODO list for markup driven features. But the jury is still out on the viability that approach; the same dynamic that makes multiple renderers possible ensures that getting them to move in a coordinated way is much harder than the unilateral feature roadmap that plugin vendors enjoy. HTML 5 and CSS 3 work is restarting those efforts, but only time will tell if we can put down the code and pick markup back up as a means to express ourselves.</p>
<p>I&#8217;ve glossed over a lot of details here, and I haven&#8217;t discussed implications for the server side of a non-text format as our lingua-franca, nor have I dug into the evolution metaphor. Many of the arguments are likewise conditional on economic assumptions. There&#8217;s lots of discussion yet to have, so if you&#8217;ve got links to concrete research in either direction or have an experience that bears on the debate post in the comments! Hopefully my fellow panelists will respond in blog form and I&#8217;ll update this post when they do.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2010/01/view-source-is-good-discuss/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
		<item>
		<title>Ending The ga.js Wait</title>
		<link>http://infrequently.org/2009/04/ending-the-gajs-wait/</link>
		<comments>http://infrequently.org/2009/04/ending-the-gajs-wait/#comments</comments>
		<pubDate>Sun, 12 Apr 2009 04:10:16 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=908</guid>
		<description><![CDATA[Google Analytics is ubiquitous, not least of all because it&#8217;s better at what it does than most of the alternatives. Also, it doesn&#8217;t require any install or maintenance. And it&#8217;s free. What&#8217;s not to like? Frankly, not much, but if I had to nit pick, I&#8217;d note that the worst part of Google Analytics is [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.google.com/analytics/">Google Analytics</a> is ubiquitous, not least of all because it&#8217;s better at what it does than most of the alternatives. Also, it doesn&#8217;t require any install or maintenance. And it&#8217;s free. What&#8217;s not to like?</p>
<p>Frankly, not much, but if I had to nit pick, I&#8217;d note that the worst part of Google Analytics is the <a href="http://www.google-analytics.com/ga.js"><code>ga.js</code></a> script that does the actual tracking of content. It&#8217;s not bad, in and of itself, but it tends to load slowly. There are several reasons for this:</p>
<ul>
<li><b>Another DNS lookup to resolve <code>http://www.google-analytics.com/</code></b>. This DNS entry is likely to be &#8220;warm&#8221; given how frequently <code>ga.js</code> is used on the web, but as <a href="http://blog.chromium.org/2008/09/dns-prefetching-or-pre-resolving.html">Jim Roskind explained on the Chromium blog</a>, it&#8217;s the outliers that kill you.</li>
<li><b>It&#8217;s kinda big</b>. At 9K on the wire (22K unzipped), <code>ga.js</code> is kinda chunky for what it does most of the time, namely tracking a single page load.</li>
<li><b>The <a href="http://code.google.com/apis/analytics/docs/tracking/gaTrackingOverview.html">default instructions</a> are bone-headed</b>. They direct you to do a <code>document.write()</code> which is a blocking, synchronous operation WRT page loading. This is tres <a href="http://raibledesigns.com/rd/entry/oscon_2008_even_faster_web">dumb</a>. Reasonable people should just include <code>ga.js</code> with a <code>&lt;script&gt;</code> tag, but nearly nobody does. Turns out that sane defaults still matter.</li>
<li><b>Load times seem totally random.</b> As with DNS lookup, <code>ga.js</code>&#8216;s latency varies wildly. This isn&#8217;t backed up by anything empirical, but many pages feel blocked by <code>ga.js</code> for a near eternity.</li>
</ul>
<p>So how to fix this? Dojo 1.3&#8242;s <code>dojox.analytics.Urchin</code> to the rescue!  Given that I was going to be including Dojo on the page to do other things anyway, I can use 1.3&#8242;s new Urchin system to help amortize the cost of using Google Analytics. The code running on this blog now includes the following code (more or less):</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
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;script type=&quot;text/javascript&quot;
  src=&quot;http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js&quot;&gt;
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
  dojo.addOnLoad(function(){
    setTimeout(function(){
      dojo.require(&quot;dojox.analytics.Urchin&quot;);
      dojo.addOnLoad(function(){
        var tracker = new dojox.analytics.Urchin({
          acct: &quot;UA-XXXXXX-X&quot; // your tracking # here
        });
      });
    }, 100);
  });
&lt;/script&gt;</pre></td></tr></table></div>

<p>You can see the real thing by looking at the bottom of this page which pulls in <a href="http://alex.dojotoolkit.org/wp-content/themes/sandbox/custom.js">custom.js</a> which includes this logic. <a href="http://higginsforpresident.net/2008/06/google-analytics-after-onload/">Pete Higgins blogged about how the module works when he first wrote it</a>, and the strategy is to load Dojo from a CDN (since the page wanted it for other things) and wait until after the page has loaded to include <code>ga.js</code>. This delayed loading ensures that the page is responsive before we start doing anything related to tracking. The nested calls to <code>dojo.addOnLoad</code> show how we can wait for one set of modules to finish before kicking off another group, and in this case we also wait until after the page is responsive to load <code>dojox.analytics.Urchin</code>. This module further delays loading of <code>ga.js</code>, meaning that it doesn&#8217;t matter how long it takes for things like DNS to resolve and for Google to serve <code>ga.ja</code> since it&#8217;s not ever blocking the user.</p>
<p>Looking at the &#8220;before&#8221; and &#8220;after&#8221; shots in firebug gives you some idea of how this technique can really make a difference:</p>
<div style="padding-left: 50px; font-style: italic;">
<div id="attachment_940" class="wp-caption aligncenter" style="width: 310px"><a href="http://alex.dojotoolkit.org/wp-content/uploads/2009/04/before_loading_detail.png"><img src="http://alex.dojotoolkit.org/wp-content/uploads/2009/04/before_loading_detail-300x103.png" alt="onload waits for ga.js" title="before_loading_detail" width="300" height="103" class="size-medium wp-image-940" /></a><p class="wp-caption-text">onload waits for ga.js</p></div></p>
<p><div id="attachment_941" class="wp-caption aligncenter" style="width: 310px"><a href="http://alex.dojotoolkit.org/wp-content/uploads/2009/04/loading_detail.png"><img src="http://alex.dojotoolkit.org/wp-content/uploads/2009/04/loading_detail-300x102.png" alt="using dojox.analytics.Urchin, we can get a responsive page and *then* track usage" title="loading_detail" width="300" height="102" class="size-medium wp-image-941" /></a><p class="wp-caption-text">using dojox.analytics.Urchin, we can get a responsive page and *then* track usage</p></div>
</div>
<p>We get page tracking and the user gets an interactive page faster. Rad.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2009/04/ending-the-gajs-wait/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Dojo 1.3 Is Out!</title>
		<link>http://infrequently.org/2009/03/dojo-13-is-out/</link>
		<comments>http://infrequently.org/2009/03/dojo-13-is-out/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 15:52:58 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dhtml]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[dojo13]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=905</guid>
		<description><![CDATA[Dojo 1.3 is here! (download site) If you&#8217;re already using Dojo, this should be a no-brainer upgrade. It&#8217;s out-and-out better. As a quick example, dojo.create("tagname", { /*properties*/ }) is now the preferred way to build DOM nodes quickly. Its simple API will be natural to anyone who has used dojo.attr(). Even better, Pete&#8217;s exciting PlugD [...]]]></description>
			<content:encoded><![CDATA[<p>Dojo 1.3 <a href="http://www.dojotoolkit.org/2009/03/31/dojo-1-3-now-available">is here</a>! (<a href="http://download.dojotoolkit.org/release-1.3.0/">download site</a>)</p>
<p>If you&#8217;re already using Dojo, this should be a no-brainer upgrade. It&#8217;s out-and-out better. As a quick example, <code>dojo.create("tagname", { /*properties*/ })</code> is now the preferred way to build DOM nodes quickly. Its simple API will be natural to anyone who has used <code>dojo.attr()</code>. Even better, Pete&#8217;s <a href="http://code.google.com/p/plugd">exciting PlugD version of dojo.js has been updated to 1.3 as well</a>.</p>
<p>1.3&#8242;s Core features the new &#8220;Acme&#8221; CSS selector engine which provides a big boost in speed for many operations in the fast-path. <a href="http://alex.dojotoolkit.org/2009/03/dojo-13b3-is-out/">I blogged before</a> about the work we did to make Acme fast, and rest assured it is (in aggregate, across all use cases) quicker than any other selector system you can get your hands on today. But selector performance isn&#8217;t where it&#8217;s really at, and I&#8217;ve been saying that for a long time. </p>
<p>Luckily, Pete Higgins decided to prove it and has been working on a new set of benchmarks with the help of other toolkit vendors (to ensure fairness) called &#8220;<a href="http://dante.dojotoolkit.org/taskspeed/">TaskSpeed</a>&#8220;. Dojo 1.3 wins by a wide margin. Across all the reported browsers so far, <b>Dojo is <em>at least</em> 2 times faster than other toolkits on common DOM operations</b>. We&#8217;ve worked very hard over the years to make sure that Dojo&#8217;s APIs don&#8217;t encourage you to do things that will hurt you later, and TaskSpeed finally shows how much this philosophy pays off:</p>
<p><a href="http://dante.dojotoolkit.org/taskspeed/report/charts.html"><img src="http://alex.dojotoolkit.org/wp-content/uploads/2009/03/taskspeed.png" alt="taskspeed" title="taskspeed" width="560" height="400" class="aligncenter size-medium wp-image-916" /></a></p>
<div style="padding-left: 3em; padding-right: 3em;"><i>The numbers above are from <a href="http://dante.dojotoolkit.org/taskspeed/">TaskSpeed</a>, a new toolkit benchmark developed by Pete Higgins with tests contributed by other toolkit authors to ensure fairness. Shorter is better.</i></div>
<p><strike>Given that DOM is the primary bottleneck in most apps</strike> <em>DOM is a big bottleneck in today&#8217;s apps, usually just behind network I/O</em> and these tests demonstrate how Dojo&#8217;s approach to keeping things fast pays off not just on micro benchmarks like CSS selector speed, performance improvements to single toolkit functions, or even file size &#8211; but on aggregate performance where it really matters. Dojo&#8217;s modern, compact syntax for these common operations doesn&#8217;t slow it down, either. For instance, if you go check out the <a href="http://dante.dojotoolkit.org/taskspeed/report/charts.html">TaskSpeed reporting page</a>, you&#8217;ll see that where browsers are slowest (IE6/7/8, etc.), Dojo&#8217;s focus on performance pays off most. Why use a toolkit that&#8217;s going to hurt you when it really counts, particularly when Dojo so easy to get started with?  Dojo&#8217;s Core has been designed from the ground up with APIs that encourage you to do things that are fast and keep you from doing things that are slow unless you really know what you&#8217;re doing. In some cases, we&#8217;ve made hard size-on-the-wire tradeoffs in order to keep actual app performance speedy. That hard engineering doesn&#8217;t show up in micro-benchmarks or single test release-over-release improvements or the &#8220;my toolkit is smaller&#8221; comparisons that some would prefer that web developers focus on. It&#8217;s easy to win rigged games, after all. It&#8217;s only when you see APIs composed together in real-world ways, across browsers, that you can start to see the real impact of a toolkit&#8217;s design philosophy. Dojo is designed to help you make things that are awesome for users, and that means they need to be <em>FAST</em>.</p>
<p>Other toolkits have released performance numbers of late, and most of them have been either reported badly or run without much rigor, so it&#8217;s exciting to see everyone finally pitching in to build end-to-end tests that show how library design decisions interact with real-world realities of browsers. The TaskSpeed tests have been designed to be both even-handed and reliable (no times below timer resolution, etc.). The <a href="http://dante.dojotoolkit.org/taskspeed/report/charts.html">reporting page is also designed to make the results understandable</a> and put them in context. A lot of care has been taken to keep this benchmark honest. JavaScript developers have suffered at the hand of <a href="http://ajaxian.com/archives/querying-the-dom-on-the-sly">chart junk</a> for far too long.</p>
<p>I can&#8217;t do 1.3 justice in a single blog post, so I recommend that you check out these resources and then just dive in:</p>
<ul>
<li><a href="http://www.dojotoolkit.org/2009/03/31/dojo-1-3-now-available">Pete&#8217;s release announcement</a></li>
<li><a href="http://www.dojotoolkit.org/book/dojo-1-3-release-notes">The Official 1.3 Release Notes</a></li>
<li><a href="http://docs.dojocampus.org/">The new Documentation (at Dojo Campus)</a></li>
<li><a href="http://download.dojotoolkit.org/release-1.3.0/cheat.html">The new 1.3 Core Cheat Sheet</a></li>
<li><a href="http://code.google.com/p/plugd/">PlugD: An even easier way to get going with Dojo</a></li>
<li><a href="http://dante.dojotoolkit.org/taskspeed/">Run the TaskSpeed tests for yourself</a> then <a href="http://dante.dojotoolkit.org/taskspeed/report/charts.html">see how the toolkits stack up</a> (hint: everything you thought you knew about JS library performance was probably wrong.)</li>
<li>Check out integrations for Dojo that you can probably drop right in to your workflow, no matter what stack you&#8217;re using: , <a href="http://www.springsource.org/webflow">Spring Web Flow (Java)</a>, <a href="http://code.google.com/p/dojango/">Dojango (Django/Python)</a>, <a href="http://code.google.com/p/d-rails/">DRails (Ruby/RoR)</a>, <a href="http://code.google.com/p/tatami/">Tatami (Java/GWT)</a>, <a href="http://framework.zend.com/">Zend (PHP)</a>, or <a href="http://dojomino.com/">Dojomino (Domino Server)</a>.</li>
</ul>
<p>Big thanks to the folks who tried out the betas and RC&#8217;s and helped make 1.3 solid.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2009/03/dojo-13-is-out/feed/</wfw:commentRss>
		<slash:comments>11</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>Joining Google</title>
		<link>http://infrequently.org/2008/11/joining-google/</link>
		<comments>http://infrequently.org/2008/11/joining-google/#comments</comments>
		<pubDate>Sun, 23 Nov 2008 21:48:40 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[openweb]]></category>
		<category><![CDATA[personal]]></category>
		<category><![CDATA[sitepen]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=840</guid>
		<description><![CDATA[Starting next month, I&#8217;ll be a Googler. To my great surprise, I&#8217;ve been at SitePen two and a half years. It has been nothing short of wonderful which may explain why it doesn&#8217;t feel like it has been that long. When I look back at what we&#8217;ve accomplished it&#8217;s also surprising that we&#8217;ve been able [...]]]></description>
			<content:encoded><![CDATA[<p>Starting next month, I&#8217;ll be a Googler.</p>
<p>To my great surprise, I&#8217;ve been at SitePen two and a half years. It has been nothing short of wonderful which may explain why it doesn&#8217;t feel like it has been that long. When I look back at what we&#8217;ve accomplished it&#8217;s also surprising that we&#8217;ve been able to do all if it in such a short timeframe. Between the huge client projects and re-building Dojo from the ground up, it has been busy bordering on nutty.</p>
<p>It already makes me sad to leave behind working with the SitePen crew, many of whom I helped to hire in and who I count among my closest friends. But I won&#8217;t be entirely gone. I&#8217;ll still be contributing to Dojo in my new role, if less frequently. Not that it&#8217;ll slow the project down any. Pete, Bill, Adam, and Tom have Dojo well in hand and have been driving things forward at a furious rate. Dojo has always been a team effort, and I&#8217;m excited about the improvements coming in 1.3. I&#8217;ve gotten a dis-proportionate amount of the credit over the years (and not enough of the blame), and as Dojo evolves from here it will continue to be because companies like <a href="http://sitepen.com">SitePen</a>, <a href="http://uxebu.com/">Uxebu</a>, <a href="http://aol.com">AOL</a>, and <a href="http://ibm.com">IBM</a> have all been able to contribute to make it happen and that leaders like Pete Higgins have stepped up to lead and teach and learn with the community. My deepest thanks go to Dylan and SitePen for having let me be a part of that process on a daily basis for the last couple of years.</p>
<p>So what could possibly pry me away from such a sweet, sweet gig at SitePen? </p>
<p>In a word, <a href="http://www.google.com/chrome">Chrome</a>.</p>
<p>Three years after many of my friends joined Google, the appeal of getting to fix the &#8220;web as platform&#8221; problem from the inside has finally proven irresistible. There&#8217;s much to do, and the WebKit platform seems like the best shot that we have (collectively) at forging a future that&#8217;s not just open, but also markedly better. At SitePen I&#8217;ve had the chance to make the web a better place through Dojo. At Google I&#8217;ll have a chance to do it from the browser itself.</p>
<p>To the friends I&#8217;m leaving, it was a privilege to work with you. To the friends I&#8217;m joining, thanks for your trust and faith.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/11/joining-google/feed/</wfw:commentRss>
		<slash:comments>35</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>ZendCon Notes</title>
		<link>http://infrequently.org/2008/09/zendcon-notes/</link>
		<comments>http://infrequently.org/2008/09/zendcon-notes/#comments</comments>
		<pubDate>Fri, 19 Sep 2008 18:35:06 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[webdev]]></category>
		<category><![CDATA[sitepen]]></category>
		<category><![CDATA[zend]]></category>
		<category><![CDATA[zendcon]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=778</guid>
		<description><![CDATA[I gave a talk on Dojo Wednesday at ZendCon, and when I walked into the room for the talk, there was some disorder as the conference center staff were taking out the tables to fit more chairs in. Even with the extra space, the room was totally packed, thanks in large part to the amazing [...]]]></description>
			<content:encoded><![CDATA[<p>I gave a talk on Dojo Wednesday at <a href="http://www.zendcon.com/ZendCon08/">ZendCon</a>, and when I walked into the room for the talk, there was some disorder as the conference center staff were taking out the tables to fit more chairs in. Even with the extra space, the room was totally packed, thanks in large part to the amazing Dojo integration work that the Zend team has done. </p>
<p>As of <a href="http://framework.zend.com/">Zend Framework 1.6</a>, you can include some trivial code inside your ZF views to pull in Dojo:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&lt;</span> ? 
	<span style="color: #666666; font-style: italic;">// setup required dojo elements:</span>
	<span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dojo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #339933;">-&gt;</span><span style="color: #004000;">enable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$this</span><span style="color: #339933;">-&gt;</span><span style="color: #004000;">dojo</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p>Once enabled on your page, ZF 1.6 also includes a full set of helpers to let you set up Dijit components from PHP. <a href="http://framework.zend.com/manual/en/zend.dojo.html">The excellent ZF docs has the full story</a>. Perhaps most exciting from my perspective, though, is how simple ZF makes getting up-and-running with Dojo and how nicely it ties in with custom builds and CDN-hosted versions of Dojo as well. <a href="http://www.zend.com/en/resources/webinars/framework">Matthew Weier O&#8217;Phinney and Will Sinclair</a> recently did a screencast that walks through a lot of these options. If you&#8217;re considering ZF+Dojo, I strongly recommend you check it out.</p>
<p>The talk I gave on Wed was mostly focused on Dojo and the reasons we built it in the layered way that we have and how you can choose to use Dojo at whatever level of abstraction feels right for your app. Slides are here (5.1MB, PDF):</p>
<p><a href="/08/ZendCon/PowerOfDojo.pdf"><br />
<img src="/08/ZendCon/PowerOfDojo.001.png" style="border: none; width: 350px;"/><br />
</a></p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/09/zendcon-notes/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Dojo&#8217;s Query System: No, Really, It&#8217;s That Fast</title>
		<link>http://infrequently.org/2008/08/dojos-query-system-no-really-its-that-fast/</link>
		<comments>http://infrequently.org/2008/08/dojos-query-system-no-really-its-that-fast/#comments</comments>
		<pubDate>Thu, 21 Aug 2008 23:51:59 +0000</pubDate>
		<dc:creator>alex</dc:creator>
				<category><![CDATA[community]]></category>
		<category><![CDATA[dojo]]></category>
		<category><![CDATA[webdev]]></category>

		<guid isPermaLink="false">http://alex.dojotoolkit.org/?p=743</guid>
		<description><![CDATA[As outlined by JQuery lead John Resig in this post, it&#8217;s hard not to notice how much Dojo&#8217;s query engine stomps on the the competition on current browsers. Dojo will load even quicker when we&#8217;re able to remove the XPath branch in the query engine which is currently only being kept on life support for [...]]]></description>
			<content:encoded><![CDATA[<p>As outlined by JQuery lead John Resig <a href="http://ejohn.org/blog/queryselectorall-in-firefox-31/">in this post</a>, it&#8217;s hard not to notice how much Dojo&#8217;s query engine stomps on the the competition on current browsers. Dojo will load even quicker when we&#8217;re able to remove the XPath branch in the query engine which is currently only being kept on life support for the benefit of Firefox.  The rest of Dojo has been designed with the same eye to real-world performance factors in mind, hence the build and package systems which help you <a href="http://video.yahoo.com/watch/1040890/3880720">implement Steve Souders&#8217; performance recommendations</a> gradually, without major code changes.</p>
<p>Regardless of how good it feels to see our numbers recognized for all the hard work that has gone into the Dojo design, I think it&#8217;s also good to keep them in perspective. Most of the available query engines are &#8220;fast enough&#8221; &ndash; although there&#8217;s really no reason why your query engine of choice should be twice as slow as Dojo&#8217;s, given that ours is <a href="http://almaer.com/blog/being-open-is-hard-as-we-have-seen-this-week">100-point Open Source</a>. Having a native implementation is nice, but the primary benefit now is in reducing the number of bytes we need to send on the wire, not in actual query speed advantages. Making queries faster isn&#8217;t in the critical path for improving the real-world performance of any Dojo apps I know of, and I bet the same is true for JQuery users. Reducing the size of the libraries, on the other hand, is still important. Now that we&#8217;re all fast enough, it&#8217;s time that we stopped beating on this particular drum lest we lose the plot and the JavaScript community continue to subject itself to endless rounds of benchmarketing.</p>
]]></content:encoded>
			<wfw:commentRss>http://infrequently.org/2008/08/dojos-query-system-no-really-its-that-fast/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>

