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

<channel>
	<title>黄澗石的博客（技术相关）</title>
	<atom:link href="http://www.huangjs.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.huangjs.net/blog</link>
	<description>Side-effect of thinking</description>
	<lastBuildDate>Wed, 28 Sep 2011 05:18:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ICFP2011 Day 1 Impression</title>
		<link>http://www.huangjs.net/blog/2011/09/20/icfp2011-day-1-impression/</link>
		<comments>http://www.huangjs.net/blog/2011/09/20/icfp2011-day-1-impression/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 16:03:30 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[icfp]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=267</guid>
		<description><![CDATA[The invited talk seems a really good summary of monadic programming, serves a good extension to Wadler's "monads for functional programming" I think. I feel so sorry for having missed this talk. Other good talks I like are, - A semantic model for graphical user interface (the use of linear type is eye opening, but [...]]]></description>
			<content:encoded><![CDATA[<p>The invited talk seems a really good summary of monadic programming, serves a good extension to Wadler's "monads for functional programming" I think. I feel so sorry for having missed this talk.</p>
<p>Other good talks I like are,</p>
<p>- A semantic model for graphical user interface (the use of linear type is eye opening, but the example code doesn't look great enough)</p>
<p>- Modular rollback through control logging (though backtracking and modification/deletion/insertion heurisitics are known techniques for error-checking parsers ... for a long time i guess)</p>
<p>- Parametric polymorphism and semantic subtyping: the logical connection (straightforward approach with proved complexity upper-bound is good :)</p>
<p>- Balanced trees inhabiting functional parallel programming (though it's known that trees should replace list for parallel programs and using balanced trees doesn't seems a big improvement to me.)</p>
<p>- Monads, zippers and views (maybe, but i don't understand enough, especially don't know how they used this in their search combinators, that seems to be a cool application)</p>
<p>I'm very ignorant in functional programming, so please correct me or leaving me comments for your ideas and opinions. :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2011/09/20/icfp2011-day-1-impression/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Implemeting tail-call optimized &#039;defun&#039; and &#039;labels&#039; in Common Lisp</title>
		<link>http://www.huangjs.net/blog/2011/06/20/implemeting-tail-call-optimized-defun-and-labels-in-common-lisp/</link>
		<comments>http://www.huangjs.net/blog/2011/06/20/implemeting-tail-call-optimized-defun-and-labels-in-common-lisp/#comments</comments>
		<pubDate>Mon, 20 Jun 2011 05:49:48 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Lisp]]></category>
		<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[implementation]]></category>
		<category><![CDATA[tail-recursion]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=251</guid>
		<description><![CDATA[(I really need to revive my blog as one of the side-effects of my thoughts and what I've learned.) Two weeks ago, a post from the Lisp-cn mailing list asked whether Emacs's elisp implementation supports tail-call optimization. Though the answer turned out to be "nope", I broke into the conversation and said he could implement [...]]]></description>
			<content:encoded><![CDATA[<p>(I really need to revive my blog as one of the side-effects of my thoughts and what I've learned.)</p>
<p>Two weeks ago, a post from the Lisp-cn mailing list asked whether Emacs's elisp implementation supports tail-call optimization. Though the answer turned out to be "nope", I broke into the conversation and said he could implement his own version of abstraction easily in Lisp. Then I followed up a new post of a small quiz for implementing tail-call optimized (but crippled) "defun" (or "define" for Schemes). Maybe because it's not a very interesting quiz, only one person showed up with his solution, and eventually it became my own amusement. However, the result that shows the optimization done by several Common Lisp implementations is not boring at least. And it can be of help when using implementations that doesn't do tail-call optimization such as ABCL or ECL.</p>
<p><strong>Task 1 Self-recursion Optimization</strong></p>
<blockquote><p><em>Write a macro called "defun-tc" that does similar things (define a toplevel function) as "defun" but also does forced tail-call optimization when calling itself recursively.</em></p></blockquote>
<p>This is a very simple one. Tail-calls are in fact gotos, but in a structured way. The point is to shadow the function definition with a local macro (nlet-tc as follows) that expands to goto.</p>

<div class="wp_codebox"><table><tr id="p25110"><td class="code" id="p251code10"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defmacro</span> nlet-tc <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">name</span> bindings <span style="color: #66cc66;">&amp;</span>body body<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>alexandria<span style="color: #66cc66;">:</span><span style="color: #555;">with-unique-names</span> <span style="color: #66cc66;">&#40;</span>entry <span style="color: #b1b100;">return</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>bindings <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'alexandria<span style="color: #66cc66;">:</span><span style="color: #555;">ensure-</span><span style="color: #b1b100;">list</span> bindings<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>vars <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> #'first bindings<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      `<span style="color: #66cc66;">&#40;</span>macrolet <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>rest args<span style="color: #66cc66;">&#41;</span>
                    `<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span>
                       <span style="color: #66cc66;">&#40;</span>psetf <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcan</span> #'<span style="color: #b1b100;">list</span> '<span style="color: #66cc66;">,</span>vars args<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> <span style="color: #66cc66;">,</span>'<span style="color: #66cc66;">,</span>entry<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span> <span style="color: #66cc66;">,</span>bindings
           <span style="color: #66cc66;">&#40;</span>block <span style="color: #66cc66;">,</span><span style="color: #b1b100;">return</span>
             <span style="color: #66cc66;">&#40;</span>tagbody
                <span style="color: #66cc66;">,</span>entry
                <span style="color: #66cc66;">&#40;</span>return-from <span style="color: #66cc66;">,</span><span style="color: #b1b100;">return</span>
                  <span style="color: #66cc66;">&#40;</span>locally <span style="color: #66cc66;">,</span>@body<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defmacro</span> defun-tc <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">name</span> args <span style="color: #66cc66;">&amp;</span>body body<span style="color: #66cc66;">&#41;</span>
  `<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> <span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">,</span>args
     <span style="color: #66cc66;">&#40;</span>nlet-tc <span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>a<span style="color: #66cc66;">&#41;</span> `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>a <span style="color: #66cc66;">,</span>a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> args<span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">,</span>@body<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>To make it more explicit, here's an example.</p>

<div class="wp_codebox"><table><tr id="p25111"><td class="code" id="p251code11"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defun-tc sum <span style="color: #66cc66;">&#40;</span>n acc<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum n acc<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>optimize speed <span style="color: #66cc66;">&#40;</span>safety <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&lt;</span> <span style="color: #66cc66;">=</span> n <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
      acc
      <span style="color: #66cc66;">&#40;</span>sum <span style="color: #66cc66;">&#40;</span>- n <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>+ acc n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>when expanded, will be:
</pre>

<div class="wp_codebox"><table><tr id="p25112"><td class="code" id="p251code12"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">DEFUN</span> SUM <span style="color: #66cc66;">&#40;</span>N ACC<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>MACROLET <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>SUM <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>REST ARGS<span style="color: #66cc66;">&#41;</span>
               `<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">PROGN</span>
                 <span style="color: #66cc66;">&#40;</span>PSETF <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">MAPCAN</span> #'<span style="color: #b1b100;">LIST</span> '<span style="color: #66cc66;">&#40;</span>N ACC<span style="color: #66cc66;">&#41;</span> ARGS<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                 <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">GO</span> #<span style="color: #66cc66;">:</span><span style="color: #555;">ENTRY967</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">LET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>N N<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>ACC ACC<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>BLOCK #<span style="color: #66cc66;">:</span><span style="color: #555;">RETURN968</span>
        <span style="color: #66cc66;">&#40;</span>TAGBODY
         #<span style="color: #66cc66;">:</span><span style="color: #555;">ENTRY967</span>
          <span style="color: #66cc66;">&#40;</span>RETURN-FROM #<span style="color: #66cc66;">:</span><span style="color: #555;">RETURN968</span>
            <span style="color: #66cc66;">&#40;</span>LOCALLY
             <span style="color: #66cc66;">&#40;</span>DECLARE <span style="color: #66cc66;">&#40;</span>FIXNUM N ACC<span style="color: #66cc66;">&#41;</span>
                      <span style="color: #66cc66;">&#40;</span>OPTIMIZE SPEED <span style="color: #66cc66;">&#40;</span>SAFETY <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
             <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">IF</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&lt;</span> <span style="color: #66cc66;">=</span> N <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
                 ACC
                 <span style="color: #66cc66;">&#40;</span>SUM <span style="color: #66cc66;">&#40;</span>- N <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span>+ ACC N<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>The following benchmark
</pre>

<div class="wp_codebox"><table><tr id="p25113"><td class="code" id="p251code13"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>defun-tc test <span style="color: #66cc66;">&#40;</span>n acc<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum n acc<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>optimize speed <span style="color: #66cc66;">&#40;</span>safety <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&lt;</span> <span style="color: #66cc66;">=</span> n <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
       acc
       <span style="color: #66cc66;">&#40;</span>test <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- n<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>+ acc<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> 
<span style="color: #66cc66;">&#40;</span>time <span style="color: #66cc66;">&#40;</span>test <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">expt</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">32</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> 
<span style="color: #66cc66;">=&gt;</span> <span style="color: #cc66cc;">4294967296</span></pre></td></tr></table></div>

<p>showed there's a little bit more overhead than SBCL's native implementation. After examination the assembly code, it turned out that in my version SBCL wil treat (1- n) and (1+ acc) as machine integer rather than fixnum as declared, and the 4 redundant shifts are the only overhead. After adding (the fixnum ...) to both form, the difference disappeared.</p>
<p>A natural improvement is to automatically add the type declaration in the "psetf" form, the following trick does that, though it turned out to be less useful in the next task.</p>

<div class="wp_codebox"><table><tr id="p25114"><td class="code" id="p251code14"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> variable-type <span style="color: #66cc66;">&#40;</span>var <span style="color: #66cc66;">&amp;</span>optional env<span style="color: #66cc66;">&#41;</span>
  <span style="color: #b1b100;">nil</span>
  #+sbcl <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">cdr</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">assoc</span> 'cl<span style="color: #66cc66;">:</span><span style="color: #555;">type</span> <span style="color: #66cc66;">&#40;</span>nth-<span style="color: #b1b100;">value</span> <span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">&#40;</span>sb-cltl2<span style="color: #66cc66;">:</span><span style="color: #555;">variable-information</span> var env<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defmacro</span> my-psetf <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>environment env <span style="color: #66cc66;">&amp;</span>rest args<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>assert <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&gt;</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span> args<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
               <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">length</span> args<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>multiple-value-bind <span style="color: #66cc66;">&#40;</span>places vals newvars<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>loop with e <span style="color: #66cc66;">=</span> args
            while e
            collect <span style="color: #66cc66;">&#40;</span>pop e<span style="color: #66cc66;">&#41;</span> into places
            collect <span style="color: #66cc66;">&#40;</span>pop e<span style="color: #66cc66;">&#41;</span> into vals
            collect <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">gensym</span> <span style="color: #ff0000;">&quot;NEW&quot;</span><span style="color: #66cc66;">&#41;</span> into newvars
            finally <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#40;</span>values places vals newvars<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    `<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">let</span>* <span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>p v n<span style="color: #66cc66;">&#41;</span>
                     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">and</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">symbolp</span> p<span style="color: #66cc66;">&#41;</span>
                              <span style="color: #66cc66;">&#40;</span>variable-type p env<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                         `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>n <span style="color: #66cc66;">&#40;</span>the <span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>variable-type p env<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">,</span>v<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                         `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>n <span style="color: #66cc66;">,</span>v<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                   places vals newvars<span style="color: #66cc66;">&#41;</span>
       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">setf</span> <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcan</span> #'<span style="color: #b1b100;">list</span> places newvars<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>Change "psetf" to "my-psetf" and the type information will be propagated in compile-time.</p>
<p><strong>Task 2 Mutual-recursion Optimization</strong></p>
<blockquote><p><em>Write a macro called "labels-tc" that does similar things as "label" but also does forced tail-call optimization when recursively calling functions defined in the same scope.</em></p></blockquote>
<p>This task is much more fun. You need to</p>
<ul>
<li>Establish tagbody scope that covers all local functions</li>
<li>Still allow local functions being used in "funcall" and "apply"</li>
<li>Handle all variables in one scope</li>
</ul>
<p>My idea is to define an anonymous local function that includes all the definitions, and use a dispatch to jump to the right entry point. All other functions will call the anonymous one. As for variable handling, I currently don't have a good solution without a full renaming. So it's ignored and I simply combined all the variables (maybe an error checking is necessary).</p>
<p>Here's the code:</p>

<div class="wp_codebox"><table><tr id="p25115"><td class="code" id="p251code15"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defmacro</span> labels-tc <span style="color: #66cc66;">&#40;</span>definitions <span style="color: #66cc66;">&amp;</span>body body<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>multiple-value-bind <span style="color: #66cc66;">&#40;</span>names argss bodies jump-tags<span style="color: #66cc66;">&#41;</span>
      <span style="color: #66cc66;">&#40;</span>loop for d in definitions
            for n <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>first d<span style="color: #66cc66;">&#41;</span>
            for a <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>second d<span style="color: #66cc66;">&#41;</span>
            for b <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span>rest <span style="color: #66cc66;">&#40;</span>rest d<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            for j <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">gensym</span> <span style="color: #66cc66;">&#40;</span>symbol-<span style="color: #b1b100;">name</span> n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
            collect n into ns
            collect a into as
            collect b into bs
            collect j into js
            finally <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">return</span> <span style="color: #66cc66;">&#40;</span>values ns as bs js<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>alexandria<span style="color: #66cc66;">:</span><span style="color: #555;">with-unique-names</span> <span style="color: #66cc66;">&#40;</span>entry exit <span style="color: #b1b100;">name</span> dispatch<span style="color: #66cc66;">&#41;</span>
      `<span style="color: #66cc66;">&#40;</span>labels <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>entry <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">&amp;</span>key <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span>remove-duplicates <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">apply</span> #'<span style="color: #b1b100;">append</span> argss<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                  <span style="color: #66cc66;">&#40;</span>macrolet <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">name</span> args jump-tag<span style="color: #66cc66;">&#41;</span>
                                         `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&amp;</span>rest arrrgs<span style="color: #66cc66;">&#41;</span>
                                                 `<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span>
                                                    <span style="color: #66cc66;">&#40;</span>my-psetf <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcan</span> #'<span style="color: #b1b100;">list</span> '<span style="color: #66cc66;">,</span>args arrrgs<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> <span style="color: #66cc66;">,</span>'<span style="color: #66cc66;">,</span>jump-tag<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                 names argss jump-tags<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span>block <span style="color: #66cc66;">,</span>exit
                      <span style="color: #66cc66;">&#40;</span>tagbody
                         <span style="color: #66cc66;">,</span>dispatch
                         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">case</span> <span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span>
                           <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">name</span> jump-tag<span style="color: #66cc66;">&#41;</span>
                                       `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> <span style="color: #66cc66;">,</span>jump-tag<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                              names jump-tags<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                         <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcan</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>jump-tag body<span style="color: #66cc66;">&#41;</span>
                                     `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>jump-tag
                                       <span style="color: #66cc66;">&#40;</span>return-from <span style="color: #66cc66;">,</span>exit
                                         <span style="color: #66cc66;">&#40;</span>locally <span style="color: #66cc66;">,</span>@body<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                   jump-tags bodies<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcar</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">name</span> args<span style="color: #66cc66;">&#41;</span>
                            `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">,</span>args
                                    <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span>entry
                                     '<span style="color: #66cc66;">,</span><span style="color: #b1b100;">name</span>
                                     <span style="color: #66cc66;">,</span>@<span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">mapcan</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">lambda</span> <span style="color: #66cc66;">&#40;</span>a<span style="color: #66cc66;">&#41;</span>
                                                 `<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">,</span><span style="color: #66cc66;">&#40;</span>alexandria<span style="color: #66cc66;">:</span><span style="color: #555;">make-keyword</span> a<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">,</span>a<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                                               args<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                    names argss<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span>locally <span style="color: #66cc66;">,</span>@body<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>So again, example:</p>

<div class="wp_codebox"><table><tr id="p25116"><td class="code" id="p251code16"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>labels-tc <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> n <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
               <span style="color: #b1b100;">nil</span>
               <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span>m<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> m <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
               t
               <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>print <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">oddp</span> <span style="color: #cc66cc;">21</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>will be expanded to:</p>

<div class="wp_codebox"><table><tr id="p25117"><td class="code" id="p251code17"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>labels <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>#<span style="color: #66cc66;">:</span><span style="color: #555;">entry</span> <span style="color: #66cc66;">&#40;</span>#<span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span> <span style="color: #66cc66;">&amp;</span>key n m<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>block #<span style="color: #66cc66;">:</span><span style="color: #555;">exit</span>
             <span style="color: #66cc66;">&#40;</span>tagbody
                #<span style="color: #66cc66;">:</span><span style="color: #555;">dispatch</span>
                <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">case</span> #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">name</span>
                  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">oddp</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                  <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">evenp</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">oddp</span>
                <span style="color: #66cc66;">&#40;</span>return-from #<span style="color: #66cc66;">:</span><span style="color: #555;">exit</span>
                  <span style="color: #66cc66;">&#40;</span>locally
                      <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> n <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
                        <span style="color: #b1b100;">nil</span>
                        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span>
                          <span style="color: #66cc66;">&#40;</span>psetf m <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">evenp</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">evenp</span>
                <span style="color: #66cc66;">&#40;</span>return-from #<span style="color: #66cc66;">:</span><span style="color: #555;">exit</span>
                  <span style="color: #66cc66;">&#40;</span>locally
                      <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> m <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
                        t
                        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">progn</span>
                          <span style="color: #66cc66;">&#40;</span>psetf n <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                          <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">go</span> #<span style="color: #66cc66;">:</span><span style="color: #b1b100;">oddp</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>#<span style="color: #66cc66;">:</span><span style="color: #555;">entry</span> '<span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">:</span><span style="color: #555;">n</span> n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
         <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span>m<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>#<span style="color: #66cc66;">:</span><span style="color: #555;">entry</span> '<span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">:</span><span style="color: #555;">m</span> m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>print <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">oddp</span> <span style="color: #cc66cc;">21</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span></pre></td></tr></table></div>

<p>Note again that this version doesn't handle variables properly except the simplest form. And as mentioned above, my-psetf has no effect here since type declarations are not visible in the scope of labels-tc.</p>
<p><strong>Benchmark and Verification</strong></p>
<p>Ok, here's the fun part, benchmark and verifying the implementation in different implementations. Here's the benchmark code:</p>

<div class="wp_codebox"><table><tr id="p25118"><td class="code" id="p251code18"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">defun</span> test <span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum n<span style="color: #66cc66;">&#41;</span>
           <span style="color: #66cc66;">&#40;</span>optimize speed <span style="color: #66cc66;">&#40;</span>safety <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #66cc66;">&#40;</span>labels-tc <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>my-<span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">&#40;</span>n<span style="color: #66cc66;">&#41;</span>
                       <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                       <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> n <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
                           <span style="color: #b1b100;">nil</span>
                           <span style="color: #66cc66;">&#40;</span>my-<span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span>the fixnum <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
              <span style="color: #66cc66;">&#40;</span>my-<span style="color: #b1b100;">evenp</span> <span style="color: #66cc66;">&#40;</span>m<span style="color: #66cc66;">&#41;</span>
                        <span style="color: #66cc66;">&#40;</span>declare <span style="color: #66cc66;">&#40;</span>fixnum m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
                        <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> m <span style="color: #cc66cc;">0</span><span style="color: #66cc66;">&#41;</span>
                            t
                            <span style="color: #66cc66;">&#40;</span>my-<span style="color: #b1b100;">oddp</span> <span style="color: #66cc66;">&#40;</span>the fixnum <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">1</span>- m<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
    <span style="color: #66cc66;">&#40;</span>my-<span style="color: #b1b100;">evenp</span> n<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
&nbsp;
<span style="color: #66cc66;">&#40;</span>time <span style="color: #66cc66;">&#40;</span>test <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">expt</span> <span style="color: #cc66cc;">2</span> <span style="color: #cc66cc;">30</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">=&gt;</span> T</pre></td></tr></table></div>

<p>And here's the result:</p>
<table border="2" cellspacing="0" cellpadding="6" rules="groups">
<colgroup>
<col align="left"></col>
<col align="right"></col>
<col align="right"></col>
</colgroup>
<thead>
<tr>
<th scope="col">Common Lisp</th>
<th scope="col">labels version (sec)</th>
<th scope="col">labels-tc version (sec)</th>
</tr>
</thead>
<tbody>
<tr>
<td>SBCL 1.0.48 (64bit)</td>
<td>0.599</td>
<td>0.594</td>
</tr>
<tr>
<td>ABCL 0.25 (OpenJDK 1.6.0<sub>22</sub>)</td>
<td>(java.lang.StackOverflowError)</td>
<td>13.171</td>
</tr>
<tr>
<td>AllegroCL 8.2 64bit</td>
<td>10.17</td>
<td>2.32</td>
</tr>
<tr>
<td>ClozureCL 1.7 64bit</td>
<td>1.664</td>
<td>0.767</td>
</tr>
<tr>
<td>Lispworks 6.0.1 64bit</td>
<td>3.657</td>
<td>2.468</td>
</tr>
<tr>
<td>Clisp 2.48</td>
<td>(Lisp stack overflow. RESET)</td>
<td>27.002</td>
</tr>
<tr>
<td>CMUCL 20B (32bit)</td>
<td>0.57</td>
<td>0.42</td>
</tr>
<tr>
<td>ECL 11.1.1</td>
<td>(Segmentation fault)</td>
<td>16.218</td>
</tr>
</tbody>
</table>
<p>* OS: Ubuntu natty 11.04 x86_64 (CPU: Core2 3.0GHz)<br />
* AllegroCL needs compiler flag to turn on the optimization on.<br />
* Since CMUCL is 32bit, to avoid fixnum overflow, I changed the benchmark to (test (expt 2 28)) and looped 4 times.</p>
<p>What amazed me is that my implementation is among the best with SBCL/CMUCL's, so if your algorithm depends heavily on mutual tail-recursion, you can use this customized labels-tc without changing a single line of your code (but be aware of the variable handling!). And I think the reason other implementations don't optimize enough is because many tail-recursion programs can be intuitively translated into ones using loop, however, in some situations, it is not case.</p>
<p>Here's the <a href="http://huangjs.net/code/tailcall.lisp" target="_blank">file</a> for download.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2011/06/20/implemeting-tail-call-optimized-defun-and-labels-in-common-lisp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>iPhone annoyance</title>
		<link>http://www.huangjs.net/blog/2009/09/17/iphone-annoyance/</link>
		<comments>http://www.huangjs.net/blog/2009/09/17/iphone-annoyance/#comments</comments>
		<pubDate>Thu, 17 Sep 2009 05:42:56 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[iphone]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=160</guid>
		<description><![CDATA[I upgraded iTunes to 9.0 yesterday and also upgraded my iPhone 3GS to 3.1. Everything seems to work fine until I plugged my headphone to it this afternoon, and it crashed (WTF!), and keep rebooting over and over again. I'm afraid I have to do the restore again. It's so annoying! I have had so [...]]]></description>
			<content:encoded><![CDATA[<p>I upgraded iTunes to 9.0 yesterday and also upgraded my iPhone 3GS to 3.1.</p>
<p>Everything seems to work fine until I plugged my headphone to it this afternoon, and it crashed (WTF!), and keep rebooting over and over again. I'm afraid I have to do the restore again. It's so annoying! I have had so many troubles with my iPhone and it's so unbelievable that the software delivered from Apple is so crappy.</p>
<p>I'd like to share my previous experience of fixing a problem that caused my iphone not to be recognized in my macbook (not even charging).</p>
<ol>
<li>For debugging USB devices I needed some <a href="http://tuvix.apple.com/hardwaredrivers/download/usbdebug.html" target="_blank">tools</a> with a debug version of the IOUSBFamily Kernel Extension</li>
<li>I started <strong>USB Prober</strong>, turned log details to high, plugged in my iPhone and hundreds of lines show up.</li>
<li>I found a line which said charging cannot be started because of error return code.</li>
<li>I found in syslog message that launchd tried to start <strong>usbmuxd</strong> every 10 seconds but failed everytime.</li>
<li>I googled usbmuxd and found it's a daemon for iPhone power management...</li>
<li>I located the binary and started it in the shell, it gave me an error message saying that it cannot find the symbol _history in <strong>libedit.dylib</strong></li>
<li>I use <strong>objdump</strong> to show the symbols in libedit and yes, there's no _history but only _the_history. It seems I have a different version of libedit.</li>
<li>I <a href="http://opensource.apple.com/source/libedit/" target="_blank">downloaded</a> the latest libedit from Apple website, compiled and installed it.</li>
<li>Problem solved!</li>
</ol>
<p>One thing I still don't understand is why they want to link to libedit in a daemon? libedit provides line-editing features for command-line tools.</p>
<p>P.S.</p>
<p>I found similar complaints here: <a href="http://theappleblog.com/2009/09/14/iphone-os-3-1-update-causing-crashes-on-iphone-3gs/" target="_blank">http://theappleblog.com/2009/09/14/iphone-os-3-1-update-causing-crashes-on-iphone-3gs/</a></p>
<p><strong>Update (2009/9/18, 00:51):</strong></p>
<p>This time none of my computers can restore iPhone anymore. It will try to reboot during the restoration and it's in a totally unusable state. Good job, Apple! And remember Apple, I'm not your tester!</p>
<p><strong>Update (2009/9/21):</strong></p>
<p>Softbank paid the price for Apple's technical failure. I got a new iPhone now. I've asked them to erase my data.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2009/09/17/iphone-annoyance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>照片的后处理</title>
		<link>http://www.huangjs.net/blog/2009/09/17/%e7%85%a7%e7%89%87%e7%9a%84%e5%90%8e%e5%a4%84%e7%90%86/</link>
		<comments>http://www.huangjs.net/blog/2009/09/17/%e7%85%a7%e7%89%87%e7%9a%84%e5%90%8e%e5%a4%84%e7%90%86/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 20:26:40 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Travel&Photography]]></category>
		<category><![CDATA[image-processing]]></category>
		<category><![CDATA[photography]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=138</guid>
		<description><![CDATA[在用单反前，我一般对数码相机（非单反）的相片做以下处理： 去噪声 调节 White Balance 调节对比度，亮度和修正过渡暴光 若需要调节 Tone curve 软件用 Noiseware 和 Lightroom 2，基本上出来的照片就很完美了。 现在用单反拍得多了，懒得一张张去调节了。]]></description>
			<content:encoded><![CDATA[<p>在用单反前，我一般对数码相机（非单反）的相片做以下处理：</p>
<ol>
<li>去噪声</li>
<li>调节 White Balance</li>
<li>调节对比度，亮度和修正过渡暴光</li>
<li>若需要调节 Tone curve</li>
</ol>
<p>软件用 Noiseware 和 Lightroom 2，基本上出来的照片就很完美了。</p>
<p>现在用单反拍得多了，懒得一张张去调节了。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2009/09/17/%e7%85%a7%e7%89%87%e7%9a%84%e5%90%8e%e5%a4%84%e7%90%86/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ICFP team 聚会</title>
		<link>http://www.huangjs.net/blog/2009/09/17/icfp-team-%e8%81%9a%e4%bc%9a/</link>
		<comments>http://www.huangjs.net/blog/2009/09/17/icfp-team-%e8%81%9a%e4%bc%9a/#comments</comments>
		<pubDate>Wed, 16 Sep 2009 17:59:47 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Japan]]></category>
		<category><![CDATA[Whatsnew]]></category>
		<category><![CDATA[icfp-contest]]></category>
		<category><![CDATA[party]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=149</guid>
		<description><![CDATA[上周四我们队2人(John Fremlin 和我)和其他能联系到的在东京的队伍进行了聚会。其中有 pepsiso, Intercaml, shinh, Purely Functional Infrastructure 和 irori 等，今年前 10 的 team 中有 4组 是在东京参赛，其中3组是日本团队，还有就是我们组。 意外中的必然，聚会中一半的人来自 Google Japan...还居然都用 C++ 参赛（ICFP是指函数式程序语言学会） 我们交流了各自的控制算法，visualizer, 以及各种失误。我比较喜欢讨论程序语言，自然聊了不少。最后大家又讨论了其他程序比赛，我虽然知道 Top Coder 和 Google Code Jam，但对这种让你快速 hack 出一个程序出来的比赛不怎么感兴趣，真正解决问题是需要大量思考和尝试的， ICFP Contest 可以说和现实最接近了。（号称Code Jam 由于没有 Google 员工的参与会简单不少, er...我看是其他公司的优秀的程序员不屑于参加吧） 据说明年的比赛组织方是澳洲的某个大学（可能是墨尔本大学），想去澳洲旅游的同学可以考虑拿个 1st prize ：） 就说道这，最近3个博客都是和比赛相关，其实我个人对比赛不是太感冒。。。是该写些其他的了。。。另外希望中国的FP爱好者们也加油参加（用C++/Java 也可以 :$ )]]></description>
			<content:encoded><![CDATA[<p>上周四我们队2人(John Fremlin 和我)和其他能联系到的在东京的队伍进行了聚会。其中有 <em><strong>pepsiso, Intercaml, shinh, Purely Functional Infrastructure 和 irori</strong></em> 等，今年前 10 的 team 中有 <strong>4组</strong> 是在东京参赛，<strong>其中3组是日本团队</strong>，还有就是我们组。</p>
<p>意外中的必然，聚会中一半的人来自 Google Japan...还居然都用 <em><strong>C++</strong></em> 参赛（ICFP是指函数式程序语言学会） 我们交流了各自的控制算法，visualizer, 以及各种失误。我比较喜欢讨论程序语言，自然聊了不少。最后大家又讨论了其他程序比赛，我虽然知道 Top Coder 和 Google Code Jam，但对这种让你快速 hack 出一个程序出来的比赛不怎么感兴趣，真正解决问题是需要大量思考和尝试的， ICFP Contest 可以说和现实最接近了。（号称Code Jam 由于没有 Google 员工的参与会简单不少, er...我看是其他公司的优秀的程序员不屑于参加吧）</p>
<p>据说明年的比赛组织方是澳洲的某个大学（可能是墨尔本大学），想去澳洲旅游的同学可以考虑拿个 1st prize ：）</p>
<p>就说道这，最近3个博客都是和比赛相关，其实我个人对比赛不是太感冒。。。是该写些其他的了。。。另外<strong>希望中国的FP爱好者们也加油参加</strong>（用C++/Java 也可以 :$ )</p>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2009/09/17/icfp-team-%e8%81%9a%e4%bc%9a/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Final scoreboard of ICFP contest</title>
		<link>http://www.huangjs.net/blog/2009/09/15/final-scoreboard-of-icfp-contest/</link>
		<comments>http://www.huangjs.net/blog/2009/09/15/final-scoreboard-of-icfp-contest/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 05:17:31 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Whatsnew]]></category>
		<category><![CDATA[icfp-contest]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=147</guid>
		<description><![CDATA[We were No. 7 this year. Not bad. Here's the scoreboard: http://icfpcontest.org/scoreboard.php]]></description>
			<content:encoded><![CDATA[<p>We were No. 7 this year. Not bad.</p>
<p>Here's the scoreboard:</p>
<p><a href="http://icfpcontest.org/scoreboard.php">http://icfpcontest.org/scoreboard.php</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2009/09/15/final-scoreboard-of-icfp-contest/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dysfunkycom (Common Lisp) 进入了 icfp contest 2009 的前10!</title>
		<link>http://www.huangjs.net/blog/2009/08/03/dysfunkycom-common-lisp-%e8%bf%9b%e5%85%a5%e4%ba%86-icfp-contest-2009-%e7%9a%84%e5%89%8d10/</link>
		<comments>http://www.huangjs.net/blog/2009/08/03/dysfunkycom-common-lisp-%e8%bf%9b%e5%85%a5%e4%ba%86-icfp-contest-2009-%e7%9a%84%e5%89%8d10/#comments</comments>
		<pubDate>Mon, 03 Aug 2009 06:25:24 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Whatsnew]]></category>
		<category><![CDATA[icfp-contest]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=144</guid>
		<description><![CDATA[刚从裁判那里得到消息，我们3人小组 dysfunkycom 用 Common Lisp 参加的 icfp contest 2009 比赛中取得了前10名的好成绩。具体名次要到8月底公布。 队名：Dysfunkycom 成员： John Fremlin (UK), Mathematical Systems Inc. (Japan) Jianshi Huang (China) (本人), Mathematical Systems Inc. (Japan) Peter Salvi (Hungary), Phd. Candidate @ University of Tokyo Lisp for the win! :) P.S. email 摘录 Dear ICFP Competitor, In order to finalize the winner of the [...]]]></description>
			<content:encoded><![CDATA[<p>刚从裁判那里得到消息，我们3人小组 dysfunkycom 用 Common Lisp 参加的 icfp contest 2009 比赛中取得了前10名的好成绩。具体名次要到8月底公布。</p>
<p>队名：Dysfunkycom</p>
<p>成员：<br />
John Fremlin (UK), Mathematical Systems Inc. (Japan)<br />
Jianshi Huang (China) (本人), Mathematical Systems Inc. (Japan)<br />
Peter Salvi (Hungary), Phd. Candidate @ University of Tokyo</p>
<p>Lisp for the win! :)</p>
<p>P.S. email 摘录</p>
<blockquote><p>Dear ICFP Competitor,</p>
<p>In order to finalize the winner of the ICFP contest by the end of this month, and be as consistent and fair as possible, we are directly soliciting help from the top 10 teams. So the good news is your entry was in the top 10!</p>
<p>--<br />
Andy Gill, Garrin Kimmell, Kevin Matlage<br />
ICFP Contest Organizers, 2009</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2009/08/03/dysfunkycom-common-lisp-%e8%bf%9b%e5%85%a5%e4%ba%86-icfp-contest-2009-%e7%9a%84%e5%89%8d10/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>为什么程序员都必须学好英语</title>
		<link>http://www.huangjs.net/blog/2009/05/15/%e4%b8%ba%e4%bb%80%e4%b9%88%e7%a8%8b%e5%ba%8f%e5%91%98%e9%83%bd%e5%bf%85%e9%a1%bb%e5%ad%a6%e5%a5%bd%e8%8b%b1%e8%af%ad/</link>
		<comments>http://www.huangjs.net/blog/2009/05/15/%e4%b8%ba%e4%bb%80%e4%b9%88%e7%a8%8b%e5%ba%8f%e5%91%98%e9%83%bd%e5%bf%85%e9%a1%bb%e5%ad%a6%e5%a5%bd%e8%8b%b1%e8%af%ad/#comments</comments>
		<pubDate>Fri, 15 May 2009 02:24:35 +0000</pubDate>
		<dc:creator>huangjs</dc:creator>
				<category><![CDATA[Programming Languages]]></category>
		<category><![CDATA[language education]]></category>

		<guid isPermaLink="false">http://www.huangjs.net/blog/?p=139</guid>
		<description><![CDATA[记得一个月前reddit上有人发个帖子说为什么程序员都需要学好英语。没有时间写全文，总结一下把自己的想法以提纲的方式贴出来。 为什么程序员都必须学好英语 1 现象 说同一种母语，但交流技术时说英语 有一部分美国人认为这是文化的帝国主义／法西斯主义 2 理由 英语有更丰富的技术用语，有助于更简洁的表达。 技术人员之间的交流需要精确的表达，而丰富的词汇很重要。(其实英语里 有大量的难以理解的技术词汇，很多是历史原因造成的，无形中造成了壁 垒，使得局外人更难以理解。我认为想中文和拉丁语之类的表达丰富易于 组合的语言更胜任创造新的词汇，可惜现状&#8230;) 技术领域里经常有新的单词出现，没有统一的翻译标准也是造成用母语沟 通的问题之一。 技术领域里的合作是没有国界的，往往是跨国界的，说写一口好英语是成 功的关键之一，而蹩脚的英语却会让别人忽略你的存在。 Get stuff done. Internet上大量的资料是用英语写的。 很现实的，有一部分的翻译相当糟糕。 3 翻译的问题，优美的／恶心的翻译举例 3.1 优美的翻译举例 化学元素(我一直认为这是翻译的典范，e.g. 氢(Hydrogen)，最轻的气体) 3.2 恶心的翻译 直接音译(滥用汉字) 中文文字是如此的丰富，非得要找几个毫无关系的汉字来注音？ e.g. 柯理化(currying) 4 假设现实的问题已被改善，用英语交流仍旧是最佳方式吗？ 有一个论点说，如果大家都用英语交流，那我们的知识库就会更庞大，于是 搜索会更有效，能更快得找到解决问题的方法。因此，用英语交流是有利于 推动技术进步的。 5 如何改善技术领域里的翻译 学好中文，学好汉字 建立标准网站，加强协作沟通，快速统一翻译标准]]></description>
			<content:encoded><![CDATA[<p>记得一个月前reddit上有人发个帖子说为什么程序员都需要学好英语。没有时间写全文，总结一下把自己的想法以提纲的方式贴出来。</p>
<h3 class="title">为什么程序员都必须学好英语</p>
<div id="outline-container-1" class="outline-3">
<h4 id="sec-1">1 现象 </h4>
<div id="text-1">
<ul>
<li>
说同一种母语，但交流技术时说英语
</li>
<li>
有一部分美国人认为这是文化的帝国主义／法西斯主义</p>
</li>
</ul>
</div>
</div>
<div id="outline-container-2" class="outline-3">
<h4 id="sec-2">2 理由 </h4>
<div id="text-2">
<ul>
<li>
英语有更丰富的技术用语，有助于更简洁的表达。
</li>
<li>
技术人员之间的交流需要精确的表达，而丰富的词汇很重要。(其实英语里<br />
有大量的难以理解的技术词汇，很多是历史原因造成的，无形中造成了壁<br />
垒，使得局外人更难以理解。我认为想中文和拉丁语之类的表达丰富易于<br />
组合的语言更胜任创造新的词汇，可惜现状&hellip;)
</li>
<li>
技术领域里经常有新的单词出现，没有统一的翻译标准也是造成用母语沟<br />
通的问题之一。
</li>
<li>
技术领域里的合作是没有国界的，往往是跨国界的，说写一口好英语是成<br />
功的关键之一，而蹩脚的英语却会让别人忽略你的存在。
</li>
<li>
Get stuff done. Internet上大量的资料是用英语写的。
</li>
<li>
很现实的，有一部分的翻译相当糟糕。</p>
</li>
</ul>
</div>
</div>
<div id="outline-container-3" class="outline-3">
<h4 id="sec-3">3 翻译的问题，优美的／恶心的翻译举例 </h4>
<div id="text-3">
</div>
<div id="outline-container-3.1" class="outline-4">
<h5 id="sec-3.1">3.1 优美的翻译举例 </h5>
<div id="text-3.1">
<ul>
<li>
化学元素(我一直认为这是翻译的典范，e.g. 氢(Hydrogen)，最轻的气体)
</li>
</ul>
</div>
</div>
<div id="outline-container-3.2" class="outline-4">
<h5 id="sec-3.2">3.2 恶心的翻译 </h5>
<div id="text-3.2">
<ul>
<li>
直接音译(滥用汉字)<br />
中文文字是如此的丰富，非得要找几个毫无关系的汉字来注音？<br />
e.g. 柯理化(currying) </p>
</li>
</ul>
</div>
</div>
</div>
<div id="outline-container-4" class="outline-3">
<h4 id="sec-4">4 假设现实的问题已被改善，用英语交流仍旧是最佳方式吗？ </h4>
<div id="text-4">
<p>有一个论点说，如果大家都用英语交流，那我们的知识库就会更庞大，于是<br />
搜索会更有效，能更快得找到解决问题的方法。因此，用英语交流是有利于<br />
推动技术进步的。
</p>
</div>
</div>
<div id="outline-container-5" class="outline-3">
<h4 id="sec-5">5 如何改善技术领域里的翻译 </h4>
<div id="text-5">
<ul>
<li>
学好中文，学好汉字
</li>
<li>
建立标准网站，加强协作沟通，快速统一翻译标准</p>
</li>
</ul>
</div>
</div>
</h3>
]]></content:encoded>
			<wfw:commentRss>http://www.huangjs.net/blog/2009/05/15/%e4%b8%ba%e4%bb%80%e4%b9%88%e7%a8%8b%e5%ba%8f%e5%91%98%e9%83%bd%e5%bf%85%e9%a1%bb%e5%ad%a6%e5%a5%bd%e8%8b%b1%e8%af%ad/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

