Irate Nate's webloghttp://www.method-combination.net/blog/debugging lifeen-usclog version 3bfroydnj@cs.rice.eduCopyright 2004 Nathan Froydon boggle solver performancehttp://www.method-combination.net/blog/archives/2009/05/06/on-boggle-solver-performance.htmlWed, 06 May 2009 21:05:00 CDT<P>The other day somebody <A HREF="http://www.imagine27.com/articles/2009-05-03-195227_i_want_to_believe_in_lisp_performance.html">wrote a blog post</A> concerning the performance of <A HREF="http://en.wikipedia.org/wiki/Boggle">Boggle</A> solvers written in C and in Common Lisp. Humorously titled &ldquo;I want to believe&rdquo;, the article (predictably) <A HREF="http://www.reddit.com/r/programming/comments/8hlls/i_want_to_believe_in_lisp_vs_c_performance/">made its way to reddit</A>, where it was met with all manner of comments. The dominant theme was that the C implementation wasn't much to write home about, the Common Lisp code was possible worse, and it was likely that the performance of the Common Lisp version could be improved. Several people even outlined plausible ways in which this could be done. The author of the original article wrote a &ldquo;yeah, the burden of proof is on you and you have <EM>nothing</EM>&rdquo; <A HREF="http://www.imagine27.com/articles/2009-05-04-185802_iwtb_in_lisp_performance_followup.html">response</A> to the comments generated.</P><P>This post is the response the author has been looking for. I will say up front that my modifications were nearly exactly what the commenters on Reddit suggested, so I'm not bringing much new to the table, just showing that they were right all along.</P><P>So, the numbers. My machine is a 1.6 GHz Core Duo with 2GB of RAM, running 32-bit Ubuntu. My Common Lisp implementation is SBCL, version 1.0.28.7, compiled with Unicode support and without thread support; the C compiler is &ldquo;gcc (Ubuntu 4.3.2-1ubuntu12) 4.3.2&rdquo;. Timings for the C program, on my machine:</P><PRE>@bishop:~/boggle-master/src/c$ time ./boggle --test --dict ../../dict/english_270k.txt &lt; \ ../../output/sample-1000x1000.txt &gt; w ; tail -n 40 w *** stack smashing detected ***: ./boggle terminated ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7e7d6d8] /lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7e7d690] ./boggle[0x804b117] ======= Memory map: ======== 08048000-0804c000 r-xp 00000000 08:04 1922146 /home/froydnj/boggle-master/src/c/boggle 0804c000-0804d000 r--p 00003000 08:04 1922146 /home/froydnj/boggle-master/src/c/boggle 0804d000-0804e000 rw-p 00004000 08:04 1922146 /home/froydnj/boggle-master/src/c/boggle 08cfb000-1b137000 rw-p 08cfb000 00:00 0 [heap] b6562000-b7503000 rw-p b7d55000 00:00 0 b7c8d000-b7d83000 rw-p b7c8d000 00:00 0 b7d83000-b7edb000 r-xp 00000000 08:04 903780 /lib/tls/i686/cmov/libc-2.8.90.so b7edb000-b7edd000 r--p 00158000 08:04 903780 /lib/tls/i686/cmov/libc-2.8.90.so b7edd000-b7ede000 rw-p 0015a000 08:04 903780 /lib/tls/i686/cmov/libc-2.8.90.so b7ede000-b7ee1000 rw-p b7ede000 00:00 0 b7ee7000-b7ef4000 r-xp 00000000 08:04 128135 /lib/libgcc_s.so.1 b7ef4000-b7ef5000 r--p 0000c000 08:04 128135 /lib/libgcc_s.so.1 b7ef5000-b7ef6000 rw-p 0000d000 08:04 128135 /lib/libgcc_s.so.1 b7ef6000-b7efa000 rw-p b7ef6000 00:00 0 b7efa000-b7f14000 r-xp 00000000 08:04 189007 /lib/ld-2.8.90.so b7f14000-b7f15000 r-xp b7f14000 00:00 0 [vdso] b7f15000-b7f16000 r--p 0001a000 08:04 189007 /lib/ld-2.8.90.so b7f16000-b7f17000 rw-p 0001b000 08:04 189007 /lib/ld-2.8.90.so bfa02000-bfa17000 rw-p bffeb000 00:00 0 [stack] Aborted real 0m57.012s user 0m54.023s sys 0m2.916s</PRE><P>Yes, that's out of the box, no modifications to the C program. Lovely, eh? The performance of the original Lisp program:</P><PRE>@bishop:~/boggle-master$ ./solve-boards.sh &lt; output/sample-1000x1000.txt &gt; w; tail -n 40 w [...lots of output scrubbed...] Evaluation took: 248.506 seconds of real time 248.331519 seconds of total run time (240.755046 user, 7.576473 system) [ Run times consist of 10.492 seconds GC time, and 237.840 seconds non-GC time. ] 99.93% CPU 413,140,979,480 processor cycles 534,709,752 bytes consed</PRE><P>The performance of my optimized version:</P><PRE>@bishop:~/boggle-master$ ./solve-boards.sh &lt; output/sample-1000x1000.txt &gt; w; tail -n 40 w [...lots of output scrubbed...] Evaluation took: 68.062 seconds of real time 68.000250 seconds of total run time (64.704044 user, 3.296206 system) [ Run times consist of 1.908 seconds GC time, and 66.093 seconds non-GC time. ] 99.91% CPU 113,153,248,150 processor cycles 50,750,728 bytes consed</PRE><P>Not quite four times faster and around 10x less consing. Not bad. Common Lisp is within roughly 20% of the peformance of C for this particular program. I'm fairly certain that all my changes to the Common Lisp code are &ldquo;non-algorithmic&rdquo;, so modifying the C implementation is a moot point. I'm also a little leery of modifying a program that falls over in the first place; I have better things to do with my time than debug C programs. At least when the O'Caml or Haskell people come around with performance benchmarks, their test programs work perfectly the first time.</P><P>The patches against git version 02a0a24257260c825f13da764fa54bdbc01dd14a (the project does not have a publicly clone-able URL) are located at <A HREF="http://method-combination.net/lisp/files/boggle-solver-patches/">http://method-combination.net/lisp/files/boggle-solver-patches/</A>, if you want to see how things work. I admit to having a large number of non-performance enhancing cleanup patches in there; rather difficult to code if you're constantly fighting some non-idiomatic coding style.</P><P>Performance notes to take away from this lesson:</P><UL><LI><P>If you want to write fast Common Lisp code, you absolutely need to understand how array types work in Common Lisp. If you aren't declaring things as <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_smp_ar.htm"><TT>simple-array</TT></A> or <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_smp_ve.htm"><TT>simple-vector</TT></A>, you're probably doing something wrong. And that goes doubly so if you are doing anything involving strings on an implementation that supports Unicode (where <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_base_c.htm"><TT>base-char</TT></A> and <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/a_ch.htm"><TT>character</TT></A> are probably different). You also need to have some idea of what <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/f_upgr_1.htm"><TT>upgraded-array-element-type</TT></A> does and why saying something is of type <TT>(VECTOR (VECTOR STRING *) *)</TT> is probably not going to perform the type-checking/inference that you think it might.</P></LI><LI><P>Likewise for declaring numeric types. If you have variables that you aren't declaring as <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_fixnum.htm"><TT>fixnum</TT></A> (or subtypes thereof), <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_short_.htm"><TT>single-float</TT></A>, <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_short_.htm"><TT>double-float</TT></A>, or <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/a_comple.htm"><TT>complex</TT></A> variants of the float types, then you're probably doing something wrong. That is, declaring things as <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_intege.htm"><TT>integer</TT></A>, or worse, <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/t_number.htm"><TT>number</TT></A> is Not Helpful for performance.</P></LI><LI><P>Listen to the compiler. The compiler tells you a lot of helpful stuff. The original code of the benchmark had some <TT>#+sbcl</TT> bits scattered about protecting slightly stricter type declarations than their <TT>#+ccl</TT> counterparts. A comment like &ldquo;ccl doesn't barf on null pointers&rdquo; usually lurked close by. First of all, &ldquo;null pointer&rdquo; is a category error in Common Lisp. Second of all, SBCL complaining about things (whether in the compiler or a runtime with <TT>(SAFETY 0)</TT>)...was correct. (I've had the same sort of experience with Lispworks.) If the compiler complains at you, fix the problem. Only turn things off or tune them out if you're absolutely sure you understand why the compiler is whinging at you and if there's nothing you can do about it.</P></LI><LI><P><A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/f_format.htm"><TT>format</TT></A> ~A is useful, but expensive. One of the biggest wins was converting the printing of the words to use <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/f_wr_stg.htm"><TT>write-string</TT></A>. Do use <TT>FORMAT</TT> for your everyday printing needs, but if you need some performance, look at Common Lisp's other IO functions, too.</P></LI><LI><P>Sprinkle optimization declarations judiciously. The original code contained a global <TT>(declaim (optimize (speed 3) (space 0) (safety 0) (debug 0) (compilation-speed 0)))</TT>. But most of the runtime (95% in the final optimized version) was spent in two functions. Putting the declarations in just those functions would have achieved the same effect. As an added bonus, the compiler will probably just tell you about ways those particular functions can be improved, rather than pointing out the hundred different ways some utility function you barely use can be improved.</P></LI><LI><P>Don't compile with <TT>(SAFETY 0)</TT>. Just don't. You can get surprisingly far, performance-wise, with type-checking and array bounds checking turned on. If you feel like you must live dangerously, make absolutely sure that everything works and that you are not lying to the compiler about types (see above note about listening to the compiler) before flipping the switch.</P></LI><LI><P>Make your code runnable from the REPL. Life is too short to spend constantly waiting for your shell script to compile and/or load all your files before it gets to the business of running your program. You should be able to invoke your benchmark with a single form typed in at the REPL.</P></LI><LI><P>If you are translating code from C, converting <TT>#define</TT>s to <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/m_defpar.htm"><TT>defparameter</TT></A>s is generally not what you want. You want <A CLASS="hyperspec" HREF="http://www.lispworks.com/documentation/HyperSpec/Body/m_defcon.htm"><TT>defconstant</TT></A> instead.</P></LI><LI><P>Don't needlessly allocate things inside loops. This should go without saying.</P></LI></UL><P>Finally, <A HREF="http://groups.google.com/group/comp.lang.lisp/msg/5489247d2f56a848">this post</A> by Juho Snellman sums up benchmarking efforts for Common Lisp (or most any other high-level language, I'd imagine) quite well.</P>lispprogrammingmichael abrash on larrabeehttp://www.method-combination.net/blog/archives/2009/05/02/michael-abrash-on-larrabee.htmlSat, 02 May 2009 23:11:00 CDT<P>Michael Abrash is writing some extremely informative articles over at Dr. Dobb's about Intel's new graphics chip, Larrabee. The <A HREF="http://www.ddj.com/architect/216402188">first article</A> covers the new instructions and general capabilities of the chip. The <A HREF="http://www.ddj.com/hpc-high-performance-computing/217200602">second article</A> discusses how to do rasterization on Larrabee--specifically, rasterization that takes advantages of the parallel processing power Larrabee brings to the table. (The techniques he discusses in the second article remind me of the adaptive mesh refinement techniques I looked at in grad school.) He's promised to write at least one more, dealing with writing shaders for Larrabee.</P>graphicslarrabeeparallel programmingworm beautyhttp://www.method-combination.net/blog/archives/2009/04/30/worm-beauty.htmlThu, 30 Apr 2009 18:21:00 CDT<P>Great lines in children's literature, from <CITE>Diary of a Worm</CITE> by Doreen Cronin:</P><BLOCKQUOTE><P>My older sister thinks she's so pretty. I told her that no matter how much time she spends looking in the mirror, her face will always look just like her rear end.</P></BLOCKQUOTE>bookschildrenpython coroutineshttp://www.method-combination.net/blog/archives/2009/04/24/python-coroutines.htmlFri, 24 Apr 2009 23:10:00 CDT<P>Good evening, class! Your assignment tonight is to read <A HREF="http://www.dabeaz.com/coroutines/Coroutines.pdf">David Beazley's slides on Python coroutines</A> from PyCon 2009. As the gurus say, contemplating the lessons found therein produces expansion of consciousness without abuse of substance.</P>pythonprogrammingscrodhttp://www.method-combination.net/blog/archives/2009/04/15/scrod.htmlWed, 15 Apr 2009 20:32:00 CDT<P>My children have a book called <CITE>Lightship</CITE>. As you might imagine, it is about <A HREF="http://en.wikipedia.org/wiki/Lightvessel">lightships</A> (Wikipedia is slightly too pedantic on this one, I think). The book has lovely drawings and is just repetitive enough to drive the points home for the kiddos while having enough variety to make you enjoy reading the book. We have a hardback edition; the back cover has a sailor on the ship reading <CITE>99 Ways to Cook Scrod</CITE>.</P><P>I would not have known what <A HREF="http://en.wikipedia.org/wiki/Scrod">scrod</A> was, except for a raid in <A HREF="http://www.wowwiki.com/Serpentshrine_Cavern">Serpentshrine Cavern</A>. I think we were standing on the platform just after Lurker and had a bit of time to kill. Our guild leader, who hails from Boston, began telling scrod jokes. Perhaps it was a tradition in the guild prior to my arrival, but scrod jokes were a regular feature of guild chat for the next four instances.</P><P>I have been WoW-free for six months today (or nearly so; I forget the exact date I last signed on). I think of my guild and raiding every time I read <CITE>Lightship</CITE> to the girls. I miss WoW.</P>warcrafttab cleanuphttp://www.method-combination.net/blog/archives/2009/04/14/tab-cleanup.htmlTue, 14 Apr 2009 12:38:00 CDT<P>When I find things that I might want to blog about, I leave a tab open in my web browser to remind me. Cleaning time has come.</P><UL><LI><P><A HREF="http://www.janegalt.net/blog/archives/005244.html">A really, really really long post about gay marriage that does not, in the end, support one side or the other</A>. Worth reading in its entirety. To quote from near the end of the article:</P><BLOCKQUOTE><P>Three laws. Three well-meaning reformers who were genuinely, sincerely incapable of imagining that their changes would wreak such institutional havoc. Three sets of utterly logical and convincing, and wrong arguments about how people would behave after a major change.</P><P>So what does this mean? That we shouldn't enact gay marriage because of some sort of social Precautionary Principle</P><P>No. I have no such grand advice.</P><P>My only request is that people try to be a leeetle more humble about their ability to imagine the subtle results of big policy changes. The argument that gay marriage will not change the institution of marriage because you can't imagine it changing your personal reaction is pretty arrogant. It imagines, first of all, that your behavior is a guide for the behavior of everyone else in society, when in fact, as you may have noticed, all sorts of different people react to all sorts of different things in all sorts of different ways, which is why we have to have elections and stuff. And second, the unwavering belief that the only reason that marriage, always and everywhere, is a male-female institution (I exclude rare ritual behaviors), is just some sort of bizarre historical coincidence, and that you know better, needs examining. If you think you know why marriage is male-female, and why that's either outdated because of all the ways in which reproduction has lately changed, or was a bad reason to start with, then you are in a good place to advocate reform. If you think that marriage is just that way because our ancestors were all a bunch of repressed bastards with dark Freudian complexes that made them homophobic bigots, I'm a little leery of letting you muck around with it.</P></BLOCKQUOTE></LI><LI><P><A HREF="http://www.antikythera-mechanism.gr/">The Antikytheea Mechanism Research Project</A>. From the project overview:</P><BLOCKQUOTE><P>More than a hundred years ago an extraordinary mechanism was found by sponge divers at the bottom of the sea near the island of Antikythera. It astonished the whole international community of experts on the ancient world. Was it an astrolabe? Was it an orrery or an astronomical clock? Or something else? For decades, scientific investigation failed to yield much light and relied more on imagination than the facts. However research over the last half century has begun to reveal its secrets. It dates from around the 1st century B.C. and is the most sophisticated mechanism known from the ancient world. Nothing as complex is known for the next thousand years. The Antikythera Mechanism is now understood to be dedicated to astronomical phenomena and operates as a complex mechanical &ldquo;computer&rdquo; which tracks the cycles of the Solar System.</P></BLOCKQUOTE></LI><LI><P><A HREF="http://chronicle.com/free/v46/i30/30a00101.htm">David Noble's Battle to Defend the Sacred Space of the Classroom</A>.</P><BLOCKQUOTE><P>Since the splash made by his first distance-education essay, Mr. Noble has published three online sequels expanding the argument. In the latest, published late last year, he provides a history of correspondence schools in the late 1800's and early 1900's. In the essay, which Mr. Noble hopes to expand into a book, he traces several parallels between such efforts and today's distance-education ventures.</P><P>Early education-by-mail efforts, he says, were marketed with the same enthusiasm as today's Internet courses. &ldquo;The chief selling point of education by means of correspondence, the firms maintained, was personalized instruction for busy people,&rdquo; he writes.</P><P>By 1926, Mr. Noble writes, more than 300 private correspondence schools had sprung up. Around the same time, about 73 traditional colleges and universities were running correspondence programs, too.</P><P>But, Mr. Noble argues, such individualized instruction turned out to be more expensive than the institutions had anticipated. To cut costs, he says, institutions soon lowered standards for correspondence teachers and expanded their workloads, diminishing the quality of instruction and prompting many students to drop out. The number of such programs eventually fell.</P></BLOCKQUOTE><P>I recently read David Noble's <CITE>The Religion of Technology</CITE>, having been prompted by this article to look into his works. The book was quite good and deserves a separate post.</P></LI><LI><P><A HREF="http://www.opensecrets.org/news/2009/04/opensecretsorg-goes-opendata.html">OpenSecrets.org goes OpenData</A>. Should be interesting to see what people come up with as far as visualizations.</P></LI><LI><P><A HREF="http://www.wired.com/techbiz/people/magazine/15-10/ff_allen?currentPage=all">GTD Guru David Allen and His Cult of Hyperefficiency</A>. The title is slightly provocative, but worth reading for a deeper look at the man behind GTD. &ldquo;Allen is remaking the self-help tradition for the information age.&rdquo; is one of the best bits of the article.</P></LI><LI><P><A HREF="http://code.google.com/p/unladen-swallow/wiki/RelevantPapers">Papers to read for unladen-swallow</A>. unladen-swallow aims to be a compiled, faster implementation of <A HREF="http://www.python.org/">Python</A> (get it?). The list is pretty good, although it could definitely be quite a bit longer.</P></LI><LI><P><A HREF="http://deletionpedia.dbatley.com/w/index.php?title=Main_Page">Deleted from Wikipedia</A>. Not sure if it's been updated recently, but interesting nonetheless.</P></LI><LI><P><A HREF="http://www.slate.com/id/2214724/pagenum/all/">It's time to kill the idea that newspaper are essential for democracy</A>. Yes, please.</P></LI></UL>linkson rsshttp://www.method-combination.net/blog/archives/2009/03/30/on-rss.htmlMon, 30 Mar 2009 13:49:00 CDT<P>I <A HREF="http://twitter.com/froydnj/status/1373898693">twittered</A> about giving up Google Reader recently. I had a short exchange with <A HREF="http://www.livejournal.com/users/tekman/">Ryan</A> in which I think he feared that I was burying my head in the sand. Herb <A HREF="http://blog.pikafoop.net/2009/03/30/so-much-google-reader/">blogged some thoughts</A> about my decision and I was DM'd about my decision as well. So herewith is the larger context of my decision.</P><P>I am not burying my head in the sand; I am still following a moderately large list of feeds, but I'm doing it with <A HREF="http://intertwingly.net/code/venus/">Venus</A> instead of letting Google automate my life. I still have my Gmail account. I purchased a G1, knowing full well that it would want to autosync a good chunk of my data to Google's servers. However, I have sync turned off and the account for my phone is a different one than the account I normally use for email. Paranoid? Maybe.</P><P>With Venus, I get to decide when I read my feeds. I realize that I have this choice with Reader. Having Reader open 24-7, however, changes the decision process--it's always there, it won't hurt if I check. It's like having a second email account. With Venus, it's consciously deciding, &ldquo;Hey, I'm going to go tap commands into my terminal and wait for a while while it checks everything for me.&rdquo; The psychology behind the decision is quite different. Now, if only I could make the same sort of psychological barriers in place for checking email...</P><P>Granted, I had to put in some elbow grease to make Venus work. Venus uses <A HREF="http://code.google.com/p/html5lib/">html5lib</A> for some form of HTML normalization. I'm sure that it does wonderful normalization according to the HTML5 specification, but browsers today don't really handle HTML5. (Hint: <TT>&lt;b&gt;&lt;/b&gt;</TT> is <EM>not</EM> the same as <TT>&lt;b/&gt;</TT> to a modern browser.) So I had to write some cleanup scripts to make rendering work right. I also had to chase down some strange bugs with the <A HREF="http://genshi.edgewall.org/">Genshi</A> templating bits that made the first parts of feeds come out duplicated. Which wasn't so bad, except for getting a double dose of every <A HREF="http://bunny-comic.com/">Bunny</A> comic. (I find it humorous that's the first hit on Google for &ldquo;bunny&rdquo;.) And even that was not always unpleasant. But just knowing that there was a bug compelled me to fix the bug.</P><P>But besides the psychological aspect, the &ldquo;share&rdquo; button was way too tempting. It was tempting to share an article discussing some philosophy or policy or whatever and know that said article would show up in the &ldquo;inbox&rdquo; of a person who did not share that philosophy or policy or whatever. It was the internet equivalent of cluster bombing. I'm fairly sure sharing the articles I did didn't change the minds of the intended readers, much less were the articles read in the first place. (Don't worry, dear reader, you were not the intended target.) I don't have a &ldquo;share&rdquo; button with Venus and I think that's a good thing. Furthermore, reading what other people thought were interesting articles...meh. I haven't missed them.</P><P>I read my feeds once, maybe twice a day now. Minus a couple of hours of ranting at Venus for being braindead prior to fixing the issues cited above, I'm enjoying my choice. And if I can't access my feeds because I don't have my computer with me, I don't think that's a particularly bad thing.</P>technologylifeironclad 0.27http://www.method-combination.net/blog/archives/2009/03/28/ironclad-027.htmlSat, 28 Mar 2009 11:08:00 CDT<P>Ironclad 0.27 has been released and uploaded to the usual place. There are a few fixes for Allegro 8.1, a fix for LispWorks 5.1, and a fix for when the user has set <A CLASS="hyperspec" HREF="http://www.xanalys.com/software_tools/reference/HyperSpec/Body/v_pr_cas.htm">*print-case*</A>. HMAC has been made somewhat more efficient and now supports <A CLASS="hyperspec" HREF="http://www.xanalys.com/software_tools/reference/HyperSpec/Body/f_reinit.htm">reinitialize-instance</A>. 64-bit variants of SHA have been added along with SHA-224. Finally, several kinds of Gray streams subclasses now support <A CLASS="hyperspec" HREF="http://www.xanalys.com/software_tools/reference/HyperSpec/Body/f_wr_seq.htm">write-sequence</A>.</P>lispbad samaritanshttp://www.method-combination.net/blog/archives/2009/03/27/bad-samaritans.htmlFri, 27 Mar 2009 19:49:00 CDT<P>I love simply browsing through the stacks at libraries--I find some of the most interesting books to check out on the spot or to file away for later reading. One such book I found recently was <CITE>Bad Samaritans: The Myth of Free Trade and the Secret History of Capitalism</CITE> by Ha-Joon Chang. I enjoy reading a contrarian book now and then, although the subtitle of this one sounded a little over-the-top. The giant-sized endorsement on the back from Noam Chomsky also made me pause. But I checked it out anyway, figuring it didn't cost me anything and I could always stop if it got to be too weird.</P><P>I read the entire book. At no point was it too weird, and it made a lot of points that made a lot of sense.</P><P>Chang's basic point is this: the rich countries in the world go about promoting free trade and capitalism (&ldquo;neo-liberalism&rdquo;) as the cure to all ills for smaller, less developed countries. The story is that such tactics have worked to propel these rich nations into their current positions and will work the same sort of improvements in living standards and personal incomes in the smaller countries. However, if you look at history, the numbers tell a different story:</P><BLOCKQUOTE><P>This story misrepresents the process of globalization among the rich countries during this period. These countries did significantly lower their tariff barriers between the 1950s and the 1970s. But during this period, they also used many other nationalistic policies to promote their own economic development -- subsidies (espeically for research and development, or R&amp;D), state-owned enterprises, government direction of banking credits, capital controls, and so on. When they started implementing neo-liberal programmes, their growth decelerated. In the 1960s and the 1970s, <EM>per capita</EM> income in the rich countries grew by 3.2% a year, but its growth rate fell substantially to 2.1% in the next two decades.</P></BLOCKQUOTE><P>Examples are given throughout the book of particular industries from particular countries who have benefitted from the protectionist policies of their governments: Toyota, Samsung, Nokia. The examples are not limited to the 20th century, either; he discusses how Britian's protectionist policies towards its textile industry helped propel Britian to the position of global influence it enjoyed in the 18th and 19th centuries. And that when Britain abandoned its protectionist policies, it was largely became it was no longer the dominant force that it once was, mostly because of the growing influence of the United States--which derived in part from its own protectionist policies.</P><P>(Interesting tidbit about Adam Smith's <CITE>The Wealth of Nations</CITE>: Smith did indeed campaign for the lifting of various protections for British industries--but only because they were mature industries and no longer needed the state to prop them up. It was time to grow up, to remove the protections, and subject the companies to actual market forces--not unlike kicking a college graduate out of the basement. (Indeed, Chang later likens the care and education of his six year old son to the protection that should be afforded to infant industries.) The father of free trade praised the <A HREF="http://en.wikipedia.org/wiki/Navigation_Acts">Navigation Acts</A>, which severly restricted the ability of British colonies to produce particular goods. History is sometimes a wee bit more complicated than the history books tell you...)</P><BLOCKQUOTE><P>During the 1960s and the 1970s, when they were purusing the `wrong' policies of pretectionism and state intervention, <EM>per capita</EM> income in the developing countries grew by 3.0% annually. As my esteemed colleague Professor Ajit Singh once pointed out, this was the period of `Industrial Revolution in the Third World'. This growth rate is a huge improvement over what they achieved under free trade during the `age of imperialism' (see above) and compares favourably with the 1-1.5% achieved by the rich countries during the Industrial Revolution in the 19th century. It also remains the best that they have ever recorded. Since the 1980s, after the implemented neo-liberal policies, they grew at only about half the speed seen in the 1960s and the 1970s (1.7%). Growth slowed down in the rich countries too, but the slowdown was less marked (from 3.2% to 2.1%), not least because they did not introduce neo-liberal policies to the same extent as the developing countries did.</P></BLOCKQUOTE><P>The same pattern is cited numerous times throughout the book: countries do not necessarily grow--and often wither instead--when adopting neo-liberal policies and countries do not necessarily wither--and often thrive instead--when they use &ldquo;bad&rdquo; policies.</P><P>The main criticism of the book falls upon the backs of the &ldquo;rich countries&rdquo; who, having achieved wealth, forbid other countries from utilizing those same strategies (&ldquo;kicking away the ladder&rdquo;). The rich countries, through the demands of the IMF, World Bank, and WTO, impose neo-liberal policies on countries that would benefit far more were they allowed more latitude in choosing their economic policies. Through tight monetary policy, draconian intellectual property laws, and the imposition of low trade barriers (which benefit the rich countries more by giving them access to cheaper goods), the developing countries are held back from actually growing those industries that will bring them sustained growth in the future.</P><P>(As an aside, I finished <CITE>Postwar</CITE> by Tony Judt recently. I only skimmed the last several chapters covering modern Europe, but I was amused at the economic posturing coming out of the EU. The EU has tigh restrictions on what sort of monetary policy entering countries must have: limits on government debt incurred on a per year basis, limits on total government debt, that sort of thing. Turns out that a couple of years ago, Germany and France (the two largest members of the EU) deliberately flouted these rules in an effort to stimulate the economies of their countries. When cries of protest were raised from other member nations (particularly nations only recently admitted who had contorted their economies to fit EU rules), Germany and France essentially said, &ldquo;We are not beholden to your rules.&rdquo;)</P><P>The above arguments comprise the core of the first three chapters of the book. The later chapters work out particular parts of the argument, discussing foreign investment, public vs. private enterprises, intellectual property laws, financial policy, and dealing with corrupt and/or undemocratic countries. The book is well-written and well-researched. I particularly appreciated the wide range of examples that Professor Chang gives: he doesn't just beat the drum and say, &ldquo;This policy didn't work for country X, that policy didn't work for country X, free trade and capitalism are broken!&rdquo; Instead, it's, &ldquo;This policy didn't work for countries M-Z, that policy didn't work for countries I-R, these policies didn't work for countries A-N...why don't we acknowledge that there are problems here?&rdquo; I also appreciated the discussion of key economic theorems about free trade...and the reminder that those theorems came with conditions that are often glossed over and/or unrealistic. If those conditions are not present, then the conclusions of the theorems are not valid, and arguments based on those theorems fall apart.</P><P>I do remember taking an economics class in college where the textbook was Paul Krugman's <CITE>International Economics</CITE> and the drum of free trade was pounded particular heavily. And during my time in that course or shortly thereafter, I do remember making myself <EM>persona non grata</EM> at a friend's house, if only for a short time, by incessently repeating the mantras of that course. If nothing else, Professor Chang's book has shown me--again--that the story in the real world is somehwat more complicated than the charts and graphs of an economics textbook suggests.</P>economicsjusticecultureon remembering historyhttp://www.method-combination.net/blog/archives/2009/03/26/on-remembering-history.htmlThu, 26 Mar 2009 22:40:00 CDT<BLOCKQUOTE><P>Those who cannot remember the past are condemned to repeat it.</P><P CLASS="quote-cite">--George Santayana</P></BLOCKQUOTE><P>The above is a quote I found fairly early in life. I thought of it upon reading some of the comments in the LWN article <A HREF="http://lwn.net/Articles/323752/">Better than POSIX?</A>:</P><BLOCKQUOTE><P>In a previous life, I worked on memory ordering models in CPUs and chipsets. During this recent ext4 hubbub, it dawned on me that the issues with ordering and atomicity in high-performance filesystem design may be isomorphic to memory ordering. Even if that's not strictly true, there's probably a lot to be learned by filesystem designers and API writers from modern CPU memory ordering models, in any case, because memory ordering is a well-explored space by this point in the history of computer engineering; and I don't just mean the technical semantics, either, but the whole social aspect, too, i.e., how to balance good performance with software complexity, how much of that complexity to expose to application programmers, who often have neither the time nor the background to understand all of the tradeoffs, let alone dot all the &ldquo;i&rdquo;s and cross all the &ldquo;t&rdquo;s, etc. Anyway, changing rename's semantics as you suggest would be the equivalent of a &ldquo;release store&rdquo; in memory ordering terms, and seems to be exactly the right kind of tradeoff in this situation.</P></BLOCKQUOTE><P>I'm guessing few people have made the connection because memory ordering is something that you start caring about when you're doing concurrent (shared-memory) programming and such programming hasn't been terribly widespread. And because all the world's an x86 machine and few people have been exposed to something like PowerPC or worse, Itanium. (And lest my comments be interpreted as coming from an expert on memory ordering, I am far from it. My own experience with atomic instructions and memory ordering comes from reading through the code for locking primitives in Linux and trying to understand papers on the Java memory model.)</P><BLOCKQUOTE><P>Thanks for that comment --- it's amazing how much knowledge we're rediscovering in computing. It's almost as if we're coming out of some kind of dark age.</P><P>One thing that struck me was a comment on a Slashdot story about a &ldquo;breakthrough&rdquo; in data center energy optimization. The comment showed that the problem of deciding when to boot up additional servers to meet demand was isomorphic to the problem of steam boiler management --- right down to the start-up and constant energy costs --- and that the problem had already been <EM>thoroughly</EM> addressed in literature from the turn of the last century. (Emphasis in the original.)</P></BLOCKQUOTE><P>Heh. That comment reminded me of a blurb I read about a week ago and cannot remember the location of it. The essential message was: Need a thesis topic? Go back 10 years in the computing literature and find an idea that can be dressed up with modern terminology and jargon. Nobody will notice.</P><P>And <EM>that</EM> reminds me of a comment I once read about hot new web technologies and discovering the next one. (I think it was related by Paul Graham, but I cannot find it on his site.) The essence was that today's hot web technology is simply a Unix service dressed up for the modern era. ICQ? <TT>talk</TT>. Blogs? <TT>.plan</TT> files. Web forums? Usenet. I suppose Twitter is <TT>finger</TT>. So if you want to invent the next hot web property, figure out what service Unix provided that hasn't be translated for a generation that's never seen a terminal.</P>computershistorystatus updatehttp://www.method-combination.net/blog/archives/2009/03/12/status-update.htmlThu, 12 Mar 2009 20:24:00 CDT<P>Wow, I haven't posted on here in over a month. Shame on me. A brief update on various activities and interesting sites, not necessarily in any sort of order, is in order. I'd prefer to split it up into nice, easily digestable, one-topic blog entries. Like one should have in a properly managed version control system. But you know those commits into version control that are just a torrent of unrelated stuff? This is the blogospheric equivalent.</P><P>I took a business trip to Texas to visit one of our partners. My flight through Chicago was delayed by several hours due to weather; I didn't get to the hotel until about 2:15AM. I had an 8AM meeting the next morning and an hour of travel time. The flight and lack of sleep notwithstanding, the trip went extremely well: the meetings were extremely productive and face-to-face time is always worth the investment.</P><P>I bought a T-Mobile G1 and SIM-unlocked it so I could use it with my current AT&amp;T plan. I admit to being partially inspired to do this by <A HREF="https://twitter.com/mikeashley/status/1187261321">a Twitter status</A> talking about reading code at meals. I thought, &ldquo;Why couldn't I take source code on my phone to read in various places?&rdquo; In the same vein, I can read <A HREF="http://www.gutenberg.org/wiki/Main_Page">Project Gutenberg</A> works on my phone. It's a little silly because I don't use any of the GPS, Bluetooth, or 3G/EDGE bits on the phone--it only gets used as a phone and a miniature computer with a Wi-Fi connection. One might think that I should have gotten a netbook instead, but a phone is more fun, easier to carry everywhere, and more socially acceptable for some value of acceptable. I'm waiting for the ARM netbooks to come out, personally.</P><P>I haven't really used the phone in its intended capacity yet because I haven't completed writing the viewer app for such files yet. (I thought about installing Debian on my phone and using vi/less/emacs, but I haven't worked up the courage to root my phone yet.) Writing the app means Java and GUI development, both of which make me feel like a complete newbie when programming. Eclipse is the preferred development environment for Android (the operating system on the phone) and is nice enough, I suppose. The code completion is somewhat weak, buffer management is horrible, and the navigation leaves something to be desired, though.</P><P>I went to a bachelor party in Chicago last weekend. We played <A HREF="http://www.whirlyball.com/">Whirlyball</A> and went to dinner at <A HREF="http://www.stefanirestaurants.com/437rush.htm">437 Rush</A>. Excellent establishments, both of them. I had the tastiest Alaskan King Crab, enhanced by Mojo's recommendation of <A HREF="http://allrecipes.com/HowTo/Browning-Butter/Detail.aspx">brown butter</A>. I also discovered a blend of alcohol that I am willing to drink: <A HREF="http://www.drinknation.com/drink/B_52">the B-52 shot</A>. Yum. (I only had one, if you must know.) After dinner, instead of going out to a bar, I went back to the hotel with Mojo, Dave, and Jerry, and we played <A HREF="http://www.boardgamegeek.com/boardgame/36218">Dominion</A> until the wee hours of the morning. A quality weekend.</P><P>I read <CITE>Watchmen</CITE> on the way home from Chicago. As a literary work, I think it's very well done: the &ldquo;watch&rdquo; theme is cleverly woven throughout, the multiple stories being told dovetail cleanly, and the basic storyline holds up well over 20 years later. That being said, I found it depressing: Good is going to get outflanked by Evil and that's just the way things are. After reading a bit about the 'net, though, I think you can argue thusly from the final page of the comic: either Good and the story Good has to tell about things is merely a crank story (still depressing), or Good really does Win, although you don't know for sure (potentially less depressing). And of course Good as represented by the final page and elsewhere is not exactly a shining moral example, which plays into the literary quality of the work. Anyway, I've thought about the book off-and-on after reading it, which I can't say for many books recently.</P><P>I checked out two books on the library recently: one about Peter Drucker, <CITE>Inside Drucker's Brain</CITE>, and a &ldquo;best of&rdquo; compilation, <CITE>The Essential Drucker</CITE>. Reading Drucker--at least in the edited compilation, the originals may not be quite as lucid--is exactly like reading your favorite business author of the current day. Christensen, Collins, Allen, Kotter, take your pick. Except that Drucker was writing it all decades ago. Fabulous stuff.</P><P><A HREF="http://community.akoha.com/">Akoha</A> looks interesting, although it suggests that Charlie Stross was not too far off the mark when he wrote about SPOOKS in <CITE>Halting State</CITE>. <A HREF="http://papersincomputerscience.org/">Papers in Computer Science</A> looks like a promising blog; I am tempted to flood him with suggestions from compilers, but will refrain for the time being. <A HREF="http://www.kk.org/cooltools/">Cool Tools</A> looks like a somewhat less pretentious and significantly more useful <A HREF="http://www.gizmodo.com/">Gizmodo</A>, of a sort. <A HREF="http://brianholmes.wordpress.com/2008/10/13/filming-the-world-laboratory/"><CITE>Das Netz</CITE></A> looks like an interesting documentary, although I'm not sure if one needs to view the film after reading the extensive review. And if you want to figure out why <A HREF="http://finance.yahoo.com/q/bc?s=VOW.DE&t=6m">Volkswagen's stock price</A> looked so crazy in October 2008, you'll definitely want to read about <A HREF="http://radian.org/notebook/porsche">Porsche hacking the financial system</A>.</P>lifestem cellshttp://www.method-combination.net/blog/archives/2009/02/08/stem-cells.htmlSun, 08 Feb 2009 13:49:00 CDT<P>I read <A HREF="http://www.firstthings.com/article.php3?id_article=6380">Stem Cells: A Political History</A> a couple weeks ago and made a note to post about it on my blog. I'm going to quote liberally from it, but you should go read the whole thing:</P><BLOCKQUOTE><P>And on November 20, 2007, two independent teams published papers--one in the journal <CITE>Cell</CITE>, and the other in the journal <CITE>Science</CITE>--about the production of pluripotent human stem cells without using embryos or eggs or cloning. And with a silent thump, the topic suddenly fell off the front pages of the nation's newspapers...Basically, however, the breakthroughs in the fall of 2007 meant that the issue of stem cells was off the political table: If scientists can make pluripotent stem cells without creating or destroying embryos, then the pro-life community will no longer resist the research; and if the pro-lifers don't resist it, then their opponents will no longer use the topic to attack them. The news reporting--in the New York Times, particularly--has undergone an astonishing change over the last year: Where once they hyped stem cells as the looming cure for everything from Alzheimer's to diabetes, they now routinely explain how far scientists are from curing anything with stem cells...</P><P>In November 2005, the work of the Korean superstar Hwang Woo Suk was revealed as a fraud. For all the major scientific journals, embryonic research had become what Robert P. George and Eric Cohen would call &ldquo;a litmus test for being pro-science and the central front in the alleged war of scientific reason against religious barbarians.&rdquo; Science magazine had fast-tracked Hwang's work to let America know the cost of President Bush's refusal to fund embryonic stem-cell research. <CITE>Scientific American</CITE> published a mea culpa for all scientific journals, and it is, George and Cohen pointed out, &ldquo;remarkable for both its honesty and remorse: `Hwang is guilty of raising false expectations, but too many of us held the ladder for him.'&rdquo;</P><P>Not that the revelations of the Korean fraud changed much. <CITE>Nature Biotechnology</CITE> carried a report in April 2006 which declared that &ldquo;the fear that United States researchers might lose ground to their international counterparts in human embryonic stem-cell research now appears to have become a fact.&rdquo; The Washington Post began its news report on the study by telling its readers that &ldquo;American scientists are falling behind researchers elsewhere in stem-cell discoveries because of U.S. limits on the use of federal funding.&rdquo;</P><P>In fact, according to one survey, 46 percent of the scientific papers on stem cells were published in the United States. As Eric Cohen noted, the report in <CITE>Nature Biotechnology</CITE> actually demonstrates that &ldquo;more than 85 percent of all the published embryonic stem-cell research in the world has used the lines approved for funding under the Bush policy. . . . It is clear that a great deal of the work done abroad has also involved these lines, even though most of it could not have been funded by the NIH. The lines are used, in other words, because they are useful, not only because they are eligible for federal support.&rdquo;...</P><P>The history of the stem-cell debate is a study of what happens when politics and science reach out to each other. The politicians were guilty, but the scientists were more guilty, for they allowed--no, they encouraged--politicians to make stem-cell research a tool in the public fights over abortion, public religion, and high finance.</P><P>In the small demagogueries of a political season, the science of stem-cell research became susceptible to the easy lie and the useful exaggeration. A little shading of truth, a little twisting of facts--yes, the politics corrupted the science, but the scientists willingly aided the corruption. And with this history in mind, who will believe America's scientists the next time they tell us something that bears on an election? We have learned something over these years: When science looks like politics, that's because it is.</P></BLOCKQUOTE><P>(Yes, I would like to grouse that the article <A HREF="http://www.method-combination.net/blog/archives/2008/10/31/using-statistics.html">doesn't actually provide citations</A> for the research articles/surveys/etc. that support its position.)</P><P>But then just this past week, I read <A HREF="http://arstechnica.com/science/news/2009/02/has-change-come-to-biology-stem-cell-research-under-obama.ars">Has change come to biology? Stem cell research under Obama</A>, which plays a significantly different tune:</P><BLOCKQUOTE><P>President Obama's promise to restore science to its rightful place has raised the hopes of biologists that there will be swift action on what many view as a serious hindrance to biology: restrictions on the use of human embryonic stem cells (hESCs). Federal funding of hESC research has been limited to lines created before August 9th, 2001--nearly nine years ago--and most of the acceptable lines have since been found to be inappropriate for clinical research; ethical issues involving informed consent affect the remaining handful. On Tuesday, the New York Stem Cell foundation hosted a panel that discussed how a lifting of the Bush-era restrictions on hESC research is likely to change hESC research.</P></BLOCKQUOTE><P>So who's telling the truth here? If you read the <CITE>First Things</CITE> article, one comes away with the impression that embryonic stem cell research is (nearly) dead in the water and that there are much more promising avenues for research. Reading the Ars Technica article, one might think that interesting biological research on stem cells was all but halted during the Bush administration years and that we are finally opening our gates to Progress. There are other, smaller conflicts: a hint of conflict between the numbers cited by Eric Cohen (85% of the embryonic stem cell research <EM>in the world</EM> has been done with Bush-approved stem cell lines) and the Ars Technica claim that &ldquo;most the acceptable lines have since been found to be inapproprite for clinical research.&rdquo; Is that 85% figure just because research has found the lines are not useful and therefore Cohen (and <CITE>First Things</CITE>) is shading the truth, or is Ars just blowing smoke?</P><P>I do not believe that <CITE>First Things</CITE> would willingly lead its readers astray, but I also note that the authors of the article in question were not actually scientists, whereas John Timmer (author of the Ars Technica piece) was writing from a scientist-populated panel hosted by <A HREF="http://www.nyscf.org/">The New York Stem Cell Foundation</A>--which obviously does have a dog in this fight.</P><P>So...who do you believe?</P>medicineculturestem cellshalting state critiquehttp://www.method-combination.net/blog/archives/2009/02/08/halting-state-critique.htmlSun, 08 Feb 2009 13:30:00 CDT<P>Courtesy of <A HREF="http://crookedtimber.org/">Crooked Timber</A>, a <A HREF="http://crookedtimber.org/2009/01/27/charles-stross-book-event/">variety of essays on Charles Stross's work</A> have been posted. I only read the <A HREF="http://www.henryfarrell.net/stross/2008/11/halting_state.html">review of <CITE>Halting State</CITE></A> and I thought it was quite good. I imagine the others are of similar quality and do an equally good job of expanding on the themes on which Stross builds his books.</P>bookscharlie strossgit code snippethttp://www.method-combination.net/blog/archives/2009/02/08/git-code-snippet.htmlSun, 08 Feb 2009 13:24:00 CDT<P>I ran across this little snippet while reading through Git source code the other night:</P><PRE> cnt = (len < 4) ? len : 4; len -= cnt; do { acc = (acc << 8) | (acc >> 24); *dst++ = acc; } while (--cnt); </PRE><P>What does the code do? It deposts a value consisting of <TT>CNT</TT> bytes, left justified in <TT>ACC</TT>, into the byte buffer <TT>DST</TT> in big-endian format. Clever, huh?</P>beautiful codegitunconvincing australianhttp://www.method-combination.net/blog/archives/2009/01/28/unconvincing-australian.htmlWed, 28 Jan 2009 20:38:00 CDT<P>Funny bit from a recent <A HREF="http://www.teamfortress.com/post.php?id=2193">post at the TF2 Official Blog</A>:</P><BLOCKQUOTE><P><STRONG>Why is the Sniper such a fake Australian? Aren't several members of the TF2 team Australian?</STRONG></P><P>Yes, it's true, the Sniper is a fairly unconvincing Australian. Most of his lines make him sound more English than Australian, and the voice actor is clearly an English actor faking an Australian accent. As for why we didn't fight to make him more authentic, we though it was appropriate that he was about as convincing an Australian as the Demoman is a Scotsman, or the Medic a German.</P></BLOCKQUOTE><P>Touch&eacute;.</P>gamingteam fortress 2building on culturehttp://www.method-combination.net/blog/archives/2009/01/25/building-on-culture.htmlSun, 25 Jan 2009 14:32:00 CDT<P>Given my recent read of a biography of Jackson Pollock, I thought this bit, from <A HREF="http://www.culture-making.com/"><CITE>Culture Making</CITE> by Andy Crouch</A>, was spot-on:</P><BLOCKQUOTE><P>[Pierre] Boulez and [John] Cage each explored the possibility of culture without culture, culture that tried to escape the culture that preceded it. Yet culture has a way of sneaking in even when it is not wanted. The modern painter Jackson Pollock, who tried to completely eradicate the difference between culture and nature, artist and gravity, produced paintings that have an insistent figural quality to them. As abstract expressionist Makoto Fujimura writes of Pollock, when art students try to imitate Pollock's seemingly grade-schoolish splatters and drips, their work does not begin to compare: Pollock's work is imbued with a tradition of painting, no matter how insistently the artist tries to overthrow that tradition. It would not be great painting without the tradition in which Pollock was trained and shaped.</P></BLOCKQUOTE><P><CITE>Culture Making</CITE> is one of the best books I've read all year, both this literal calendar year and the logical last year. I suspect it will wind up high on the list at the end of the calendar year, as well.</P>culturejackson pollockcommon lisp and javascripthttp://www.method-combination.net/blog/archives/2009/01/24/common-lisp-and-javascript.htmlSat, 24 Jan 2009 21:29:00 CDT<P>I haven't done a lot of Lisp hacking lately. I've done a little bit of experimentation with assembly routines in Ironclad and a little hacking for GNU <TT>tar</TT> extensions and <TT>pax</TT> headers in <TT>ARCHIVE</TT>. The bulk of the twiddling with Lisp lately has been experimenting with a visualization tool for our home finances.</P><P>I record all our finance bits (well, at least what we spend on a day-to-day basis; nothing like tracking my 401(k) or anything like that) in <A HREF="http://www.newartisans.com/blog/projects/ledger.html">Ledger</A>. Ledger is great as far as it goes, but is somewhat lacking in being able to make pretty pictures--which is fine. But my wife would like to get a picture of where the money goes in our household, so I sat down to try to put something together for her.</P><P>Version 0.1 was about ten minutes of thinking about creating hand-drawn graphs with something like <A HREF="http://weitz.de/cl-gd/">CL-GD</A>. That sounded like a lot of tedious work, and it wouldn't necessarily be more accessible to my wife than teaching her the various invocations of Ledger at the command line, which was right out. So I quickly moved onto version 1.0.</P><P>Version 1.0 was an exercise in having Ledger generate XML output, parsed by <A HREF="http://common-lisp.net/project/cxml/">CXML</A>, which was then turned into web pages served by <A HREF="http://weitz.de/hunchentoot/">Hunchentoot</A>, screen-scraped by <A HREF="http://mochikit.com/">MochiKit</A>, and then be turned into snazzy plots by <A HREF="http://www.liquidx.net/plotkit/">PlotKit</A>. This actually worked pretty well; programming in JavaScript is fairly painless, MochiKit is pleasant to use, and PlotKit is straightforward enough. Even better was that I could just stick the whole thing on a server in our house and my wife could view the ins and outs of our budget with no difficulty. But scraping these tables was tedious and it seemed like there ought to be a better way.</P><P>Version 2.0 came about when I realized that I could expose the XML that Ledger generated as <A HREF="http://json.org/">JSON</A> URIs, and virtually all of the page layout and so forth could be driven by JavaScript. So I grabbed <A HREF="http://common-lisp.net/project/yason/">YASON</A> for generating the JSON, scrapped a good bit of the JavaScript I had written, and went off to the races. This worked much better and I was able to learn how to use the nifty asynchronous bits of MochiKit to boot.</P><P>One bit about using YASON: the approved way of turning Lisp bits into JavaScript objects is to send a hashtable through YASON. This is uncontroversial, but I found myself wanting to pass a dictionary to JavaScript to fake keyword arguments. Common Lisp's hashtables are not really suited for such one-off bits (no literal syntax)--using an alist or a plist is much easier for this sort of thing. (Yes, I could use custom Lisp-side objects, but that's almost more heavyweight than hashtables.) YASON didn't support this sort of usage, so I tweaked it accordingly:</P><PRE>(defmethod json:encode ((list list) &amp;optional (stream *standard-output*)) (labels ((json-alist-p (list) (or (null list) (and (consp (first list)) (json-alist-p (rest list))))) (json-plist-p (list) (or (null list) (and (keywordp (first list)) (consp (rest list)) (json-plist-p (cddr list))))) (encode-key/value (key value) (let ((string (symbol-name key))) (json:encode-object-element string value))) (json-encode-alist (alist) (json:with-output (stream) (json:with-object () (loop for (key . value) in alist do (encode-key/value key value))))) (json-encode-plist (plist) (json:with-output (stream) (json:with-object () (loop for (key value . rest) on plist by #'cddr do (encode-key/value key value)))))) (cond ((json-alist-p list) (json-encode-alist list)) ((json-plist-p list) (json-encode-plist list)) (t (write-char #[ stream) (let (printed) (dolist (value list) (if printed (write-char #, stream) (setf printed t)) (json:encode value stream))) (write-char #] stream))) list))</PRE><P>Much better. I considered <A CLASS="hyperspec" HREF="http://www.xanalys.com/software_tools/reference/HyperSpec/Body/f_stg_up.htm">string-downcase</A>'ing the symbols used for keys, but while that would be easier for simple cases (no need to || symbols), it prevents you from actually having capital letters in your object properties.</P><P>The result so far is that I have about 400 lines of Common Lisp and about 150 lines of JavaScript; that gets several useful views onto the data: a yearly summary, a breakdown of each spending category by month, and a breakdown of each month by category. The next steps are to add some links between them, an easy way to get information on individual transactions in the latter two views, and some information on how we're doing versus the budget that we've decided on. Ironclad and <TT>ARCHIVE</TT> can wait, for the moment; I'm having too much fun with this.</P>lisplifefinancesreturn addresseshttp://www.method-combination.net/blog/archives/2009/01/21/return-addresses.htmlWed, 21 Jan 2009 22:48:00 CDT<P>I was writing bills tonight and had to write my address several times in the return address area. Theoretically, this shouldn't be needed: those nicely typed addresses showing through the clear plastic should always be there, are always right, and will always get the bill to the correct destination. But I am slightly paranoid about what happens if the return stub gets jostled a bit and the address no longer shows through (especially for some bills that are significantly smaller than the envelope, like the water bill)...so I write my address on every single envelope.</P><P>Now, I've already seen a solution to this, one that doesn't require the wastage of address labels: our previous health insurance company used to <EM>print their own address</EM> as the return address on the envelopes. So the bill was virtually guaranteed to get to the right place. (IIRC, it wasn't the corporate address, either; it was the actual P.O. box or whatever billing address they were using at the time.) Why can't more companies do this?</P>miscchildhood tokenshttp://www.method-combination.net/blog/archives/2009/01/20/childhood-tokens.htmlTue, 20 Jan 2009 22:40:00 CDT<P>Quoth <A HREF="http://www.theatlantic.com/doc/print/200812/twilight-vampires">What Girls Want</A>, an extended review of the <CITE>Twilight</CITE> phenomenon:</P><BLOCKQUOTE><P>One of the signal differences between adolescent girls and boys is that while a boy quickly puts away childish things in his race to initiate a sexual life for himself, a girl will continue to cherish, almost to fetishize, the tokens of her little-girlhood. She wants to be both places at once--in the safety of girl land, with the pandas and jump ropes, and in the arms of a lover, whose sole desire is to take her completely. And most of all, as girls work all of this out with considerable anguish, they want to be in their rooms, with the doors closed and the declarations posted. The biggest problem for parents of teenage girls is that they never know who is going to come barreling out of that sacred space: the adorable little girl who wants to cuddle, or the hard-eyed young woman who has left it all behind.</P></BLOCKQUOTE><P>I would like to believe that raising adolescent daughters will not involve these wildly moodish females, that somehow the foundation Tricia and I are laying in these years will bear fruit a decade hence. But that's not what I quoted the above passage for. I quoted it for the opening sentence.</P><P>The opening sentence rings true in my life, in discussions with my wife about what to keep and what to throw away. I had a protracted discussion over Thanksgiving with my wife, who was horrified that I would so casually consign my high school yearbooks to the trash. My reasoning was that I haven't looked at them in a decade or so...and I don't imagine I'll look at them again anytime soon. Why bother? She maintained that my current and potential future children will get a charge out of a window into their father's former life. After much pleading and enlisting the help of my mother to find a suitable &ldquo;hiding place&rdquo;, Tricia saved the weighty tomes of pictures from the scrap heap. Sigh.</P><P>However, after going through my few remaining things at my parents' house, I did save a few tokens of childhood, or at least days gone past:</P><UL><LI>A <CITE>Lego</CITE> Technic F1 race car (along with all my other Legos; the race car was still assembled, though);</LI><LI>C.S. Lewis's Space Trilogy;</LI><LI><CITE>New Worlds: In Search of the Planets</CITE>, which I hope my daughters will enjoy perusing in later years for the photos and (gasp!) information, despite being somewhat out of date by then;</LI><LI>A nearly complete collection of Tom Swift, Jr. books 1-30 in decent condition. I think these will probably get sold on Ebay or to Half-Price Books;</LI><LI>A couple of books by Samuel Delany and A.E. van Vogt (I think);</LI><LI>A picture of a friend and I from high school (Tricia: &ldquo;who's this, hmmm?&rdquo; me: &ldquo;we were not romantically involved&rdquo;);</LI><LI>The <EM>coup de grace</EM>, although not from my childhood: <CITE>The Bell System Technical Journal</CITE>, Vol. 57, No. 6, Part 2, July-August 1978. Topic? The Unix Time-Sharing System. Win.</LI></UL><P>Hey, my wife keeps her old baby teeth, yearbooks, and hand-written journals from elementary and middle school, I keep old sci-fi books and technical journals. Seems fair enough to me. (We no longer have the baby teeth, however.)</P>life3d fractalshttp://www.method-combination.net/blog/archives/2009/01/18/3d-fractals.htmlSun, 18 Jan 2009 23:16:00 CDT<P><A HREF="http://www.webdesignerdepot.com/2009/01/40-amazing-3d-fractals-using-apophysis/">40 Amazing 3D Fractals Using Apophysis</A> is full of win. I particularly like Ulliroyal's splash, the interwoven light sticks by Babymilk, the budding flower by MyNameIsShailo, Spiralum by AmyL, and the underwater mushroom city by RedHotCold. Props to <A HREF="http://50ft.com/">50ft</A> and <A HREF="http://edward.oconnor.cx/">Ted</A> for the link.</P>funlinks