<?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"
	>

<channel>
	<title>Graceful Exits &#187; paradigms</title>
	<atom:link href="http://www.jpstacey.info/blog/category/paradigms/www.jpstacey.info/blog/category/paradigms/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jpstacey.info/blog</link>
	<description>Garbage collection, in a very real sense</description>
	<pubDate>Thu, 01 Jan 2009 23:18:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6.3</generator>
	<language>en</language>
			<item>
		<title>Variable assignment in Django templates, sort of</title>
		<link>http://www.jpstacey.info/blog/2008/05/29/variable-assignment-in-django-templates-sort-of/</link>
		<comments>http://www.jpstacey.info/blog/2008/05/29/variable-assignment-in-django-templates-sort-of/#comments</comments>
		<pubDate>Thu, 29 May 2008 13:08:33 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[efficiency]]></category>

		<category><![CDATA[hacking]]></category>

		<category><![CDATA[layers]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[assignment]]></category>

		<category><![CDATA[django]]></category>

		<category><![CDATA[equals]]></category>

		<category><![CDATA[hack]]></category>

		<category><![CDATA[include]]></category>

		<category><![CDATA[template]]></category>

		<category><![CDATA[variable]]></category>

		<category><![CDATA[with]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2008/05/29/variable-assignment-in-django-templates-sort-of/</guid>
		<description><![CDATA[Use and abuse of the "with" programmatic statement to make your Django template code less mad.]]></description>
			<content:encoded><![CDATA[<p>Django&#8217;s templating language is intentionally quite restrictive. The idea is that you have to do all your data munging in the control-ish sublayer of the view layer, in the method registered as handling the view in <code>urls.py</code>. In principle this simplifies templates, but in practice it can make life for the developer more difficult: you have to really think ahead, and assemble your variables properly, so that the templating language can use simple iterative loops to prepare your HTML.</p>
<p>What if you want the same output for several different data structures? Let&#8217;s say we have three people, and we&#8217;d like to run the following <a href="http://www.djangoproject.com/documentation/templates/#include" >include</a>, saved as <code>name.html</code>, on all three:</p>
<blockquote class="code"><p>&lt;p>{{ person.firstname }} {{ person.surname }}&lt;/p></p>
</blockquote>
<p>Ideally you&#8217;d have the three people in a structure called <code>people</code>, and be able to run:</p>
<blockquote class="code"><p>{% for person in people %}{% include &#8220;name.html&#8221; %}{% endfor %}</p>
</blockquote>
<p>But what if the order matters? What if you need <code>account_director</code> to do different things in the template from <code>project_manager</code>? You&#8217;d want to send them through as separate data structures, and this:</p>
<blockquote class="code"><p>{% include &#8220;name.html&#8221; %}<br />
{% include &#8220;name.html&#8221; %}<br />
{% include &#8220;name.html&#8221; %}</p>
</blockquote>
<p>would just do nothing, because it references <code>person</code> and not <code>account_director</code>. An alternative is to turn <code>name.html</code> into a custom tag, taking arguments; but if the content of <code>name.html</code> were any more HTML-heavy then you might want to abstract it into the include nonetheless, and then you&#8217;d just be running a custom tag method, to pass variables to a template fragment, to render the fragment, to pass it back up to the template. It&#8217;d be nicer if we could do this with core functionality instead.</p>
<p>Using the <a href="http://www.djangoproject.com/download/" >latest development version of Django</a>, we can implement basic variable assignment&#8212;getting <code>person</code> to reference whatever we want in the template layer&#8212;using the <a href="http://www.djangoproject.com/documentation/templates/#with" ><code>with</code> template tag</a>. This means that we can wrap each <code>include</code> tag to produce the required output:</p>
<blockquote class="code"><p>{% with account_director as person %}<br />
&nbsp;&nbsp;{% include &#8220;name.html&#8221; %}<br />
{% endwith %}<br />
{% with project_manager as person %}<br />
&nbsp;&nbsp;{% include &#8220;name.html&#8221; %}<br />
{% endwith %}<br />
{% with lead_developer as person %}<br />
&nbsp;&nbsp;{% include &#8220;name.html&#8221; %}<br />
{% endwith %}</p>
</blockquote>
<p>It seems like overkill for our <code>name.html</code> example, but there are plenty of situations&#8212;I just found one, hence this post&#8212;where it makes sense to factor out code into an include: being able to fiddle with the template context before including it is a lightweight alternative to template tags and a tidy alternative to dumping the HTML right there in the primary template.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2008/05/29/variable-assignment-in-django-templates-sort-of/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Compiling languages down to Javascript</title>
		<link>http://www.jpstacey.info/blog/2008/05/12/compiling-languages-down-to-javascript/</link>
		<comments>http://www.jpstacey.info/blog/2008/05/12/compiling-languages-down-to-javascript/#comments</comments>
		<pubDate>Mon, 12 May 2008 14:39:46 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[futurology]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[quickies]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[browser]]></category>

		<category><![CDATA[convergence]]></category>

		<category><![CDATA[ide]]></category>

		<category><![CDATA[java]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[virtual]]></category>

		<category><![CDATA[vm]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2008/05/12/compiling-languages-down-to-javascript/</guid>
		<description><![CDATA[A hundred years from now, all code will look both similar and different.]]></description>
			<content:encoded><![CDATA[<p>If it&#8217;s really the case that <a href="/blog/2008/05/11/emacs-as-an-anagram-of-ecma-s/">browsers, virtual machines and IDEs will one day converge</a>, then the first steps would be to <a href="http://ejohn.org/blog/running-java-in-javascript/">run Java, Ruby and other languages in a browser using Javascript</a>. (Hat tip to <a href="http://gagravarr.livejournal.com/">Nick</a> for the timely links.)</p>
<p>[Edit: <a href="http://codespeak.net/pypy/dist/pypy/doc/js/whatis.html">run Python using Javascript</a> too.]</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2008/05/12/compiling-languages-down-to-javascript/feed/</wfw:commentRss>
		</item>
		<item>
		<title>&#8220;You have to have something bad happen to you&#8221;</title>
		<link>http://www.jpstacey.info/blog/2008/01/07/you-have-to-have-something-bad-happen-to-you/</link>
		<comments>http://www.jpstacey.info/blog/2008/01/07/you-have-to-have-something-bad-happen-to-you/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 12:05:11 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[diagnostics]]></category>

		<category><![CDATA[efficiency]]></category>

		<category><![CDATA[hacking]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[projects]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[bloat]]></category>

		<category><![CDATA[code]]></category>

		<category><![CDATA[copy]]></category>

		<category><![CDATA[debug]]></category>

		<category><![CDATA[ide]]></category>

		<category><![CDATA[paste]]></category>

		<category><![CDATA[rants]]></category>

		<category><![CDATA[reuse]]></category>

		<category><![CDATA[steve]]></category>

		<category><![CDATA[yegge]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2008/01/07/you-have-to-have-something-bad-happen-to-you/</guid>
		<description><![CDATA[Steve Yegge on code&#8217;s worst enemy:
&#8230; This brings us to the second obviously-bad thing that can go wrong with code bases: copy and paste. It doesn&#8217;t take very long for programmers to learn this lesson the hard way. It&#8217;s not so much a rule you have to memorize as a scar you&#8217;re going to get [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://steve-yegge.blogspot.com/">Steve Yegge</a> on <a href="http://steve-yegge.blogspot.com/2007/12/codes-worst-enemy.html">code&#8217;s worst enemy</a>:</p>
<blockquote><p>&#8230; This brings us to the second obviously-bad thing that can go wrong with code bases: copy and paste. It doesn&#8217;t take very long for programmers to learn this lesson the hard way. It&#8217;s not so much a rule you have to memorize as a scar you&#8217;re going to get whether you like it or not. Computers make copy-and-paste really easy, so every programmer falls into the trap once in a while. The lesson you eventually learn is that code always changes, always always always, and as soon as you have to change the same thing in N places, where N is more than 1, you&#8217;ll have earned your scar&#8230;.</p>
</blockquote>
<p>Code reuse is great, although some languages punish you for it: Coldfusion takes a performance hit on behalf of debug logging whenever it crosses a component boundary, even if debugging is turned off. And a lot of includes scattered across the place can make it difficult to track what&#8217;s going on (unless you use those very IDEs that Steve suggests treat code like heaps of dirt to be rearranged). I suppose ultimately it&#8217;s about developing an instinct for balancing short-term performance, ongoing maintainability and long-term scalability, and you only learn that by dint of many, many scars.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2008/01/07/you-have-to-have-something-bad-happen-to-you/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pretending that Javascript is XSL, part 3: hCard to vCard</title>
		<link>http://www.jpstacey.info/blog/2007/12/20/pretending-that-javascript-is-xsl-part-3-hcard-to-vcard/</link>
		<comments>http://www.jpstacey.info/blog/2007/12/20/pretending-that-javascript-is-xsl-part-3-hcard-to-vcard/#comments</comments>
		<pubDate>Thu, 20 Dec 2007 21:07:55 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[hacking]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[standards]]></category>

		<category><![CDATA[browser]]></category>

		<category><![CDATA[client]]></category>

		<category><![CDATA[conversion]]></category>

		<category><![CDATA[functional]]></category>

		<category><![CDATA[hcard]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[microformats]]></category>

		<category><![CDATA[suda]]></category>

		<category><![CDATA[tree]]></category>

		<category><![CDATA[vcard]]></category>

		<category><![CDATA[x2v]]></category>

		<category><![CDATA[xsl]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/12/20/pretending-that-javascript-is-xsl-part-3-hcard-to-vcard/</guid>
		<description><![CDATA[In previous posts (part 1, part 2) I established the possibility that there were advantages to making Javascript more functional, to bring it in line with CSS and XSL. I didn&#8217;t say what these were, particularly, but I then provided a few bits and pieces on top of jQuery to make Javascript just that: functional [...]]]></description>
			<content:encoded><![CDATA[<p>In previous posts (<a href="/blog/?p=109">part 1</a>, <a href="/blog/?p=110">part 2</a>) I established the possibility that there were advantages to making Javascript more functional, to bring it in line with CSS and XSL. I didn&#8217;t say what these were, particularly, but I then provided a few bits and pieces on top of jQuery to make Javascript just that: functional and quasi-XSL in its behaviour.</p>
<p>Now I&#8217;d like to start exploiting that behaviour, and I&#8217;m going to use the <a href="http://microformats.org/wiki/hcard">hCard microformat</a> to illuminate its use. Briefly: a microformat is a set of agreed HTML classes used to invisibly encode structured semantic data in HTML; hCard is the implementation in HTML of the <a href="http://www.ietf.org/rfc/rfc2426.txt">vCard</a> specification for &#8220;virtual business card&#8221; files, using microformat classes. If you mark up people&#8217;s addresses using the hCard classes, then it&#8217;s possible to automate the conversion from hCard-enabled HTML to vCards, meaning you can click on buttons on webpages and have a vCard served up to you containing the contact information present in the webpage, verbatim, in a format you can put into your address book of choice.</p>
<p>One of the most-used conversion methods&#8212;<a href="http://suda.co.uk/projects/X2V/">Brian Suda&#8217;s X2V</a>, a web service which converts XHTML with hCard markup into vCards and then presents them to the site visitor&#8212;uses XSL. In fact, that was what got me thinking about this whole system. Brian&#8217;s work is neat, although his own server takes a hit every time someone uses the web service (and it only works on XHTML, not non-XML HTML. What if, I thought, we could get the browser to do it instead; if we could implement template-like functional Javascript? </p>
<p>Anyway, below we find a couple of <a href="http://microformats.org/wiki/hcard">hCards</a>, culled more or less directly from the <a href="http://microformats.org/wiki/hcard-examples">Microformats examples page</a>. </p>
<blockquote>
<div class="vcard">
	<a class="url fn" href="http://home.earthlink.net/~fdawson">Frank Dawson</a></p>
<div class="org">Lotus Development Corporation</div>
<div class="adr">
		<span class="type">work</span> address 	(<abbr class="type" title="postal">mail</abbr> and <abbr class="type" title="parcel">packages</abbr>):</p>
<div class="street-address">6544 Battleford Drive</div>
<p>		<span class="locality">Raleigh</span> <span class="region">NC</span> <span class="postal-code">27613-3502</span></p>
<div class="country-name">U.S.A.</div>
</div>
<div class="tel">
		<span class="value">+1-919-676-9515</span> (<abbr class="type" title="WORK">w</abbr>, <abbr class="type" title="VOICE">v</abbr><abbr class="type" title="MSG">m</abbr>)
	</div>
<div class="tel">
		<span class="value">+1-919-676-9564</span> (<abbr class="type" title="WORK">w</abbr><abbr class="type" title="FAX">f</abbr>)
	</div>
<p>	<a class="email" href="mailto:Frank_Dawson@Lotus.com">Frank_Dawson@Lotus.com</a> <span class="email"><abbr class="type" title="VOICE">alt</abbr>ernative email <em>fdawson@earthlink.net</em></span>
</p>
</div>
<div class="vcard">
	<a class="email fn" href="mailto:howes@netscape.com">Tim Howes</a></p>
<div class="org">Netscape Communications Corp.</div>
<div class="adr">
		<span class="type">work</span> address:</p>
<div class="street-address">501 E. Middlefield Rd.</div>
<p>		<span class="locality">Mountain View</span>, <span class="region">CA</span> <span class="postal-code">94043</span></p>
<div class="country-name">U.S.A.</div>
</div>
<div class="tel">
		<span class="value">+1-415-937-3419</span> (<abbr class="type" title="WORK">w</abbr>, <abbr class="type" title="VOICE">v</abbr><abbr class="type" title="MSG">m</abbr>)
	</div>
<div class="tel">
		<span class="value">+1-415-528-4164</span> (<abbr class="type" title="WORK">w</abbr><abbr class="type" title="FAX">f</abbr>)
	</div>
</div>
</blockquote>
<p>They look like slightly unstructured HTML, don&#8217;t they? That&#8217;s sort of the point. But hidden in the HTML are vCard classes. How do we tease them out with Javascript?</p>
<p>Well, there&#8217;s a question to be asked before that, I suppose, which is: why would we follow your method, and not someone else&#8217;s? What&#8217;s so good about functional Javascript? Good question. Well, if every hCard looked like the above, then you could write some completely procedural Javascript to turn it into a vCard. No problem.</p>
<p>But what if the order of the content was changed? The hCard&#8212;indeed, microformats in general&#8212;has quite a malleable structure, with some classes sometimes appearing on elements inside other elements, and sometimes not. What if there were more telephone numbers and email addresses, and what if they turned up in all sorts of different orders? These are just HTML classes, after all. With procedural Javascript you could start writing <code>switch</code>/<code>case</code> statements to cover every opportunity, and essentially come up with one big unavoidably recursive function. It&#8217;ll be hard to structure, hard to maintain and completely unmodular.  A document-driven method of extracting the vCard, on the other hand, doesn&#8217;t need to worry about all the various different combinations of nested elements: it would just keep one eye on context and process whatever it found. Also, the development cycle could be faster, because templates could be overridden without breaking existing behaviour: just use the <code>template()</code> command to override existing behaviour.</p>
<p>Let&#8217;s instead assume you&#8217;re following my every word. For this next bit, you&#8217;ll need Firefox and Firebug, or to stuff all these instructions into a single file. Otherwise, you&#8217;ll have to take my word for it. Firstly, I&#8217;ve included jQuery on every page of my blog, so if you&#8217;ve got the &#8216;bug then you don&#8217;t have to resort to my <a href="http://www.jpstacey.info/blog/2007/12/10/insert-any-javascript-bookmarklet/">insert-JS bookmarklet</a> to squirt it in. </p>
<p>So: first, create the <code>treewalker()</code> and <code>template()</code> functions from part 2. Next, assign <code>treewalker()</code> to <code>body</code> and everything below it:</p>
<blockquote class="code"><p>
template(&quot;body, body *&quot;, treewalker);<br />
template(&quot;body, body *&quot;, treewalker, &quot;default&quot;);
</p>
</blockquote>
<p>You could restrict this assignment to everything within the <code>.vcard</code> elements, by giving the relevant CSS specifier instead, if there were a lot of content outside the hCards. It would speed up the initial setup phase, but it does complicate the demonstration so I&#8217;ve left that refinement out.</p>
<p>Remember we ran the treewalking before? Do that now:</p>
<blockquote class="code"><p>var result = document.body.treewalk();</p>
</blockquote>
<p>All being well, you should get a blank string back. Now it&#8217;s time to start adding some alternative rules with <code>template()</code>. Try this:</p>
<blockquote class="code"><p>
template(&quot;.vcard&quot;, function() { return &quot;BEGIN:VCARDn&quot; + this.default() + &quot;END:VCARDn&quot; });
</p>
</blockquote>
<p>Now run the treewalker again. Oh, each hCard has just given you a vCard! An&#8230; empty vCard. Isn&#8217;t that great? Um. We can add to that, though:</p>
<blockquote class="code"><p>
template(&quot;.vcard .fn&quot;, function() { return &quot;FN:&quot; + $(this).text() + &quot;n&quot; + this.default(); });<br />
template(&quot;.vcard .org&quot;, function() { return &quot;ORG:&quot; + $(this).text() + &quot;n&quot; + this.default(); });
</p>
</blockquote>
<p>Now <code>document.body.treewalk()</code> doesn&#8217;t just return a vCard for every hCard, but it knows about names and organisations. Also, because we keep including the call to <code>this.default()</code> in our overrides, we still treewalk into any element inside the FN or ORG containers.</p>
<p>What about emails? Well, in the source we can spot an <code>a.email</code> element up there, so let&#8217;s give the following a whirl:</p>
<blockquote class="code"><p>
template(&quot;.vcard .email&quot;, function() { return &quot;EMAIL;TYPE=internet:&quot; + this.href.replace(/mailto:/, &quot;&quot;) + &quot;n&quot; + this.default(); });
</p>
</blockquote>
<p>Try running <code>document.body.treewalk()</code> again. Hm. I don&#8217;t know about you, but I&#8217;m getting an error from that. Ah, wait: sometimes we have <code>span.email</code> rather than <code>a.email</code>. Spans don&#8217;t have <code>@href</code> attributes. Well, we could change the above rule and immediately reapply it using <code>template()</code> with no ill effects. But instead let&#8217;s keep it in place, and use a more specific specifier to override it <em>just on spans</em>:</p>
<blockquote class="code"><p>
template(&quot;.vcard span.email&quot;, function() { return &quot;EMAIL;TYPE=internet:&quot; + $(this).find(&quot;.value&quot;).text() + &quot;n&quot; + this.default(); });
</p>
</blockquote>
<p>Re-run the treewalker. It now finds all email hCard elements and brings them out into the vCards!</p>
<p>I&#8217;ll leave you with one more demonstration, for the slightly more complex TELephone field. As you can see above, there are lots of &#8220;types&#8221; for this field (Work, VoiceMail, etc.) and these sit in child elements of the telephone element. So we need to assign overrides to both the telephone element and its children.</p>
<p>Here&#8217;s a rule for the TELephone container:</p>
<blockquote class="code"><p>
template(&quot;.vcard .tel&quot;, function() {<br />
&nbsp;&nbsp;var t = &quot;TEL&quot;;<br />
&nbsp;&nbsp;// Run defaults to get types where appropriate<br />
&nbsp;&nbsp;t += this.default().replace(/,/, &quot;;&quot;) + &quot;:&quot;;<br />
&nbsp;&nbsp;// See if we&#8217;ve got a &#8220;value&#8221; child<br />
&nbsp;&nbsp;var val = $(this).find(&quot;.value&quot;);<br />
&nbsp;&nbsp;return t + (val.length ? val.text() : $(this).text()) + &quot;n&quot;;<br />
});
</p>
</blockquote>
<p>This method is a bit more complex because we need <code>default()</code> to just get the <code>.type</code> children, and then we reach down to get. Maybe if we could give specifier argument to the default behaviour e.g. <code>default('.type')</code> first, then <code>default('.value')</code>&#8230; But that&#8217;s a project for another day, I think. Right now, let&#8217;s assign a rule to the types children and then run our treewalker:</p>
<blockquote class="code"><p>
template(&quot;.vcard .tel .type&quot;, function() {<br />
&nbsp;&nbsp;var jQ = $(this);<br />
&nbsp;&nbsp;return &quot;,&quot; + (jQ.attr(&quot;title&quot;) ? jQ.attr(&quot;title&quot;) : jQ.text());<br />
});
</p>
</blockquote>
<p>Result? You should now have Javascript which can produce vCards (currently without geographical address support, as I don&#8217;t have time and you might get bored) from the hCard microformat. It&#8217;s easy to extend, easy to maintain and, in my opinion, fairly concise. Here&#8217;s the whole shebang, less the two framework functions from my previous posts:</p>
<blockquote class="code"><p>
// Start with body<br />
template(&quot;body, body *&quot;, treewalker);<br />
template(&quot;body, body *&quot;, treewalker, &quot;default&quot;);<br />
// vCard wrapper<br />
template(&quot;.vcard&quot;, function() { return &quot;BEGIN:VCARDn&quot; + this.default() + &quot;END:VCARDn&quot; });<br />
// FN and ORG<br />
template(&quot;.vcard .fn&quot;, function() { return &quot;FN:&quot; + $(this).text() + &quot;n&quot; + this.default(); });<br />
template(&quot;.vcard .org&quot;, function() { return &quot;ORG:&quot; + $(this).text() + &quot;n&quot; + this.default(); });<br />
// Email - A and SPAN tags<br />
template(&quot;.vcard .email&quot;, function() { return &quot;EMAIL;TYPE=internet:&quot; + this.href.replace(/mailto:/, &quot;&quot;) + &quot;n&quot; + this.default(); });<br />
template(&quot;.vcard span.email&quot;, function() { return &quot;EMAIL;TYPE=internet:&quot; + $(this).find(&quot;.value&quot;).text() + &quot;n&quot; + this.default(); });<br />
// TEL<br />
template(&quot;.vcard .tel&quot;, function() {<br />
&nbsp;&nbsp;var t = &quot;TEL&quot;;<br />
&nbsp;&nbsp;// Run defaults to get types where appropriate<br />
&nbsp;&nbsp;t += this.default().replace(/,/, &quot;;&quot;) + &quot;:&quot;;<br />
&nbsp;&nbsp;// See if we&#8217;ve got a &#8220;value&#8221; child<br />
&nbsp;&nbsp;var val = $(this).find(&quot;.value&quot;);<br />
&nbsp;&nbsp;return t + (val.length ? val.text() : $(this).text()) + &quot;n&quot;;<br />
});<br />
// TEL types<br />
template(&quot;.vcard .tel .type&quot;, function() {<br />
&nbsp;&nbsp;var jQ = $(this);<br />
&nbsp;&nbsp;return &quot;,&quot; + (jQ.attr(&quot;title&quot;) ? jQ.attr(&quot;title&quot;) : jQ.text());<br />
});
</p>
</blockquote>
<p>And that&#8217;s it. I hope the approach comes in useful. By next year, you&#8217;ll have hCard-enabled pages, with vCard conversion in the browser. Happy Christmas!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/12/20/pretending-that-javascript-is-xsl-part-3-hcard-to-vcard/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pretending that Javascript is XSL, part 2: jQuery++</title>
		<link>http://www.jpstacey.info/blog/2007/12/19/pretending-that-javascript-is-xsl-part-2-jquery/</link>
		<comments>http://www.jpstacey.info/blog/2007/12/19/pretending-that-javascript-is-xsl-part-2-jquery/#comments</comments>
		<pubDate>Wed, 19 Dec 2007 09:23:08 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[hacking]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[standards]]></category>

		<category><![CDATA[css]]></category>

		<category><![CDATA[dom]]></category>

		<category><![CDATA[foreach]]></category>

		<category><![CDATA[functional]]></category>

		<category><![CDATA[html]]></category>

		<category><![CDATA[implicit]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[jquery]]></category>

		<category><![CDATA[traversing]]></category>

		<category><![CDATA[tree]]></category>

		<category><![CDATA[walking]]></category>

		<category><![CDATA[xsl]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/12/19/pretending-that-javascript-is-xsl-part-2-jquery/</guid>
		<description><![CDATA[If you&#8217;re here, then you probably came from here, and you want to make Javascript more functional. If you didn&#8217;t come from there&#8212;and this is getting a bit like a Choose-Your-Own-Adventure book, isn&#8217;t it?&#8212;then you might want to go there first, to see if you want to be here.
So: functional Javascript. Not just functional, but [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re here, then you probably came from <a href="/blog/?p=109">here</a>, and you want to make Javascript more functional. If you didn&#8217;t come from there&#8212;and this is getting a bit like a Choose-Your-Own-Adventure book, isn&#8217;t it?&#8212;then you might want to go there first, to see if you want to be here.</p>
<p>So: functional Javascript. Not just functional, but with all the automation of XSL transformations and CSS applications, where you can set it all running and it&#8217;ll produce <em>something</em> and hopefully throw no errors. Let&#8217;s start with jQuery.</p>
<p>jQuery provides Javascript with a functional framework. Here&#8217;s the equivalent of the examples in XSL and CSS, supported by the inclusion of <code>jquery.js</code>:</p>
<blockquote class="code"><p>jQuery(&quot;p.intro&quot;).each(<br />
&nbsp;&nbsp;function() { this.style.color = green; }<br />
);</p>
</blockquote>
<p>I hope the similarities are clear, and not too strained. Now all three languages do implicit looping over sets of element nodes, and no longer require checks for missing elements; that&#8217;s evidence that it&#8217;s starting to behave functionally. There&#8217;s still a few pieces missing, though. We&#8217;d like to be able to iterate over the tree with a set of default rules, and also replace the default rules with our own where necessary. </p>
<p>What would the default rule look like? Well, we can pass around all sorts of objects&#8212;this being an object-oriented language&#8212;but for now let&#8217;s play it safe and follow XSL&#8217;s lead, and have each node return the concatenated text returned by all its child nodes. That means that, by default, the whole HTML document would return an empty string. It might be nice to return an array of equivalent objects, or even some transformed tree, but let&#8217;s remain old-skool. Anyway, we can always serialize any HTML elements we want to include as text, and then stick them back into the DOM later. There&#8217;s probably a way of doing some of these tasks with core jQuery, but as we&#8217;re also passing result data around as well as input data, I&#8217;m going to step outside the framework (its extension model typically takes a jQuery object in, and returns a modified jQuery object, which isn&#8217;t quite what we&#8217;re after).</p>
<p>Here&#8217;s a default rule: it says &#8220;call the default rule (i.e. me) on all my children&#8221;. We&#8217;ll call this rule <code>treewalker</code>, because that&#8217;s what it does. We&#8217;ll also assume that we&#8217;re going to assign this function as the <code>.treewalk</code> method on each element:</p>
<blockquote class="code"><p>
var treewalker = function(i) {<br />
&nbsp;&nbsp;var t = &quot;&quot;;<br />
&nbsp;&nbsp;$(this).children().each(function(i) { t += this.treewalk(); } );<br />
&nbsp;&nbsp;return t;<br />
}
</p>
</blockquote>
<p>And here&#8217;s a way of assigning rules to elements. It&#8217;ll assign the rule as the <code>.treewalk</code> method unless we specify otherwise. </p>
<blockquote class="code"><p>
var template = function(specifier, fn, property) {<br />
&nbsp;&nbsp;if (typeof property == &quot;undefined&quot;) property = &quot;treewalk&quot;;<br />
&nbsp;&nbsp;$(specifier).each(function(i) { this[property] = fn; });<br />
}
</p>
</blockquote>
<p>It looks a bit clunky, because falling back on the default property means we have to have an if-exists check. That&#8217;s to be avoided where possible in functional programming, but bear in mind that we&#8217;re still looking under the bonnet (or &#8220;hood&#8221; if you like), not at the actual functional code. We&#8217;ll get to the fully-functional bit shortly.</p>
<p>We&#8217;ve got one last bit and we&#8217;re done. We want to put the default rule on every element within a certain scope: we&#8217;ll assume for now that the whole HTML document body is to be treated; that might be computationally heavy for big documents, but we could change that. We&#8217;ve already defined a way of putting rules onto things, so let&#8217;s use that to put the treewalker function in as both <code>.treewalk</code> and <code>.default</code>. That way, we have a copy of the method hanging around, that we can fall back on if we overwrite it:</p>
<blockquote class="code"><p>
template(&quot;body, body *&quot;, treewalker);<br />
template(&quot;body, body *&quot;, treewalker, &quot;default&quot;);
</p>
</blockquote>
<p>That&#8217;s it. We&#8217;re now ready to pretend our Javascript is XSL. Here&#8217;s how we run it:</p>
<blockquote class="code"><p>var result = document.body.treewalk();</p>
</blockquote>
<p>Try it. &#8220;But that&#8217;s just an empty string!&#8221; you might, if you were feeling ungrateful, complain. Are you never satisfied? <a href="/blog/?p=114">More on this later</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/12/19/pretending-that-javascript-is-xsl-part-2-jquery/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pretending that Javascript is XSL, part 1: XSL, CSS and JS side by side</title>
		<link>http://www.jpstacey.info/blog/2007/12/18/pretending-that-javascript-is-xsl-part-1-xsl-css-and-js-side-by-side/</link>
		<comments>http://www.jpstacey.info/blog/2007/12/18/pretending-that-javascript-is-xsl-part-1-xsl-css-and-js-side-by-side/#comments</comments>
		<pubDate>Tue, 18 Dec 2007 10:26:57 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[hacking]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[software]]></category>

		<category><![CDATA[standards]]></category>

		<category><![CDATA[css]]></category>

		<category><![CDATA[dom]]></category>

		<category><![CDATA[functional]]></category>

		<category><![CDATA[html]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[object-oriented]]></category>

		<category><![CDATA[xhtml]]></category>

		<category><![CDATA[xsl]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/12/18/pretending-that-javascript-is-xsl-part-1-xsl-css-and-js-side-by-side/</guid>
		<description><![CDATA[There are three main technologies that your browser employs to present HTML for you: XSL, CSS and Javascript. The first two of these are functional: that is, they turn your incoming (X)HTML documents into a set of functions, or behaviours if you like. Because CSS isn&#8217;t generally considered a language, let alone a functional one, [...]]]></description>
			<content:encoded><![CDATA[<p>There are three main technologies that your browser employs to present HTML for you: XSL, CSS and Javascript. The first two of these are <em>functional</em>: that is, they turn your incoming (X)HTML documents into a set of functions, or behaviours if you like. Because CSS isn&#8217;t generally considered a language, let alone a functional one, then it&#8217;s worth seeing an example in both languages. Here&#8217;s the CSS:</p>
<blockquote class="code"><p>p.intro { color: green; }</p>
</blockquote>
<p>And here&#8217;s a sort-of XSL equivalent:</p>
<blockquote class="code"><p>
&lt;xsl:template match=&quot;p[@class=&apos;intro&apos;]&quot;&gt;<br />
&nbsp;&nbsp;&lt;p color=&quot;green&quot;&gt;&lt;xsl:apply-templates /&gt;&lt;/p&gt;<br />
&lt;/xsl:template&gt;
</p>
</blockquote>
<p>They both take place in the context of some generic processor, which rattles through the document executing default rules (XSL: strip out all but text nodes; CSS: apply the plain styles of your browser) unless <em>your</em> program&#8212;a list of disconnected rules, really&#8212;tells it differently. The combination of (XSL/CSS)+(X)HTML+defaults is thus turned into an explicit script for the browser to run.</p>
<p>So far, so reasonable. But what about the third technology, Javascript? Well, plain Javascript is an object-oriented procedural language. It orders the browser around for a bit, and then when you want to do something to the current page, Javascript manipulates the (X)HTML tree by grasping hold of it with both hands and giving it a tug, using DOM methods like <code>.getElementById(id)</code> and attributes like <code>.parentNode</code>. This procedural approach expects the tree to have a certain structure, or at the very least has to keep checking if the structure has changed and coping with that. This means that the programmer generally has to construct a lot of loops over, say, child elements, and also check for existence a lot. There&#8217;s a slight anomaly, in that you could think of the event-driven aspect of Javascript as being functional&#8212;it turns the user&#8217;s input through clicks, mouse movement and keypresses into browser behaviour, remaining otherwise dormant&#8212;but by and large Javascript&#8217;s meat is procedural.</p>
<p>There&#8217;s two routes you can take at this point. You can either say that, because Javascript is meant to be object-oriented, then the best way to work with it is to augment its functionality and simplify object construction, but ultimately leave it as that: if it weren&#8217;t functional, then it wouldn&#8217;t be Javascript. Or you can say that, given the advantages that XSL and CSS gain by being functional&#8212;a kind of &#8220;safety&#8221;, some scaleability, and document-driven processing&#8212;Javascript might want to have a piece of that too, while sacrificing some of its object orientation.</p>
<p>The first route is entirely laudable, because some problems are object-shaped and some are function-shaped. But, in the spirit of adventure, let&#8217;s investigate the second route for a while: pack some sandwiches and get some stout shoes on, and I&#8217;ll meet you in <a href="/blog/?p=110">my next blog post</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/12/18/pretending-that-javascript-is-xsl-part-1-xsl-css-and-js-side-by-side/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Working out chaotic things</title>
		<link>http://www.jpstacey.info/blog/2007/12/10/working-out-chaotic-things/</link>
		<comments>http://www.jpstacey.info/blog/2007/12/10/working-out-chaotic-things/#comments</comments>
		<pubDate>Mon, 10 Dec 2007 10:22:05 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[business]]></category>

		<category><![CDATA[culture]]></category>

		<category><![CDATA[futurology]]></category>

		<category><![CDATA[non-programming]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[albatross]]></category>

		<category><![CDATA[cd]]></category>

		<category><![CDATA[digital]]></category>

		<category><![CDATA[discbox]]></category>

		<category><![CDATA[download]]></category>

		<category><![CDATA[inrainbows]]></category>

		<category><![CDATA[missingthepoint]]></category>

		<category><![CDATA[mp3]]></category>

		<category><![CDATA[music]]></category>

		<category><![CDATA[radiohead]]></category>

		<category><![CDATA[revolution]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/12/10/working-out-chaotic-things/</guid>
		<description><![CDATA[I&#8217;m so impressed with Radiohead. I was a fan back in the days of The Bends (y&#8217;know: before they literally, if not metaphorically, sold out), and have more affection for Pablohoney than most. But in an era when it&#8217;s trivial to get whatever music you want for free off your mate who happened to buy [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m so impressed with Radiohead. I was a fan back in the days of <cite>The Bends</cite> (y&#8217;know: before they literally, if not metaphorically, sold out), and have more affection for <cite>Pablohoney</cite> than most. But in an era when it&#8217;s trivial to get whatever music you want for free off your mate who happened to buy it, they accepted that fact and gave alternative distribution a whirl. And maybe it worked and maybe it didn&#8217;t: it depends on who you&#8217;re talking to. </p>
<p>Certainly marketing genius and total orphan Lily Allen, and internationally renowned cuttinge-edge futurologist Gene Simmonds are pulling the sort of pouts you&#8217;d expect from them both, and Guy Hands has a look on him like they just cancelled Christmas. But even in these hilariously gurning faces of criticism, and amid the wafting and intermittent atmospheres of genial misunderstanding of how content works these days from the TV and radio monoliths, <a href="http://observer.guardian.co.uk/omm/story/0,,2221299,00.html">Radiohead are keeping chipper.</a> Far more so than I&#8217;ve ever seen them before, in fact. And when everyone&#8217;s on YouTube for free, letting rip with their <a href="http://www.musicisart.ws/?p=503">Thumbs Down webcast</a>, and accepting its reappearance&#8212;syndication, if you like&#8212;all over the shop very shortly afterwards, was a refreshing change from everywhere else exercising rigid control at the loss of an audience.</p>
<p>But for those of you (like me) who were thinking of taking part in Radiohead&#8217;s distribution revolution, yet weren&#8217;t keeping an eye on the time:</p>
<ul>
<li>The download-only area of &#8220;In Rainbows&#8221; <a href="http://www.radiohead.com/deadairspace/index.php?c=303">closed this morning</a>. I just managed to get a copy of the tracks yesterday: I&#8217;m sure if you&#8217;ve missed out then you&#8217;ll all know someone who&#8217;s got a copy they can loan you, right? Loan you until the plain old CD comes out at the start of 2008, right?</li>
<li>Discboxes (40-quid monstrosities that I was secretly waiting till next year to buy) are actually already out and <em>limited stock</em>. I thought from various reportings of the event that they too weren&#8217;t going to be on sale till the new year. <a href="http://www.waste.uk.com/Store/waste-radiohead-dii-11-10023-discbox+audio.html">Get yours while it&#8217;s hot</a>.</li>
</ul>
<p>If there&#8217;s demand I bet there&#8217;ll be more discboxes, but frankly if Radiohead don&#8217;t stamp &#8220;SECOND IMPRESSION&#8221; over the next lot then <a href="http://biz.yahoo.com/ap/071002/apple_iphone_lawsuit.html">I might sue</a>. Actually, if my discbox doesn&#8217;t have &#8220;A TOTAL W.A.S.T.E. OF CARBON&#8221; scrawled over it then I&#8217;ll be terribly disappointed.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/12/10/working-out-chaotic-things/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Programming shouldn&#8217;t be degrading</title>
		<link>http://www.jpstacey.info/blog/2007/09/19/programming-shouldnt-be-degrading/</link>
		<comments>http://www.jpstacey.info/blog/2007/09/19/programming-shouldnt-be-degrading/#comments</comments>
		<pubDate>Wed, 19 Sep 2007 13:33:42 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[layers]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[standards]]></category>

		<category><![CDATA[accessibility]]></category>

		<category><![CDATA[convert]]></category>

		<category><![CDATA[css]]></category>

		<category><![CDATA[design]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[didhesayparadigm]]></category>

		<category><![CDATA[enhancement]]></category>

		<category><![CDATA[form]]></category>

		<category><![CDATA[html]]></category>

		<category><![CDATA[javascript]]></category>

		<category><![CDATA[progressive]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/09/19/programming-shouldnt-be-degrading/</guid>
		<description><![CDATA[Steve compares &#8220;graceful degradation&#8221; with &#8220;progressive enhancement.&#8221; Mostly he takes issue (rightly) with the rhetorical spin that the former applies to the idea of building a website. But I think you can compare them with each other as if they were two different types of crowbar instead: two ways of prising open the task in [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://nascentguruism.com/journal/grace">Steve compares &#8220;graceful degradation&#8221; with &#8220;progressive enhancement.&#8221;</a> Mostly he takes issue (rightly) with the rhetorical spin that the former applies to the idea of building a website. But I think you can compare them with each other as if they were two different types of crowbar instead: two ways of prising open the task in hand.</p>
<p>What I like most about <a href="http://www.makemineatriple.com/2007/04/the-highland-fling/" title="Bryan talks about The Highland Fling conference">progressive enhancement</a> is that it gives me a way of tackling the age-old problem of turning a design for a client into a workable, accessible page without going completely mental. Before, if I saw a dropdown on the designs without a submit button or some such, I&#8217;d think, well, the HTML won&#8217;t have a submit button either, so I need to build the Javascript at the same time and get it all to work at once. This led me into all sorts of tangles&#8212;each one on its own easy to extricate myself from&#8212;and at the end of it I would have a form that would work or look right without <em>every</em> layer of technology in place.</p>
<p>But if you&#8217;re thinking progressively at the back of your mind all the time, you can start with an unstyled, unscripted form that works, and then use subtle styling to get exactly where you want to be. Some onloaded Javascript can give you a <code>body.js</code> class with which to hide unwanted submit buttons. At the end, if nothing else, the form still submits when Javascript is turns off, and it looks OK because you checked at the outset. </p>
<p>Progressive enhancement, ironically for the amount of work it implies, actually places the least stress (and maintenance workload) on the developer, and makes them learn a thing or two about layering and modularity at the same time. And as Steve points out, in this model there is no degradation: just the near-hotswapping of a range of technologies on top of a sturdy markup language that has been around in various forms for over a decade.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/09/19/programming-shouldnt-be-degrading/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Software simple and software facile</title>
		<link>http://www.jpstacey.info/blog/2007/09/12/software-simple-and-software-facile/</link>
		<comments>http://www.jpstacey.info/blog/2007/09/12/software-simple-and-software-facile/#comments</comments>
		<pubDate>Wed, 12 Sep 2007 09:07:45 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[business]]></category>

		<category><![CDATA[culture]]></category>

		<category><![CDATA[enterprise]]></category>

		<category><![CDATA[information]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[api]]></category>

		<category><![CDATA[barcamp]]></category>

		<category><![CDATA[brighton]]></category>

		<category><![CDATA[consumer]]></category>

		<category><![CDATA[development]]></category>

		<category><![CDATA[rest]]></category>

		<category><![CDATA[soap]]></category>

		<category><![CDATA[vendor]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/09/12/software-simple-and-software-facile/</guid>
		<description><![CDATA[Assaf writes about, among other things, REST as a simplifier of development against an existing system:
REST plays the same role as open source and open APIs: It eliminates tooling and vendoring as artificial barriers to adoption.

Interestingly, a corollary to this was brought up at Barcamp Brighton this weekend. During Gareth Rushgrove&#8217;s talk about REST and [...]]]></description>
			<content:encoded><![CDATA[<p>Assaf writes about, among other things, <a href="http://blog.labnotes.org/2007/09/10/rounded-corners-144-slight-of-hand/">REST as a simplifier of development against an existing system</a>:</p>
<blockquote><p><i>REST plays the same role as open source and open APIs: It eliminates tooling and vendoring as artificial barriers to adoption.</i></p>
</blockquote>
<p>Interestingly, a corollary to this was brought up at Barcamp Brighton this weekend. During <a href="http://www.morethanseven.net/">Gareth Rushgrove&#8217;s</a> talk about REST and <a href="http://www.nabaztag.com/">Nabaztag</a>, a chap whose name I&#8217;ve <em>again</em> forgotten (although I&#8217;m sure someone like <a href="http://fatbusinessman.com/">Fatty</a> will <a href="/blog/2007/09/10/post-mortem-post-brighton/#comments">enlighten me</a>) pointed out that much of the push of SOAP is coming from the vendors, because the vendors make their money from selling tools, and REST development needs very few tools, most of which are free.</p>
<p>Undoubtedly there&#8217;s a set of problems that REST finds hard, but this truism is extended by SOAP vendors to the hard-to-prove (but also hard-to-contradict) claim that it&#8217;s a larger set, or a set more pertinent to enterprise solutions, than the set which SOAP finds hard. It convinces the consumers, because intelligent data mining and storage has always been a difficult problem, and a simple solution like REST feels like underkill for the job in hand. They let you confuse <i>libre</i> and <i>gratis</i>, the vendors point out (I see them sitting on the consumer&#8217;s shoulders with tridents at this point): so where&#8217;s the hidden cost of <em>this</em> free lunch?</p>
<p>(hat tip to <a href="http://simonwillison.net/2007/Sep/10/">Simon Willison</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/09/12/software-simple-and-software-facile/feed/</wfw:commentRss>
		</item>
		<item>
		<title>The point-to-point is the point</title>
		<link>http://www.jpstacey.info/blog/2007/09/04/the-point-to-point-is-the-point/</link>
		<comments>http://www.jpstacey.info/blog/2007/09/04/the-point-to-point-is-the-point/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 13:04:47 +0000</pubDate>
		<dc:creator>jps</dc:creator>
		
		<category><![CDATA[culture]]></category>

		<category><![CDATA[paradigms]]></category>

		<category><![CDATA[bonding]]></category>

		<category><![CDATA[festival]]></category>

		<category><![CDATA[mobile]]></category>

		<category><![CDATA[myspace]]></category>

		<category><![CDATA[networks]]></category>

		<category><![CDATA[phone]]></category>

		<category><![CDATA[social]]></category>

		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.jpstacey.info/blog/2007/09/04/the-point-to-point-is-the-point/</guid>
		<description><![CDATA[A comment on Ask the Wizard&#8217;s post about obviousness bemoans the non-obviousness of a particular social network&#8217;s use:
You wouldn&#8217;t happen to have a video you could link to of that person who showed you Twitter being valuable. Why? Because I (still) don&#8217;t get it&#8230;

I know how he feels. I still don&#8217;t get MySpace, and according [...]]]></description>
			<content:encoded><![CDATA[<p>A comment on <a href="http://www.burningdoor.com/askthewizard/2007/09/lessons_learned_obviously_its.html" title="Obviously, itâ€™s not Obvious">Ask the Wizard&#8217;s post</a> about obviousness bemoans the non-obviousness of a particular social network&#8217;s use:</p>
<blockquote><p>You wouldn&#8217;t happen to have a video you could link to of that person who showed you Twitter being valuable. Why? Because I (still) don&#8217;t get it&#8230;</p>
</blockquote>
<p>I know how he feels. I still don&#8217;t get <a href="http://www.myspace.com/">MySpace</a>, and <a href="http://www.nytimes.com/2007/09/02/magazine/02rubin.t.html?pagewanted=3&#38;_r=1">according to Rick Rubin</a> it&#8217;s already on its way out. No wonder I&#8217;m starting to feel old. </p>
<p>It took life events to really make me understand Twitter; it took actually fiddling around with it and trying to use it. A more committed Luddite would have bowed out long before I did, and I could hardly blame them. During the last Glastonbury festival, I twittered the events happening around me at a much smaller festival near the Ascot racing ground. My friends at Glastonbury twittered back. Later on, <a href="http://www.chiark.greenend.org.uk/~janetmck/">Janet McKnight</a> was to exclaim: &#8220;oh! I thought you were making your festival up to be part of the gang.&#8221; That aside, as we were all telling each other what we were up to at these large, disparate, staged events, it dawned on me that we&#8217;d basically built an add-on to the Glastonbury Festival, without having to deal with the odious Michael Eavis, and I thought: I get Twitter.</p>
<p>That&#8217;s a specific instance, of course, but in a more general sense Twitter is providing a narrative version of where you&#8217;re at, a real-time way of positioning yourself&#8212;and reading off the positions of others&#8212;in terms of what you see, hear and smell rather than in terms of a longitude and latitude. It takes all those narratives and binds them together: or not, if you don&#8217;t want.</p>
<p>So maybe they should market it as the alternative to an address book: &#8220;if you liked knowing where your friends are currently living, you might also want to know what they&#8217;re currently up to.&#8221; Or how about: &#8220;Twitter: the RFID tag for the soul!&#8221; Actually, that sounds a lot more sinister than chicken soup.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jpstacey.info/blog/2007/09/04/the-point-to-point-is-the-point/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
