<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Invisible Blocks</title>
	<atom:link href="http://invisibleblocks.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://invisibleblocks.com</link>
	<description>for building invisible machines</description>
	<lastBuildDate>Thu, 01 Dec 2011 13:42:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='invisibleblocks.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Invisible Blocks</title>
		<link>http://invisibleblocks.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://invisibleblocks.com/osd.xml" title="Invisible Blocks" />
	<atom:link rel='hub' href='http://invisibleblocks.com/?pushpress=hub'/>
		<item>
		<title>Redder Pastures</title>
		<link>http://invisibleblocks.com/2011/08/17/redder-pastures/</link>
		<comments>http://invisibleblocks.com/2011/08/17/redder-pastures/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 01:46:44 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=470</guid>
		<description><![CDATA[What the hell happened? I mean, I don&#8217;t care for &#8220;I haven&#8217;t been blogging because&#8230;&#8221; posts either, but it&#8217;s been quiet here lately, hasn&#8217;t it? The explanation comes in two parts: After I announced I was releasing WordCram, I worked like mad on it. In my last post, the one announcing WordCram, I said &#8220;There’s still work [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=470&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>What the hell happened? I mean, I don&#8217;t care for &#8220;I haven&#8217;t been blogging because&#8230;&#8221; posts either, but it&#8217;s been <em>quiet</em> here lately, hasn&#8217;t it?</p>
<p>The explanation comes in two parts:</p>
<p>After I announced I was releasing <a href="http://wordcram.org">WordCram</a>, I worked like mad on it. In my last post, the one announcing WordCram, I said &#8220;There’s still work to do, but that’s the fun part,&#8221; but I had no idea. And it&#8217;s not even a big library, or do anything useful! And there is certainly still work to do. I have a new, visceral appreciation for how much open source software developers give us. That&#8217;s the first part.</p>
<p>But all that stopped last April, when my employer began going through some &#8211; I guess &#8220;changes&#8221; is a safe enough word. Nevermind what they were. It got me thinking it was time to find a job I liked better. The job search is the second part of the explanation. I didn&#8217;t want another ordinary-business kind of job, but I didn&#8217;t know which direction to head in. After  sinking myself in some Processing.org dataviz, science, and Ruby, talking to a bunch of excellent people, and finding some luck, I got a spot on the <a href="http://seeclickfix.com">SeeClickFix</a> team, doing Ruby on Rails, and helping citizens improve their community.</p>
<p>Get a great job, working in a great language, making the world a little bit better:</p>
<p><a href="http://invisibleblocks.files.wordpress.com/2011/08/checked_box.jpg"><img class="size-full wp-image-473 alignnone" style="border-color:initial;border-style:initial;border-width:0;" title="checked_box" src="http://invisibleblocks.files.wordpress.com/2011/08/checked_box.jpg?w=500" alt=""   /></a><br />
<img class="alignright" style="border-color:initial;border-style:initial;border-width:0;" src="http://upload.wikimedia.org/wikipedia/commons/7/73/Ruby_logo.svg" alt="" width="100" height="100" />I start in September, right before I start classes at <a href="http://university.rubymendicant.com/">Ruby Mendicant University</a>. It&#8217;s been a busy spring and summer, and it&#8217;ll be a busy fall, too.</p>
<p>And at some point, I have some WordCram things to finish&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/470/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/470/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/470/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=470&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2011/08/17/redder-pastures/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2011/08/checked_box.jpg" medium="image">
			<media:title type="html">checked_box</media:title>
		</media:content>

		<media:content url="http://upload.wikimedia.org/wikipedia/commons/7/73/Ruby_logo.svg" medium="image" />
	</item>
		<item>
		<title>WordCram: Open-Source Word Clouds for Processing</title>
		<link>http://invisibleblocks.com/2010/08/31/wordcram-open-source-word-clouds-for-processing/</link>
		<comments>http://invisibleblocks.com/2010/08/31/wordcram-open-source-word-clouds-for-processing/#comments</comments>
		<pubDate>Wed, 01 Sep 2010 01:31:08 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[WordCram]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=463</guid>
		<description><![CDATA[I just released a project I&#8217;ve been working on for a while, called WordCram.  As the title says, it&#8217;s a Processing library for generating word clouds. I found wordle.net a few years ago and really liked it, and after seeing the code for Algirdas Rascius&#8217; Scattered Letters on OpenProcessing.org, I tried making some of my [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=463&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I just released a project I&#8217;ve been working on for a while, called <a href="http://wordcram.wordpress.com">WordCram</a>.  As the title says, it&#8217;s a Processing library for generating word clouds.</p>
<p>I found <a href="http://wordle.net">wordle.net</a> a few years ago and really liked it, and after seeing the code for Algirdas Rascius&#8217; <a href="http://www.openprocessing.org/visuals/?visualID=1811">Scattered Letters</a> on OpenProcessing.org, I tried making <a href="http://www.flickr.com/photos/bonsai_giant/tags/wordle/">some of my own</a>.  It was fun, but I thought it ran too slowly to bother bundling it into a Processing library.</p>
<p>After reading the <a href="http://blog.wordle.net/2010/05/wordle-as-beautiful-visualization.html">Wordle chapter</a> from <a href="http://www.amazon.com/gp/product/1449379869?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449379869">Beautiful Visualization</a>, I learned a few new tricks, and it&#8217;s a bit faster now, so here it is.  There&#8217;s still work to do, but that&#8217;s the fun part.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/463/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/463/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/463/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=463&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2010/08/31/wordcram-open-source-word-clouds-for-processing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>
	</item>
		<item>
		<title>After OsCon 2010</title>
		<link>http://invisibleblocks.com/2010/07/28/after-oscon-2010/</link>
		<comments>http://invisibleblocks.com/2010/07/28/after-oscon-2010/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 12:07:24 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=445</guid>
		<description><![CDATA[OsCon 2010 is done, and I&#8217;m pooped. I met some great people, the talks were good, and I saw some promising ideas and technologies. Portland is a great city, with free public transportation, good beer, veggie-friendly restaurants, and Mt. Hood close by. What more could you want? Here&#8217;s my highlights and impressions. Innovation Rolf Skyberg [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=445&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.oscon.com/oscon2010">OsCon 2010</a> is done, and I&#8217;m pooped. I met some great people, the talks were good, and I saw some promising ideas and technologies. Portland is a great city, with free public transportation, good beer, veggie-friendly restaurants, and <a href="http://images.google.com/images?q=mt+hood+oregon">Mt. Hood</a> close by. What more could you want?</p>
<p>Here&#8217;s my highlights and impressions.</p>
<h4>Innovation</h4>
<p><a href="http://www.oscon.com/oscon2010/public/schedule/detail/13553">Rolf Skyberg</a> explained where corporate innovation initiatives come from, and <a href="http://www.oscon.com/oscon2010/public/schedule/detail/14836">Simon Wardley</a> talked about innovation. Those links are to the talk descriptions, but you can watch <a href="http://www.youtube.com/watch?v=5Oyf4vvJyy4&amp;feature=PlayList&amp;p=12696FB0B040FA53&amp;playnext_from=PL&amp;index=39">Simon&#8217;s talk on youtube</a>, since it was a keynote.</p>
<p>As a company ages, Rolf says it gets more risk-averse, and that stifles innovation. He names each life-stage of a company for its most prominent employees: innovators, rock-stars, proceduralists, optimizers, and vultures. Once the company becomes so risk-averse that new ideas are stifled, and it starts losing money, the CEO assumes the problem is a lack of new ideas, rather than a culture that can&#8217;t absorb them.<em></em></p>
<p>As a technology matures, Simon says it gets more stable and ubiquitous, becoming a commodity. This &#8220;creative destruction&#8221; frees us up to do more interesting things.</p>
<p>I&#8217;ll be going back over their presentations, thinking about the commonalities between their talks.</p>
<h4>Google&#8217;s Go</h4>
<p>Rob Pike&#8217;s talk <a href="http://www.youtube.com/watch?v=5kj5ApnhPAE&amp;feature=PlayList&amp;p=12696FB0B040FA53&amp;playnext_from=PL&amp;index=25">Public Static Void</a> gave  some context around Google&#8217;s new(-ish) language, <a href="http://golang.org/">Go</a>, which I&#8217;d pretty much ignored. A few choice bits:</p>
<ul>
<li>&#8220;there&#8217;s a false dichotomy between nice &amp; dynamic &amp; interpreted, and ugly &amp; static &amp; compiled&#8221;</li>
<li>Scala is &#8220;beautiful and rigorous&#8221;</li>
<li>(my favorite) &#8220;a language should be light on the page&#8221;</li>
</ul>
<h4>Processing</h4>
<p>I got to show Processing to a bunch of people, which made me happy &#8212; Processing is a great tool, and a lot of fun.  <a href="http://www.kathrynaaker.com/blog/">Kathryn Aaker</a> was there, and she even made a <a href="http://openprocessing.org/visuals/?visualID=10950">sketch</a> on the flight home.</p>
<p>I also talked with a guy whose name I can&#8217;t remember, and whose card I didn&#8217;t get, about how his friend used Processing to teach math concepts to his kids.  That&#8217;s a pretty amazing thing. Take that, <a href="http://www.maa.org/devlin/LockhartsLament.pdf">Mathematician&#8217;s Lament</a>!</p>
<h4>Scala, Mirah?</h4>
<p>I really enjoy <a href="http://processing.org">Processing</a>, but&#8230;Java. Can we have something fast, but with closures and easy syntax, please? Either Scala or Mirah might meet that need.</p>
<p><a href="http://www.mirah.org/">Mirah</a> is a Java compiler that reads Ruby-like syntax: looks like Ruby, but  it&#8217;s still Java. That seems promising, but I don&#8217;t think you can use,  say, Array.map, since it&#8217;s not part of Java&#8217;s core library.</p>
<p><a href="http://www.scala-lang.org/">Scala</a> is a functional/OO hybrid language that brings closures and  higher-order programming to Java, with a helping of type inference.  It  seems promising, but it also seems like a lot of features mixed in  together; compared to Io or Scheme, there&#8217;s tons to learn.  But maybe  that&#8217;s the wrong way to look at it &#8212; maybe it&#8217;s close enough to Java that it&#8217;ll be fairly quick to learn.</p>
<h4>Powell&#8217;s Technical Books</h4>
<p>Powell&#8217;s books is humbling, and amazing. There are whole sections I&#8217;m not even smart enough to understand. I still walked out with three books, though.</p>
<p><a href="http://invisibleblocks.files.wordpress.com/2010/07/img_2860-small.jpg"><img class="alignnone size-full wp-image-448" src="http://invisibleblocks.files.wordpress.com/2010/07/img_2860-small.jpg?w=500" alt="I'm a book fiend"   /></a></p>
<p>The first one is <a href="http://www.amazon.com/gp/product/0312186509?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0312186509">The Philosophical Programmer</a><img class=" byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze" style="border:none!important;margin:0!important;" src="http://www.assoc-amazon.com/e/ir?t=invisblock-20&amp;l=as2&amp;o=1&amp;a=0312186509" border="0" alt="" width="1" height="1" />, which I&#8217;d never heard of, but for $6, I had to grab it.  (Yes, it&#8217;s an old library book.)  I got <a href="http://www.amazon.com/gp/product/0262561158?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0262561158">A Little Java, A Few Patterns</a><img class=" byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze" style="border:none!important;margin:0!important;" src="http://www.assoc-amazon.com/e/ir?t=invisblock-20&amp;l=as2&amp;o=1&amp;a=0262561158" border="0" alt="" width="1" height="1" /> because I loved <a href="http://www.amazon.com/gp/product/0262560992?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0262560992">The Little Schemer</a><img class=" byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze" style="border:none!important;margin:0!important;" src="http://www.assoc-amazon.com/e/ir?t=invisblock-20&amp;l=as2&amp;o=1&amp;a=0262560992" border="0" alt="" width="1" height="1" />.  <a href="http://www.amazon.com/gp/product/354021304X?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=354021304X">Grammatical Picture Generation</a><img class=" byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze" style="border:none!important;margin:0!important;" src="http://www.assoc-amazon.com/e/ir?t=invisblock-20&amp;l=as2&amp;o=1&amp;a=354021304X" border="0" alt="" width="1" height="1" /> is about writing tiny languages that generate fractal-type images, something I&#8217;ve been playing with recently.  And I actually bought <a href="http://www.amazon.com/gp/product/1449379869?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1449379869">Beautiful Visualization</a><img class=" byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi byxmxweyeumkaqzmwcfi hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze hiumsgquelgxvvjyynze" style="border:none!important;margin:0!important;" src="http://www.assoc-amazon.com/e/ir?t=invisblock-20&amp;l=as2&amp;o=1&amp;a=1449379869" border="0" alt="" width="1" height="1" /> at the conference itself, not at Powell&#8217;s.  It&#8217;s fantastic, though, I read it the whole flight home.</p>
<p>OK!  Enough fawning over books, I&#8217;m embarrassing myself.</p>
<h4>Asynchronous JavaScript</h4>
<p>My team&#8217;s been bogged down lately by some ASPX pages with very complex javascript behavior.  Somewhere between <a href="http://stratifiedjs.org/">Stratefied.js</a> and <a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx">Reactive Extensions for JS</a>, there might be a way to tame them.</p>
<p>Stratefied.js introduces new language constructs to javascript to implement concurrency semantics. I&#8217;m not 100% on the semantics themselves &#8212; they bear looking further into, but they don&#8217;t seem terribly complicated. The part I thought was neat was how they&#8217;re implemented in all browsers, even geriatric IE6:</p>
<p><pre class="brush: xml;">
&lt;script src=&quot;stratefied.js&quot; type=&quot;text/js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/sjs&quot;&gt;
  /* your code here, including new syntax */
&lt;/script&gt;
</pre></p>
<p>Notice the type attribute of the second script?  Once the page is loaded, Stratefied.js loads all scripts of type &#8220;text/sjs&#8221;, and does some source-transformation, turning the new constructs into (I&#8217;m guessing) gnarly, but standard, javascript.</p>
<p>Reactive Extensions for JS come from open source&#8217;s best friend Microsoft. The gist is this: asynchronous coding with call-backs is hard, but if you treat events (from the user, from ajax HTTP, or whatever) as a collection that you can subscribe to, and you can map and filter those collections with anonymous functions, it&#8217;s easier. We&#8217;ll have to see. The speaker, Erik Meijer, gave a <a href="http://live.visitmix.com/MIX10/Sessions/FTL01">pretty similar talk at MIX</a>.</p>
<h4>Badges, with Ribbons</h4>
<p><a href="http://invisibleblocks.files.wordpress.com/2010/07/img_2857-small.jpg"><img class="alignnone size-full wp-image-447" src="http://invisibleblocks.files.wordpress.com/2010/07/img_2857-small.jpg?w=500" alt="my badge"   /></a></p>
<p>They took some flak for the ribbon color-text, especially for the <a href="http://www.flickr.com/photos/oreillyconf/4816395283/in/set-72157624428101453/">desperate perl hackers</a>, but they were pretty good about it.  They even asked what ribbons we&#8217;d like to see next year, so we don&#8217;t have to customize quite so much.</p>
<h4>Inspiration and Awesomeness</h4>
<p>The world is full of inventive, stubborn people doing really cool things to make the world better. <a href="http://mifos.org/">Mifos.org</a> helps microfinance banks run smoothly. <a href="http://arduino.cc">Arduino</a> and <a href="http://www.concurrency.cc/">Plumbing</a> making hardware hacking accessible to whole new audiences.  <a href="http://www.oscon.com/oscon2010/public/schedule/detail/13425">OpenSETI</a> wants to involve programmers more in finding whether we&#8217;re alone in the universe.  <a href="http://codeforamerica.org/">Code for America</a> can help our government be more efficient and transparent.  If you ever wanted to start contributing to open source, joining <em>any</em> of these projects should be a great start.</p>
<h4>Pretend You Were There!</h4>
<p>Or re-live the experience, if you were!  Here&#8217;s the <a href="http://www.youtube.com/view_play_list?p=12696FB0B040FA53">keynotes on youtube</a>, and <a href="http://www.flickr.com/photos/oreillyconf/sets/72157624428101453/">photos on flickr</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/445/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/445/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/445/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/445/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/445/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/445/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/445/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/445/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=445&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2010/07/28/after-oscon-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2010/07/img_2860-small.jpg" medium="image">
			<media:title type="html">I'm a book fiend</media:title>
		</media:content>

		<media:content url="http://www.assoc-amazon.com/e/ir?t=invisblock-20&#038;l=as2&#038;o=1&#038;a=0312186509" medium="image" />

		<media:content url="http://www.assoc-amazon.com/e/ir?t=invisblock-20&#038;l=as2&#038;o=1&#038;a=0262561158" medium="image" />

		<media:content url="http://www.assoc-amazon.com/e/ir?t=invisblock-20&#038;l=as2&#038;o=1&#038;a=0262560992" medium="image" />

		<media:content url="http://www.assoc-amazon.com/e/ir?t=invisblock-20&#038;l=as2&#038;o=1&#038;a=354021304X" medium="image" />

		<media:content url="http://www.assoc-amazon.com/e/ir?t=invisblock-20&#038;l=as2&#038;o=1&#038;a=1449379869" medium="image" />

		<media:content url="http://invisibleblocks.files.wordpress.com/2010/07/img_2857-small.jpg" medium="image">
			<media:title type="html">my badge</media:title>
		</media:content>
	</item>
		<item>
		<title>Disable Your Links, or Gate Your Functions?</title>
		<link>http://invisibleblocks.com/2010/07/01/disable-your-links-or-gate-your-functions/</link>
		<comments>http://invisibleblocks.com/2010/07/01/disable-your-links-or-gate-your-functions/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 23:02:18 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=434</guid>
		<description><![CDATA[It&#8217;s pretty common to disable links and buttons that cause updates, so those updates don&#8217;t happen twice, and re-enable them when the update has finished. At work, our app&#8217;s links are usually wired to javascript functions that use jQuery to scrape the form data and post it to web services via ajax. We normally disable [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=434&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s pretty common to disable links and buttons that cause updates, so those updates don&#8217;t happen twice, and re-enable them when the update has finished.</p>
<p>At work, our app&#8217;s links are usually wired to javascript functions that use jQuery to scrape the form data and post it to web services via ajax.  We normally disable links and buttons something like this:</p>
<p><pre class="brush: jscript;">
var updateLink = $('#updateLink');  // Find the link.
updateLink.click(function() {       // When it's clicked...
   updateLink.disable();            // disable it...
   ajax({
      data: getFormData(),          // ... &amp; send the form data
      url: 'http://someWebService', // to some web service.
      success: function(results) {  // When the service
         if (results.hasErrors) {   // finishes,
            showErrors(results);    // show any errors,
            updateLink.enable();    // and enable the link
         }                          // so they can try again.
      }
   });
});
</pre></p>
<p>We added those enable() and disable() functions to jQuery &#8212; they just add or remove the <code>disabled</code> attribute from whatever they&#8217;re called on.  But it seems Firefox doesn&#8217;t support <code>disabled</code> on anchor tags, like IE8 does, so we couldn&#8217;t stop the repeat-calls that way.</p>
<p>We got to thinking, what if the link <em>always</em> called its javascript function, but the function could turn itself off after the first call, and back on after a successful ajax post?  That led to this:</p>
<p><pre class="brush: jscript;">
function makeGated(fn) {
   var open = true;
   var gate = {
      open: function() { open = true; }
      shut: function() { open = false; }
   };

   return function() {
      if (open) {
         fn(gate);
      }
   };
}
</pre></p>
<p>makeGated takes your function, and wraps it in another function, a gate function (it &#8220;makes your function a gated function&#8221;).  When you call the function it creates, it will only call your function if the gate is open &#8212; which it is, at first. But then, your function can decide whether to close the gate (that&#8217;s why the gate is passed to your function).  You could use it like this:</p>
<p><pre class="brush: jscript;">
var updateLink = $('#updateLink');  // Find the link.
updateLink.click(
   makeGated(function(gate) {       // When it's clicked...
      gate.shut();                  // shut the gate...
      ajax({
         data: getFormData(),       // ...same as before...
         url: 'http://someWebService',
         success: function(results) {
            if (results.hasErrors) {
               showErrors(results);
               gate.open();  // Open the gate
                             // so they can try again.
            }
         }
      });
   }));
</pre></p>
<p>We dropped this in, and it worked pretty much as expected: you can click all you want, and the update will only fire once; when the update completes, it&#8217;ll turn back on.</p>
<p>The downside? Since it doesn&#8217;t disable the link, the user has no idea what&#8217;s going on.  In fact, since the closed-gate function finishes so quickly, it seems like the button&#8217;s not doing anything at all, which might even make it look broken.</p>
<p>So we chucked it, and hid the links instead. It&#8217;s not as nifty, and it&#8217;s not reusable, but it&#8217;s clear enough for both end-users and programmers who don&#8217;t grok higher-order functions.  Even when you have a nice, flexible language, and can make a sweet little hack, it doesn&#8217;t mean the dumb approach won&#8217;t sometimes win out.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/434/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/434/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/434/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=434&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2010/07/01/disable-your-links-or-gate-your-functions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>
	</item>
		<item>
		<title>Where the Abstraction Leaks: JavaScript&#8217;s Fake Arrays</title>
		<link>http://invisibleblocks.com/2010/06/15/where-the-abstraction-leaks-javascripts-fake-arrays/</link>
		<comments>http://invisibleblocks.com/2010/06/15/where-the-abstraction-leaks-javascripts-fake-arrays/#comments</comments>
		<pubDate>Tue, 15 Jun 2010 16:01:08 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=369</guid>
		<description><![CDATA[Ruby arrays have a nice feature: you can construct a new array with an integer N, and a block, which will be called N times, to fill up the array: I tried to recreate this in JavaScript: Oops! I guess the Array constructor works differently in JavaScript. No worries, we can just call map on [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=369&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ruby arrays have a nice feature: you can construct a new array with an integer N, and a block, which will be called N times, to fill up the array:</p>
<p><pre class="brush: ruby;">
Array.new(5) { 'yo' }
# gives:
[&quot;yo&quot;, &quot;yo&quot;, &quot;yo&quot;, &quot;yo&quot;, &quot;yo&quot;]

# Closures, too!
i = 0
Array.new(4) { i = i + 1 }
# gives:
[1, 2, 3, 4]
</pre></p>
<p>I tried to recreate this in JavaScript:</p>
<p><pre class="brush: jscript;">
new Array(5, function() { return &quot;drip&quot;; });
// gives:
[5, function() {
    return &quot;drip&quot;;
}]
</pre></p>
<p>Oops!  I guess the Array constructor works differently in JavaScript.  No worries, we can just call map on the new array.</p>
<p><pre class="brush: jscript;">
new Array(5).map(function() { return &quot;drip&quot;; });
// gives:
[, , , , ]
</pre></p>
<p>&#8230;um, what?  Shouldn&#8217;t that be <code>["drip", "drip", "drip", "drip", "drip"]</code>?  If I call <code>new Array(3)</code>, I should get a brand new array, with 3 slots, all set to <code>undefined</code>; and I should be able to map over it, and fill up the array.</p>
<p>Let&#8217;s see what its elements are:<br />
<pre class="brush: jscript;">
var array = new Array(5);
array[0]; // undefined, as expected
array[1]; // also undefined
</pre></p>
<p>So far, so good.  What arguments are passed to the function?<br />
<pre class="brush: jscript;">
function printAndDrip(arg) {
    print(arg);
    return &quot;drip&quot;;
}
array.map(printAndDrip); // prints nothing, and returns [, , , , ]
</pre></p>
<p>It looks like the <code>printAndDrip</code> function is never being called, almost like the array has no contents.</p>
<p>Let&#8217;s try setting a value manually, <i>then</i> mapping:</p>
<p><pre class="brush: jscript;">
array[2] = &quot;hey there&quot;; // [, , &quot;hey there&quot;, , ], as expected
array.map(printAndDrip);
// prints &quot;hey there&quot;, and returns [, , &quot;drip&quot;, , ]
</pre></p>
<p>So, it only calls the function for values we&#8217;ve manually put there.  Maybe map doesn&#8217;t call the function if the value of a slot is undefined?  I know, I&#8217;m reaching here&#8230;</p>
<p><pre class="brush: jscript;">
array = [1, undefined, 2];
array.map(printAndDrip);

/* prints:
1
undefined
2
then outputs:
[&quot;drip&quot;, &quot;drip&quot;, &quot;drip&quot;]
*/
</pre></p>
<p>So it <i>does</i> call the function for undefined values!  Then why didn&#8217;t it in our newly-created array?</p>
<p>This is when it hit me, and it&#8217;s a funny JavaScript fact that I always forget: JavaScript has fake arrays.</p>
<p>They&#8217;re actually closer to hash tables, whose keys are numbers.  <code>["zero", "one"]</code> is just syntax sugar: it creates an object with two properties, named 0 and 1; 0 points to &#8220;zero&#8221;, and 1 points to &#8220;one&#8221;.  </p>
<p><pre class="brush: jscript;">
// pretty much the same:
var arrayLiteral = [&quot;zero&quot;, &quot;one&quot;];
var objectLiteral = { 0: &quot;zero&quot;, 1: &quot;one&quot; };
</pre></p>
<p>Apparently, if you use the <code>new Array(10)</code> constructor, it creates an array with length 10, but with no named properties.</p>
<p>We can see the properties an object has with the <a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Object/hasOwnProperty">hasOwnProperty</a> method, so we can use that to test our hypothesis.</p>
<p><pre class="brush: jscript;">
var emptyArray = new Array(10);
emptyArray.hasOwnProperty(0); // false
emptyArray.hasOwnProperty(1); // false

var fullArray = [1,2,3];
fullArray.hasOwnProperty(0); // true
fullArray.hasOwnProperty(1); // true
fullArray.hasOwnProperty(99); // false: gone past the end
</pre></p>
<p>So where does that leave us? Nowhere, really.  At least I&#8217;m a little clearer about JavaScript&#8217;s fake arrays.  Imitating Ruby&#8217;s Array constructor is pretty much out; it&#8217;s easy enough, though a bit unsatisfying, to hand-roll our own:</p>
<p><pre class="brush: jscript;">
Array.filled = function(n, fn) {
    var array = [];
    while(n-- &gt; 0) {
        array.push(fn());
    }
    return array;
}
Array.filled(5, function() { return &quot;drip&quot;; });
// gives:
[&quot;drip&quot;, &quot;drip&quot;, &quot;drip&quot;, &quot;drip&quot;, &quot;drip&quot;]
</pre></p>
<p>Perhaps the folks working on the new JavaScript standards can put in a line-item about initializing Arrays with all the right numbered slots, and that&#8217;ll be unnecessary.</p>
<p><i>While writing this post, I used the <a href="http://www.squarefree.com/shell/shell.html">JavaScript Shell 1.4</a> in FireFox 3.6.3 on Windows 7.  I also redefined <code>Array.prototype.toString</code> to <a href="http://invisibleblocks.wordpress.com/2010/02/02/array-prototype-tostring/">display JavaScript arrays the way you type them</a>.</i></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/369/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/369/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/369/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/369/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/369/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/369/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/369/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/369/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=369&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2010/06/15/where-the-abstraction-leaks-javascripts-fake-arrays/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>
	</item>
		<item>
		<title>Array.prototype.toString</title>
		<link>http://invisibleblocks.com/2010/02/02/array-prototype-tostring/</link>
		<comments>http://invisibleblocks.com/2010/02/02/array-prototype-tostring/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 18:27:30 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=366</guid>
		<description><![CDATA[This is one of my favorite javascript tricks, because of its effort-to-payoff ratio. Problem: the default Array.prototype.toString hides any nested structure. Solution: override Array.prototype.toString.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=366&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This is one of my favorite javascript tricks, because of its effort-to-payoff ratio.</p>
<p>Problem: the default Array.prototype.toString hides any nested structure.</p>
<p><pre class="brush: jscript;">
[1, 2, 3, 4, 5].toString(); //-&gt; &quot;1, 2, 3, 4, 5&quot;
[1, 2, [3, 4], 5].toString(); //-&gt; &quot;1, 2, 3, 4, 5&quot;
</pre></p>
<p>Solution: override Array.prototype.toString.</p>
<p><pre class="brush: jscript;">
Array.prototype.toString = function() {
    return '[' + this.join(', ') + ']';
};

[1, 2, 3, 4, 5].toString(); //-&gt; &quot;[1, 2, 3, 4, 5]&quot;
[1, 2, [3, 4], 5].toString(); //-&gt; &quot;[1, 2, [3, 4], 5]&quot;
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/366/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/366/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/366/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/366/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/366/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/366/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/366/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/366/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=366&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2010/02/02/array-prototype-tostring/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>
	</item>
		<item>
		<title>Firebug and Monaco, on Windows</title>
		<link>http://invisibleblocks.com/2009/11/20/firebug-and-monaco-on-windows/</link>
		<comments>http://invisibleblocks.com/2009/11/20/firebug-and-monaco-on-windows/#comments</comments>
		<pubDate>Fri, 20 Nov 2009 22:06:45 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Tools]]></category>
		<category><![CDATA[Firebug Monaco fonts]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=351</guid>
		<description><![CDATA[I&#8217;ve been running Firebug at work for a long time, it&#8217;s a really solid tool. A while ago, I started using a Monaco.ttf for Windows. I think it looks much better on my Ubuntu system, but it&#8217;s nice to have on Vista. Firebug was apparently written for the Mac, because it uses Monaco all over [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=351&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been running <a href="http://getfirebug.com/">Firebug</a> at work for a long time, it&#8217;s a really solid tool.  A while ago, I started using a <a href="http://www.webdevkungfu.com/textmate-envy-aka-monaco-font-for-windows/">Monaco.ttf for Windows</a>.  I think it looks much better on my Ubuntu system, but it&#8217;s nice to have on Vista.</p>
<p>Firebug was apparently written for the Mac, because it uses Monaco all over the place. That would be very nice, but on Windows, a bold Monaco is a wider Monaco.  This makes the line number gutters uneven, and makes the screen flash when you scroll through text:</p>
<p><a href="http://invisibleblocks.files.wordpress.com/2009/11/firebug-monaco-vista2.gif"><img class="alignnone size-full wp-image-361" title="Firebug and Monaco on Vista" src="http://invisibleblocks.files.wordpress.com/2009/11/firebug-monaco-vista2.gif?w=500" alt=""   /></a></p>
<p>I finally got irritated enough to google it, and I found this <a href="http://toscho.de/2009/schrift-in-firebug-aendern/" target="_blank">post by Thomas Scholz</a> (it&#8217;s in German, here&#8217;s <a href="http://translate.google.com/translate?js=y&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;u=http%3A%2F%2Ftoscho.de%2F2009%2Fschrift-in-firebug-aendern%2F&amp;sl=de&amp;tl=en">Google&#8217;s translation</a>).</p>
<p>The details: Firebug&#8217;s CSS files are located in its extension directory, which is probably someplace like this:</p>
<ul>
<li>Vista: C:\Users\{<strong>USERNAME</strong>}\AppData\Roaming\Mozilla\Firefox\Profiles\{<strong>alphanumerics</strong>}.default\extensions\firebug@software.joehewitt.com\skin\classic</li>
<li>XP: C:\Documents and Settings\{<strong>USERNAME</strong>}\Application Data\Mozilla Firefox\Profiles\extensions\firebug@software.joehewitt.com\skin\classic</li>
</ul>
<p>Search-and-replace the Monaco away, and restart Firefox.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/351/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/351/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/351/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=351&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2009/11/20/firebug-and-monaco-on-windows/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2009/11/firebug-monaco-vista2.gif" medium="image">
			<media:title type="html">Firebug and Monaco on Vista</media:title>
		</media:content>
	</item>
		<item>
		<title>Clojure Changing My Mind</title>
		<link>http://invisibleblocks.com/2009/11/13/clojure-changing-my-mind/</link>
		<comments>http://invisibleblocks.com/2009/11/13/clojure-changing-my-mind/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 22:15:17 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=328</guid>
		<description><![CDATA[As good as Processing is, it&#8217;s still java. I&#8217;ve slowly been learning clojure, and trying to use it with Processing, via clj-processing. While the clojure docs and the book are both good, I&#8217;m still in that flounder-around stage, trying out tiny experiments to understand how things work. I wanted a function to make saw-step sequences: [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=328&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>As good as <a href="http://processing.org">Processing</a> is, it&#8217;s still java.  I&#8217;ve slowly been learning <a href="http://clojure.org">clojure</a>, and trying to use it with Processing, via <a href="http://github.com/rosado/clj-processing">clj-processing</a>. While <a href="http://clojure.org/Reference">the clojure docs</a> and <a href="http://www.amazon.com/gp/product/1934356336?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1934356336">the book</a> are both good, I&#8217;m still in that flounder-around stage, trying out tiny experiments to understand how things work.</p>
<p>I wanted a function to make saw-step sequences: (1 2 3 2 1 2 3 2 &#8230;).  You give it the low bound, the high bound, and the step-size.  For example:</p>
<ul>
<li><code>(saw-step 1 4 1)</code> gives <code>(1 2 3 4 3 2 1 2 3 4 3 ...)</code></li>
<li><code>(saw-step 0 15 5)</code> gives <code>(0 5 10 15 10 5 0 5 ...)</code></li>
<li><code>(saw-step 0 5 2)</code> gives <code>(0 2 4 5 3 1 0 2 4 5 ...)</code></li>
</ul>
<p>I&#8217;ve coded this kind of thing up in ruby, javascript, or java a dozen times, though it&#8217;s usually inside a loop, not returning a list.  Something like this:</p>
<p><pre class="brush: jscript;">
var min = 3;
var max = 7;
var step = 2;

var n = min;
while(shouldContinue()) {
    doSomethingWith(n);
    n += step;
    if (n+step &gt; max || n-step &lt; min) {
        step *= -1;  // turn around
    }
}
</pre></p>
<p>My first try in clojure took a similar tack.  I never got it right, but it was something like this:</p>
<pre style="font-size:1.2em;">(defn saw-step
  [min max step-size]
    (let [step (ref step-size)]
      (iterate
       (fn [x]
         (if (or ( min (- x @step)))
           (dosync (alter step -)))
         (+ @step x))
         min)))</pre>
<p>It&#8217;s a disaster &#8212; the parentheses don&#8217;t even match &#8212; but you get the gist.  I was trying to cram the same imperative algorithm into clojure: keep some mutable state, add <code>step</code> to it, and when you reach the edges, mutate <code>step</code> to change direction.  I kept getting bugs where it would go one step beyond the edge, or it would start working its way back from one edge, only to turn around again, and bounce against the edge forever.</p>
<p>I gave up and went to bed, but a few days later, I had better luck.</p>
<pre style="font-size:1.2em;">(defn saw-step
  [min max step]
     (cycle
      (into (vec (range min max step)) ; vec, so (into) adds to end
	    (for [x
		  (iterate #(- % step) max)
		  :while (&gt; x min)] x))))</pre>
<p>The first not-entirely-wrong step I made was to try breaking the list of numbers I wanted into two parts: the going-up numbers, and the coming-down numbers.  (0 2 4 5 3 1) is just (0 2 4) + (5 3 1).  The <code>(range min max step)</code> part gives you the going-ups, and the <code>(for [x (iterate ...)</code> stuff is the going-downs, as a list comprehension.</p>
<p>(One mistake I made was trying <code>(range max min step)</code> for the going-downs, which yields an empty list; another was using <code>(iterate dec max)</code>, which never ends, because it keeps decrementing into the negatives.  I found my way out with the list comprehension, but I bet there&#8217;s a better way.)</p>
<p>Once you have those two lists, you can use <code>into</code> to add each item from the second list to the first, giving you (0 2 4 5 3 1).  That goes into <code>cycle</code> for a lazy, infinite sequence.</p>
<p>The solution&#8217;s not too bad: a saw-step is a cycle of the going-ups, followed by the going-downs.  The code looks about that way.</p>
<p>(It occurred to me after that I could always use a default step of 1, and pipe the result through a scaling map.  That would give me the bounds I wanted, with the extra benefit of evenly-spaced steps.  Maybe I&#8217;ll remove <code>step</code> later.)</p>
<p><a href="http://www.cs.yale.edu/quotes.html">Alan Perlis</a> said, &#8220;A language that doesn&#8217;t affect the way you think about programming, is not worth knowing.&#8221;  He also said, &#8220;The only difference(!) between Shakespeare and you was the size of his idiom list &#8211; not the size of his vocabulary.&#8221;  Clojure&#8217;s changing my mind, a bit at a time.</p>
<p><em> </em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/328/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/328/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/328/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/328/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/328/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/328/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/328/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/328/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=328&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2009/11/13/clojure-changing-my-mind/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>
	</item>
		<item>
		<title>A JavaScript War Story</title>
		<link>http://invisibleblocks.com/2009/10/20/a-javascript-war-story/</link>
		<comments>http://invisibleblocks.com/2009/10/20/a-javascript-war-story/#comments</comments>
		<pubDate>Wed, 21 Oct 2009 02:03:46 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[scheme]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=294</guid>
		<description><![CDATA[What follows is an account from the author&#8217;s experience. Some details have been changed for the usual reasons, and a poor memory has fuzzed out the rest. UPDATE: it turns out the technique described below is known as debouncing. What an awesome name! My last job was for a company that made case-management software. With [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=294&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><i>What follows is an account from the author&#8217;s experience.  Some details have been changed for the usual reasons, and a poor memory has fuzzed out the rest.</i></p>
<p><i><b>UPDATE:</b> it <a href="http://www.reddit.com/r/javascript/comments/9w53i/a_javascript_war_story/c0eqxrd">turns out</a> the technique described below is known as <a href="http://en.wikipedia.org/wiki/Switch#Contact_bounce">debouncing</a>.  What an awesome name!</i></p>
<p>My last job was for a company that made case-management software.  With this software, you could track all kinds of data about your case: you could categorize it, sub-categorize it, say where and when it happened, note whether it was still open, track who was responsible&#8230;all kinds of stuff, great for data fiends.</p>
<p>One of our customers&#8217; favorite features was the reports, and they were pretty spiffin&#8217;.  But, not being ones to rest on our laurels, we were adding pivot-table reports, so you could count the number of cases, grouped by any criteria you wanted.  The input screen let the customer pick their pivot criterion, and which criteria they wanted as columns, for sub-counts.  We struggled to name these UI fields &#8212; something lucid, something explanatory, something <i>evocative</i> &#8212; something to make them understand what kind of report they were in for.  After a while, we decided to just <i>show</i> them: when they changed their pivot criterion, we&#8217;d run some javascript to render a skeleton report, same as the real report, but minus the data.  It would save them time, and save our servers.</p>
<p>The javascript was pretty involved.  It had to generate the same HTML as we did for the pivot table, which meant it had to know (or make up) values for each criterion, like all the case categories and sub-categories, and which sub-categories belonged to which categories.  And we let the customers pivot on up to THREE, count &#8216;em, different criteria.  And it had to happen each time the user picked different pivot criteria.  It took a few tricks, but we got it working.  It ran slowly, maybe a few seconds, but it was quick enough, probably, especially once we threw in a little &#8220;please wait&#8221; spinner.  Then we realized we needed to re-render whenever the window resized.</p>
<p>No biggie, I thought, and I quickly added <code>window.onResize(reportPreview);</code>.  It worked great, except it re-rendered the report with every pixel-wide movement of the mouse, as the window was dragged to new widths and heights.  Calling a function, one that runs for a few seconds, <i>a hundred times</i> in the time it took to widen the browser an inch, meant a locked browser.  It meant &#8220;time to get more coffee,&#8221; and after, &#8220;time to fix the bug.&#8221;</p>
<p>I knew we could delay calling <code>reportPreview</code>, but we only wanted to delay it when the window was being resized &#8212; when the user changed the columns, there was no reason to wait.  I was sure <code>window.setTimeout()</code> would do what we needed, but I didn&#8217;t want to muck up <code>reportPreview()</code> with it.</p>
<p>I&#8217;d been reading <a href="http://www.amazon.com/gp/product/0262560992?ie=UTF8&amp;tag=invisblock-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0262560992">The Little Schemer</a> lately, and noticing some striking similarities between javascript and scheme: first-class functions, and higher-order functions that take functions as arguments, and return other functions as values.  It was fun reading, with its strange teacher-student dialog style.  The material was better than brainteasers, and I knew it would make me a better programmer down the road, but I didn&#8217;t think of it as relevant to the day-job, as&#8230;applicable.</p>
<p>Then I realized higher-order functions were a way out of this.  I could write a function, <code>delay</code>, that would wrap one long-running, slow-poke function in <i>another</i> function: an intermediary that you could call as many times a second as you wanted, but it would only call the slow-poke once things had settled down.  <code>delay</code> would let us keep <code>setTimeout</code> out of <code>reportPreview</code>.  Something like this:</p>
<p><pre class="brush: jscript;">
function delay(millis, slowPoke) {
    var timeoutId = undefined;

    // This is the intermediary.  Call it lots, it won't hurt.
    return function() {
        if (timeoutId) {  // If we're waiting...
            clearTimeout(timeoutId); // re-start the clock.
        }
        timeoutId = window.setTimeout(slowPoke, millis);
    }
}
</pre></p>
<p>The first time you call the intermediary, it tells the window to call <code>slowPoke</code> after a bit, but every time you call it after that, it starts the clock over.  It&#8217;s like when you&#8217;re in a five-minute time-out, and you start acting up after only three, so your mom says &#8220;Ok, buster, another five minutes.&#8221;</p>
<p><pre class="brush: jscript;">
var fiveMinutes = 5 * 60 * 1000;
var screamAndShout = delay(fiveMinutes, function() {
    getBackToPlaying();
});

screamAndShout(); // Aw nuts, I'm in time-out.

// I'll be good for as long as I can, but...
screamAndShout(); // dang, five MORE minutes!
</pre></p>
<p>Once <code>delay</code> was in place, running <code>reportPreview</code> when the window was resized was no problem.</p>
<p><pre class="brush: jscript;">
function reportPreview() {
    // recursion, DOM manipulation, insanity...
}
columnPicker.onChange(reportPreview);
window.onResize(delay(100, reportPreview));
</pre></p>
<p>After testing, we found that delaying it for 100 milliseconds made all the difference in the world.</p>
<p><i>Do you have a war story?  Share it, and start the healing: tell a short one in the comments, or link to a longer one on your own damn blog.</i>   </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/294/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/294/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/294/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=294&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2009/10/20/a-javascript-war-story/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>
	</item>
		<item>
		<title>Higher-Order Functions and Function Composition, with Processing</title>
		<link>http://invisibleblocks.com/2009/05/04/higher-order-functions-and-function-composition-with-processing/</link>
		<comments>http://invisibleblocks.com/2009/05/04/higher-order-functions-and-function-composition-with-processing/#comments</comments>
		<pubDate>Mon, 04 May 2009 17:41:53 +0000</pubDate>
		<dc:creator>Daniel Bernier</dc:creator>
				<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://invisibleblocks.wordpress.com/?p=250</guid>
		<description><![CDATA[I was looking for a good way to illustrate functional composition and higher order functions, and thought that something could be done with Processing, a java-based graphics tool. Among other things, Processing exposes raw pixel data for the images it renders, and you can update the pixels programatically, providing a simple kind of image filtering. [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=250&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I was looking for a good way to illustrate functional composition and higher order functions, and thought that something could be done with <a href="http://processing.org">Processing</a>, a java-based graphics tool. Among other things, Processing exposes raw pixel data for the images it renders, and you can update the pixels programatically, providing a simple kind of image filtering.</p>
<p>For example, here&#8217;s some code that converts a color image to grayscale. Just like with HTML, colors are represented<sup><a name="f1" href="#1">1</a></sup> as 3 channels (red, green, blue), and each channel has 255 increments. A gray pixel has equal amounts of red, green, and blue, so if you get the overall brightness of a pixel, and set its color to that much red, green, and blue, it should turn the image gray.</p>
<p><pre class="brush: java;">
PImage img = loadImage(&quot;tattoo.jpg&quot;);
size(img.width, img.height);  // set the window size
image(img, 0, 0);  // render the image at x:y = 0:0

loadPixels(); // load the image's pixels into an array
for (int i = 0; i &lt; pixels.length; i++) {
    // get the color for this pixel
    color c = pixels[i];

    // get its brightness
    float bright = brightness(c);

    // Change its color to its grayscale equivalent
    pixels[i] = color(bright, bright, bright);
}
updatePixels();  // render the new pixels to the screen
</pre></p>
<p>Here&#8217;s the original image:</p>
<p><a href="http://invisibleblocks.files.wordpress.com/2009/05/tattoo.jpg"><img class="size-medium wp-image-265" src="http://invisibleblocks.files.wordpress.com/2009/05/tattoo.jpg?w=300&#038;h=199" alt="the original image" width="300" height="199" /></a></p>
<p>&#8230;and here&#8217;s the filtered version:</p>
<p><a href="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_grayscale.jpg"><img class="size-medium wp-image-266" src="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_grayscale.jpg?w=300&#038;h=199" alt="the image in grayscale" width="300" height="199" /></a></p>
<p>You can define a bunch of routines like this, each looping through the pixels the same way, but adjusting the colors differently. But if you can separate the pixel-changing part from the pixel-looping part, then you can swap in ANY pixel-changing routine, giving you a flexible image filtering system.</p>
<p>The pixel-changing code is essentially a function that turns one pixel&#8217;s color into a new color, and the pixel-looping code uses it to replace each pixel&#8217;s original color.  The pixel-changing function could be described like this:</p>
<p><pre class="brush: java;">
color transform(color c) {
    ...
}
</pre></p>
<p>Many modern programming languages support first-class functions, which are a natural way to model this. Processing uses a form of Java, which doesn&#8217;t have first-class functions, but we can wrap the functions in a class, giving us an object called a functor.  I called this one ColorTrans, for &#8220;color transformer&#8221;.</p>
<p><pre class="brush: java;">
abstract class ColorTrans {
    public abstract color transform(color c);
}
</pre></p>
<p>The ColorTrans class&#8217; only method, <code>transform</code>, is our pixel-changing function. We can re-write the loop from before to use a ColorTrans filter, and while we&#8217;re at it, we&#8217;ll move it into a method that takes the filename as a parameter, too.</p>
<p><pre class="brush: java;">
void filterImage(String path, ColorTrans filter) {
    PImage img = loadImage(path);
    size(img.width, img.height);
    image(img, 0, 0);

    loadPixels();
    for (int i = 0; i &lt; pixels.length; i++) {
        // use the filter parameter
        pixels[i] = filter.transform(pixels[i]);
    }
    updatePixels();
}
</pre></p>
<p>We can easily recreate the grayscale filter from earlier as a ColorTrans.</p>
<p><pre class="brush: java;">
ColorTrans grayscale = new ColorTrans() {
    color transform(color c) {
        float bright = brightness(c);
        return color(bright, bright, bright);
    }
};

filterImage(&quot;tattoo.jpg&quot;, grayscale);
</pre></p>
<p>Another really easy filter to write is an inverter. If a pixel has R:100, G:30, B:255, an inverter will return the color R:(255-100), G:(255-30), B:(255-255), or R:155, G:225, B:0.</p>
<p><pre class="brush: java;">
ColorTrans invert = new ColorTrans() {
    color transform(color c) {
        return color(255 - red(c),
                     255 - green(c),
                     255 - blue(c));
    }
};

filterImage(&quot;tattoo.jpg&quot;, invert);
</pre></p>
<p>The image produced by an inverter is like a film negative.</p>
<p><a href="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_invert.jpg"><img class="size-medium wp-image-268" src="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_invert.jpg?w=300&#038;h=199" alt="inverted, like a negative" width="300" height="199" /></a></p>
<p>Now we begin to see the benefits of keeping the-parts-that-change separate from the-parts-that-don&#8217;t: we can easily define and swap in new filters. This is one of the big parts of higher-order programming: writing routines that are configured by passing in functions (or functors, in this case) to do part of the work.</p>
<h3>Manufacturing a ColorTrans</h3>
<p>A useful kind of filter is one that increases (or decreases) the color on one channel: add some red, or remove some green. This kind of filter is easy to create:</p>
<p><pre class="brush: java;">
ColorTrans aFifthMoreRed = new ColorTrans() {
    color transform(color c) {
    	return color(red(c) * 1.2, green(c), blue(c));
    }
};
</pre></p>
<p>This filter will increase the amout of red in the image by 20%. But 20% is a pretty arbitrary number; it&#8217;d be better if we could tell the filter how much to increase the red by. Generally, you&#8217;d add an &#8220;amount&#8221; parameter to the transform method, but then filterImage would have to know that this ColorTrans object takes an extra parameter. It&#8217;s kind of nice having filterImage treat all ColorTrans objects the same, just passing in the color.</p>
<p>Instead, we can make a method that builds ColorTrans objects: we tell it how much to increase the red by, and it builds a ColorTrans that does it for us.</p>
<p><pre class="brush: java;">
ColorTrans ampRed(final float amount) {
    return new ColorTrans() {
        color transform(color c) {
            color(red(c) * amount, green(c), blue(c));
        }
    };
}

ColorTrans aQuarterMoreRed = ampRed(1.25);
ColorTrans aThirdLessRed = ampRed(2/3);
ColorTrans noRedAtAll = ampRed(0);
</pre></p>
<p>(If you&#8217;re curious why <code>amount</code> is final, the short answer is &#8220;because the compiler says so,&#8221; but there&#8217;s a better answer<sup><a name="f2" href="#2">2</a></sup>.)</p>
<p>This is pretty nice, because we can use this inside an animation loop, animating the amount of color amplification.</p>
<p><pre class="brush: java;">
float theta = 0.0;

void setup() {
    filterImage(&quot;tattoo.jpg&quot;, noChange);
}

void draw() {
    float ampRedAmount = sin(theta) * 1.2;
    filterImage(&quot;tattoo.jpg&quot;, ampRed(ampRedAmount));
    theta += 0.1;
}
</pre></p>
<p>[Here's where I'd link to the applet, nicely hosted somewhere, if I had a hosting service that allowed applets.  I'll try to find a place to put all the code, so you can try it yourself.]</p>
<p>Processing calls <code>setup</code> to initialize the animation, and calls <code>draw</code> once per &#8220;tick&#8221;, to advance the animation. Here, in each frame of the animation, a new ColorTrans is constructed by <code>ampRed</code>, with the amount tied to the sine wave function, oscillating between 0 and 1.2. When viewed, the amount of red in the image swells and falls, and back again<sup><a name="f3" href="#3">3</a></sup>.</p>
<p>This is another big part of higher-order programming: writing functions that build other functions, based on some arguments. Combined with routines that take functions as arguments, it&#8217;s a handy way to break down some problems. If done well, the routines that take functions as arguments, and the functions that build those functions, can become a sort of mini-language, a fluent interface, or almost an embedded DSL.</p>
<h3>Plugging filters together &#8211; filter composition</h3>
<p>This is where it gets fun. Suppose you&#8217;ve created an ampBlue that works just like ampRed, and now you want to filter an image with <em>both</em> of them.  One approach might be something like this:</p>
<p><pre class="brush: java;">
void draw() {
    filterImage(&quot;tattoo.jpg&quot;, ampRed(sin(theta) * 1.2));
    filterImage(&quot;tattoo.jpg&quot;, ampBlue(cos(theta) * 1.2));
}
</pre></p>
<p>Using the sine and cosine functions, the image should pulse nicely through reds and blues. The only problem is that it doesn&#8217;t really work, because filterImage loads the image fresh from the filesystem each time, so you only get the effect of the ampBlue filter. So how can we apply multiple filters?</p>
<p>We plug them together. We want a filter that does the work of two other filters, and we want it to look like any other filter, so filterImage won&#8217;t know the difference. To get this, we can add a method to ColorTrans that returns a <em>new</em> ColorTrans, which calls first the one, and then the other.</p>
<p><pre class="brush: java;">
class ColorTrans {
    ...
    public ColorTrans then(final ColorTrans applySecond) {
        final ColorTrans applyFirst = this;
        return new ColorTrans() {
	    color transform(color c) {
	        return applySecond(applyFirst(c));
	    }
	};
    }
}

filterImage(&quot;tattoo.jpg&quot;, grayscale.then(invert));
</pre></p>
<p><a href="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_grayscale_invert.jpg"><img class="size-medium wp-image-268" src="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_grayscale_invert.jpg?w=300&#038;h=199" alt="first grayscaled, then inverted" width="300" height="199" /></a></p>
<p>Combining filters becomes a matter of chaining them together through <code>then</code>. The red-and-blue example becomes:</p>
<p><pre class="brush: java;">
void draw() {
   filterImage(&quot;tattoo.jpg&quot;,
        ampRed(sin(theta) * 1.2).then(
            ampBlue(cos(theta) * 1.2)));
}
</pre></p>
<h3>Processing does it kind of this way, too</h3>
<p>If you look at the <a href="http://dev.processing.org/source/">source for Processing</a>, in <a href="http://dev.processing.org/source/index.cgi/trunk/processing/core/src/processing/core/PImage.java?view=markup&amp;rev=5417">PImage.java</a> on line 619, you&#8217;ll find code that looks kind of like this:</p>
<p><pre class="brush: java;">
  public void filter(int kind) {
    loadPixels();

    switch (kind) {
      case BLUR: ...
      case GRAY: ...
      case INVERT: ...
      case POSTERIZE: ...
      case RGB: ...
      case THRESHOLD: ...
      case ERODE: ...
      case DILATE: ...
    }
    updatePixels();  // mark as modified
  }
</pre></p>
<p>It basically does just what I&#8217;ve been doing, except the operations are hard-coded into the source, rather than being separated behind a class interface. The filters aren&#8217;t composable directly, though you can call a number of them in a row:</p>
<p><pre class="brush: java;">
filter(INVERT);
filter(THRESHOLD);
filter(DILATE);
</pre></p>
<p>One benefit of this approach is that it&#8217;s easy to see, line-by-line, exactly what&#8217;s happening.  I&#8217;d bet it beats the pants off of the ColorTrans version in benchmarks, too. But filters aren&#8217;t composeable, and it&#8217;s certainly not extendable. When you&#8217;re doing computation-intensive graphics, every bit of speed is important; when you&#8217;re illustrating a programming idea, it&#8217;s not.  Decide for yourself which is more important for your needs.</p>
<p>____________________________________</p>
<p><a name="1"></a><br />
1. It may seem weird, if you know Java, that the parameter&#8217;s type is <code>color</code> &#8212; it&#8217;s not a java primitive, but it doesn&#8217;t follow the normal classname conventions. It&#8217;s just the way Processing does it. You can read more about the <a href="http://processing.org/reference/color_.html">color constructor in the Processing reference</a>.  <a href="#f1">[back]</a></p>
<p><a name="2"></a><br />
2. Taken from the <a href="http://c2.com/cgi/wiki?AnonymousInnerClass">AnonymousInnerClasses</a> page on the Portland Patterns Repository, 2009-04-30:</p>
<blockquote><p>AnonymousInnerClasses can also be used to create something like closures in the JavaLanguage. However they do not &#8220;close over&#8221; the lexical environment so they aren&#8217;t TrueClosures. (They can capture the value of local variables, but they do not have access to the variable binding so they can&#8217;t change the original variable. Which Java makes quite clear by only allowing InnerClasses to refer to local variables that have been declared final (so no-one can change them)).</p></blockquote>
<p><a href="#f2">[back]</a></p>
<p><a name="3"></a><br />
3. The <code>noChange</code> filter returns the same color it was given &#8212; an identity function.  <code>filterImage</code> is called inside <code>setup</code> only so the window size is set correctly, since setting the size inside <code>draw</code> has no effect. And <em>theta</em> is just a Greek letter often used for angles and trigonometry.<a href="#f3">[back]</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/invisibleblocks.wordpress.com/250/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/invisibleblocks.wordpress.com/250/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/invisibleblocks.wordpress.com/250/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/invisibleblocks.wordpress.com/250/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/invisibleblocks.wordpress.com/250/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/invisibleblocks.wordpress.com/250/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/invisibleblocks.wordpress.com/250/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/invisibleblocks.wordpress.com/250/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=invisibleblocks.com&amp;blog=290283&amp;post=250&amp;subd=invisibleblocks&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://invisibleblocks.com/2009/05/04/higher-order-functions-and-function-composition-with-processing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/360300f6962b973dae989991dc204f75?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">bonsaigiant</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2009/05/tattoo.jpg?w=300" medium="image">
			<media:title type="html">the original image</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_grayscale.jpg?w=300" medium="image">
			<media:title type="html">the image in grayscale</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_invert.jpg?w=300" medium="image">
			<media:title type="html">inverted, like a negative</media:title>
		</media:content>

		<media:content url="http://invisibleblocks.files.wordpress.com/2009/05/tattoo_grayscale_invert.jpg?w=300" medium="image">
			<media:title type="html">first grayscaled, then inverted</media:title>
		</media:content>
	</item>
	</channel>
</rss>
