<?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>Michael Lauer's Weblog</title>
	<atom:link href="http://mrlauer.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://mrlauer.wordpress.com</link>
	<description></description>
	<lastBuildDate>Thu, 17 Nov 2011 17:32:11 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='mrlauer.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Michael Lauer's Weblog</title>
		<link>http://mrlauer.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mrlauer.wordpress.com/osd.xml" title="Michael Lauer&#039;s Weblog" />
	<atom:link rel='hub' href='http://mrlauer.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Kindle Fire</title>
		<link>http://mrlauer.wordpress.com/2011/11/17/kindle-fire/</link>
		<comments>http://mrlauer.wordpress.com/2011/11/17/kindle-fire/#comments</comments>
		<pubDate>Thu, 17 Nov 2011 17:23:05 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Nerd Stuff]]></category>
		<category><![CDATA[electronic toys]]></category>
		<category><![CDATA[H. P. Lovecraft]]></category>
		<category><![CDATA[Kindle fire]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/?p=543</guid>
		<description><![CDATA[For the first time in my life, I seem to be the first person I&#8217;ve talked to to have the latest electronic toy, one of these. It doesn&#8217;t have the enormous coolness factor of something shiny and made by Apple, but still. Overall I&#8217;m loving it. I&#8217;m using it more as an extra-portable and convenient [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=543&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><img style="float:right;border:0;" src="http://mrlauer.files.wordpress.com/2011/11/kindle-fire.gif?w=149&#038;h=135" alt="Fire!" width="149" height="135" />For the first time in my life, I seem to be the first person I&#8217;ve talked to to have the latest electronic toy, one of these. It doesn&#8217;t have the enormous coolness factor of something <a href="http://www.theonion.com/video/apple-introduces-revolutionary-new-laptop-with-no,14299/">shiny and made by Apple</a>, but still.</p>
<p>Overall I&#8217;m loving it. I&#8217;m using it more as an extra-portable and convenient web-browser/time-waster than as a reader and Amazon-content-delivery system (its obvious purpose), more cheap-and-small iPad than expensive Kindle. Which was pretty much my plan. It works great for that. It even works for some things I honestly didn&#8217;t expect it to, like reading powerpoint presentations (I wasn&#8217;t surprised so much that it tried as that it succeeded).</p>
<p>Of course there are some annoying things about it. Many would (I assume) apply to any mobile touch-screen toy—typing is painful, mobile websites are missing bits I take for granted (e.g. formatting in gmail). Some (many? most?) android apps don&#8217;t seem to be available in the amazon appstore—that is probably changing even as I write.</p>
<p>But the single most annoying thing is something I had expected to be trivial. I had figured it would be trivial to download a free ebook—from <a href="http://www.gutenberg.org/">Project Gutenberg</a>, say—and start reading it immediately. Not so! You can download a .mobi file, and then it just sits there refusing to be read. The quickest way I&#8217;ve found to get the demmed things to import is to</p>
<ul>
<li>open QuickOffice</li>
<li>Documents/Downloads</li>
<li>Hold your finger down on the file, and pick &#8220;Send&#8221; when the menu comes up</li>
<li>Email it to your kindle account</li>
<li>Wait a while. Wait some more.</li>
</ul>
<p>Isn&#8217;t there a better way to do this? If not, for the love of heaven why?<sup>*</sup></p>
<p>On the subject of free ebooks, I&#8217;d like to give a shoutout to someone calling herself <a href="http://cthulhuchick.com/">Cthulhuchick</a> for digitizing the complete works of H. P. Lovecraft and making them available in a nice free edition. Also for picking a great nom d&#8217;internet.</p>
<p>* Maybe I&#8217;ll answer my own question: Amazon has no interest in my reading stuff I didn&#8217;t buy from them.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/543/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/543/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/543/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=543&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/11/17/kindle-fire/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>

		<media:content url="http://mrlauer.files.wordpress.com/2011/11/kindle-fire.gif" medium="image">
			<media:title type="html">Fire!</media:title>
		</media:content>
	</item>
		<item>
		<title>Out of Bembo</title>
		<link>http://mrlauer.wordpress.com/2011/11/15/out-of-bembo/</link>
		<comments>http://mrlauer.wordpress.com/2011/11/15/out-of-bembo/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 20:52:34 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[typography]]></category>
		<category><![CDATA[Wicked]]></category>
		<category><![CDATA[Gregory Maguire]]></category>
		<category><![CDATA[Out of Oz]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/?p=540</guid>
		<description><![CDATA[I just got a copy of Out of Oz from the library, and the first thing I notice is that the typeface is back to the Truesdell of the original Wicked, rather than the always lovely but comparatively bourgeois and anodyne Bembo of Son of a Witch and A Lion Among Men. I hope this means the book is as weird as [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=540&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I just got a copy of <em><a href="http://www.amazon.com/Out-Oz-Final-Wicked-Years/dp/0060548940/ref=sr_1_1?ie=UTF8&amp;qid=1321390082&amp;sr=8-1">Out of Oz</a></em> from the library, and the first thing I notice is that the typeface is back to the <a href="http://www.identifont.com/find?font=truesdell&amp;q=Go">Truesdell</a> of the original <em>Wicked,</em> rather than the always lovely but comparatively bourgeois and anodyne <a href="http://www.identifont.com/find?font=bembo&amp;q=Go">Bembo</a> of <em>Son of a Witch</em> and <em>A Lion Among Men</em>. I hope this means the book is as weird as the first one was.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/540/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/540/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/540/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=540&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/11/15/out-of-bembo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
		<item>
		<title>In Other News, Sun to Rise in East</title>
		<link>http://mrlauer.wordpress.com/2011/11/15/in-other-news-sun-to-rise-in-east/</link>
		<comments>http://mrlauer.wordpress.com/2011/11/15/in-other-news-sun-to-rise-in-east/#comments</comments>
		<pubDate>Tue, 15 Nov 2011 20:42:00 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[economics]]></category>
		<category><![CDATA[Daniel Klein]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[Zeljka Buturovic]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/2011/11/15/in-other-news-sun-to-rise-in-east/</guid>
		<description><![CDATA[In June 2010, Daniel Klein published a gratuitously silly piece in the Wall Street Journal&#8217;s gratuitously silly op-ed section, purporting to show that liberals are stupider than conservatives and libertarians, at least in terms of basic economics. This occasioned some amount of delight among conservatives and libertarians&#8212;vide Veronique de Rugy in the reliably obnoxious National [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=539&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In June 2010, Daniel Klein published a gratuitously silly <a href="http://online.wsj.com/article/SB10001424052748703561604575282190930932412.html">piece</a> in the Wall Street Journal&#8217;s gratuitously silly op-ed section, purporting to show that liberals are stupider than conservatives and libertarians, at least in terms of basic economics. This occasioned some amount of delight among conservatives and libertarians&#8212;vide <a href="http://www.nationalreview.com/corner/231568/which-political-party-understands-economics-best-veronique-de-rugy">Veronique de Rugy</a> in the reliably obnoxious National Review Online (to be fair, not all <a href="http://hotair.com/archives/2010/06/08/wsj-liberals-fail-economics-test-conservative-and-libertarians-score-best/">conservative pundits</a> fell for it). The &#8220;methodology&#8221; Klein relied on centered around a series of agree-or-disagree statements, things like &#8220;Third World workers working for American companies overseas are being exploited&#8221; and &#8220;Minimum wage laws raise unemployment,&#8221; most of which I would call at best &#8220;arguable,&#8221; all of which are pretty clearly politically charged in that they challenged various liberal positions, and all of whose &#8220;correct&#8221; answers were on the conservative/liberal sides of various issues. So, surprise! liberals did worse on the &#8220;do I agree with the conservative/liberaltarian author&#8221; test than conservatives and liberaltarian.<sup>1</sup></p>
<p>To his (relative) credit, Klein eventually realized the problem, and he did a similar exercise with questions slanted the other way (&#8220;gun-control laws fail to reduce people&rsquo;s access to guns&#8221;). To what should be no one&#8217;s surprise, this time he found that conservatives were the stupid ones. Read about it in the current <em><a href="http://www.theatlantic.com/magazine/archive/2011/12/i-was-wrong-and-so-are-you/8713/">Atlantic</a></em>. Klein now thinks what both surveys demonstrate is &#8220;myside bias.&#8221; Really!</p>
<p>I feel a little sorry for&nbsp;Zeljka Buturovic,&nbsp;Klein&#8217;s (possibly more academic) collaborator. According to Klein&#8217;s <em>Atlantic</em>&nbsp;article, her goal wasn&#8217;t to prove anything about economic literacy, but rather to &#8220;[explore] the possibility that ideological differences stem more from differences in people&rsquo;s beliefs about how the world works than from differences in their basic values.&#8221; There might be something to that, although I don&#8217;t know how to sort out the causality there (and I haven&#8217;t read the journal articles). Since she wasn&#8217;t the one who wrote either the WSJ or <em>Atlantic</em>&nbsp;articles, I don&#8217;t want to tar her with the same brush. Sorry,&nbsp;Zeljka!</p>
<p>Oh, another annoying thing. The questions and &#8220;correct&#8221; answers are reported in the most confusing way imaginable. From the <em>Atlantic</em>, citing the questions with the canonically <em>incorrect</em> answers in quotes:</p>
<blockquote><p>Here&rsquo;s what we came up with, again with the incorrect response in parentheses: a dollar means more to a poor person than it does to a rich person (disagree); making abortion illegal would increase the number of black-market abortions (disagree); legalizing drugs would give more wealth and power to street gangs and organized crime (agree); drug prohibition fails to reduce people&rsquo;s access to drugs (agree); gun-control laws fail to reduce people&rsquo;s access to guns (agree); by participating in the marketplace in the United States, immigrants reduce the economic well-being of American citizens (agree);&nbsp;&#8230;</p>
</blockquote>
<p>So how many negatives to I have to wade through to figure out what an enlightened person thinks of gun control laws? I&#8217;m pretty sure Klein thinks they reduce access to guns (I think that too), but that&#8217;s more because that&#8217;s what you would ask if your goal is to prove conservatives are wrong than from trying to cancel out the &#8220;fail to&#8221; and the &#8220;incorrect response in parentheses.&#8221;</p>
<p>&nbsp;</p>
<p>1. For what it&#8217;s worth, on the original set of questions I would probably have mostly given the &#8220;conservative&#8221; answers, but only if &#8220;it depends&#8221; wasn&#8217;t an option, and only if I had inferred the context that would be generally implied from the fact that someone was asking about that particular set of things and using that particular phrasing.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/539/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/539/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/539/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=539&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/11/15/in-other-news-sun-to-rise-in-east/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
		<item>
		<title>node.js</title>
		<link>http://mrlauer.wordpress.com/2011/11/13/node-js/</link>
		<comments>http://mrlauer.wordpress.com/2011/11/13/node-js/#comments</comments>
		<pubDate>Sun, 13 Nov 2011 21:31:11 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[node.js]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/?p=529</guid>
		<description><![CDATA[I&#8217;ve been looking at node.js, the server-side (more general than that, really) javascript execution environment. My gut reaction is that I like it&#8211;I like it a lot. But I think it will take some serious investigation to determine whether it&#8217;s ready for an industrial-strength application. Now some details, aimed at node-n00bs such as myself. Anyone [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=529&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been looking at node.js, the server-side (more general than that, really) javascript execution environment. My gut reaction is that I like it&#8211;I like it a lot. But I think it will take some serious investigation to determine whether it&#8217;s ready for an industrial-strength application.</p>
<p>Now some details, aimed at node-n00bs such as myself. Anyone who would like to point out how badly I&#8217;ve gotten things wrong, feel free!</p>
<p>First, it&#8217;s important to know that node.js is architected to solve a specific problem, to wit, scalability in the presence of lots of concurrent access. The usual way something like apache/php handles concurrency is to spawn a thread for each server request. But threads have overhead, and there&#8217;s only so far you can push that before you have to buy more servers.</p>
<p>node.js has pretty much the opposite philosophy. The buzzwords you see are &#8220;asynchronous&#8221; and &#8220;event-driven&#8221; or just &#8220;evented&#8221;&#8212;its central element is a single-threaded event loop. But that doesn&#8217;t tell you much about why it&#8217;s a good idea. I found a much more revealing tagline here: &#8220;everything runs in parallel, except your code.&#8221;</p>
<p>The idea is that in a typical (non-trivial) server request most of the processing time is taken up in things like database or filesystem access, henceforth referred to generically (and not always completely correctly) as &#8220;IO.&#8221; Those are things that either don&#8217;t take a lot of CPU cycles, or at least are already in their own threads or processes. If the thread running those IO operations waits for them to complete, it will be sitting idle; in a single-threaded event loop that means it will block anything waiting for it. So in a single-threaded event loop, you don&#8217;t wait! IO operations in node.js don&#8217;t return their data directly; instead, they accept callbacks to process the results when they&#8217;re ready. Those callbacks are themselves processed in the event loop.</p>
<p>The callback functions themselves should all be lightweight, so that tens of thousands of them can be executed per second. They palm off all the hard work to &#8220;IO functions,&#8221; black boxes that may in turn add more callbacks. The node.js API, and good node.js plugin modules, are structured to make it positively difficult to do anything that blocks.</p>
<p>Here&#8217;s a &#8220;hello world&#8221; webserver, straight from the node.js front page, that responds to any request with, er, &#8220;hello world&#8221;:</p>
<p><pre class="brush: jscript;">
var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(1337, &quot;127.0.0.1&quot;);
</pre></p>
<p>The guts of that there&#8211;the argument to http.createServer&#8211;is the callback that gets called from the event loop whenever the server fires the &#8220;request&#8221; event (you don&#8217;t see the event loop yourself; you just add callbacks for events, and they are called from the event loop). It does the actual responding by calling methods on res, a ServerResponse object.</p>
<p>Of course a real response will be more complicated (starting with url-parsing, which I&#8217;ll ignore completely). Traditionally that might look something like</p>
<p><pre class="brush: jscript;">
http.createServer(function (req, res) {
  var data = do_some_io_operation(req);
  var output = do_some_more_processing(data);
  res.writeHead(200, {'Content-Type': 'text/html'});
  res.end(output);
}).listen(1337, &quot;127.0.0.1&quot;);
</pre></p>
<p>But those two function calls, if they do anything IO-ish or otherwise nontrivial, are not kosher node.js. This should be something like this:</p>
<p><pre class="brush: jscript;">
http.createServer(function (req, res) {
  do_some_io_operation(req, function(data) {
    do_some_more_processing(data, function(output) {
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.end(output);
    });
  });
}).listen(1337, &quot;127.0.0.1&quot;);
</pre></p>
<p>What happens on a request is:</p>
<ul>
<li>The handler calls do_some_io_operation, which registers a callback and fires off whatever the operation is. It&#8211;and the handler&#8211;return immediately, and processing can move on to anything that&#8217;s waiting in the event queue.</li>
<li>When the io operation completes, the first inner callback gets executed. That calls do_some_more_processing, which registers yet another callback, starts whatever it starts, and returns.</li>
<li>When THAT finishes, the inner callback finally takes all the data it now has available and finishes responding to the request.</li>
</ul>
<p>Database access might look something like this (not real code, but it might be close, modulo error handling)</p>
<p><pre class="brush: jscript;">
http.createServer(function (req, res) {
  dbase.connect('tcp://whateverdbase@localhost/whatever', function(connection) {
    var query = connection.query('SELECT * FROM some_table');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    query.on('row', function(row) {
      res.write('&lt;p&gt;' + row + '&lt;/p&gt;');
    });
    query.on('end', function(row) {
      res.end('Hello World\n');
    });
  });
}).listen(1337, &quot;127.0.0.1&quot;);
</pre></p>
<p>Connecting to the dbase is an IO operation, and since everything depends on that almost the whole response function is inside a callback. Setting up the query as I have it here doesn&#8217;t necessarily do anything immediately, so it does NOT need to take a callback, but that would be an alternative API. However, you do have to wait for the results of the query, so it gets callbacks for its &#8220;row&#8221; and &#8220;end&#8221; events.</p>
<p>I rather like this functional quasi-<a href="http://en.wikipedia.org/wiki/Continuation_passing" target="_blank">continuation-passing</a> style of programming, mostly because I like finding out the abstruse theoretical concepts turn out to be useful for real. It might get a bit messy in real examples, though. At the very least I wonder if it would call for a different indentation style .</p>
<p>[And I have a "<a href="https://github.com/mrlauer/coffee-script-monads">solution</a>" for that. Or at least something that's kept me happily occupied for the last couple of days. More on it later, if I ever get around to it.]</p>
<p>The fact that this is all in javascript has a few real advantages. Javascript is halfway to being a functional language, and is thus well suited to this style of programming. But it&#8217;s not Lisp or Haskell, so existing programmers don&#8217;t have to rewire their brains to use it. (<a href="http://mrlauer.wordpress.com/2010/12/18/rambling-thoughts-about-comonads/">I love Haskell</a>, but I can&#8217;t imagine trying to find and manage a team to write a Real Product with it.) Indeed, any web programmer will already be fluent in javascript, and used to working with callbacks, if not quite to the pervasive level that node.js requires.</p>
<p>Using the same language on the client and server is a nice benefit, too. It makes it easy to share code between the two sides, something that can be useful (caveat: writing javascript that will work properly in a browser and inside node.js is NOT completely trivial, but it&#8217;s usually not that difficult either). And it&#8217;s nice for us programmers to avoid the annoying context switches between languages. Going from javascript to python, for example, I am forever forgetting to put quotes around dictionary keys.</p>
<p>And compared to other dynamic languages, javascript on google&#8217;s V8 engine, which node uses, is really fast. For &#8220;pure&#8221; stuff, just function calls and for loops and the like, it appears to be more in the C/C++ range than the Python/Ruby/php range.</p>
<p>Now for the downsides. Actually, for all I know there aren&#8217;t any prohibitive ones! But node.js is still relatively new, and I although I think the core is relatively stable the general ecosystem isn&#8217;t. There are lots and lots of modules for doing various things, but in this sort of open-source world it&#8217;s really difficult to know what you can trust. In the Perl world, for example, I&#8217;ve seen CPAN hailed as the greatest thing since sliced bread, but I&#8217;ve seen a lot of crap there, and sorting through it can be a real cost.</p>
<p>node.js itself is quite low-level, lower-level even than php. Someone needs to encapsulate even simple things like (e.g.) gathering get and especially post data into dictionaries of query values and data (not that that&#8217;s hard, but it does need to happen). There are some embryonic higher-level frameworks&#8212;<a href="http://expressjs.com/">Express</a> looks very promising, and at least does that post-data processing&#8212;I am fairly certain there&#8217;s nothing anywhere near as mature and trustworthy as Ruby on Rails or Django (or <a href="http://asp.net/" target="_blank">asp.net</a>, if you like that sort of thing).</p>
<p>And conceptually not everyone agrees that eventing is the way to handle concurrency. There are lots of partisans of Erlang and the aforementioned Haskell and even of traditional threading who beg to differ. I&#8217;m a bit out of my depth here, so can&#8217;t comment usefully.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/529/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/529/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/529/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/529/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/529/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/529/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/529/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/529/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=529&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/11/13/node-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
		<item>
		<title>Blame Ben Nelson!</title>
		<link>http://mrlauer.wordpress.com/2011/08/03/blame-ben-nelson/</link>
		<comments>http://mrlauer.wordpress.com/2011/08/03/blame-ben-nelson/#comments</comments>
		<pubDate>Wed, 03 Aug 2011 13:31:51 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Politics]]></category>
		<category><![CDATA[Ben Nelson]]></category>
		<category><![CDATA[debt ceiling]]></category>
		<category><![CDATA[Tea Party]]></category>

		<guid isPermaLink="false">https://mrlauer.wordpress.com/?p=527</guid>
		<description><![CDATA[In any sort of catastrophe it&#8217;s important to decide who to blame. A good scapegoat almost never helps to avoid future catastrophes, but who cares? Blame is fun! So who do we blame for the Sugar-coated Satan Sandwich? Which on its own merits isn&#8217;t as bad as it could have been, really&#8230; at least civilization [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=527&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In any sort of catastrophe it&#8217;s important to decide who to blame. A good scapegoat almost never helps to avoid future catastrophes, but who cares? Blame is fun!</p>
<p>So who do we blame for the Sugar-coated Satan Sandwich? Which on its own merits isn&#8217;t as bad as it could have been, really&#8230; at least civilization didn&#8217;t collapse, as was a real possibility; and the creation of the terrifyingly-named Super Congress has the great virtue of postponing the really awful decisions for a few months. No, the real problems with it are the precedents it set, and the fact that our governing class&#8217;s (including the punditocracy) has decided to respond to a genuine economic crisis by focusing on the single least relevant factor and as a result implementing the stupidest possible policies. Who can we blame for that?</p>
<p>The obvious answer for liberalish coastal elites like me is the Tea Party. But that&#8217;s too easy. Sure, the Tea Partiers are stupid and crazy, and it&#8217;s absolutely terrifying how much power they wield. But <a href="http://en.wikipedia.org/wiki/The_Scorpion_and_the_Frog">that is their nature</a>, and you can&#8217;t expect them to go against their nature. They&#8217;ve said all along that they don&#8217;t like government, so by golly they&#8217;re going to try to get rid of it any way they can. They&#8217;re the mad bomber from <em><span style="color:#ffffff;">Source Code</span></em> (name whited out in case you don&#8217;t want to know what I&#8217;m very mildly spoiling) (paraphrasing, because I forget the real quote): &#8220;We can build a new and better society out of the rubble. We just need to make the rubble first.&#8221; No wonder they&#8217;re cross that they got everything they asked for: they didn&#8217;t hold the government and economy hostage to have their demands met; they made their demands so they could shoot the hostage. This is crazy, but, well, they&#8217;re crazy, and have a pretty credible insanity defense. &#8220;Forgive them, father, for they know not what they do.&#8221;</p>
<p>The sane Republicans, insofar as that&#8217;s not an oxymoron now, are considerably more culpable. They at least knew what they were doing, and I can only hope they&#8217;re full of self-loathing now. This goes double, of course, for Boehner and Cantor, who remind me of <a href="http://en.wikipedia.org/wiki/Count_Baltar">Count Baltar</a> from the old <em>Battlestar Galactica</em> (Baltar from the NEW <em>Battlestar Galactica</em> is much more interesting), allying with the sworn enemies of their very existence. But I can almost understand them; like so many politicians through history, they&#8217;re acting out of fear, terrified for their jobs. Well, Cantor is trying to get a better job, but close. Again, you can&#8217;t expect someone to against their nature.</p>
<p>How about the Republicans&#8217; corporate masters? We&#8217;re getting closer here. At the risk of having Godwin&#8217;s Law justifiably invoked, they are treading perilously close to the Weimar-era German business interests who backed the Nazis, thinking they would be easily-controlled tools. I do hope the Chamber of Commerce is reconsidering its priorities. But business leaders in our society, even the allegedly brilliant ones, are always short-sighted, greedy, and stupid, so again you sort of have to expect this.</p>
<p>Pundits? Journalists? Bloggers? Well, yes, they&#8217;re mostly pretty bad. But there&#8217;s only so much pundits can do to influence the national debate, as much as they would like to think otherwise.</p>
<p>It&#8217;s fashionable among my progressive brethren and sisteren to blame Obama for all this. Now I won&#8217;t pretend that I&#8217;m not disappointed in Obama, but honestly, what could he have done? Obama really wants to make deals and compromise and bring people together, not productive strategies in dealing with modern Republicans, but I honestly don&#8217;t know what anyone could have done, no matter how tough. You can&#8217;t play chicken with someone who WANTS a head-on collision. Yeah, I know, he should have <a href="http://www.thedailyshow.com/watch/mon-august-1-2011/dealageddon----a-compromise-without-revenues">seen this coming</a>, but IIRC that was just after the LAST hostage crisis; even if Obama could have imagined the teabaggers were that crazy it would have been difficult to continue. It&#8217;s kind of like the way we didn&#8217;t attack the Russkies in August 1945.</p>
<p>So who do I blame? How did we get to this point anyway? The proximate cause is of course the great Shellacking of 2010, an inevitable result of a lousy economy and a high unemployment rate (and a fickle Democratic base). But one lousy election&#8212;one where only one house of Congress changed parties&#8212;really shouldn&#8217;t have sent the nation&#8217;s political discourse so quickly off the sanity cliff. I can easily imagine a parallel universe in which the Democrats lost the House not to the Tea Partiers but to more or less sane Republicans. My theory is that the underlying problem is in what should have been Obama&#8217;s greatest triumph, <a href="http://en.wikipedia.org/wiki/Patient_Protection_and_Affordable_Care_Act">health care reform</a>. You&#8217;d think that people would be pleased with some guarantee of health insurance, but no, they HATE it. And it was that hatred (say I) more than anything else that allowed the teahadists to sweep into office, so cowing Democrats that in their confusion and terror they willingly stipulated to the Republican view of the world.</p>
<p>Obviously much of the anti-Obamacare bile is due to Republican lies, not just the flashy ones like Death Panels, but the underlying lie that our health care system is The Best In The World (something I think you can only believe if you&#8217;ve never actually meant someone from another country). But lies can only get you so far. As I see it the real problem was with the Democrats themselves, specifically with the Senate Democrats, for doing such a miserable job of getting the the thing passed, and inviting the world in for an open house at the <a href="http://en.wikiquote.org/wiki/Talk:Otto_von_Bismarck#law_and_sausages">Sausage Factory</a>. The most egregious example (that I know of; perhaps were even worse things that weren&#8217;t so obvious) was the legendarily odious <a href="http://www.google.com/search?aq=0&amp;oq=ben+nelson+cornhus&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=ben+nelson+cornhusker+kickback">Cornhusker Kickback</a>&#8212;even though it didn&#8217;t make it into the final bill, it was so appalling that it rather justifiably convinced the world that the whole process was corrupt and its result inevitably evil. So, on behalf of the Tea Party, thank you Ben Nelson!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/527/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/527/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/527/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=527&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/08/03/blame-ben-nelson/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
		<item>
		<title>Historical Writing</title>
		<link>http://mrlauer.wordpress.com/2011/08/02/historical-writing/</link>
		<comments>http://mrlauer.wordpress.com/2011/08/02/historical-writing/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 18:50:56 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[Strange Victory]]></category>

		<guid isPermaLink="false">https://mrlauer.wordpress.com/2011/08/02/historical-writing/</guid>
		<description><![CDATA[One more note on the previous post: It&#8217;s not fair of me to expect the same level of juicy detail from ancient history as there is (or can be) in classical or modern history; there is simply more information about the more recent periods. As far as I know the Egyptians had no analogs of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=525&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One more note on the <a href="http://mrlauer.wordpress.com/2011/08/02/the-rise-and-fall-of-ancient-egypt/-fall-of-ancient-egypt/">previous post</a>:</p>
<p>It&#8217;s not fair of me to expect the same level of juicy detail from ancient history as there is (or can be) in classical or modern history; there is simply more information about the more recent periods. As far as I know the Egyptians had no analogs of the wonderfully chatty and gossipy (and unreliable) classical historians, and although they were great record-keepers there just isn&#8217;t the same sort of detail we have about more recent times. But I&#8217;ll compare anyway. Here&#8217;s the sort of thing I love, from <i><a href="http://www.amazon.com/Strange-Victory-Hitlers-Conquest-France/dp/B00026W2OO/ref=sr_1_1?ie=UTF8&amp;qid=1312310954&amp;sr=8-1">Strange Victory</a></i> , by Ernest May (which I recommend!):</p>
<blockquote>
<p>Canaris was a strange character. There were many such, of course, at the center of the Third Reich, but Canaris stands out among them&#8230;. Five feet four, with prematurely white hair, he detested tall men and, above all, tall men with small ears. The loves of his life were Seppel and Sabine, two dachshunds from whom he was almost inseparable. When traveling, he would require from his staff frequent reports on their apparent emotions and their bowel movements&#8230;</p>
<p>&#8230;[A]other possibility is anger over encroachments in his domain by Reinhard Heydrich, the head of Himmler&#8217;s security service. Outwardly, his relationship with Heydrich was cordial; the Canarises and the Heydrichs were neighbors and dined together. But Heydrich was thought repulsive by men who had no such reaction to Himmler or Bormann. Also, he was very tall and had small ears.</p>
</blockquote>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/525/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/525/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/525/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/525/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/525/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/525/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/525/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/525/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=525&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/08/02/historical-writing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
		<item>
		<title>The Rise and Fall of Ancient Egypt</title>
		<link>http://mrlauer.wordpress.com/2011/08/02/the-rise-and-fall-of-ancient-egypt/</link>
		<comments>http://mrlauer.wordpress.com/2011/08/02/the-rise-and-fall-of-ancient-egypt/#comments</comments>
		<pubDate>Tue, 02 Aug 2011 18:45:21 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[history]]></category>
		<category><![CDATA[The Rise and Fall of Ancient Egypt]]></category>
		<category><![CDATA[Toby Wilkinson]]></category>

		<guid isPermaLink="false">https://mrlauer.wordpress.com/2011/08/02/the-rise-and-fall-of-ancient-egypt/</guid>
		<description><![CDATA[<p>Those Sumerian city states have great names like Uruk and Ur and Lagash and Eridu but (apart from Abraham's alleged origin in Ur of the Chaldees; doubtless he left to escape the mole people) I have no idea which is which or why we should care. ... That is a long time, half as long again as it's been since its end, and apart from "Cleopatra was at the end" all that history is compressed in our collective unconscious into an undifferentiated mass of pyramids and mummies and sarcophagi for cats and animal-headed gods and King Tut and Yul Brynner and Anne Baxter.</p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=524&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>For years I&#8217;ve loved ancient history without really knowing much about it. I&#8217;ve never been able to keep the Babylonians and Assyrians completely straight, let alone the Akkadians, and what any of them have to do with the Sumerians (my knowledge of whom comes primarily from having seen <i><a href="http://www.imdb.com/title/tt0049516/" title="The Mole People">The Mole People</a></i> at an impressionable age). I&#8217;ve never been quite sure of who the Hittites and Amorites and Mittanians and Chaldeans were. Those Sumerian city states have great names like Uruk and Ur and Lagash and Eridu but (apart from Abraham&#8217;s alleged origin in Ur of the Chaldees; doubtless he left to escape the mole people) I have no idea which is which or why we should care. The comings and goings of the MInoans and Mycenaeans and Achaeans and Dorians and other proto-Greeks are a mystery to me, providing only a little background for the <i>Iliad</i> and <i>Odyssey</i> and some half-remembered Mary Renault novels.</p>
<p><img src="http://mrlauer.files.wordpress.com/2011/08/yul-and-anne.jpg?w=167&#038;h=167" width="167" height="167" alt="yul-and-anne.jpg" style="float:right;margin-bottom:5px;" /></p>
<p>And then there&#8217;s Egypt. Egypt is far more familiar to us American rubes than Babylonians and Assyrians and Mittanians. It&#8217;s hard not to be exposed to all sorts of things about Egypt, romantic things like pyramids and mummies and sarcophagi for cats and animal-headed gods and King Tut. Yul Brynner and Anne Baxter (&#8220;Mo-o-o-ossses&#8230;&#8221;) are deeply ingrained as my Platonic forms of Pharaoh and Pharaohess (Pharaoness? Pharessa?). But the ancient Egyptian civilization lasted for <i>3,000 years</i>. That is a long time, half as long again as it&#8217;s been since it it became part of Rome until now, and apart from &#8220;Cleopatra was at the end&#8221; all that history is compressed in our collective unconscious into an undifferentiated mass of pyramids and mummies and sarcophagi for cats and animal-headed gods and King Tut and Yul Brynner and Anne Baxter.</p>
<p>So when I read about Toby Wilkinson&#8217;s <i>The Rise and Fall of Ancient Egypt</i>, a popular history of the entire civilization, I hied me to the library and found a copy. It serves its purpose well: I&#8217;m much clearer&#8212;well, somewhat less vague&#8212;on what the difference between the Old and Middle and New Kingdoms, and where Memphis was (and why), and who the Hyksos and the Sea People were, and even to a certain extent which king was which and which did what. I know now where the word &#8220;Pharaoh&#8221; comes from (&#8220;Per-aa,&#8221; or &#8220;Great House,&#8221; applied metonymically to its inhabitant) and why (awkwardness about what to call Hatshepsut&#8212;there was no such thing as a &#8220;Queen&#8221;). The book is easy to read, and it zips right along. If you&#8217;re looking for a summary of all of ancient Egyptian history, bearing in mind that a &#8220;summary of all of ancient Egyptian history&#8221; will necessarily be a few hundred pages, this is it.</p>
<p><img src="http://mrlauer.files.wordpress.com/2011/08/file-narmerpalette_rom-gamma.jpg?w=221&#038;h=156" width="221" height="156" alt="File-NarmerPalette_ROM-gamma.jpeg" style="float:right;" /></p>
<p>One of the highlights (I thought) comes at the very beginning of the Egyptian kingdom. Among the artifacts of that era, now a highlight of the Egyptian Museum of Cairo (and of Adrian Veidt&#8217;s&#8212;Ozymandias&#8217;s!&#8212;office in <i>Watchmen</i>) is the <a href="http://en.wikipedia.org/wiki/Narmer_Palette">Narmer Palette</a>. That&#8217;s &#8220;palette&#8221; as in a thing for mixing paints, in particular cosmetics; the ur-Eqyptians apparently used them as ceremonial objects in those days, a development of sacred face painting among in nomadic cultures or some such. The Narmer palette (apparently) commemorates the very unification of the Two Kingdoms of Egypt under Narmer, Egypt&#8217;s possibly mythical first king and founder of its First Dynasty. The obverse is full of Mespotamian motifs: the king as a bull destroying a walled town, those &#8220;serpopards&#8221; whose intertwined necks frame the pigment-mixing depression. The reverse is more distinctly Egyptian, with the now-human king wearing the crown of Upper Egypt. Although to my untrained and untrustworthy eye there is still some of Mesopotamia there&#8212;the king&#8217;s calf muscles look distinctly Assyrian to me, and I wonder how much those cows at the top (proto-Hathors, apparently) owe to Mesopotamian predecessors&#8212;the Narmer palette represents the very beginning not only of the Egyptian kingdom but of Egyptian, which (again to my untrained eye) remained remarkably consistent for millennia thereafter.</p>
<p>But this isn&#8217;t a perfect book. Reading it is a great first step in understanding Egyptian history, but all those kings still blur together. To some extent, I suppose that&#8217;s unavoidable&#8212;there were a lot of them, after all, and really I don&#8217;t know that there is always much to distinguish them. But Wilkinson&#8217;s (I hate to say it) somewhat cliched writing doesn&#8217;t really help. There are too many &#8220;brilliant demonstrations of the unite-and-rule concept&#8221; and &#8220;brilliant flashes of inspiration&#8221; and &#8220;brilliant but simple expedients.&#8221; I&#8217;m sure there is precious little that can really be said about any individual, king or otherwise, especially given Egyptian kings&#8217; perennial habit of erasing all record of their predecessors, but I would desperately like more indivuating details, and anecdotes.</p>
<p>And I&#8217;d also like to know more about the Egyptian religion (or should that be religions?). Gods and priests and temples obviously permeate Egyptian history and life, but really all I can say I got from the book is that there were a confusingly large number of gods, whose cults were more or less important in various cities. How did those cults develop, and split and merge, and relate to each other in general? How did perceptions of the gods and details of their cults change over time? What did all those priests do all day, anyway?</p>
<p>So, definite thumbs up, but I am left wanting more. Which is certainly better than left wanting less&#8212;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/524/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/524/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/524/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=524&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/08/02/the-rise-and-fall-of-ancient-egypt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>

		<media:content url="http://mrlauer.files.wordpress.com/2011/08/yul-and-anne.jpg" medium="image">
			<media:title type="html">yul-and-anne.jpg</media:title>
		</media:content>

		<media:content url="http://mrlauer.files.wordpress.com/2011/08/file-narmerpalette_rom-gamma.jpg" medium="image">
			<media:title type="html">File-NarmerPalette_ROM-gamma.jpeg</media:title>
		</media:content>
	</item>
		<item>
		<title>WebGL performance</title>
		<link>http://mrlauer.wordpress.com/2011/06/16/webgl-performance/</link>
		<comments>http://mrlauer.wordpress.com/2011/06/16/webgl-performance/#comments</comments>
		<pubDate>Thu, 16 Jun 2011 13:09:48 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/?p=519</guid>
		<description><![CDATA[It turns out the performance problem I mentioned in Chrome is entirely down to Float32Array. Known problem, apparently. In particular it looks to me like garbage collection, as it only shows up every few dozen frames (few hundred in less geometry-intensive cases).<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=519&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It turns out the performance problem I <a href="http://mrlauer.wordpress.com/2011/06/14/webgl/">mentioned</a> in Chrome is entirely down to Float32Array. <a href="http://www.google.com/search?aq=f&amp;sourceid=chrome&amp;ie=UTF-8&amp;q=chrome+float32array+performance">Known problem</a>, apparently. In particular it looks to me like garbage collection, as it only shows up every few dozen frames (few hundred in less geometry-intensive cases).</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/519/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/519/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/519/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=519&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/06/16/webgl-performance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
		<item>
		<title>WebGL</title>
		<link>http://mrlauer.wordpress.com/2011/06/14/webgl/</link>
		<comments>http://mrlauer.wordpress.com/2011/06/14/webgl/#comments</comments>
		<pubDate>Tue, 14 Jun 2011 17:46:19 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[WebGL]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/?p=505</guid>
		<description><![CDATA[I&#8217;ve been learning about WebGL recently, not that I have any particular reason to use it. My first experiments, selected mostly because they look neat, are here: A Hopf fibration viewer. The Hopf fibration is interesting and important mathematically&#8212;it&#8217;s part of the reason homotopy theory turns out to be so much more complicated than homology, [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=505&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been learning about <a title="WebGL" href="http://www.khronos.org/webgl/">WebGL</a> recently, not that I have any particular reason to use it. My first experiments, selected mostly because they look neat, are <a title="My WebGL demos" href="http://www.mrlauer.org/webgl/">here</a>:</p>
<ul>
<li><img class="alignright size-medium wp-image-507" title="Julia set" src="http://mrlauer.files.wordpress.com/2011/06/julia-snapshot.jpg?w=240&#038;h=122" alt="A Julia set" width="240" height="122" />A Hopf fibration viewer. The Hopf fibration is interesting and important mathematically&#8212;it&#8217;s part of the reason homotopy theory turns out to be so much more complicated than homology, for example&#8212;but its real importance to me is that it makes for great pretty pictures.</li>
<li>AMandelbrot set &#8220;explorer.&#8221; That&#8217;s the first thing everyone does when they learn about shaders, right?</li>
<li>A Julia set explorer. It turned out far trippier than I had hoped for.</li>
</ul>
<p>I&#8217;m comfortably certain these are not models of good WebGL practice. (Or good html/javascript practice, for that matter).</p>
<p>So what have I learned? For starters, half the people I&#8217;ve tried to show these things to can&#8217;t run them, for whatever old-browser and old-graphics card/driver reasons. How long will it be before you can reasonably assume any random user is likely to be able to use this stuff? I suppose it does make sense to learn it now so as to be ready in five years when it&#8217;s generally supported. Or maybe it&#8217;s that the primary audience is gamers, happy to have an excuse to buy a new graphics monstrocard every few months.</p>
<p>As for the thing itself, it&#8217;s interesting comparing it to what little I remember from the days when I knew OpenGL. From a high level it&#8217;s pretty much what you&#8217;d expect from a translation of OpenGL, or a stripped-down version of it, into javascript, the most obvious difference being that you have to provide your own shaders. I&#8217;m rather glad to have to reason to learn about shaders, really; they&#8217;re new since my day.</p>
<p>I haven&#8217;t figured out all the nuances of GLSL. As an example of the sort of thing I&#8217;ve run into, the Mandelbrot fragment shader has a big loop to count iterations. for-loops in GLSL must be of a form like</p>
<pre>    for(int i=0; i&lt;CONST; i++) {</pre>
<p>where CONST is some actual constant&#8212;I assume, possibly wrongly, that that&#8217;s so loops can be implemented by unrolling. That I learned quickly enough. Where I ran into problems was figuring out what the CONST could be. Some machines, at least older ones, seem to have a cutoff of 255, and behave oddly (it doesn&#8217;t look like a simple mod, but I haven&#8217;t tried to figure it out) if the bound exceeds that. The GLSL <a href="http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf">spec</a> (which appears to be somewhat out of sync with what WebGL as implemented uses; am I looking in the wrong place, or otherwise missing something?) wasn&#8217;t much help there.</p>
<p>Back to WebGL vs. OpenGL in general, the other immediate difference is that there&#8217;s no more glBegin/glEnd: you have to do everything with buffers. That seems to add to the boilerplate. And of course a lot of the familiar OpenGL and glu methods for things like matrix handling are missing, so you have to provide them yourself. Or find a library that does them all. I don&#8217;t think I particularly like either of the ones I&#8217;ve seen, but haven&#8217;t really thought about them much yet. I can see performance being an issue with getting libraries right.</p>
<p>And finally it&#8217;s a bit annoying that WebGL only knows from floats, not doubles. That rather surprises me, but I don&#8217;t know enough about this stuff to rant without making a fool of myself.</p>
<p>As long as I can stick to my machine, a relatively beefy Macbook Pro, I&#8217;m impressed by how well this stuff works, despite the whingeing above. I haven&#8217;t done any real stress tests, but what I have done seems to work well and quickly. As expected, both chrome and Firefox support it. Interestingly, the Firefox implementation seems to be noticably more performant than Chrome. During animations Chrome seems to seize up (garbage collecting?) every couple of seconds. Firefox is nice and smooth.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/505/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/505/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/505/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=505&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2011/06/14/webgl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>

		<media:content url="http://mrlauer.files.wordpress.com/2011/06/julia-snapshot.jpg?w=300" medium="image">
			<media:title type="html">Julia set</media:title>
		</media:content>
	</item>
		<item>
		<title>Rambling Thoughts about Comonads</title>
		<link>http://mrlauer.wordpress.com/2010/12/18/rambling-thoughts-about-comonads/</link>
		<comments>http://mrlauer.wordpress.com/2010/12/18/rambling-thoughts-about-comonads/#comments</comments>
		<pubDate>Sat, 18 Dec 2010 22:56:56 +0000</pubDate>
		<dc:creator>mrlauer</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Comonads]]></category>
		<category><![CDATA[Functional Programming]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://mrlauer.wordpress.com/?p=483</guid>
		<description><![CDATA[[Slightly revised since first posted.] This entire post is, or is intended to be, a Literate Haskell file. You can copy-paste the whole thing into an .lhs file and run it with ghc (I vouch for it only in version 6.12.3). Some caveats: I am not a Haskell programmer. At worst you should suspect everything [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=483&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>[Slightly revised since first posted.]</p>
<p>This entire post is, or is intended to be, a Literate Haskell file. You can copy-paste the whole thing into an .lhs file and run it with ghc (I vouch for it only in version 6.12.3).  Some caveats: I am not a Haskell programmer. At worst you should suspect everything I say of being, well, wrong, and at best I’m comfortably certain the code in here is not as elegant as it ought to be. Apologies for all the references that I neglected to include either out of ignorance or out of laziness. And as will be clear I’ve been awfully sloppy throughout.</p>
<p>A while back I started thinking about comonads. I now have little   idea why&#8212;“a while” is nearly two years&#8212;but I think I must have been troubled by the apparent lack of symmetry between monads and comonads in functional programming. It seemed somehow ufair that monads are so useful and get so much attention, while their poor duals are neglected. Really I just wondered whether some of the standard monad constructions and connections&#8212;monad notation, most obviously, and the connection with Applicative Arrows&#8212;had any dual consructions, and whether they might be useful. It turns out they there are indeed dual constructions, although I suppose  I can’t truly swear to the usefulness part. Herein are most of my collected thoughts on the subject.</p>
<p>BTW, I have little idea how much of what follows is original, but a couple of things way down below the fold might be. You can easily find a fair bit about comonads and examples thereof, but I haven’t seen either real proposals for comonad notation (not that I’m claiming there’s one of those here either) or anything about “Coapplicative Arrows” elsewhere. </p>
<p><span id="more-483"></span></p>
<p>First, some preliminaries:</p>
<div style="overflow:auto;">
<pre>
&gt; {-# OPTIONS_GHC -XArrows -XImpredicativeTypes #-}
&gt;
&gt; import Prelude hiding (id, (.))
&gt; import Control.Category
&gt; import Control.Arrow
&gt; import Control.Monad
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>We’ll be using arrows, so we need to turn on arrow notation and import the relevant modules. We’ll also need Impredicative Types later on. GHC 6.12 will warn about impredicative types, but I hope that something very much like this will work in GHC 7 (maybe with more type annotations, probably not a bad thing). Since Control.Category defines . and id, we’ll hide the Prelude versions.  The comonad module (here missing its module declaration, for pedagogical purposes) was lifted from  <a href="//www.eyrie.org/~zednenem/2004/hsce/Control/Comonad.html”">here</a>.</p>
<p>Now to work. So what’s a comonad, anyway? As a quondam mathematician, I find it easiest to think of both monads and comonads in terms of  categories and arrows. For programming purposes an “arrow” is a generalization of “function”&#8212;they are things that can be composed like functions, but which can have all manner of other structure. In Haskell they are encapsulated by the Arrow class. See <a href="//www.haskell.org/haskellwiki/Arrows”">this</a> for an introduction to Haskell arrows&#8212;this post will make little sense if you don’t&#8212;and  <a>this</a> for a very nice lecture about monads from this perspective.</p>
<p>Now many arrows can be expressed in terms of plain old functions. It may happen that </p>
<div style="overflow:auto;">
<pre>
    a b c
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>can be expressed as the set of functions from b to some more compicated type based on c:</p>
<div style="overflow:auto;">
<pre>
    a b c = b -&gt; m c ,
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>And that’s what a monad is! Or rather, the type constructor m is a monad. From the Arrow class’s composition &gt;&gt;&gt; we can construct the usual bind and join operations on the monad, and from the arrow laws we can derive the monad laws.</p>
<p>Some other arrows can be expressed the other way round. That is they’re functions from some complicated thing to a plain old type:</p>
<div style="overflow:auto;">
<pre>
    a b c = w b -&gt; c
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>In that case w (“w” is a sort of upside-down “m”&#8230;) is a comonad.</p>
<p>In category theory comonads are the duals of comonads, pretty much the same things with all the arrows turned around. In functional programming more or less the same is true. Just as you can always “put something into” a monad with return, you can always “get something out of” a comonad. As you can flatten multiple levels of monad constructors with join, you can introduce more levels of comonadic constructors. Bind has an obvious analog in cobind. In detail</p>
<div style="overflow:auto;">
<pre>
&gt; infixl 1 =&gt;&gt;
&gt; infixl 1 .&gt;&gt;
&gt;
&gt; class Functor w =&gt; Comonad w where
&gt;   extract :: w a -&gt; a
&gt;   (=&gt;&gt;) :: w a -&gt; (w a -&gt; b) -&gt; w b
&gt;   duplicate :: w a -&gt; w (w a)
&gt;   (.&gt;&gt;) :: (w a -&gt; b) -&gt; (w b -&gt; c) -&gt; w a -&gt; c
&gt;
&gt;   duplicate x = x =&gt;&gt; id
&gt;   f .&gt;&gt; g = \x -&gt; g ( x =&gt;&gt; f )
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>[Credit: as I said, I stole this from <a href="//www.eyrie.org/~zednenem/2004/hsce/Control/Comonad.html”">here</a>].</p>
<p>The comonad functions should satisfy laws that are the duals of the monad laws, e.g.</p>
<div style="overflow:auto;">
<pre>
    extract ( x =&gt;&gt; f ) = f(x)
    x =&gt;&gt; extract = x
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>We’ll also have occasion to use comonadic fixpoints:</p>
<div style="overflow:auto;">
<pre>
&gt; class (Comonad w) =&gt; ComonadFix w where
&gt;     wfix :: w (w a -&gt; a) -&gt; a
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>This will make sense with examples. The simplest one is of course the Identity functor, but that is too simple. Slightly more interesting is taking a product with some fixed type:</p>
<div style="overflow:auto;">
<pre>
&gt; instance Comonad ((,) c) where
&gt;   extract   (c,x) = x
&gt;   (c,x) =&gt;&gt; f = (c, (f (c, x)))
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>This is dual to the Either monad; mathematically we get a monad from a coproduct and a comonad from a product (and vice versa, sort of&#8212;see  below). It’s also left adjoint to the (-&gt;) monad: the same arrow type can be expressed as either a monad or a comonad. That is,</p>
<div style="overflow:auto;">
<pre>
    (c, b) -&gt; d
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>is the same as</p>
<div style="overflow:auto;">
<pre>
    b -&gt; c -&gt; d .
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>More interesting still is state. This is one of the principal inspiration for the use of monads, where we have the State monad</p>
<div style="overflow:auto;">
<pre>
    St s a = s -&gt; (s, a)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>(well, conceptually that’s what it is). An object of a State monad type is a “state transformer,&#8221; a function that takes transforms a state while extracting a value. That makes more sense (to me!) as a model for computation in terms of arrows: the associated Arrow type is</p>
<div style="overflow:auto;">
<pre>
    a b c  =  b -&gt; (s -&gt; (s, c))
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>which through the Cartesion adjunction is the same thing as</p>
<div style="overflow:auto;">
<pre>
    a b c  =  (s, b) -&gt; (s, c)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>The arrows are plain old functions, but we’ve tacked states on to everything.</p>
<p>We can do the same thing with (-&gt;) rather than (,). From the arrow type</p>
<div style="overflow:auto;">
<pre>
    a b c  =  (s -&gt; b) -&gt; (s -&gt; c)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>we can use the adjunction the other way and get a COmonad</p>
<div style="overflow:auto;">
<pre>
    a b c  =  (s, s -&gt; b) -&gt; c .
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>These arrows are functions that map “value extractors” into each other. In gory detail,</p>
<div style="overflow:auto;">
<pre>
&gt; data CoState s a = CoState s (s-&gt;a)
&gt;
&gt; instance Functor (CoState s) where
&gt;     fmap g (CoState s f) = CoState s (g . f)
&gt;
&gt; instance Comonad (CoState s) where
&gt;     extract (CoState s f) = f s
&gt;     cs@(CoState s f) =&gt;&gt; g =
&gt;           CoState s (\x -&gt; g (CoState x f))
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>These can represent a notion of “computation in a context.&#8221; And indeed comonads generally can be viewed as a way of adding context to computations.</p>
<p>Another prototypical example is streams, that is, endless lists. We can define them, and their comonad structure (and some generally useful functions) thusly (see  <a href="//www.jucs.org/jucs_11_7/signals_and_comonads/jucs_11_7_1311_1327_vene.pdf”">this</a>, from which this example and the next were adapted,  for more details on streams):</p>
<div style="overflow:auto;">
<pre>
&gt; infixr 1 :&lt;
&gt; data Stream a = a :&lt; Stream a
&gt;
&gt; instance Functor Stream where
&gt;     fmap f (v :&lt; s) = (f v) :&lt; fmap f s
&gt;
&gt; instance Comonad Stream where
&gt;   extract (v :&lt; _)    = v
&gt;   val@(x :&lt; xs) =&gt;&gt; f = f val :&lt; (xs =&gt;&gt; f)
&gt;
&gt; headS (h :&lt; t) = h
&gt; tailS (a :&lt; t) = t
&gt;
&gt; takeS :: Int -&gt; Stream a -&gt; [a]
&gt; takeS 0 s = []
&gt; takeS i (v :&lt; s) = v : (takeS (i-1) s)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>Cobinding a function to a stream simply applies the function to each successive “tail” in turn:</p>
<div style="overflow:auto;">
<pre>
    (1, 2, 3, 4, ... ) =&gt;&gt; f =
        ((f (1, 2, 3, 4, ... ),
            (f (2, 3, 4, 5, ...),
                (f (3, 4, 5, 6, ...), ...)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>Duplicate collects all the tails into a single stream, so</p>
<div style="overflow:auto;">
<pre>
    duplicate (1, 2, 3, 4, ... ) =
        ((1, 2, 3, 4, ...),
            (2, 3, 4, 5, ...),
               (3, 4, 5, 6, ...), ...)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>Comonadic stream computations&#8212;the associated arrows&#8212;map streams to streams in a “historyless” way. The nth value in the resulting stream depends only on the nth and greater values in the origin stream. If we want something more general we can add a list representing “what we’ve seen so far”:</p>
<div style="overflow:auto;">
<pre>
&gt; data LS a = LS [a] (Stream a)
&gt;
&gt; instance Functor LS where
&gt;     fmap f (LS l s) = LS (fmap f l) (fmap f s)
&gt;
&gt; instance Comonad LS where
&gt;     extract (LS _ (h :&lt; _)) = h
&gt;     ls@(LS l s) =&gt;&gt; f = LS (bindL l s) (bindS l s)
&gt;         where
&gt;             bindL [] _ = []
&gt;             bindL l@(h:t) s = h2:l2
&gt;                 where
&gt;                     h2 = f(LS t (h :&lt; s))
&gt;                     l2 = bindL t (h :&lt; s)
&gt;             bindS l s@(h :&lt; t) = h2 :&lt; s2
&gt;                 where
&gt;                     h2 = f(LS l s)
&gt;                     s2 = bindS (h:l) t
&gt;
&gt; nextLS (LS l (h:&lt; t)) = LS (h:l) t
&gt;
&gt; instance ComonadFix LS where
&gt;     wfix fls@(LS fl fs) = v where
&gt;         wff [] (f :&lt; fs) ls@(LS h s) =
&gt;             let v = f ls
&gt;                 LS _ t = wff []
&gt;                   fs (LS (v:h) (tailS s))
&gt;             in LS h (v :&lt; t)
&gt;         wff (fh : ft) fs ls =
&gt;                   nextLS (wff ft (fh :&lt; fs) ls)
&gt;         LS h t = wff fl fs (LS [] t)
&gt;         v = extract (LS h t)
&gt;
&gt; toStream :: LS a -&gt; Stream a
&gt; toStream (LS [] s) = s
&gt; toStream (LS (h:t) s) = toStream (LS t (h :&lt; s))
&gt;
&gt; nextLSF (LS _ (_:&lt; h:&lt; _)) = h
&gt;
&gt; -- go back to the previous place in the "history"
&gt; -- if we're already at the beginning, prepend
&gt; -- the given value
&gt; delayCF :: a -&gt; LS a -&gt; a
&gt; delayCF a (LS [] _) = a
&gt; delayCF a (LS (h:_) _) = h
&gt;
&gt; delay :: a -&gt; LS a -&gt; LS a
&gt; delay a w = w =&gt;&gt; delayCF a
&gt;
&gt; takeLS :: Int -&gt; LS a -&gt; [a]
&gt; takeLS n = takeS n . toStream
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>That’s also equivalent to a “stream with position.&#8221;</p>
<p>Simlarly, comonads can be used to represent all sorts of structures with positions therein. Cellular automata on various sorts of regular grids provide another example.</p>
<p>Armed with specific examples&#8212;Stream is generally a good one&#8212;we can think about some generalities. We’ve seen some of the relationship between arrows and monads and comands, but let’s make it more precise. If we have a monad we can make an arrow type by taking Kleisli arrows. And pretty much the same thing works with comonads (including fixpoints):</p>
<div style="overflow:auto;">
<pre>
&gt; newtype CoKleisli w a b =
&gt;       CoKleisli { unCoKleisli :: w a -&gt; b }
&gt;
&gt; instance (Comonad w) =&gt; Category (CoKleisli w)
&gt;       where
&gt;           id = CoKleisli extract
&gt;           (CoKleisli f) . (CoKleisli g) =
&gt;               CoKleisli (\x -&gt; f (x =&gt;&gt; g))
&gt;
&gt; instance Functor (CoKleisli w a) where
&gt;   fmap f (CoKleisli g) = CoKleisli (f . g)
&gt;
&gt; instance (Comonad w) =&gt; Arrow (CoKleisli w) where
&gt;   arr f = CoKleisli (f . extract)
&gt;
&gt;   CoKleisli a &amp;&amp;&amp; CoKleisli b
&gt;         = CoKleisli (a &amp;&amp;&amp; b)
&gt;
&gt;   CoKleisli a *** CoKleisli b
&gt;         = CoKleisli (a . fmap fst
&gt;             &amp;&amp;&amp; b . fmap snd)
&gt;
&gt;   first a  = a *** arr id
&gt;   second a = arr id *** a
&gt;
&gt; extractA :: (Comonad w) =&gt; (CoKleisli w) b b
&gt; extractA = CoKleisli extract
&gt;
&gt; instance ComonadFix w =&gt; ArrowLoop (CoKleisli w)
&gt;   where
&gt;     loop (CoKleisli f) =
&gt;         let
&gt;             -- g :: w a -&gt; w (w (a, b) -&gt; (a, b))
&gt;             g wa = wa =&gt;&gt; (\a -&gt; \wab -&gt;
&gt;                        (extract a, snd (f wab)))
&gt;             -- k :: w a -&gt; (a, b)
&gt;             k wa = wfix (g wa)
&gt;         in
&gt;             CoKleisli (\wa -&gt; fst (f (wa =&gt;&gt; k )))
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>Something interesting (by my nerdly definition of “interesting”) here is that, in a sense, comonads make better Arrows than monads do. The product function *** as applied to monads is not really a product in the categorical sense. It’s not necessarily even a functor. We really should have</p>
<div style="overflow:auto;">
<pre>
    (f *** g) &gt;&gt;&gt; (arr fst) = (arr fst) &gt;&gt;&gt; f
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>but we don’t&#8212;try it with lists, for example. But in the comonadic case *** really does act like a proper product. </p>
<p>On the other hand, monads do have nice Choice functions&#8212;(+++) is a real coproduct. Comonads do not. We can still define (+++) for CoKleisli arrows, but it is ill-behaved in the same way as products in the monadic case. This we can do by extracting a value from the comonad, constructing a new “constant comonad” from that value, and apply the given function. For left, that looks like</p>
<div style="overflow:auto;">
<pre>
&gt; instance (Comonad w) =&gt; ArrowChoice (CoKleisli w)
&gt;   where
&gt;     left (CoKleisli f) =
&gt;         let
&gt;             g (Left x) cm = Left $
&gt;                   f (cm =&gt;&gt; \y -&gt; x )
&gt;             g (Right x) cm = Right x
&gt;             h x = g (extract x) x
&gt;         in
&gt;             CoKleisli h
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>I don’t know if this is practically useful or not.</p>
<p>Mathematically (and here you might want to skip to the next paragraph, even if you’ve somehow managed to make it this far), that’s a deepish result of the nature of monads and comonads. Given a monad M in some category, we have adjoint functors F |- G, where F sends objects to their counterparts in the Kleisli category, while G sends them back to their monadified versions. Since F is a left adjoint, it preserves colimits, including coproducts, so (F (x|y)) is the coproduct F x | F y. There’s no particular reason for the same to hold with products, though. Looking at arrows and translating to Haskell, that leads to the observations above. Since comonads are dual, we can apply the same reasoning switching “left” and “right”, adding “co-&#8221; everywhere it isn’t, and removing it  everywhere it is. We thus find that the functor to the CoKleisli category is a right adjoint and preserves limits, including products.</p>
<p>Haskell’s monad notation is of course enormously convenient, so it’s natural to ask whether something similar could be done with comonads. There are of course complications. We can’t really identify a (co)do black with a comand, but rather with a comonadic arrow. We’ll use (probably unwisely) “proc” to name the argument, as with arrows.   We also can’t really use the nice nested-lambda translation that is one definition of a monadic do-block, or at least it’s awkward to get it to work (try it!). Instead we’ll “push” the do-bound variables through each line, as in arrow notation (more or less) or in actual implementations of monadic do-blocks (I think).</p>
<p>Suppose we want to attach a meaning to</p>
<div style="overflow:auto;">
<pre>
    proc w -&gt; do
        x &lt;- foo
        y &lt;- bar
        baz
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>foo, bar, and baz are expressions of “simple” type in which w, x, and y appear free as variables of comonadic type. We would like that to mean something along the lines of</p>
<div style="overflow:auto;">
<pre>
    (\w -&gt; foo) .&gt;&gt; (\x -&gt; bar) .&gt;&gt; (\y -&gt; baz)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>but that won’t work if w appears in bar or baz. We can get around this by defining the do-block  to be (here using “fst”, “snd”, and the imaginary “third” very loosely!)</p>
<div style="overflow:auto;">
<pre>
    \m0 -&gt;
    let m1 = m0 =&gt;&gt; (\w -&gt; (extract w, foo))
        m2 = m1 =&gt;&gt; (\m -&gt;
                let w = fmap fst m
                    x = fmap snd m
                in (extract w, extract x, bar)
        m3 = m2 =&gt;&gt; (\m -&gt;
                let w = fmap fst m
                    x = fmap snd m
                    y = fmap third m
                in bar
    in extract m3
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>or something like that. Needs some work.</p>
<p>However it should work, there’s no comonad notation now, but there is arrow notation, and we can use that to assemble comonadic functions. So let’s go back to the relationship between comonads and arrows. </p>
<p>The Kleisli arrows of a monad are instances of ArrowApply, with an arrow </p>
<div style="overflow:auto;">
<pre>
    app :: a (a b c, b) c
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>This is just an arrowfied version of the usual eval function</p>
<div style="overflow:auto;">
<pre>
    eval :: (b -&gt; c, b) -&gt; c
    eval (f, x) = f x
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>Conversely, any instance of ArrowApply whose app satisfies a few conditions leads to a monad, where (in psedocode now)</p>
<div style="overflow:auto;">
<pre>
    m b = a () b
    x &gt;&gt;= f = () -&gt; arr ( () -&gt; (f, x) ) &gt;&gt;&gt; app
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>We’ve “tied up” the first type argument of an arrow type simply by setting it to (), analogously to the fact that</p>
<div style="overflow:auto;">
<pre>
    b &lt;-&gt; () -&gt; b
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>Then we can “apply” an arrow to a monadic object in the obvious way:</p>
<div style="overflow:auto;">
<pre>
    m b &gt;&gt;= f  &lt;-&gt;  a () b &gt;&gt;&gt; f
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>If we can establish a corresponence between arrows and monadic functions then we’re done: and this is where we use the app arrow:</p>
<div style="overflow:auto;">
<pre>
    f :: a b c  &lt;-&gt;
        \x -&gt; arr (\(y::a () b) -&gt;
                (y &gt;&gt;&gt; f, ())) &gt;&gt;&gt; app
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>What about comonads? We already know how to get an arrow from a comonad, but can we go back the other way? It turns out that we can. To do that we need to be able to construct some type w a from an arrow type and establish some correspondence between arrows and ordinary functions w a -&gt; b.   To get a comonadic type from an arrow we need to tie up the second type argument. This takes a little more cleverness than the monadic case did. We can do it by taking a sort of double dual:</p>
<div style="overflow:auto;">
<pre>
    w b = forall c . (a b c -&gt; c)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>(and here’s where we start seeing impredicative types). We can easily cobind an arrow to such a thing</p>
<div style="overflow:auto;">
<pre>
    x =&gt;&gt; f  =  \y -&gt; x ( f &gt;&gt;&gt; y )
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>To associate an arrow to a comonadic function we can use a sort of adjoint to app:</p>
<div style="overflow:auto;">
<pre>
    coapp :: a b (forall c . a b c -&gt; c)
    f :: w b -&gt; c  &lt;-&gt;  coapp &gt;&gt;&gt; arr (\x -&gt; f x)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>This works if coapp satisfies conditions including</p>
<div style="overflow:auto;">
<pre>
    coapp &gt;&gt;&gt; arr (\g -&gt; g id) = id
    f &gt;&gt;&gt; coapp =
        coapp &gt;&gt;&gt; arr (\g -&gt; (\h -&gt; g (f &gt;&gt;&gt; h)))
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>To formalize all this we’ll define a type class</p>
<div style="overflow:auto;">
<pre>
&gt; class Arrow a =&gt; ArrowCoApply a where
&gt;     coapp :: a b (forall c . a b c -&gt; c)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>CoKleisli arrows are coapplicative:</p>
<div style="overflow:auto;">
<pre>
&gt; instance (Comonad w) =&gt; ArrowCoApply (CoKleisli w)
&gt;   where
&gt;     coapp = CoKleisli (\wb -&gt; \(CoKleisli f) -&gt; f wb)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>It’s easy to check the coapp conditions. And now to go back from arrows to comonads:</p>
<div style="overflow:auto;">
<pre>
&gt; newtype ArrowCoApply a =&gt; ArrowComonad a b =
&gt;     ArrowComonad (forall c . a b c -&gt; c)
&gt;
&gt; instance ArrowCoApply a =&gt; Functor (ArrowComonad a)
&gt;   where
&gt;       fmap f (ArrowComonad g) =
&gt;           ArrowComonad (\h -&gt; g (arr f &gt;&gt;&gt; h))
&gt;
&gt; instance ArrowCoApply a =&gt; Comonad (ArrowComonad a)
&gt;   where
&gt;     extract (ArrowComonad f) = f (arr id)
&gt;     (ArrowComonad f) =&gt;&gt; g =
&gt;         let garr = coapp &gt;&gt;&gt;
&gt;               arr (\x -&gt; g (ArrowComonad x)) in
&gt;         ArrowComonad (\h -&gt; f (garr &gt;&gt;&gt; h))
&gt;
&gt; -- Translation between arrows and
&gt; --    comonadic functions
&gt; comonadToArrow :: (ArrowCoApply a) =&gt; ((ArrowComonad a b) -&gt; c) -&gt; a b c
&gt; comonadToArrow g = coapp &gt;&gt;&gt; arr (\x -&gt; g (ArrowComonad x))
&gt;
&gt; arrowToComonad :: (ArrowCoApply a) =&gt; a b c -&gt; (ArrowComonad a b) -&gt; c
&gt; arrowToComonad x (ArrowComonad f) = f x
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>We’ll close by demonstrating that this actually works by using comonads and arrows to compute Fibonacci numbers in a few increasingly abstruse ways. A simple one first, using CoKleisli arrows of streams; we’ll use arrow notation to make comonadic functions:</p>
<div style="overflow:auto;">
<pre>
&gt; -- a utility class for streams and LS's:
&gt; -- a comonadic "next" function
&gt; class Comonad s =&gt; HasNext s where
&gt;       next :: s a -&gt; a
&gt; instance HasNext Stream where
&gt;       next (_ :&lt; x :&lt; xs) = x
&gt; instance HasNext LS where
&gt;       next = extract . nextLS
&gt; nextA :: HasNext w =&gt; CoKleisli w a a
&gt; nextA = CoKleisli next
&gt;
&gt; fibhelp :: Stream Integer-&gt; Integer
&gt; fibhelp =
&gt;     let f = proc x -&gt; do
&gt;         y &lt;- nextA -&lt; x
&gt;         extractA -&lt; x+y
&gt;     in unCoKleisli f
&gt;
&gt; fibs :: Stream Integer
&gt; fibs = 1 :&lt; 1 :&lt; (fibs =&gt;&gt; fibhelp)
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>If we use streams-with-history, we can build the recursion  into the proc/do block, through ArrowLoop:</p>
<div style="overflow:auto;">
<pre>
&gt; delayA x = CoKleisli (delayCF x)
&gt;
&gt; fibhelp2 :: LS () -&gt; Integer
&gt; fibhelp2 =
&gt;     let f = proc a -&gt; do
&gt;                 rec z &lt;- extractA -&lt; x + y
&gt;                     y &lt;- delayA 1 -&lt; z
&gt;                     x &lt;- delayA 1 -&lt; y
&gt;                 extractA -&lt; x
&gt;     in (unCoKleisli f )
&gt;
&gt; nothingS = () :&lt; nothingS
&gt; fibs2 = (LS [] nothingS) =&gt;&gt; fibhelp2
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>and for a particularly recondite and impractical last act,  we can take one of these comonads, turn it into an arrow, and then back into a comonad:</p>
<div style="overflow:auto;">
<pre>
&gt; -- take a comonad into the "double dual" comonad
&gt; -- via CoKleisli and ArrowComonad
&gt; toCC :: Comonad w =&gt; w a -&gt; ArrowComonad (CoKleisli w) a
&gt; toCC x = ArrowComonad $ \(CoKleisli f) -&gt; f x
&gt;
&gt; fibsCC = toCC fibs
&gt; fibsLSCC = toCC fibs2
&gt;
&gt; nextCC :: HasNext w =&gt;
&gt;       ArrowComonad (CoKleisli w) a -&gt; a
&gt; nextCC = arrowToComonad nextA
&gt;
&gt; takeCC :: HasNext w =&gt;
&gt;       Integer -&gt;
&gt;           (ArrowComonad (CoKleisli w) a) -&gt; [a]
&gt; takeCC 0 x = []
&gt; takeCC n x =
&gt;       (extract x) : takeCC (n-1) (x =&gt;&gt; nextCC)
&gt;
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<p>And we use all this machinery in a main function of startling banality</p>
<div style="overflow:auto;">
<pre>
&gt; main = do
&gt;       putStrLn "Comonad testing"
&gt;       putStrLn "Streams:"
&gt;       putStrLn $ show $ takeS 10 fibs
&gt;       putStrLn "LS:"
&gt;       putStrLn $ show $ takeLS 10 fibs2
&gt;       putStrLn "Streams via arrows and back:"
&gt;       putStrLn $ show $ takeCC 10 fibsCC
&gt;       putStrLn "LS via arrows and back:"
&gt;       putStrLn $ show $ takeCC 10 fibsLSCC
</pre>
</div>
<p style="height:0;margin:0;">&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mrlauer.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mrlauer.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mrlauer.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mrlauer.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mrlauer.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mrlauer.wordpress.com/483/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mrlauer.wordpress.com/483/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mrlauer.wordpress.com/483/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mrlauer.wordpress.com&amp;blog=2333344&amp;post=483&amp;subd=mrlauer&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mrlauer.wordpress.com/2010/12/18/rambling-thoughts-about-comonads/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/b26170b155bdddaafdc4e60bd60d483f?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mrlauer</media:title>
		</media:content>
	</item>
	</channel>
</rss>
