<?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:creativeCommons="http://backend.userland.com/creativeCommonsRssModule"
>

<channel>
	<title>Stephan Sokolow's Blog &#187; Geek Stuff</title>
	<atom:link href="http://blog.ssokolow.com/archives/category/general/geek-stuff/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ssokolow.com</link>
	<description>Fanfiction Reviews, Interesting Links, and General Geekery</description>
	<lastBuildDate>Sat, 31 Jul 2010 02:43:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
<cloud domain='blog.ssokolow.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com" />
	<atom:link rel="hub" href="http://superfeedr.com/hubbub" />
			<item>
		<title>A Quick And Dirty m0n0wall &#8220;Get WAN IP&#8221; API</title>
		<link>http://blog.ssokolow.com/archives/2010/07/30/a-quick-and-dirty-m0n0wall-get-wan-ip-api/</link>
		<comments>http://blog.ssokolow.com/archives/2010/07/30/a-quick-and-dirty-m0n0wall-get-wan-ip-api/#comments</comments>
		<pubDate>Sat, 31 Jul 2010 02:43:51 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=437</guid>
		<description><![CDATA[Until recently, I&#8217;d been using WhatIsMyIP.com&#8217;s API to fill in the external IP field in my Conky readout, but a few days ago, they started a very silly thing where, for whatever reason, clients have to follow a 301 redirect to the URL they just asked for in order to get the IP. I decided [...]]]></description>
			<content:encoded><![CDATA[<p>Until recently, I&#8217;d been using WhatIsMyIP.com&#8217;s API to fill in the external IP field in my <a href="http://conky.sourceforge.net/">Conky</a> readout, but a few days ago, they started a very silly thing where, for whatever reason, clients have to follow a 301 redirect to the URL they just asked for in order to get the IP. I decided that was excuse enough to write a more direct solution.</p>
<p>Since, recently, I&#8217;d learned that it&#8217;s possible to muck about in m0n0wall without pulling the CF card (despite the lack of proper SSH), I decided to take m0n0wall&#8217;s interfaces readout page, strip out everything that wasn&#8217;t necessary to get the WAN IPv4 address, and add an explode() call to separate the IP from the hostmask.</p>
<p>If you want it for your own m0n0wall box, here are the instructions:</p>
<ol>
<li>Grab <code><a href="http://gist.github.com/501674">api_wan_ipaddr4.php</a></code> from my GitHub Gist.</li>
<li>﻿﻿﻿﻿Go to exec.php on your m0n0wall box (<a href="http://192.168.1.1/exec.php">http://192.168.1.1/exec.php</a> with the default DHCP configuration)</li>
<li>(optional) Type &#8220;<code>status_interfaces.php</code>&#8221; into the download box and use a tool like diff to verify that I haven&#8217;t added anything nefarious.</li>
<li>Use the exec.php upload interface to upload <code>api_wan_ipaddr4.php</code>.</li>
<li>Run these commands using the exec field:
<pre><code>mv /tmp/api_wan_ipaddr4.php /usr/local/www
chmod 755 api_wan_ipaddr4.php</code></pre>
</li>
<li>Load it in your browser (<a href="http://192.168.1.1/api_wan_ipaddr4.php">http://192.168.1.1/api_wan_ipaddr4.php</a> with defaults) to confirm that it&#8217;s working.</li>
<li>Use wget/curl/etc. with HTTP authentication to retrieve your external IP whenever you want. I use this command for my conky:<br />
<code></p>
<pre style="overflow: auto;">curl -s --insecure --anyauth --netrc https://192.168.0.1/api_wan_ipaddr4.php</pre>
<p></code></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/07/30/a-quick-and-dirty-m0n0wall-get-wan-ip-api/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>My Unofficial &#8220;How to Extend distutils&#8221; FAQ</title>
		<link>http://blog.ssokolow.com/archives/2010/07/28/my-unofficial-how-to-extend-distutils-faq/</link>
		<comments>http://blog.ssokolow.com/archives/2010/07/28/my-unofficial-how-to-extend-distutils-faq/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 20:20:10 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=413</guid>
		<description><![CDATA[Whenever I have to set up a Python project, I&#8217;m always amazed at how little documentation there is on extending distutils to add new commands or otherwise deal with un-anticipated (and apparently, some anticipated) circumstances. In the absence of an easily found HOWTO or guide, I&#8217;ve had to go source-diving&#8230; and when I do that, [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever I have to set up a Python project, I&#8217;m always amazed at how little documentation there is on extending distutils to add new commands or otherwise deal with un-anticipated (and apparently, some anticipated) circumstances. In the absence of an easily found HOWTO or guide, I&#8217;ve had to go source-diving&#8230; and when I do that, it&#8217;s only good manners that I share what I found.</p>
<p>The following questions are things I found myself frequently wondering, but <span style="text-decoration: underline;">feel free to ask me other questions</span>. I&#8217;ll add answers for the &#8220;likely to be frequent&#8221; ones as time permits.</p>
<dl>
<dt>How do I create a new command for distutils?</dt>
<dd>As I find myself often forgetting this, I&#8217;ve posted a <a href="http://gist.github.com/495943">template with explanatory comments</a> as a GitHub Gist.</dd>
<dt>How do I add my custom command to multiple projects without including it and setting <code>cmdclass</code> in each one?</dt>
<dd>As far as I know, using only distutils, you can&#8217;t. However, setuptools <a href="http://peak.telecommunity.com/DevCenter/setuptools#creating-distutils-extensions">provides a mechanism</a>.</dd>
<dt>How do I make a custom command fail gracefully if non-optional dependencies aren&#8217;t present?</dt>
<dd>
<ul>
<li>For dependencies internal to Python (modules, specific module versions, etc.), you can define your command inside a <code>try/except</code> or <code>if</code> block. <a href="http://gist.github.com/495943">my template</a> includes an example.</li>
<li>For external commands, I recommend defining your command inside an <code>if</code> block and using a <a href="http://twistedmatrix.com/trac/browser/tags/releases/twisted-9.0.0/twisted/python/procutils.py">which</a> function to test for them. (Using an external &#8220;which&#8221; command is ugly and fragile)</li>
</ul>
</dd>
<dt>How do I access the attributes I passed to <code>setup()</code> from my custom command?</dt>
<dd>This was a surprisingly involved thing to figure out.  <code>setup()</code> passes its arguments to an instance of <code>distutils.dist.Distribution</code> which then parcels them out to various places.</p>
<p>The simple explanation is that, if it&#8217;s set in <code>setup()</code> and setup.py doesn&#8217;t complain about it being unrecognized, your command can access it as an attribute of either <code>self.distribution</code> or <code>self.distribution.metadata</code>. (With the possible exception of it being a command-specific option. I forget how those work)</p>
<p>However, the metadata also offers a comprehensive collection of getter methods which return strings like &#8220;UNKNOWN&#8221; in place of None, so you&#8217;ll probably want to ask PyDoc for details:</p>
<pre><code>pydoc distutils.dist.DistributionMetadata</code></pre>
<p>A practical example of the most common use I&#8217;ve had for this is retrieving the list of packages to be installed via <code>self.distribution.packages</code> so a tool like <a href="http://epydoc.sourceforge.net/">Epydoc</a> or <a href="http://www.logilab.org/857">Pylint</a> can be run on them.</p>
</dd>
<dt>Is there a clean, sane way to bundle resources (eg. custom toolbar icons) with my project</dt>
<dd>Not really. <a href="http://stackoverflow.com/questions/1395593/managing-resources-in-a-python-project">[1]</a> <a href="http://wiki.python.org/moin/Distutils/Cookbook/AutoDataDiscovery">[2]</a> <a href="http://wiki.python.org/moin/Distutils/Cookbook/InstallDataScattered">[3]</a> The approaches linked aren&#8217;t pretty, but they&#8217;re all I&#8217;ve been able to find.</dd>
<dt>Where do I find new commands?</dt>
<dd>Given that Python has PyPI, you&#8217;d think there would at least be a repository of commands for setuptools. However, aside from the commands that come bundled with their associated programs (nosetests, flakes, build_sphinx, etc.), I haven&#8217;t found anything. The wiki mentioned in the next question has a very sparse <a href="http://wiki.python.org/moin/Distutils/Cookbook">cookbook</a> though.</dd>
<dt>There&#8217;s really no community documentation for this stuff?</dt>
<dd><a href="http://wiki.python.org/moin/Distutils">There is</a>, but it only covers <em>some</em> of the questions listed here. One of these days when I&#8217;m not feeling so unmotivated, I&#8217;ll merge this FAQ into theirs.</dd>
<dt>Isn&#8217;t anybody working to fix this mess?</dt>
<dd><a href="http://tarekziade.wordpress.com/2010/03/03/the-fate-of-distutils-pycon-summit-packaging-sprint-detailed-report/">Yes, but it&#8217;s not going to happen overnight.</a></dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/07/28/my-unofficial-how-to-extend-distutils-faq/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Game Reviews: Aquaria</title>
		<link>http://blog.ssokolow.com/archives/2010/06/28/game-reviews-aquaria/</link>
		<comments>http://blog.ssokolow.com/archives/2010/06/28/game-reviews-aquaria/#comments</comments>
		<pubDate>Mon, 28 Jun 2010 18:34:47 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>
		<category><![CDATA[Otaku Stuff]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=400</guid>
		<description><![CDATA[Rating: 4.5/5
A few months back, I was informed of an offering known as the Humble Indie Bundle. Seeing it as an opportunity to finally pick up a copy of World of Goo, I bought in. However, my brother quickly insisted that I try another one of the games in the bundle&#8230;
Aquaria is an aquatic platformer. [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Rating:</strong> 4.5/5</p>
<p>A few months back, I was informed of an offering known as the <a href="http://www.wolfire.com/humble">Humble Indie Bundle</a>. Seeing it as an opportunity to finally pick up a copy of <a href="http://2dboy.com/games.php">World of Goo</a>, I bought in. However, my brother quickly insisted that I try another one of the games in the bundle&#8230;</p>
<p><a href="http://www.bit-blot.com/aquaria/">Aquaria</a> is an aquatic platformer. More specifically, an aquatic platformer with <a href="http://www.bit-blot.com/aquaria/media.html">gorgeous art</a>, <a href="http://infiniteammo.bandcamp.com/track/the-traveller">beautiful music</a>, and a focus on semi-linear exploration. If <a href="http://www.braid-game.com/">Braid</a> is one possible expression of &#8220;<a href="http://en.wikipedia.org/wiki/Super_Mario_Bros.">Super Mario Bros.</a>&#8217;s almost nonexistant story done right&#8221; (A review for another day), then Aquaria is an expression of &#8220;<a href="http://en.wikipedia.org/wiki/Super_Metroid">Super Metroid</a> done right&#8221;.</p>
<p>Everything about the game seems carefully crafted to emphasize the atmosphere around you and it makes exploration a treat, there&#8217;s a wide variety of enemies, and the &#8220;forms&#8221; system throws back to the various weapons <a href="http://en.wikipedia.org/wiki/Samus_Aran">Samus</a> had to use&#8230; though with less focus on different attacks and more on different skills to pass region barriers.</p>
<p>However, it is still firmly a platformer, so while the story gets a fair bit more work than Super Metroid, there are some rough edges which clearly show that storytelling was not the creators&#8217; specialty and that, while a significant improvement on Super Metroid, improvements still could be made.</p>
<p>The combat mechanic does sometimes take precedence in situations where it&#8217;s detrimental to the atmosphere (for example, the boss battles where, without fail, you have to defeat enraged or corrupted gods, receiving boons from them in moments of lucidity before they finally die) and the descent into the abyss near the end of the game does make the game less engaging&#8230; something a corresponding increase in story-focus could have mitigated.</p>
<p>However, given how rare Metroid-style exploration platformers are and how much I enjoyed exploring the world, I&#8217;m willing to forgive that somewhat. It would definitely have been nicer, though, if they&#8217;d provided more &#8220;ancient turtle&#8221; warp points. (The three largest regions in the game still only get one apiece and one surprise region of respectable size gets none at all, while the surface waters get two) More frequent save points would also have probably been a good idea, given that not everybody is as flexible with their schedule as I am.</p>
<p>A more significant problem, story wise, was the feeling that, toward the end, the story was at once both rushed and sparse. Structuring the game more like an essay, with most of the abyss-crawling in the middle and the triumphant revelation of the coral reefs of the surface (or some &#8220;beyond&#8221; area) would have helped significantly, as would more voice-acted &#8220;vision&#8221; sequences. As is, it feels as if it&#8217;s building toward something as you head for the surface waters&#8230; and then the plunge into the abyss quickly ends the story with loose plot threads being tied up before they could fully be developed.</p>
<p>The fact that, apparently, some recipes in the cooking system are alternate paths to dishes and can only be found by experimentation further develops this impression as players tend to measure their progress by the proportion of discoverable items they&#8217;ve found compared to the total number. Speaking of the cooking system&#8230;</p>
<p>I did find the cooking mechanic enjoyable, primarily because it let me handle my health and powerup management in my own distinctive fashions (and because I used to play games like <a href="http://en.wikipedia.org/wiki/Harvest_Moon_(video_game)">Harvest Moon</a>), but I felt that, to use a programming term, the set of recipes was oriented too much toward depth rather than breadth. Too many ingredients useful in only one recipe, too many recipes that require multiple steps, and too much dependence on a small set of core ingredients that aren&#8217;t proportionally available unless you grind sources of them. Nonetheless, it was fun.</p>
<p>Finally, the collectable trophies seemed too &#8220;collectable for the sake of having them&#8221;, given how thoroughly hidden some of them were. (In some cases, you have to either know where they are already, or be just plain insane to find them) Of all the trophies I collected, the one I still like most is the ever-respawning pot of fish meat. (one of those few over-utilized base ingredients I talked about)</p>
<p>Overall, it gives the impression that the designers had plenty of skill and envisioned something that they, at the time, didn&#8217;t realize would be twice as long as they had the budget for. Nonetheless, I&#8217;d give it a solid 4.5 out of 5 and encourage anyone who enjoyed the old 2D Metroid games (or enjoys 2D platformers and 3D Metroid).</p>
<p>P.S. If you really want to feel the atmosphere to its fullest, let a friend or family member wait through the intro that plays the first time you start the game so you don&#8217;t see it, then click on the crystal in the menu screen to view it (for the first time) after completing Mithalas Cathedral. That way, you won&#8217;t have any potentially inaccurate preconceptions to color Naija&#8217;s initial realization that she knows nothing of her origins.</p>
<p><strong>Update:</strong> If you get the chance, listen to the special OST-only track &#8220;Fear the Dark&#8221; before <em>and</em> after you play Aquaria. It&#8217;s a beautiful piece (<a href="http://infiniteammo.ca/blog/aquaria-ost-launches-saturday-w-live-pj-jam/">preview</a>) and it does a beautifully clever job of hiding its relation to Aquaria so that you only &#8220;get&#8221; it once you&#8217;ve beaten the game. (Thanks to their clever use of pronouns and implicit subjects, it just sounds like very beautiful, if ordinary, love song unless you know who is being talked about)</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/06/28/game-reviews-aquaria/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Many Tanks Site Updates</title>
		<link>http://blog.ssokolow.com/archives/2010/05/14/many-tanks-site-updates/</link>
		<comments>http://blog.ssokolow.com/archives/2010/05/14/many-tanks-site-updates/#comments</comments>
		<pubDate>Fri, 14 May 2010 13:25:00 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>
		<category><![CDATA[Site Updates]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=395</guid>
		<description><![CDATA[Just a quick status update.
I&#8217;ve done some significant re-theming on http://www.ficfan.org/ and fixed a bug that was causing many of the quotes to not show their additional metadata.
While doing so, I noticed that, because of how wp-lifestream caches paths (though I can see no benefit to it), the switchover to the new fileserver caused it [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick status update.</p>
<p>I&#8217;ve done some significant re-theming on http://www.ficfan.org/ and fixed a bug that was causing many of the quotes to not show their additional metadata.</p>
<p>While doing so, I noticed that, because of how wp-lifestream caches paths (though I can see no benefit to it), the switchover to the new fileserver caused it to get in a fight with PHP&#8217;s safe_mode. (Why doesn&#8217;t anybody tell me these things?) That is now fixed.</p>
<p>Finally, now that I&#8217;m on vacation, I had time to dig into wp-lifestream and add a workaround for the double-encoded YouTube links. YouTube faves in my lifestream now actually work.</p>
<p>Enjoy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/05/14/many-tanks-site-updates/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Google Chrome, A Testament to Hubris</title>
		<link>http://blog.ssokolow.com/archives/2010/04/18/google-chrome-a-testament-to-hubris/</link>
		<comments>http://blog.ssokolow.com/archives/2010/04/18/google-chrome-a-testament-to-hubris/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 21:00:52 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=384</guid>
		<description><![CDATA[Before I begin with my argument, let me say that I generally like Google Chrome (or more correctly, Chromium, the open-source release). It&#8217;s the only reasonably responsive open-source (not Opera) browser for tabbed-browsing freaks on Linux, the minimalist UI and &#8220;prevent amateur authors from cluttering things&#8221; extension API work very nicely to keep things clean [...]]]></description>
			<content:encoded><![CDATA[<p>Before I begin with my argument, let me say that I generally like Google Chrome (or more correctly, Chromium, the open-source release). It&#8217;s the only reasonably responsive open-source (not Opera) browser for tabbed-browsing freaks on Linux, the minimalist UI and &#8220;prevent amateur authors from cluttering things&#8221; extension API work very nicely to keep things clean yet functional, and I love the little touches like extending the active areas of edge widgets like scrollbars and the tab bar all the way to the edge of the screen in maximized windows.</p>
<p>I also agree that, to make progress, you have to experiment. However, when the Chrome devs start making not-so-smart changes, ignoring mass-complaint by the users of their &#8220;Dev Channel&#8221; releases, not even compromising with a simple checkbox, and marking well-starred issues as WontFix, they start to approach the level of arrogance and hubris I once thought reserved for the developers of The GIMP. (They&#8217;re not quite there since, in my experience, GIMP developers will also insult you or dismiss valid complaints as rude before setting RESO INVALID or RESO WONTFIX)</p>
<p>Here are a few of the more controversial changes, to put it politely, which they have forced on Chrome users in the last few months:</p>
<ul>
<li><a href="http://code.google.com/p/chromium/issues/detail?id=26140">Chrome Linux single click does not select all</a> (An &#8220;experiment&#8221; that has now lasted roughly 6 months, proven a bit divisive in the early-adopter community, and received neither the requested checkbox nor a satisfying response from the devs.)</li>
<li><a href="http://code.google.com/p/chromium/issues/detail?id=150">Type-ahead-find</a> [<a href="http://code.google.com/p/chromium/issues/detail?id=90">2</a>] (Apparently, the devs feel keybinding purity is more important than users&#8230; and &#8220;/&#8221; without modifiers is impure)</li>
<li><a href="http://code.google.com/p/chromium/issues/detail?id=147">Warn when closing with multiple tabs open</a> (Apparently data loss is preferable to modal dialogs with &#8220;remember my choice&#8221; checkboxes)</li>
<li><a href="http://code.google.com/p/chromium/issues/detail?id=41467">URL bar no longer shows http://</a> (A pointless nod to space-constrained cellphone address bars which has caused <a href="http://code.google.com/p/chromium/issues/list?q=label:HTTPStripping">various regressions</a>&#8230; including some not mentioned in the bug tracker)
<ul>
<li>It makes novice web developers <a href="http://www.osnews.com/permalink?419597">more likely to produce broken links</a></li>
<li>It makes life <a href="http://www.osnews.com/permalink?419614">more difficult</a> for professional web developers</li>
<li>It&#8217;s not that different from the old &#8220;change for change&#8217;s sake&#8221; that UI design best practices warn against.</li>
</ul>
</li>
</ul>
<p>&#8230;and that doesn&#8217;t even cover the many issues that should be trivial fixes but have languished for months or even years&#8230; presumably while the UI change reviews required by Google are continually de-prioritized in favor of whatever it is that the devs actually care about. (eg. <a href="http://code.google.com/p/chromium/issues/detail?id=33181">native RSS support</a>, <a href="http://code.google.com/p/chromium/issues/detail?id=255">reliable middle-click</a>, <a href="http://code.google.com/p/chromium/issues/detail?id=6363">debugged pop-up blocker</a>, <a href="http://code.google.com/p/chromium/issues/detail?id=333">file associations</a>, <a href="http://code.google.com/p/chromium/issues/detail?id=1674">working blur()/focus()</a>, <a href="http://code.google.com/p/chromium/issues/detail?id=9018">download completion protection</a>, <a href="http://code.google.com/p/chromium/issues/detail?id=9845">a comfortable download shelf</a> [<a href="http://code.google.com/p/chromium/issues/detail?id=23767">1</a>] [<a href="http://code.google.com/p/chromium/issues/detail?id=27797">2</a>] [<a href="http://code.google.com/p/chromium/issues/detail?id=23628">3</a>], and various others.</p>
<p>I&#8217;m not saying they should do things my way, but I find it, at the very least, insulting to be forced to do things their way without so much as an about:config or hard-to-find checkbox.</p>
<p>To be perfectly honest, for all its flaws, if Firefox 4.x can provide compact toolbars and a properly responsive GUI on Linux, I&#8217;ll switch back in a heartbeat. It may be a messy free-for-all with an extension system based on fragile <a href="http://en.wikipedia.org/wiki/Monkey_patch">monkey-patching</a> and a rendering engine that&#8217;s more sumo wrestler than rocket, but at least it doesn&#8217;t presume to tell me how to use my own browser.</p>
<p><strong>Update:</strong> As I mentioned in one of the following comments, another reason this really gets to me is the condescension, arrogance, and hypocrisy of claiming to make these changes &#8220;for the user&#8221; and then implicitly qualifying it with &#8220;We know what you want better than you do&#8221;. There&#8217;s a reason I don&#8217;t like Apple, there&#8217;s a reason I don&#8217;t like Microsoft, there&#8217;s a reason I don&#8217;t like the Apple fanboys in charge of GNOME and Ubuntu UI design, and now it looks like I also have a reason to not like Google&#8230; especially given the good arguments for reverting and the convoluted excuses against reverting that I&#8217;m seeing on the issue tracker entry for the removal of http:// from the omnibar.</p>
<p><strong>Update 2:</strong> And, in what seems like an admission of defeat to me, the Google Chrome devs have now marked the issue entry for the removal of http:// read-only. In my experience, that&#8217;s the corporate equivalent of  &#8221;Ohh, nothing&#8217;s going my way. Mom!&#8221;</p>
<p><strong>Update 3:</strong> While Google still seems to be convinced that their &#8220;we know you better than you do&#8221; approach to UI design is correct, they are not completely immune to reason. According to the Chrome 5.0.375.17 ChangeLog, they&#8217;ve temporarily reverted &#8220;http:// truncation, star icon, etc&#8230;&#8221;. Their official stance is &#8220;We are currently examining ways to address the usability issues that were raised and plan to reintroduce in a future release&#8221; though, so I doubt they&#8217;ll be willing to admit that stripping http:// on a non-cellphone browser is inherently a dumb idea.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/04/18/google-chrome-a-testament-to-hubris/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Der Untergang, Bizarro-style</title>
		<link>http://blog.ssokolow.com/archives/2010/04/15/der-untergang-bizarro-style/</link>
		<comments>http://blog.ssokolow.com/archives/2010/04/15/der-untergang-bizarro-style/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 06:26:35 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Web Wandering & Opinion]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=371</guid>
		<description><![CDATA[You may be familiar with the &#8220;Hitler rants&#8221; meme which produced such parodies as &#8220;Hitler gets banned from Xbox Live&#8220;.  However, what you probably haven&#8217;t noticed is that, thanks to a user named hitlerrantsparodies, a continuity has started to coalesce in which Hitler&#8217;s greatest enemy is apparently not the Allies, but his prankster brother-in-law Fegelein [...]]]></description>
			<content:encoded><![CDATA[<p>You may be familiar with the &#8220;Hitler rants&#8221; meme which produced such parodies as &#8220;<a href="http://www.youtube.com/watch?v=sfkDxF2kn1I">Hitler gets banned from Xbox Live</a>&#8220;.  However, what you probably haven&#8217;t noticed is that, thanks to a user named hitlerrantsparodies, a continuity has started to coalesce in which Hitler&#8217;s greatest enemy is apparently not the Allies, but his prankster brother-in-law Fegelein who continually talks Günsche into informing Hitler of stupid, pointless things until finally Fegelein steals Hitler&#8217;s pizza takeout and the others decide to make Fegelein leader.</p>
<p>Here&#8217;s my interpretation of said Bizarro world&#8217;s timeline:</p>
<ol>
<li><a href="http://www.youtube.com/watch?v=1ksrAfYzCjE">Hitler is asked &#8220;Why so serious?&#8221;</a> (where we see that Fegelein hasn&#8217;t yet distracted Hitler to the point where he essentially forgets about the Allies)</li>
<li><a href="http://www.youtube.com/watch?v=50Ln6su5kOI">Hitler is informed he is Fegelein</a> (which apparently takes place before Hitler catches on to the source of Günsche&#8217;s stupid reports)</li>
<li><a href="http://www.youtube.com/watch?v=gUEYOcQYeg4">Hitler is informed Fegelein has locked him into his room</a> (where Hitler starts to realize that Fegelein is the source of all his problems)</li>
<li><a href="http://www.youtube.com/watch?v=oH7Jphxk07g">Hitler is informed he is Hitler</a> (&#8230;but he still hasn&#8217;t realized that Günsche is in on it)</li>
<li><a href="http://www.youtube.com/watch?v=uOnNuNjmnng">Hitler is informed he is sitting down</a> (&#8230;and now he has)</li>
<li><a href="http://www.youtube.com/watch?v=L9LO4EUJ0ZI">Hitler&#8217;s glued to his chair</a> (Fegelein&#8217;s twisted sense of humor responds to the previous incident,  we see how typical this kind of thing is, and Hitler&#8217;s patience wears thin)</li>
<li>&#8211; Fegelein leaks the parodies which arrived on the web first &#8211;</li>
<li><a href="http://www.youtube.com/watch?v=RElwKjgn490">Hitler is informed Fegelein is missing</a> (when Günsche tells Hitler that Fegelein&#8217;s ass-kicking for leaking the early parodies will have to wait)</li>
<li>Various Pranks: <a href="http://www.youtube.com/watch?v=MQrgYGmpKJQ">Helium</a>, <a href="http://www.youtube.com/watch?v=1zBkT7raIKg">Fegelein&#8217;s Death</a>, <a href="http://www.youtube.com/watch?v=LP12x81uYDU">Mass Cloning</a>, etc.</li>
<li><a href="http://www.youtube.com/watch?v=C9ugLUF3Rik">Hitler is losing his voice</a> (from ranting about Fegelein&#8217;s antics all the time)</li>
<li><a href="http://www.youtube.com/watch?v=7cz3RziObB8">Hitler is informed his pizza will arrive late</a></li>
<li><a href="http://www.youtube.com/watch?v=9Mw7w_Jx0GM">Hitler Phones Fegelein</a></li>
<li><a href="http://www.youtube.com/watch?v=Aqz-myKSgRY">Hitler is informed Fegelein is now the leader</a></li>
</ol>
<p>All I can say is that it made my <span style="text-decoration: line-through;">day</span> evening.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 89px; width: 1px; height: 1px;"><a href="http://www.youtube.com/watch?v=gUEYOcQYeg4">http://www.youtube.com/watch?v=gUEYOcQYeg4</a></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/04/15/der-untergang-bizarro-style/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Scribblenauts and /b/-tards</title>
		<link>http://blog.ssokolow.com/archives/2010/02/24/scribblenauts-and-b-tards/</link>
		<comments>http://blog.ssokolow.com/archives/2010/02/24/scribblenauts-and-b-tards/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 17:08:04 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Web Wandering & Opinion]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=362</guid>
		<description><![CDATA[Well, I was wandering around YouTube (no clue why) when I found evidence that the Scribblenauts developers may be /b/-tards. At the very least, they&#8217;re pretty good at catching all the noteworthy memes.
Here are just some of the noteworthy objects I&#8217;d never thought to try:

Longcat (possibly the only thing which can beat God, in-game)
Tacgnol
Keyboard Cat
Ceiling [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I was wandering around YouTube (no clue why) when I found <a href="http://www.youtube.com/watch?v=YCld7luiMKY">evidence</a> that the <a href="http://en.wikipedia.org/wiki/Scribblenauts">Scribblenauts</a> developers may be <a href="http://en.wikipedia.org/wiki/4chan">/b/-tards</a>. At the very least, they&#8217;re pretty good at catching all the noteworthy memes.</p>
<p>Here are just some of the noteworthy objects I&#8217;d never thought to try:</p>
<ul>
<li><a href="http://www.youtube.com/watch?v=dNdFtuf6oo0">Longcat</a> (possibly the only thing which can beat God, in-game)</li>
<li><a href="http://www.youtube.com/watch?v=QvAapR-nl9M">Tacgnol</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Keyboard Cat</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Ceiling Cat</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Philosoraptor</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">O Rly</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Giant Enemy Crab</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Epic Fail</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Monorail Cat</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">All Your Base Are Belong To Us</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Over Nine Thousand</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">I See What You Did There</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Ninja Cat</a></li>
<li><a href="http://www.youtube.com/watch?v=YCld7luiMKY">Om Nom Nom Nom</a></li>
<li><a href="http://www.youtube.com/watch?v=mBpHWIwLgG4">LOLWUT</a> or <a href="http://www.youtube.com/watch?v=mBpHWIwLgG4">LOL WUT</a></li>
<li><a href="http://www.youtube.com/watch?v=6gv_wOBo-1Y">RickRoll</a></li>
<li><a href="http://www.youtube.com/watch?v=yKch13rmYGI">Large Hadron Collider</a> or <a href="http://www.youtube.com/watch?v=yKch13rmYGI">LHC</a> (which will produce a black hole if you turn it on)</li>
<li><a href="http://www.youtube.com/watch?v=cEk_lL439h4">ROFLcopter</a> (and lollerskates)</li>
<li><a href="http://en.wikipedia.org/wiki/Scribblenauts#Pre-release">Two One Seven</a>, <a href="http://en.wikipedia.org/wiki/Scribblenauts#Pre-release">Neogaf</a>, and <a href="http://en.wikipedia.org/wiki/Scribblenauts#Pre-release">Feep</a> (proof that they&#8217;re not above letting culture feed back into their creation)</li>
<li><a href="http://www.youtube.com/watch?v=bpx0u5nj-qU">Mongolian Death Worm</a></li>
<li><a href="http://www.youtube.com/watch?v=vvwZ_eF68ac">Yomama</a> or <a href="http://www.youtube.com/watch?v=vvwZ_eF68ac">Your Mom</a></li>
</ul>
<p>I also ran across some interesting ways to combine items (some of which exploit flaws in the engine):</p>
<ul>
<li><a href="http://www.youtube.com/watch?v=yLf5u_UaM5M">Lasso + Trampoline</a></li>
<li><a href="http://www.youtube.com/watch?v=f_rR98dfwrM">Doc Ock</a></li>
<li><a href="http://www.youtube.com/watch?v=dTYKtmmNr3k">Two One Seven + Tornado</a></li>
<li><a href="http://www.youtube.com/watch?v=X9Ll5RRSiyE">Mind Control Device + Dragon</a></li>
<li><a href="http://www.youtube.com/watch?v=ML_5RjrrCU4">Shoggoth + Shrink Magic</a></li>
</ul>
<p>Commenters also recommended these terms:</p>
<ul>
<li>Ninja Shark</li>
<li>Chinese Dragon (Unlike European dragons, these guys are friendly)</li>
<li>Edison (A bandana-wearing T-Rex)</li>
<li>Blob</li>
<li>Chupacabra</li>
<li>Maxwell (a copy of your character) and a Black Hole</li>
<li>Urn (disturb it and you get a ghost)</li>
<li>Corpse + Chain + Car Battery (or Lightning)</li>
<li>Scribblenaut</li>
</ul>
<p>Finally, just in case you want it, a <a href="http://www.wiinintendo.net/wp-content/uploads/2009/09/scribblenauts.txt">complete list</a> of all the terms the English version of Scribblenauts will recognize. Enjoy. <img src='http://blog.ssokolow.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/02/24/scribblenauts-and-b-tards/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Our Sick Society</title>
		<link>http://blog.ssokolow.com/archives/2010/01/28/our-sick-society/</link>
		<comments>http://blog.ssokolow.com/archives/2010/01/28/our-sick-society/#comments</comments>
		<pubDate>Thu, 28 Jan 2010 11:29:21 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Web Wandering & Opinion]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/?p=336</guid>
		<description><![CDATA[A few months ago, my mother sent me an interesting TED talk about motivation. It turns out that the carrot-and/or-stick model for encouraging rewards stifles creativity. We need more businesses like Atlassian and Google which employ &#8220;intrinsic motivation&#8221; (you do the work because it&#8217;s inherently a desirable thing to do) techniques like &#8220;20% time&#8221; and [...]]]></description>
			<content:encoded><![CDATA[<p>A few months ago, my mother sent me an interesting <a href="http://www.ted.com/talks/lang/eng/dan_pink_on_motivation.html">TED talk about motivation</a>. It turns out that the carrot-and/or-stick model for encouraging rewards stifles creativity. We need more businesses like Atlassian and Google which employ &#8220;intrinsic motivation&#8221; (you do the work because it&#8217;s inherently a desirable thing to do) techniques like &#8220;<a href="http://en.wikipedia.org/wiki/Google#Innovation_Time_Off">20% time</a>&#8221; and research commissioned by people like the US Federal Reserve agrees. Fair enough.</p>
<p>More recently, I was reminded of an interesting article titled <a href="http://www.wesjones.com/gatto1.htm">Against School</a> by John Taylor Gatto that originally appeared in Harper&#8217;s Magazine. More controversial, but also well-referenced and my personal experience generally agrees. Force kids to be surrounded by other kids, doing boring work and you&#8217;ll get mostly emotionally-driven, easily-manipulated adults with the less controllable being outcasts.</p>
<p>It wasn&#8217;t until today, though, that I realized how it all tied together. I discovered a long but very interesting article named &#8220;<a href="http://www.tikkun.org/article.php/nov_dec_09_eisler">Roadmap to a New Economics: Beyond Capitalism and Socialism</a>&#8221; by Riane Eisler. The central point of said article being that rather than thinking of capitalism vs. socialism, we should be thinking of domination systems vs. partnership systems.</p>
<p>It seems fairly obvious in retrospect that the real root of all these problems is this &#8220;Dominate first, co-operate only if that fails&#8221; mentality that our chimpanzee instincts encourage and society strengthens, and as my mother puts it, &#8220;bullying is endemic in our society&#8221;, but it doesn&#8217;t have to be that way.</p>
<p>I&#8217;ll leave this on a related note. I don&#8217;t have a URL handy, but I remember reading an article a few months ago about how, all around the world, there&#8217;s a direct inverse correlation between the size of the gap between rich and poor in a society and the life expectancy of everyone, rich and poor alike. (In other words, for whatever reason, the more unequal your society, the more years lost off your life&#8230; no matter how rich you are. Personally, I suspect stress as the culprit.)</p>
<p><strong>Update:</strong> Since writing this, I received another TED talk about <a href="http://www.ted.com/talks/liz_coleman_s_call_to_reinvent_liberal_arts_education.html">the necessity and lack of true liberal arts education</a> in modern western society and an article about how <a href="http://www.psychologytoday.com/blog/freedom-learn/201002/children-teach-themselves-read">kids teach themselves to read</a>&#8230; and how could I have forgotten Bertrand Russell&#8217;s <a href="http://www.zpub.com/notes/idle.html">In Praise of Idleness</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2010/01/28/our-sick-society/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>SQL Pagination Without OFFSET</title>
		<link>http://blog.ssokolow.com/archives/2009/12/23/sql-pagination-without-offset/</link>
		<comments>http://blog.ssokolow.com/archives/2009/12/23/sql-pagination-without-offset/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 13:19:11 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Web Wandering & Opinion]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/archives/2009/12/23/sql-pagination-without-offset/</guid>
		<description><![CDATA[Just thought I&#8217;d look up how people paginate efficiently in SQLite since, apparently, OFFSET is just an alias for &#8220;discard N first results&#8221;. The recommended solution is to use a WHERE clause to mimic offset using the same column index you use for sorting&#8230; but that&#8217;s only really possible for &#8220;Next&#8221; or &#8220;More&#8230;&#8221; links.
I ended [...]]]></description>
			<content:encoded><![CDATA[<p>Just thought I&#8217;d look up how people paginate efficiently in SQLite since, apparently, OFFSET is just an alias for &#8220;discard N first results&#8221;. The recommended solution is to use a WHERE clause to mimic offset using the same column index you use for sorting&#8230; but that&#8217;s only really possible for &#8220;Next&#8221; or &#8220;More&#8230;&#8221; links.</p>
<p>I ended up discovering that MS SQL, Firebird, Oracle, and DB2 also lack OFFSET and <a href="http://www.phpbuilder.com/board/showpost.php?p=10376515&#038;postcount=6">the solution</a> (MS SQL version) is to grab a list of primary keys which should be skipped using a subquery. (because retrieving just primary keys is faster than retrieving and discarding all the columns you don&#8217;t need)</p>
<p>To make sure I didn&#8217;t forget, I threw up an SQLite version on <a href="http://gist.github.com/262503">GitHub Gists</a>.<br />
<script src="http://gist.github.com/262503.js?file=pagination_example.sql"></script></p>
<p>While doing that, I also ran across <a href="http://tympanus.net/codrops/2009/11/17/jpaginate-a-fancy-jquery-pagination-plugin/">jPaginate</a> (<a href="http://tympanus.net/jPaginate/">demo</a>), a jQuery pagination plugin that, as long as you provide a gracefully-degrading fallback, is probably my new favorite design for a page selector.</p>
<p><b>Update:</b> <a href="http://troels.arvin.dk/db/rdbms/#select-limit">This site</a> is also useful.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2009/12/23/sql-pagination-without-offset/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
		<item>
		<title>Functional Programming Concepts for the Lay Programmer &#8211; Part 1</title>
		<link>http://blog.ssokolow.com/archives/2009/12/21/functional-programming-concepts-for-the-lay-programmer-part-1/</link>
		<comments>http://blog.ssokolow.com/archives/2009/12/21/functional-programming-concepts-for-the-lay-programmer-part-1/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 15:45:06 +0000</pubDate>
		<dc:creator>Stephan Sokolow</dc:creator>
				<category><![CDATA[Geek Stuff]]></category>

		<guid isPermaLink="false">http://blog.ssokolow.com/archives/2009/12/21/functional-programming-concepts-for-the-lay-programmer-part-1/</guid>
		<description><![CDATA[Despite the growing interest in functional programming, most people (myself included) seem to have a lot of trouble grasping the core concepts and constructs. (Probably because the early adopters are all, to some extent, math geeks who have never needed to practice explaining things to the lay-person.) Since I finally decided to sit down and [...]]]></description>
			<content:encoded><![CDATA[<p>Despite the growing interest in functional programming, most people (myself included) seem to have a lot of trouble grasping the core concepts and constructs. (Probably because the early adopters are all, to some extent, math geeks who have never needed to practice explaining things to the lay-person.) Since I finally decided to sit down and figure these things out, I thought it only fair that I share the Google results that led me to my various epiphanies.</p>
<p><b>Note:</b> The closest I&#8217;ve come to actual functional programming languages is adopting parts of the functional style in Python. If my terminology is a little off but I got the gist of the thing, be diplomatic in your complaints. (I&#8217;ve had too much experience with math teachers who seem to think that it&#8217;s pointless to know how to use math without perfectly comprehending the relevant proofs and being able to write your own.)</p>
<h3>The Easy Stuff</h3>
<p>First, let&#8217;s cover a few things which are generally easy to understand&#8230; but only if you&#8217;ve heard of them:</p>
<dl>
<dt>Higher-order Function</dt>
<dd>A function which takes another function as an argument. To make this more comfortable, many languages treat functions and data equally. (In object-oriented languages, this is &#8220;everything is an object&#8221; taken to its logical conclusion). This allows for things like <code>results = filter(arbitrary_test, input_data)</code>. This is an especially useful feature when combined with other features like closures. (explained later)</dd>
<dt>Pure Function</dt>
<dd>A function that only uses its arguments as input, doesn&#8217;t modify variables visible outside itself, and provides all of its output using the language&#8217;s &#8220;return&#8221; statement (or equivalent). In other words, a function with no hidden inputs or side-effects. Pure functions are a Good Thing™ because you know that, with a given set of arguments, they&#8217;ll always do the same thing. This helps immensely with testing and debugging. (and makes unit testing much easier and more reliable)</dd>
<dt>Tail Recursion</dt>
<dd>Getting loop-like behaviour by having functions re-call themselves as the last thing they do. People consider this a good thing because it lets you write loops in a purely functional fashion. (see previous explanation) Functional languages generally optimize this internally so you still get the speed and stack-avoidance of a loop.</dd>
</dl>
<h3>List Comprehensions</h3>
<p>Practically speaking, a list comprehension is just a shorthand for saying &#8220;Take the elements from list X that satisfy condition Y and perform operation Z on them, then return a list of the results&#8221;. The benefit of list comprehensions is that they&#8217;re a quick, easy, concise alternative to declaring an empty list and then wrapping a function in a for loop and an if statement. (Technically speaking, they let you build one list from another using <a href="http://en.wikipedia.org/wiki/Set-builder_notation">set builder notation</a>.) </p>
<p>For example, In Python, you could get the squares of all positive numbers in a list with <code>new_list = [x**2 for x in old_list if x > 0]</code>. Keep in mind, however, that list comprehensions aren&#8217;t limited to working with numbers. I often use one to quickly implement a simple, one-line input normalizer that, in plain English, would be &#8220;Take all lines which aren&#8217;t empty or beginning with # and strip leading and trailing whitespace.&#8221;</p>
<h3>Monads</h3>
<p>As <a href="http://stackoverflow.com/questions/44965/what-is-a-monad/71697#71697">one answer on StackOverflow</a> put it, &#8220;Monads are simply a way [of] wrapping things and provid[ing] methods to do operations on the wrapped stuff without unwrapping it.&#8221; It&#8217;s a clear definition&#8230; but its doesn&#8217;t really give you that &#8220;Aha!&#8221; moment I was looking for. If you have any experience at all with Javascript, the explanations and examples in <a href="http://importantshock.wordpress.com/2009/01/18/jquery-is-a-monad/">jQuery is a Monad</a> should do just that. In short, Monads are useful for changing the set of verbs and how they behave.</p>
<p>The final realization of how useful they can be (and my first recognition of how nifty it can get when you mix functional and imperative styles in a compatible language came from <a href="http://stackoverflow.com/questions/44965/what-is-a-monad/194207#194207">another StackOverflow answer</a> (same question) which showed how, in F#, you can use a monad to do Javascript-style asynchronous HTTP I/O without having to explicitly write callbacks.</p>
<h3>Lazy Evaluation</h3>
<p>When a programming language is given a statement or block of statements, there are various ways it can do things, ranging from fully strict evaluation to fully lazy evaluation. These are usually easier to explain with examples.</p>
<p>The most common subset of lazy evaluation is probably short-circuit evaluation. This means that, if I run something like <code>fileContent = getFromCache(url) or getFromWeb(url)</code> in Python and getFromCache returns something other than None, an empty string, or the like, getFromWeb will never run because &#8220;True or anything&#8221; will always be true, so why bother evaulating the second half? This can be confusing if you don&#8217;t expect it, but as my example shows, it can also be very useful.</p>
<p>As you probably guessed, strict evaluation operates on the premise that &#8220;they said to run it, so we run it&#8230; whether or not we&#8217;re throwing away the output&#8221;. Naturally, in every language, if/then/else constructs use lazy evaluation.</p>
<p>The area of lazy evaluation that is sometimes confusing is eager evaluation versus delayed evaluation. If you&#8217;re still reading this, you&#8217;re almost certainly familiar with eager evaluation. For example, if you look at a list, you might see something like <code>[1, 2, 3, 4, 5, 6]</code>.</p>
<p>The gist of delayed evaluation is that, at any given time, that list could look more like <code>[1, 2, 3, ...]</code> with the language evaluating further into the &#8220;<code>...</code>&#8221; as needed. This is useful because you can do things like creating an infinite list (<a href="http://en.wikipedia.org/wiki/Lazy_evaluation#Delayed_evaluation">Wikipedia</a> uses the Fibonacci sequence as an example) and then retrieving specific values from it.</p>
<p>On a more mundane note, lazy evaluation is also commonly used for improving program performance. For example, in graphical systems where drawing is done only at the last minute so that &#8220;Oops. Looks like those pixels aren&#8217;t visible to the user after all&#8221; doesn&#8217;t impair performance.</p>
<h3>Haskell</h3>
<p>I haven&#8217;t actually used Haskell yet, but from what I&#8217;ve seen, I think I&#8217;ll try to make time for it soon. (When I do, I&#8217;ll update this post) Here are the posts that brought me to that conclusion (In concert with what I&#8217;ve already linked, of course):</p>
<ul>
<li><a href="http://intoverflow.wordpress.com/2009/01/13/why-haskell-is-beyond-ready-for-prime-time/">Why Haskell is Beyond Ready for Prime Time</a> (This is the more convincing one in my opinion)</li>
<li><a href="http://cdsmith.wordpress.com/2007/07/29/37-reasons-to-love-haskell-playing-off-the-ruby-article/">37 Reasons to Love Haskell</a></li>
</ul>
<p>Among other things, I love the idea of a code repository where you can search for functions by specifying the inputs and return types you need.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ssokolow.com/archives/2009/12/21/functional-programming-concepts-for-the-lay-programmer-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	<creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license>
	</item>
	</channel>
</rss>
