<?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>fleurer &#187; 笔记</title>
	<atom:link href="http://www.fleurer-lee.com/category/%e7%ac%94%e8%ae%b0/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fleurer-lee.com</link>
	<description>rage and love, story of my life.</description>
	<lastBuildDate>Thu, 02 Sep 2010 11:07:00 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>GCC内联汇编的笔记</title>
		<link>http://www.fleurer-lee.com/2010/06/10/gcc%e5%86%85%e8%81%94%e6%b1%87%e7%bc%96%e7%9a%84%e7%ac%94%e8%ae%b0/</link>
		<comments>http://www.fleurer-lee.com/2010/06/10/gcc%e5%86%85%e8%81%94%e6%b1%87%e7%bc%96%e7%9a%84%e7%ac%94%e8%ae%b0/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 13:38:25 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[ASM]]></category>
		<category><![CDATA[C]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645885</guid>
		<description><![CDATA[起比VC风格的内联汇编，GCC的确实要别扭些，一开始要不看手册肯定一头雾水。

int foo = 10, bar = 15;
asm volatile&#40;&#34;addl  %%ebx,%%eax&#34;
            :&#34;=a&#34;&#40;foo&#41;                //output constraint
            :&#34;a&#34;&#40;foo&#41;, &#34;b&#34;&#40;bar&#41;    [...]]]></description>
			<content:encoded><![CDATA[<p>起比VC风格的内联汇编，GCC的确实要别扭些，一开始要不看手册肯定一头雾水。</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">int</span> foo <span style="color: #339933;">=</span> <span style="color: #0000dd;">10</span><span style="color: #339933;">,</span> bar <span style="color: #339933;">=</span> <span style="color: #0000dd;">15</span><span style="color: #339933;">;</span>
asm <span style="color: #993333;">volatile</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;addl  %%ebx,%%eax&quot;</span>
            <span style="color: #339933;">:</span><span style="color: #ff0000;">&quot;=a&quot;</span><span style="color: #009900;">&#40;</span>foo<span style="color: #009900;">&#41;</span>                <span style="color: #666666; font-style: italic;">//output constraint</span>
            <span style="color: #339933;">:</span><span style="color: #ff0000;">&quot;a&quot;</span><span style="color: #009900;">&#40;</span>foo<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;b&quot;</span><span style="color: #009900;">&#40;</span>bar<span style="color: #009900;">&#41;</span>      <span style="color: #666666; font-style: italic;">//input constraint</span>
            <span style="color: #339933;">:</span>                            <span style="color: #666666; font-style: italic;">//clobbered registers(ignored)</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>指令大家都明白，不过:&#8221;=a&#8221;(foo)这样的语法就古怪了。:后面的东西好像叫做约束，指明了输出和输入中用到的变量和寄存器。第一个的&#8221;=a&#8221;(foo)是输出的约束，就表示汇编执行完毕后foo=a。后面的&#8221;a&#8221;(foo)是输入的约束，表示汇编执行前的a=foo。这一来C和汇编就可以在约束下边交换数据了。</p>
<p>刚才这个a就是表示分配eax寄存器。</p>
<p>各种约束还挺多的&#8230;</p>
<table>
<tr>
<th>a,b,c,d</th>
<th>对应eax,ebx,ecx,edx</th>
</tr>
<tr>
<th>S,D</th>
<th>对应esi,edi</th>
</tr>
<tr>
<th>I</th>
<th>常数</th>
</tr>
<tr>
<th>q</th>
<th>eax,ebx,ecx,edx中静态分配一个</th>
</tr>
<tr>
<th>r</th>
<th>eax,ebx,ecx,edx,esi,edi中静态分配一个</th>
</tr>
<tr>
<th>m</th>
<th>内存定位</th>
</tr>
<tr>
<th>A</th>
<th>同时分配eax和ebx，形成一64位的寄存器</th>
</tr>
<tr>
<th>i</th>
<th>一个编译时确定的立即数。好像ljmp指令的第一个参数就必须得是立即数，比如ljmp $0&#215;80, $label。如果ljmp ax, $label就绘出现一个“Error: suffix or operands invalid for &#8216;ljmp&#8217;的错误”</th>
</tr>
</table>
<p>为什么要这么难看的语法呢&#8230;我猜这东西最早应该是给编译器而不是给人类设计的吧，比起VC风格的内联汇编，它可以得到更多关于变量和寄存器的信息，编译器分配起寄存器来可以心里有数，不用怕自作聪明的人类把事情都搞乱掉。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/06/10/gcc%e5%86%85%e8%81%94%e6%b1%87%e7%bc%96%e7%9a%84%e7%ac%94%e8%ae%b0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>随记</title>
		<link>http://www.fleurer-lee.com/2010/05/18/%e9%9a%8f%e8%ae%b0/</link>
		<comments>http://www.fleurer-lee.com/2010/05/18/%e9%9a%8f%e8%ae%b0/#comments</comments>
		<pubDate>Tue, 18 May 2010 14:49:03 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645854</guid>
		<description><![CDATA[无论何时，只要单个资源需要在多个用户间共享，就必须处理一致性的问题。
回头想下“函数式语言无副作用适合写并发程序”之类的说法，只是在计算上的并发，对存储上的并发照样得上锁上钥匙。
win32的窗体使用handle而不是指针
一个窗体可能会被多个进程处理，也可以隐藏窗体对象的内部实现。
真空管和三极管的共性
都可以将信号放大，这一来就可以用电信号来控制开关了。就有了逻辑电路&#8230;
lua从堆栈机转到寄存器机
因为lua实现里表示值的那个结构体Tvalue是个tagged union，个头太大了(两个指针这么长)。在堆栈上push/pop一来一回吃资源，搞成寄存器机可以省些搬运。
为什么要有链接器
可以把程序分成模块。
C中结构体不可比较
因为结构体里数据对齐的空隙里面的东西可能随机的。
C++为什么不用printf
类型不安全。像cout好像是对每个内置类型都重载了一个]]></description>
			<content:encoded><![CDATA[<p><strong>无论何时，只要单个资源需要在多个用户间共享，就必须处理一致性的问题。</strong><br />
回头想下“函数式语言无副作用适合写并发程序”之类的说法，只是在计算上的并发，对存储上的并发照样得上锁上钥匙。</p>
<p><strong>win32的窗体使用handle而不是指针</strong><br />
一个窗体可能会被多个进程处理，也可以隐藏窗体对象的内部实现。</p>
<p><strong>真空管和三极管的共性</strong><br />
都可以将信号放大，这一来就可以用电信号来控制开关了。就有了逻辑电路&#8230;</p>
<p><strong>lua从堆栈机转到寄存器机</strong><br />
因为lua实现里表示值的那个结构体Tvalue是个tagged union，个头太大了(两个指针这么长)。在堆栈上push/pop一来一回吃资源，搞成寄存器机可以省些搬运。</p>
<p><strong>为什么要有链接器</strong><br />
可以把程序分成模块。</p>
<p><strong>C中结构体不可比较</strong><br />
因为结构体里数据对齐的空隙里面的东西可能随机的。</p>
<p><strong>C++为什么不用printf</strong><br />
类型不安全。像cout好像是对每个内置类型都重载了一个<<操作符</p>
<p><strong>x86实模式的逻辑地址</strong><br />
x86实模式的逻辑地址是段寄存器（如cs）里存一个基地址(16位)，左移四位再加上一个16位的偏移。<br />
为什么要这么蛋疼，因为当时的主线有20位（可寻址1mb），但是intel的寄存器只有16位。</p>
<p><strong>自动机</strong><br />
就是根据输入自动切换状态的计算模型。不过状态有限，识别的语言(语言就是字符串的集合)是最少的。自动机可以识别的语言就叫正则语言。<br />
给自动机加一个堆栈就是下推自动机，这样状态就可以无限了，可以识别的语言就叫上下文无关语言。<br />
给自动机加一个随机存储，就是图灵机了。可以识别的语言就叫可判定语言。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/05/18/%e9%9a%8f%e8%ae%b0/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>动态作用域</title>
		<link>http://www.fleurer-lee.com/2010/04/15/%e5%8a%a8%e6%80%81%e4%bd%9c%e7%94%a8%e5%9f%9f/</link>
		<comments>http://www.fleurer-lee.com/2010/04/15/%e5%8a%a8%e6%80%81%e4%bd%9c%e7%94%a8%e5%9f%9f/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 04:45:27 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[PL]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645799</guid>
		<description><![CDATA[好像刚弄明白动态作用域是怎么回事，拿个例子：

var a=0; //global
def f1&#40;&#41;:
    a=1
def f2&#40;&#41;:
    var a; //local
    f1&#40;&#41;
&#160;
f2&#40;&#41;
puts a

若是静态作用域，f2调用f1，f1修改全局变量a的值为1，输出1。这个多自然&#8230;
可是动态作用域就&#8230;输出0，全局变量a的值没有变化。
f2不是调用了f1么，f1不是改变a的值么&#8230;是啊，f2调用的那个f1改变的是f2那个局部变量a的值。也就是说，同一个函数在不同的环境下调用会有不同的行为。
好吧我正在纳闷为什么会有这种东西存在过&#8230;囧
]]></description>
			<content:encoded><![CDATA[<p>好像刚弄明白动态作用域是怎么回事，拿个例子：</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> a<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//global</span>
def f1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
    a<span style="color: #339933;">=</span><span style="color: #CC0000;">1</span>
def f2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">:</span>
    <span style="color: #003366; font-weight: bold;">var</span> a<span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//local</span>
    f1<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
&nbsp;
f2<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
puts a</pre></div></div>

<p>若是静态作用域，f2调用f1，f1修改全局变量a的值为1，输出1。这个多自然&#8230;<br />
可是动态作用域就&#8230;输出0，全局变量a的值没有变化。</p>
<p>f2不是调用了f1么，f1不是改变a的值么&#8230;是啊，f2调用的那个f1改变的是f2那个局部变量a的值。也就是说，同一个函数在不同的环境下调用会有不同的行为。</p>
<p>好吧我正在纳闷为什么会有这种东西存在过&#8230;囧</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/04/15/%e5%8a%a8%e6%80%81%e4%bd%9c%e7%94%a8%e5%9f%9f/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>各种垃圾收集的随便笔记</title>
		<link>http://www.fleurer-lee.com/2010/04/11/%e5%90%84%e7%a7%8d%e5%9e%83%e5%9c%be%e6%94%b6%e9%9b%86/</link>
		<comments>http://www.fleurer-lee.com/2010/04/11/%e5%90%84%e7%a7%8d%e5%9e%83%e5%9c%be%e6%94%b6%e9%9b%86/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 15:04:18 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645788</guid>
		<description><![CDATA[GC多好多好就不多说了。没银弹嘛，什么好处什么坏处都了解下就好 TvT
引用计数
“穷人的垃圾收集”。实现简单，可以在对象失去引用时立即收集，不过对付不了循环引用。“立即收集”容易给人一种“高效”的印象，其实正相反，引用计数中的每个mov指令后面都必须跟着几条额外指令，引用的局部性还不好。跟各种GC算法比起来，引用计数的效率是最低的 :(
CPython是引用计数加备用的mark-sweep，（好像如果一开始就使用GC的话就没必要引入那套复杂的内存池机制了？
mark-sweep
从根（寄存器、局部变量和全局变量等）开始，遍历所有可访问的对象并标记之;再遍历所有变量，将所有没mark的对象收集。
C\C++中的GC实现大约是扫描bss段和堆栈什么的，找到全局变量和局部变量。C\C++中你不知道一块数据是指针还是一个纯洁的整数，所以只能用个is point to heap来猜它是不是指针，如果这个整数恰好是一块内存的地址，就只能“保守地”当它是指针mark掉了。保守式的GC中比较有名的就是Boehm的GC（貌似很靠谱！）。
停止-复制
这个需要额外一倍的内存空间。先将一切活动停止，遍历堆中所有可以访问的对象并将其拷贝到另个堆中，并将将原先的指针统统指向新的堆中对应的地址，完毕后继续程序的执行。
停止复制的同时也紧缩了内存，因而不存在内存碎片的问题（malloc/free在整理堆中碎片时候的各种搬运不容小觑），性能上好像要优于mark-sweep。缺点就是对空间浪费比较大（一倍啊一倍~）。
分代收集
遍历所有对象时候的停滞会比较厉害。想办法把停滞缩短到人类察觉不到吧&#8230;就有了分代收集和增量收集 TvT
分代收集基于这样的假设: 
1.对象越新，生存期越短;
2.对象越老，生存期越长;
3.少有指向新对象的老对象
就把堆分成n块，对应n代的对象（三代就差不多吧）。再加个记忆表什么的记下指向新对象的老对象，以记忆表中的老对象以及活跃的变量等做根，重点照顾最新的这代就行了。
.net那CLR好像是分代的&#8230;缺点是经过多次收集，较老的代会积攒比较多的垃圾。
增量收集
增量收集好像是记住上次遍历到了什么地方，然后每次遍历一点，最后集中收集。
有个三色标记：
  白色：未被访问的对象;
  灰色：已经被访问过，子对象还未访问;
  黑色：已经被访问过，子对象也已被访问;
然后就是性质：
  当没有灰色对象时，所有的白色对象都是垃圾;
  不会有黑色对象指向白色对象;
  每个灰色对象都位于收集器的队列中（作为下次收集的根）;
]]></description>
			<content:encoded><![CDATA[<p>GC多好多好就不多说了。没银弹嘛，什么好处什么坏处都了解下就好 TvT</p>
<h3>引用计数</h3>
<p>“穷人的垃圾收集”。实现简单，可以在对象失去引用时立即收集，不过对付不了循环引用。“立即收集”容易给人一种“高效”的印象，其实正相反，引用计数中的每个mov指令后面都必须跟着几条额外指令，引用的局部性还不好。跟各种GC算法比起来，引用计数的效率是最低的 :(</p>
<p>CPython是引用计数加备用的mark-sweep，（好像如果一开始就使用GC的话就没必要引入那套复杂的内存池机制了？</p>
<h3>mark-sweep</h3>
<p>从根（寄存器、局部变量和全局变量等）开始，遍历所有可访问的对象并标记之;再遍历所有变量，将所有没mark的对象收集。</p>
<p>C\C++中的GC实现大约是扫描bss段和堆栈什么的，找到全局变量和局部变量。C\C++中你不知道一块数据是指针还是一个纯洁的整数，所以只能用个is point to heap来猜它是不是指针，如果这个整数恰好是一块内存的地址，就只能“保守地”当它是指针mark掉了。保守式的GC中比较有名的就是Boehm的GC（貌似很靠谱！）。</p>
<h3>停止-复制</h3>
<p>这个需要额外一倍的内存空间。先将一切活动停止，遍历堆中所有可以访问的对象并将其拷贝到另个堆中，并将将原先的指针统统指向新的堆中对应的地址，完毕后继续程序的执行。</p>
<p>停止复制的同时也紧缩了内存，因而不存在内存碎片的问题（malloc/free在整理堆中碎片时候的各种搬运不容小觑），性能上好像要优于mark-sweep。缺点就是对空间浪费比较大（一倍啊一倍~）。</p>
<h3>分代收集</h3>
<p>遍历所有对象时候的停滞会比较厉害。想办法把停滞缩短到人类察觉不到吧&#8230;就有了分代收集和增量收集 TvT</p>
<p>分代收集基于这样的假设: </p>
<p>1.对象越新，生存期越短;<br />
2.对象越老，生存期越长;<br />
3.少有指向新对象的老对象</p>
<p>就把堆分成n块，对应n代的对象（三代就差不多吧）。再加个记忆表什么的记下指向新对象的老对象，以记忆表中的老对象以及活跃的变量等做根，重点照顾最新的这代就行了。</p>
<p>.net那CLR好像是分代的&#8230;缺点是经过多次收集，较老的代会积攒比较多的垃圾。</p>
<h3>增量收集</h3>
<p>增量收集好像是记住上次遍历到了什么地方，然后每次遍历一点，最后集中收集。</p>
<p>有个三色标记：<br />
  白色：未被访问的对象;<br />
  灰色：已经被访问过，子对象还未访问;<br />
  黑色：已经被访问过，子对象也已被访问;</p>
<p>然后就是性质：<br />
  当没有灰色对象时，所有的白色对象都是垃圾;<br />
  不会有黑色对象指向白色对象;<br />
  每个灰色对象都位于收集器的队列中（作为下次收集的根）;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/04/11/%e5%90%84%e7%a7%8d%e5%9e%83%e5%9c%be%e6%94%b6%e9%9b%86/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>State Monad笔记二</title>
		<link>http://www.fleurer-lee.com/2010/03/05/state-monad%e7%ac%94%e8%ae%b0%e4%ba%8c/</link>
		<comments>http://www.fleurer-lee.com/2010/03/05/state-monad%e7%ac%94%e8%ae%b0%e4%ba%8c/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 10:25:08 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[FP]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[monad]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645752</guid>
		<description><![CDATA[老师：Monad想到什么呢？
同学：毛茸茸的猫猫!
好同学们，请默念“Warm and Fuzzy”100遍~
。。
。。
。。
。
。
。
。
。
。

。
。
。
。。
。。
100遍了没。。。好，我们先看看State猫猫的类型吧 ^_^

newtype State s a = State &#123; runState :: s -&#62; &#40;a, s&#41; &#125;

里面有个难看的record syntax，咱们无视之，改成：

data State g v = State &#40;g -&#62; &#40;v, g&#41;&#41;

就是一个lambda，外加一二元组：v表示猫猫正经计算中的值，g就表示猫猫的状态啦(就一个全局变量嘛)~那个lambda的参数g也一样。相应的猫猫Instance也就是如下：

instance Monad &#40;State g&#41; where
    return v = 
        State $ \g -&#62; &#40;v, g&#41;
&#160;
    &#40;&#62;&#62;=&#41; [...]]]></description>
			<content:encoded><![CDATA[<p>老师：Monad想到什么呢？<br />
同学：毛茸茸的猫猫!</p>
<p>好同学们，请默念“Warm and Fuzzy”100遍~</p>
<p>。。<br />
。。<br />
。。<br />
。<br />
。<br />
。<br />
。<br />
。<br />
。<br />
<a href="http://www.fleurer-lee.com/wp-content/uploads/2010/03/p_large_Pg4a_4600000102612d0c.jpg"><img src="http://www.fleurer-lee.com/wp-content/uploads/2010/03/p_large_Pg4a_4600000102612d0c-300x225.jpg" alt="" title="p_large_Pg4a_4600000102612d0c" width="600" class="alignnone size-medium wp-image-645756" /></a><br />
。<br />
。<br />
。<br />
。。<br />
。。</p>
<p>100遍了没。。。好，我们先看看State猫猫的类型吧 ^_^</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">newtype</span> State s a <span style="color: #339933; font-weight: bold;">=</span> State <span style="color: green;">&#123;</span> runState <span style="color: #339933; font-weight: bold;">::</span> s <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>a<span style="color: #339933; font-weight: bold;">,</span> s<span style="color: green;">&#41;</span> <span style="color: green;">&#125;</span></pre></div></div>

<p>里面有个难看的record syntax，咱们无视之，改成：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> State g v <span style="color: #339933; font-weight: bold;">=</span> State <span style="color: green;">&#40;</span>g <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>v<span style="color: #339933; font-weight: bold;">,</span> g<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span></pre></div></div>

<p>就是一个lambda，外加一二元组：v表示猫猫正经计算中的值，g就表示猫猫的状态啦(就一个全局变量嘛)~那个lambda的参数g也一样。相应的猫猫Instance也就是如下：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">instance</span> <span style="color: #cccc00; font-weight: bold;">Monad</span> <span style="color: green;">&#40;</span>State g<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span>
    <span style="font-weight: bold;">return</span> v <span style="color: #339933; font-weight: bold;">=</span> 
        State <span style="color: #339933; font-weight: bold;">$</span> \g <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>v<span style="color: #339933; font-weight: bold;">,</span> g<span style="color: green;">&#41;</span>
&nbsp;
    <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">&gt;&gt;=</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>State m<span style="color: green;">&#41;</span> f <span style="color: #339933; font-weight: bold;">=</span> 
        State <span style="color: #339933; font-weight: bold;">$</span> \g <span style="color: #339933; font-weight: bold;">-&gt;</span> 
                <span style="color: #06c; font-weight: bold;">let</span> <span style="color: green;">&#40;</span>v<span style="color: #339933; font-weight: bold;">,</span> g'<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> m g
                    <span style="color: green;">&#40;</span>State m'<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> f v
                <span style="color: #06c; font-weight: bold;">in</span>  m' g'</pre></div></div>

<p>还是一环套一环，函数编程没有变量，那就向下传递的时候改变它的值就行了。再加两个小喽骡：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">get<span style="color: #339933; font-weight: bold;">_</span>g <span style="color: #339933; font-weight: bold;">=</span> State <span style="color: #339933; font-weight: bold;">$</span> \g <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>g<span style="color: #339933; font-weight: bold;">,</span> g<span style="color: green;">&#41;</span>
set<span style="color: #339933; font-weight: bold;">_</span>g v <span style="color: #339933; font-weight: bold;">=</span> State <span style="color: #339933; font-weight: bold;">$</span> \<span style="color: #339933; font-weight: bold;">_</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#40;</span>v<span style="color: #339933; font-weight: bold;">,</span> v<span style="color: green;">&#41;</span></pre></div></div>

<p>全局变量的值不也在那个lambda的参数里么，get_g它设成计算中的值，这样在do-notation中就可以g <- get_g了。set_g则是把它的参数设到g里，而原先的g无视扔掉即可。</p>
<p>加个函数试验下：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">run <span style="color: green;">&#40;</span>State m<span style="color: green;">&#41;</span> i <span style="color: #339933; font-weight: bold;">=</span> m i 
&nbsp;
add1 <span style="color: #339933; font-weight: bold;">::</span> State <span style="color: #cccc00; font-weight: bold;">Int</span> <span style="color: #cccc00; font-weight: bold;">Int</span>
add1 <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> <span style="color: green;">&#123;</span>
    g <span style="color: #339933; font-weight: bold;">&lt;-</span> get<span style="color: #339933; font-weight: bold;">_</span>g;
    set<span style="color: #339933; font-weight: bold;">_</span>g <span style="color: #339933; font-weight: bold;">$</span> g <span style="color: #339933; font-weight: bold;">+</span> <span style="color: red;">1</span>;
<span style="color: green;">&#125;</span>
&nbsp;
add3 <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> <span style="color: green;">&#123;</span>
    add1;
    add1;
    add1;
<span style="color: green;">&#125;</span></pre></div></div>

<p>进ghci输入run add3 1可得(4,4)，可见那个“全局变量”就这么变化了。</p>
<p>回头再想想它的类型，一个二元组不就够了嘛，为什么要套那层lambda呢？试下就知道</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;"><span style="color: #06c; font-weight: bold;">data</span> State g v <span style="color: #339933; font-weight: bold;">=</span> State <span style="color: green;">&#40;</span>g<span style="color: #339933; font-weight: bold;">,</span> v<span style="color: green;">&#41;</span> 
&nbsp;
<span style="color: #06c; font-weight: bold;">instance</span> <span style="color: #cccc00; font-weight: bold;">Monad</span> <span style="color: green;">&#40;</span>State g<span style="color: green;">&#41;</span> <span style="color: #06c; font-weight: bold;">where</span>
    <span style="color: green;">&#40;</span><span style="color: #339933; font-weight: bold;">&gt;&gt;=</span><span style="color: green;">&#41;</span> <span style="color: green;">&#40;</span>State <span style="color: green;">&#40;</span>g<span style="color: #339933; font-weight: bold;">,</span> v<span style="color: green;">&#41;</span><span style="color: green;">&#41;</span> f <span style="color: #339933; font-weight: bold;">=</span> <span style="color: green;">&#40;</span>g<span style="color: #339933; font-weight: bold;">,</span> f v<span style="color: green;">&#41;</span></pre></div></div>

<p>看着不错，接着来：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">    <span style="font-weight: bold;">return</span> v <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #339933; font-weight: bold;">...</span></pre></div></div>

<p>发现问题了没，return我们实现不了&#8230;搞不到原先g的值，链子就断在了这一环。解决方法就是把它推后，不是没有g么，于是放到参数里等着别人(>>=)给，这算不算惰性呢？ :)</p>
<p>ps:明白了State是怎么回事，附一山寨parsec ^_^ <a href="http://github.com/Fleurer/FParser">http://github.com/Fleurer/FParser</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/03/05/state-monad%e7%ac%94%e8%ae%b0%e4%ba%8c/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>State Monad笔记一</title>
		<link>http://www.fleurer-lee.com/2010/02/25/state-monad%e7%ac%94%e8%ae%b0%e4%b8%80/</link>
		<comments>http://www.fleurer-lee.com/2010/02/25/state-monad%e7%ac%94%e8%ae%b0%e4%b8%80/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 12:19:40 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[FP]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[monad]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645747</guid>
		<description><![CDATA[去年听王猫猫讲过之后就一直心安理得再也没看过Monad，以至于到昨天还不知State Monad为何物&#8230;囧
关于State Monad，似乎见过的教材都是拿随机数作例子，拿Monad跟一堆let对比，满眼的二元组绕啊绕啊，我给你个Monad让它不那么绕（存疑）～其实什么东西理解不了，往往就是因为不知道它怎么用（比如复变函数 =&#8221;=）
换个例子，像那个筛掉一个List中重复元素的nub函数多好&#8230;.在命令式语言下边大约是这样：

def nub&#40;xs&#41;
    result=&#91;&#93;
    for x in xs
        if not result.include? x
	     result &#60;&#60; x
    return result

若在函数式语言下边，用迭代大约是这样：

inub :: &#40;Eq a&#41; =&#62; &#91;a&#93; -&#62; &#91;a&#93;
inub = inub' &#91;&#93; 
inub' rs &#91;&#93; = rs
inub' rs [...]]]></description>
			<content:encoded><![CDATA[<p>去年听王猫猫讲过之后就一直心安理得再也没看过Monad，以至于到昨天还不知State Monad为何物&#8230;囧</p>
<p>关于State Monad，似乎见过的教材都是拿随机数作例子，拿Monad跟一堆let对比，满眼的二元组绕啊绕啊，我给你个Monad让它不那么绕（存疑）～其实什么东西理解不了，往往就是因为不知道它怎么用（比如复变函数 =&#8221;=）</p>
<p>换个例子，像那个筛掉一个List中重复元素的nub函数多好&#8230;.在命令式语言下边大约是这样：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> nub<span style="color: black;">&#40;</span>xs<span style="color: black;">&#41;</span>
    result=<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
    <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> xs
        <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> result.<span style="color: black;">include</span><span style="color: #66cc66;">?</span> x
	     result <span style="color: #66cc66;">&lt;&lt;</span> x
    <span style="color: #ff7700;font-weight:bold;">return</span> result</pre></div></div>

<p>若在函数式语言下边，用迭代大约是这样：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">inub <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span><span style="color: #cccc00; font-weight: bold;">Eq</span> a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span>
inub <span style="color: #339933; font-weight: bold;">=</span> inub' <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> 
inub' rs <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">=</span> rs
inub' rs <span style="color: green;">&#40;</span>x:xs<span style="color: green;">&#41;</span> 
    <span style="color: #339933; font-weight: bold;">|</span> x `<span style="font-weight: bold;">elem</span>` rs    <span style="color: #339933; font-weight: bold;">=</span> inub' rs xs
    <span style="color: #339933; font-weight: bold;">|</span> <span style="font-weight: bold;">otherwise</span>     <span style="color: #339933; font-weight: bold;">=</span> inub' <span style="color: green;">&#40;</span>rs<span style="color: #339933; font-weight: bold;">++</span><span style="color: green;">&#91;</span>x<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span> xs</pre></div></div>

<p>inub&#8217;这个函数中有个rs参数，就相当于前面那个result变量。它的值会随着迭代发生改变，不同之处就是ts是引用透明的没有副作用。每次函数调用就是一个状态，状态就是一个值。</p>
<p>不喜欢给函数多加个参数怎么办？State Monad可以做到。在State Monad里面有两个函数可以使用：put，设置当前状态的值；get，获得当前状态的值。就相当于给函数加了一个（只有一个）可变的全局变量，在调用别的函数或者递归时这个值可以保留。</p>
<p>State Monad版本（我没觉得好看 =&#8221;=）：</p>

<div class="wp_syntax"><div class="code"><pre class="haskell" style="font-family:monospace;">mnub <span style="color: #339933; font-weight: bold;">::</span> <span style="color: green;">&#40;</span><span style="color: #cccc00; font-weight: bold;">Eq</span> a<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=&gt;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">-&gt;</span> <span style="color: green;">&#91;</span>a<span style="color: green;">&#93;</span>
mnub xs <span style="color: #339933; font-weight: bold;">=</span> evalState <span style="color: green;">&#40;</span>mnub' xs<span style="color: green;">&#41;</span> <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span>
mnub' <span style="color: green;">&#91;</span><span style="color: green;">&#93;</span> <span style="color: #339933; font-weight: bold;">=</span> get
mnub' <span style="color: green;">&#40;</span>x:xs<span style="color: green;">&#41;</span> <span style="color: #339933; font-weight: bold;">=</span> <span style="color: #06c; font-weight: bold;">do</span> <span style="color: green;">&#123;</span>
    rs <span style="color: #339933; font-weight: bold;">&lt;-</span> get;
    <span style="color: #06c; font-weight: bold;">if</span> x `<span style="font-weight: bold;">elem</span>` rs <span style="color: #06c; font-weight: bold;">then</span> <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">do</span> <span style="color: green;">&#123;</span>
        mnub' xs;
    <span style="color: green;">&#125;</span><span style="color: green;">&#41;</span>
    <span style="color: #06c; font-weight: bold;">else</span> <span style="color: green;">&#40;</span><span style="color: #06c; font-weight: bold;">do</span> <span style="color: green;">&#123;</span>
        put <span style="color: #339933; font-weight: bold;">$</span> <span style="color: green;">&#40;</span>rs<span style="color: #339933; font-weight: bold;">++</span><span style="color: green;">&#91;</span>x<span style="color: green;">&#93;</span><span style="color: green;">&#41;</span>;
        mnub' xs;
    <span style="color: green;">&#125;</span><span style="color: green;">&#41;</span>;
<span style="color: green;">&#125;</span></pre></div></div>

<p>原理大约就是do-notation中的每个语句都是用一个wrapper的类型包起来再不断往下传递么，而State的wrapper就是个类型为(a,s)的二元组（外加一层lambda？），每个语句的返回值放到s里，那个全局的值则放在a里&#8230;具体还有点迷糊，哪天推导下再说好了  >_<</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/02/25/state-monad%e7%ac%94%e8%ae%b0%e4%b8%80/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>typedef unsigned long VALUE;</title>
		<link>http://www.fleurer-lee.com/2010/01/19/typedef-unsigned-long-value/</link>
		<comments>http://www.fleurer-lee.com/2010/01/19/typedef-unsigned-long-value/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 08:38:24 +0000</pubDate>
		<dc:creator>fleurer</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[VM]]></category>

		<guid isPermaLink="false">http://www.fleurer-lee.com/?p=645669</guid>
		<description><![CDATA[因为swdpress.cn的死掉严重打击积极性，好久没更新了。此文纯凑数。
ruby中除了Fixnum，其余所有类型的值都是引用传递。读《ruby hacking guide》时看到如下的定义：

typedef unsigned long VALUE;

同lua那union+tag不一样，ruby中所有类型的值都存放在一个VALUE中，而没有tag指明其类型。如果是Fixnum，就把数值直接放在VALUE里；如果是其它类型，则存放其地址（unsigned long和C中指针类型的长度一致）。不过万一作为Fixnum的VALUE指向的地址与其他对象有重叠怎么办？它又怎么区别数值和地址呢？
这用到了一点tricks，C的struct在内存中都是以4字节对齐，因此ruby中所有对象的地址都偶数。在表示Fixnum时，ruby就将C的int值左移一位再加一，使其看起来总是个奇数，这样就不会与ruby的其它对象有重叠。

 123  #define INT2FIX(i) ((VALUE)(((long)(i))&#60;&#60;1 &#124; FIXNUM_FLAG))
 122  #define FIXNUM_FLAG 0x01
&#40;ruby.h&#41;

判断一个VALUE是Fixnum还是地址，只需判断VALUE是奇数还是偶数就行了。
表示true,false和nil是这样：

 164  #define Qfalse 0        /* Ruby's false */
 165  #define Qtrue  2        /* Ruby's true */
 166  #define [...]]]></description>
			<content:encoded><![CDATA[<p>因为swdpress.cn的死掉严重打击积极性，好久没更新了。此文纯凑数。</p>
<p>ruby中除了Fixnum，其余所有类型的值都是引用传递。读《<a href="http://code.google.com/p/rhgchs/">ruby hacking guide</a>》时看到如下的定义：</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #993333;">typedef</span> <span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> VALUE<span style="color: #339933;">;</span></pre></div></div>

<p>同lua那union+tag不一样，ruby中所有类型的值都存放在一个VALUE中，而没有tag指明其类型。如果是Fixnum，就把数值直接放在VALUE里；如果是其它类型，则存放其地址（unsigned long和C中指针类型的长度一致）。不过万一作为Fixnum的VALUE指向的地址与其他对象有重叠怎么办？它又怎么区别数值和地址呢？</p>
<p>这用到了一点tricks，C的struct在内存中都是以4字节对齐，因此ruby中所有对象的地址都偶数。在表示Fixnum时，ruby就将C的int值左移一位再加一，使其看起来总是个奇数，这样就不会与ruby的其它对象有重叠。</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"> <span style="color: #0000dd;">123</span>  <span style="color: #339933;">#define INT2FIX(i) ((VALUE)(((long)(i))&lt;&lt;1 | FIXNUM_FLAG))</span>
 <span style="color: #0000dd;">122</span>  <span style="color: #339933;">#define FIXNUM_FLAG 0x01</span>
<span style="color: #009900;">&#40;</span>ruby.<span style="color: #202020;">h</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>判断一个VALUE是Fixnum还是地址，只需判断VALUE是奇数还是偶数就行了。</p>
<p>表示true,false和nil是这样：</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"> <span style="color: #0000dd;">164</span>  <span style="color: #339933;">#define Qfalse 0        /* Ruby's false */</span>
 <span style="color: #0000dd;">165</span>  <span style="color: #339933;">#define Qtrue  2        /* Ruby's true */</span>
 <span style="color: #0000dd;">166</span>  <span style="color: #339933;">#define Qnil   4        /* Ruby's nil */</span>
<span style="color: #009900;">&#40;</span>ruby.<span style="color: #202020;">h</span><span style="color: #009900;">&#41;</span></pre></div></div>

<p>都是偶数。像刚才说的，它们不会被当作是地址了么？这就用到了另一个trick：进程虚拟地址空间的前一部分都是不可访问的。因而0,2,4的地址上不会存在ruby对象。</p>
<p>PS: 感谢FX大大提醒，这套方法有个标准的名字叫做“tagged pointer” :)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2010/01/19/typedef-unsigned-long-value/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>eval, class_eval, instance_eval和binding</title>
		<link>http://www.fleurer-lee.com/2009/12/13/eval-class_eval-instance_eval%e5%92%8cbinding/</link>
		<comments>http://www.fleurer-lee.com/2009/12/13/eval-class_eval-instance_eval%e5%92%8cbinding/#comments</comments>
		<pubDate>Sun, 13 Dec 2009 12:27:06 +0000</pubDate>
		<dc:creator>ssword</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[trick]]></category>

		<guid isPermaLink="false">http://swdpress.cn/?p=645586</guid>
		<description><![CDATA[前些天写html生成器的时候用到了erb，在生成html的时候是这么一句：

html=tpl.result(binding)

binding这个变量（Kernel的一个方法 T_T）有点古怪，就搜了下。它表示了ruby的当前作用域，没有任何对外可见的成员函数，唯一的用途就是传递给eval作第二个参数。因而可以这样：

def test_binding
    magic='brother Chun is PURE MAN'
    return binding
end
eval &#34;puts magic&#34;, test_binding

这样就穿越了一个作用域。
有时可以见到这样的构造函数：

a=Baby.new &#123;
    name &#34;Makr&#34;
    father &#34;Mike&#34;
    age 0.2
&#125;
a.cry

好处就是好看。实现起来其实也很容易，用instance_eval：

class Baby
    def initialize&#40;&#38;blc&#41;
        instance_eval&#40;&#38;blc&#41; #here
    end
&#160;
  [...]]]></description>
			<content:encoded><![CDATA[<p>前些天写html生成器的时候用到了erb，在生成html的时候是这么一句：</p>

<div class="wp_syntax"><div class="code"><pre class="erb" style="font-family:monospace;">html=tpl.result(binding)</pre></div></div>

<p>binding这个变量（Kernel的一个方法 T_T）有点古怪，就搜了下。它表示了ruby的当前作用域，没有任何对外可见的成员函数，唯一的用途就是传递给eval作第二个参数。因而可以这样：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> test_binding
    magic=<span style="color:#996600;">'brother Chun is PURE MAN'</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#CC0066; font-weight:bold;">binding</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#CC0066; font-weight:bold;">eval</span> <span style="color:#996600;">&quot;puts magic&quot;</span>, test_binding</pre></div></div>

<p>这样就穿越了一个作用域。</p>
<p>有时可以见到这样的构造函数：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">a=Baby.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    name <span style="color:#996600;">&quot;Makr&quot;</span>
    father <span style="color:#996600;">&quot;Mike&quot;</span>
    age <span style="color:#006666;">0.2</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
a.<span style="color:#9900CC;">cry</span></pre></div></div>

<p>好处就是好看。实现起来其实也很容易，用instance_eval：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Baby
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>blc<span style="color:#006600; font-weight:bold;">&#41;</span>
        instance_eval<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>blc<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#008000; font-style:italic;">#here</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> name<span style="color:#006600; font-weight:bold;">&#40;</span>str=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@name</span>=str <span style="color:#9966CC; font-weight:bold;">if</span> str
        <span style="color:#0066ff; font-weight:bold;">@name</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> age<span style="color:#006600; font-weight:bold;">&#40;</span>num=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@age</span>=num <span style="color:#9966CC; font-weight:bold;">if</span> num
        <span style="color:#0066ff; font-weight:bold;">@age</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> father<span style="color:#006600; font-weight:bold;">&#40;</span>str=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0066ff; font-weight:bold;">@father</span>=str <span style="color:#9966CC; font-weight:bold;">if</span> str
        <span style="color:#0066ff; font-weight:bold;">@father</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> cry
        <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{name} is only #{age.to_s} year old, he wanna milk! Brother Chun is PURE MAN!&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>有重复代码？用class_eval缩短之，有点像宏了：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Baby
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>blc<span style="color:#006600; font-weight:bold;">&#41;</span>
        instance_eval<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&amp;</span>blc<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> Baby.<span style="color:#9900CC;">my_attr</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>names<span style="color:#006600; font-weight:bold;">&#41;</span>
        names.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>n<span style="color:#006600; font-weight:bold;">|</span>
            class_eval <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>
                <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#008000; font-style:italic;">#{n}(x=nil)</span>
                    @<span style="color:#008000; font-style:italic;">#{n}=x if x</span>
                    @<span style="color:#008000; font-style:italic;">#{n}</span>
                <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#006600; font-weight:bold;">&#125;</span>
        <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    my_attr <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:father</span>, <span style="color:#ff3333; font-weight:bold;">:age</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> cry
        <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{name} is only #{age.to_s} year old, he wanna milk! Brother Chun is PURE MAN!&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
a=Baby.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    name <span style="color:#996600;">&quot;Makr&quot;</span>
    father <span style="color:#996600;">&quot;Mike&quot;</span>
    age <span style="color:#006666;">0.2</span>
<span style="color:#006600; font-weight:bold;">&#125;</span>
a.<span style="color:#9900CC;">cry</span></pre></div></div>

<p>这里class_eval穿越到了类的作用域，实现了动态添加函数。instance_eval也是，穿越到了实例的作用域，实现修改其内部数据。明白了它们的穿越关系，我们可以实现自己的class_eval和instance_eval——从合适的地方搞到binding就行了。</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Baby
    <span style="color:#9966CC; font-weight:bold;">def</span> my_instance_eval<span style="color:#006600; font-weight:bold;">&#40;</span>code<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">eval</span> code, <span style="color:#CC0066; font-weight:bold;">binding</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> Baby.<span style="color:#9900CC;">my_class_eval</span><span style="color:#006600; font-weight:bold;">&#40;</span>code=<span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">eval</span> code, <span style="color:#CC0066; font-weight:bold;">binding</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>就这么简单。调用的时候就像这样：</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Baby
    <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>code<span style="color:#006600; font-weight:bold;">&#41;</span>
        my_instance_eval<span style="color:#006600; font-weight:bold;">&#40;</span>code<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    my_attr <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:father</span>, <span style="color:#ff3333; font-weight:bold;">:age</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
a=Baby.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">%</span><span style="color:#006600; font-weight:bold;">&#123;</span>
    name <span style="color:#996600;">&quot;Test&quot;</span>
    father <span style="color:#996600;">&quot;Orz&quot;</span>
    age <span style="color:#006666;">0.2</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>刚才省略了一点，那就是class_eval和instance_eval可以接受block代替字符串。搜了下，貌似没找到eval接受block的方法，所以这顶多算是只能eval字符串的山寨class_eval。</p>
<p>update: 想起来ruby中lambda和proc在作用域上的小区别，也就是binding的不同了。proc直接使用原先的binding，lambda继承原先作用域创建一个新的binding。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2009/12/13/eval-class_eval-instance_eval%e5%92%8cbinding/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>mips汇编入门</title>
		<link>http://www.fleurer-lee.com/2009/11/03/645538/</link>
		<comments>http://www.fleurer-lee.com/2009/11/03/645538/#comments</comments>
		<pubDate>Tue, 03 Nov 2009 05:35:15 +0000</pubDate>
		<dc:creator>ssword</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[ASM]]></category>
		<category><![CDATA[MIPS]]></category>
		<category><![CDATA[trick]]></category>

		<guid isPermaLink="false">http://swdpress.cn/?p=645538</guid>
		<description><![CDATA[据说若要深入学习MIPS开发的话，《MIPS处理器设计透视》这书是必不可少的。不过若只是学习MIPS汇编，这书可能就不大合适了。汇编语言还是隐藏了CPU的很多细节，而这本书里讲的貌似就是这部分，在对汇编有所了解之后再来阅读可能要更好。
学习函数式语言的时候总是满足于看书，理解下语法语义即可，真正写的代码则少的可怜，不过确实“改变了编程的看法”，目的也算达到了。汇编就不行了，看书不够，一定得动手。所以学MIPS需要一个模拟器。pcspim应该是比较标准的了，不过感觉Mars可能要更好用（准确地说，Mars非常非常好用）。
MIPS是以优雅著称，据说即使是其竞争对手也如此认为。RISC么，32个寄存器，指令长度都一样。其中的指令大约这么三种形式：

j 1000
li $1, 10
add $1, $2,$3

差异就是各个参数的长度不同。如add指令的三个参数都只有两个位宽（0~255），每个参数表示一个寄存器。如果把指令看作函数，那参数就可以看作是有类型的。而MIPS的汇编器是很强大的（听说可以进行窥孔优化），像add $t0, $0, 10这样的指令会被汇编器翻译成addi $t0,$0,10。汇编器处理前后指令的对比可以在Mars中显示出来。
记几个helloworld吧，
求3的阶乘：

li $t0, 0
li $t1, 1
if_1:
add $t0, $t0, 1
mul $t1, $t1, $t0
bne $t0, 3, if_1

在Mars下可以看到寄存器的变化，最后$t1寄存器的值是6。
mips汇编的分支（branch）指令分b系（bne，beq，bgt等等）和j系（j, jr等），差别就是b系指令的跳转都是有条件的，而且地址在参数中指明，而j系的跳转都是无条件的。j系指令的地址长度更长，寻址范围要更大，所以远程跳转都是j。
输出Helloworld：

.text
.globl main
&#160;
main:
li $v0, 4                     # just the print syscall in SPIM
la $a0, [...]]]></description>
			<content:encoded><![CDATA[<p>据说若要深入学习MIPS开发的话，《MIPS处理器设计透视》这书是必不可少的。不过若只是学习MIPS汇编，这书可能就不大合适了。汇编语言还是隐藏了CPU的很多细节，而这本书里讲的貌似就是这部分，在对汇编有所了解之后再来阅读可能要更好。</p>
<p>学习函数式语言的时候总是满足于看书，理解下语法语义即可，真正写的代码则少的可怜，不过确实“改变了编程的看法”，目的也算达到了。汇编就不行了，看书不够，一定得动手。所以学MIPS需要一个模拟器。<a href="http://pages.cs.wisc.edu/~larus/spim.html">pcspim</a>应该是比较标准的了，不过感觉<a href="http://courses.missouristate.edu/KenVollmar/MARS/">Mars</a>可能要更好用（准确地说，Mars非常非常好用）。</p>
<p>MIPS是以优雅著称，据说即使是其竞争对手也如此认为。RISC么，32个寄存器，指令长度都一样。其中的指令大约这么三种形式：</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">j <span style="color: #0000ff;">1000</span>
li $<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">10</span>
<span style="color: #00007f; font-weight: bold;">add</span> $<span style="color: #0000ff;">1</span><span style="color: #339933;">,</span> $<span style="color: #0000ff;">2</span><span style="color: #339933;">,</span>$<span style="color: #0000ff;">3</span></pre></div></div>

<p>差异就是各个参数的长度不同。如add指令的三个参数都只有两个位宽（0~255），每个参数表示一个寄存器。如果把指令看作函数，那参数就可以看作是有类型的。而MIPS的汇编器是很强大的（听说可以进行窥孔优化），像add $t0, $0, 10这样的指令会被汇编器翻译成addi $t0,$0,10。汇编器处理前后指令的对比可以在Mars中显示出来。</p>
<p>记几个helloworld吧，</p>
<p>求3的阶乘：</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;">li $t0<span style="color: #339933;">,</span> <span style="color: #0000ff;">0</span>
li $t1<span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>
if_1<span style="color: #339933;">:</span>
<span style="color: #00007f; font-weight: bold;">add</span> $t0<span style="color: #339933;">,</span> $t0<span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>
<span style="color: #00007f; font-weight: bold;">mul</span> $t1<span style="color: #339933;">,</span> $t1<span style="color: #339933;">,</span> $t0
bne $t0<span style="color: #339933;">,</span> <span style="color: #0000ff;">3</span><span style="color: #339933;">,</span> if_1</pre></div></div>

<p>在Mars下可以看到寄存器的变化，最后$t1寄存器的值是6。</p>
<p>mips汇编的分支（branch）指令分b系（bne，beq，bgt等等）和j系（j, jr等），差别就是b系指令的跳转都是有条件的，而且地址在参数中指明，而j系的跳转都是无条件的。j系指令的地址长度更长，寻址范围要更大，所以远程跳转都是j。</p>
<p>输出Helloworld：</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #339933;">.</span>text
<span style="color: #339933;">.</span>globl main
&nbsp;
main<span style="color: #339933;">:</span>
li $v0<span style="color: #339933;">,</span> <span style="color: #0000ff;">4</span>                     # just the print <span style="color: #000000; font-weight: bold;">syscall</span> <span style="color: #00007f; font-weight: bold;">in</span> SPIM
la $a0<span style="color: #339933;">,</span> <span style="color: #00007f; font-weight: bold;">str</span>
<span style="color: #000000; font-weight: bold;">syscall</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">.data</span>
<span style="color: #00007f; font-weight: bold;">str</span><span style="color: #339933;">:</span>
<span style="color: #339933;">.</span>asciiz <span style="color: #7f007f;">&quot;hello world&quot;</span></pre></div></div>

<p>这应该算个比较完整的汇编程序了。程序的可执行代码都是在.text段，数据在.data段。.globl指明程序的入口地址，那个:str指代的就是这段字符串的地址。字符串么，就是数组。数组不就是指针么。</p>
<p>其中这个syscall会与操作系统的不同而有差异。系统调用的号码由$v0指明，参数在$a系的寄存器中传递，返回值放回到$v0。这里调用的是spim实现的4号系统调用，即print string。</p>
<p>定义一个函数f_add，它可以将两个数相加：</p>

<div class="wp_syntax"><div class="code"><pre class="asm" style="font-family:monospace;"><span style="color: #339933;">.</span>text
<span style="color: #339933;">.</span>globl main
&nbsp;
f_add<span style="color: #339933;">:</span>
<span style="color: #00007f; font-weight: bold;">add</span> $v0<span style="color: #339933;">,</span> $a0<span style="color: #339933;">,</span> $a1
jr $ra
&nbsp;
main<span style="color: #339933;">:</span>
li $a0<span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>
li $a1<span style="color: #339933;">,</span> <span style="color: #0000ff;">2</span>
jal f_add
&nbsp;
<span style="color: #00007f; font-weight: bold;">add</span> $t0<span style="color: #339933;">,</span> $v0<span style="color: #339933;">,</span> $<span style="color: #0000ff;">0</span>
&nbsp;
li $v0<span style="color: #339933;">,</span> <span style="color: #0000ff;">1</span>
<span style="color: #00007f; font-weight: bold;">add</span> $a0<span style="color: #339933;">,</span> $<span style="color: #0000ff;">0</span><span style="color: #339933;">,</span> $t0
<span style="color: #000000; font-weight: bold;">syscall</span></pre></div></div>

<p>在使用jal指令的时候，它会把发生跳转的地址记录在$ra寄存器中。这样函数在结尾的时候就可以用jr返回原先的位置了。</p>
<p>使用寄存器传递参数的好处貌似就是约定了函数的调用规范，兼容性要更好。例如x86下的BASIC和C在参数传递时压栈的顺序貌似就是相反的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2009/11/03/645538/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>理解Y组合子</title>
		<link>http://www.fleurer-lee.com/2009/09/19/%e7%90%86%e8%a7%a3y%e7%bb%84%e5%90%88%e5%ad%90/</link>
		<comments>http://www.fleurer-lee.com/2009/09/19/%e7%90%86%e8%a7%a3y%e7%bb%84%e5%90%88%e5%ad%90/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 06:00:55 +0000</pubDate>
		<dc:creator>ssword</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[FP]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[Y-combinator]]></category>

		<guid isPermaLink="false">http://swdpress.cn/?p=645477</guid>
		<description><![CDATA[众所周知，lambda演算通过递归就可以图灵完备。好，用纯lambda演算写个递归吧。
等等，要递归必须得有名字，而lambda演算里赋予名字的唯一方式就是传递参数。像lisp那样define可不行啊。只能这样绕个圈子：

&#40;\f.\x.
    &#40;if  &#40;= x 1&#41;
        1
        &#40;* x &#40;f f  &#40;- x 1&#41;&#41;&#41;&#41;&#41;

这里把函数本身作为第一个参数传递给自己，从而实现的递归。要调用这个递归函数，还得套一个let（当然，换成lambda形式）:

&#40;&#40;\fac. &#40;fac fac 5&#41;&#41;
        &#40;\f.\x.
             [...]]]></description>
			<content:encoded><![CDATA[<p>众所周知，lambda演算通过递归就可以图灵完备。好，用纯lambda演算写个递归吧。</p>
<p>等等，要递归必须得有名字，而lambda演算里赋予名字的唯一方式就是传递参数。像lisp那样define可不行啊。只能这样绕个圈子：</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span>\f<span style="color: #66cc66;">.</span>\x<span style="color: #66cc66;">.</span>
    <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span>  <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> x <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #cc66cc;">1</span>
        <span style="color: #66cc66;">&#40;</span>* x <span style="color: #66cc66;">&#40;</span>f f  <span style="color: #66cc66;">&#40;</span>- x <span style="color: #cc66cc;">1</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></div></div>

<p>这里把函数本身作为第一个参数传递给自己，从而实现的递归。要调用这个递归函数，还得套一个let（当然，换成lambda形式）:</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;"><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>\fac<span style="color: #66cc66;">.</span> <span style="color: #66cc66;">&#40;</span>fac fac <span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
        <span style="color: #66cc66;">&#40;</span>\f<span style="color: #66cc66;">.</span>\x<span style="color: #66cc66;">.</span>
              <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> x <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
                    <span style="color: #cc66cc;">1</span>
                    <span style="color: #66cc66;">&#40;</span>* x <span style="color: #66cc66;">&#40;</span>f f <span style="color: #66cc66;">&#40;</span>- x <span style="color: #cc66cc;">1</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></div></div>

<p>真难看！每次递归都得把自己当作参数传递一遍，很机械！机械的活不应由人类做！想下，如果将递归函数里的(f f (- x 1))换成(f (- x 1))，或许还可以接受…好，Y组合子应运而生，现在你可以这样自然地递归了：</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;">Y <span style="color: #66cc66;">&#40;</span>\f<span style="color: #66cc66;">.</span>\x
     <span style="color: #66cc66;">&#40;</span><span style="color: #b1b100;">if</span> <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">=</span> x <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>
          <span style="color: #cc66cc;">1</span>
          <span style="color: #66cc66;">&#40;</span>* x <span style="color: #66cc66;">&#40;</span>f <span style="color: #66cc66;">&#40;</span>- x <span style="color: #cc66cc;">1</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: #cc66cc;">5</span></pre></div></div>

<p>数学家在追求美感上可是不遗余力啊。不过Y是如何做到的？</p>
<p>想想，Y组合子又叫不动点函数。什么是不动点？x=f(x)=f(f(x))…，这个x就是不动点：不管套多少层函数调用，在不动点上的值总是相等。Y f = f (Y f)=f (f (Y f))，这个Y f就是个不动点，高阶函数的不动点。什么是组合子？很简单，可以柯里化、没有自由变量的函数就是组合子 :)</p>
<p>便于理解，我们给(\f.\x (if (= x 1) 1 (* x (f (- x 1)))))这个lambda一个名字fac，看看一步步的递归是怎么来的：</p>

<div class="wp_syntax"><div class="code"><pre class="lisp" style="font-family:monospace;">Y fac <span style="color: #cc66cc;">3</span>
<span style="color: #66cc66;">&gt;</span> fac <span style="color: #66cc66;">&#40;</span>Y fac<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">3</span>         	//transform<span style="color: #66cc66;">,</span> Y<span style="color: #66cc66;">!</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>Y fac<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>        	//<span style="color: #cc66cc;">3</span> <span style="color: #66cc66;">!=</span><span style="color: #cc66cc;">1</span> so recurse
<span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span>fac <span style="color: #66cc66;">&#40;</span>Y fac<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">2</span><span style="color: #66cc66;">&#41;</span>    	//Y transform again
<span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#40;</span>Y fac<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>       //<span style="color: #cc66cc;">2</span> <span style="color: #66cc66;">!=</span><span style="color: #cc66cc;">1</span> so recurse
<span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span>fac <span style="color: #66cc66;">&#40;</span>Y fac<span style="color: #66cc66;">&#41;</span> <span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>   	//Y transform again
<span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;"> * </span><span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">2</span><span style="color: #66cc66;"> * </span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">&#41;</span>             	//<span style="color: #cc66cc;">1</span><span style="color: #66cc66;">=</span><span style="color: #cc66cc;">1</span><span style="color: #66cc66;">,</span> so recursion ends<span style="color: #66cc66;">.</span>
<span style="color: #66cc66;">&gt;</span> <span style="color: #cc66cc;">6</span></pre></div></div>

<p>就是这样了。里面有柯里化，也有惰性求值（缺一不可！）。一环套一环，然后就递归了。</p>
<p>Y组合子的定义：Y = \y. (\x.y (x x)) (\x.y (x x))，天知道大神（大神的名字叫做Haskell Curry! -v-）是怎么想出来的 =v=</p>
<p>不妨自己在纸上推倒一下(也只能在纸上推倒，这东西在实际的编程中貌似是没有应用的 :D)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2009/09/19/%e7%90%86%e8%a7%a3y%e7%bb%84%e5%90%88%e5%ad%90/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
