<?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; continuation</title>
	<atom:link href="http://www.fleurer-lee.com/tag/continuation/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>理解continuation</title>
		<link>http://www.fleurer-lee.com/2009/06/06/%e7%90%86%e8%a7%a3continuation/</link>
		<comments>http://www.fleurer-lee.com/2009/06/06/%e7%90%86%e8%a7%a3continuation/#comments</comments>
		<pubDate>Sat, 06 Jun 2009 05:34:20 +0000</pubDate>
		<dc:creator>ssword</dc:creator>
				<category><![CDATA[笔记]]></category>
		<category><![CDATA[continuation]]></category>
		<category><![CDATA[FP]]></category>

		<guid isPermaLink="false">http://swdpress.cn/?p=645159</guid>
		<description><![CDATA[当时小，不懂事，初学函数式编程时一头就扎的就是continuation和monad，一直搞不明白就一直放着。上个星期在ShiningRay老师的这篇《简介延续“Continuation”》里看到：

def call_cc&#40;f,c&#41;:
     f&#40;c,c&#41;

貌似很泪流满面的样子，没想到这东西有这么简单。之后在图书馆里写了一个小时的伪代码，貌似搞明白了。按照Continuation Passing Style(cps)的设定，函数没有返回值，而是用函数的运算结果调用函数最后一个参数，很简单吧。不过那些特性又是从何而来呢，像保存状态尾递归优化之类？现在想想，之前之所以不理解，大概就是因为不会写cps的递归吧，其实动手写的话也就那回事。国父孙先生不是说么，知难行易。
如下伪代码，求前n个自然数的和：

def sum&#40;n&#41;:
    if &#40;n==0&#41;: 0
    else :
        n+sum&#40;n-1&#41;

换成等价的前缀形式(if就懒得改了，知道这回事就好)：

def sum&#40;n&#41;:
	if &#40;n==0&#41;: return 0
    else
        return add&#40;n, sum&#40;sub&#40;n,1&#41;&#41;&#41;

好，换成cps：

def sum&#40;n,c&#41;:
    if &#40;n==0&#41;: c&#40;0&#41; #“延续”下去，而不是返回
 [...]]]></description>
			<content:encoded><![CDATA[<p>当时小，不懂事，初学函数式编程时一头就扎的就是continuation和monad，一直搞不明白就一直放着。上个星期在ShiningRay老师的这篇《<a href="http://shiningray.cn/continuations.html">简介延续“Continuation”</a>》里看到：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> call_cc<span style="color: black;">&#40;</span>f,c<span style="color: black;">&#41;</span>:
     f<span style="color: black;">&#40;</span>c,c<span style="color: black;">&#41;</span></pre></div></div>

<p>貌似很泪流满面的样子，没想到这东西有这么简单。之后在图书馆里写了一个小时的伪代码，貌似搞明白了。按照Continuation Passing Style(cps)的设定，函数没有返回值，而是用函数的运算结果调用函数最后一个参数，很简单吧。不过那些特性又是从何而来呢，像保存状态尾递归优化之类？现在想想，之前之所以不理解，大概就是因为不会写cps的递归吧，其实动手写的话也就那回事。国父孙先生不是说么，知难行易。</p>
<p>如下伪代码，求前n个自然数的和：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>n<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>n==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>: <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">else</span> :
        n+<span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>n-<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span></pre></div></div>

<p>换成等价的前缀形式(if就懒得改了，知道这回事就好)：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>n<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>n==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #ff4500;">0</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>
        <span style="color: #ff7700;font-weight:bold;">return</span> add<span style="color: black;">&#40;</span>n, <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>sub<span style="color: black;">&#40;</span>n,<span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>好，换成cps：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #008000;">sum</span><span style="color: black;">&#40;</span>n,c<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>n==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>: c<span style="color: black;">&#40;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#“延续”下去，而不是返回</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        sub n, <span style="color: #ff4500;">1</span>, <span style="color: black;">&#40;</span>\x1 -<span style="color: #66cc66;">&gt;</span> <span style="color: #808080; font-style: italic;">#一个lambda，匿名函数</span>
        <span style="color: #008000;">sum</span> x1, <span style="color: black;">&#40;</span>\x2 -<span style="color: #66cc66;">&gt;</span> <span style="color: #808080; font-style: italic;">#递归在这里</span>
        add x2 ,n ,c<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>再一个迭代的例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> iter_sum<span style="color: black;">&#40;</span>n, r<span style="color: black;">&#41;</span>:
     <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>n==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span> : <span style="color: #ff7700;font-weight:bold;">return</span> r
     <span style="color: #ff7700;font-weight:bold;">else</span> : iter_sum<span style="color: black;">&#40;</span>n-<span style="color: #ff4500;">1</span>, r+n<span style="color: black;">&#41;</span></pre></div></div>

<p>换成前缀：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> iter_sum<span style="color: black;">&#40;</span>n,r<span style="color: black;">&#41;</span>:
     <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>n==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>: <span style="color: #ff7700;font-weight:bold;">return</span> r
     <span style="color: #ff7700;font-weight:bold;">else</span> : iter_sum<span style="color: black;">&#40;</span>sub<span style="color: black;">&#40;</span>n, <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span>, add<span style="color: black;">&#40;</span>r,n<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>cps:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> c_iter_sum<span style="color: black;">&#40;</span>n,r,c<span style="color: black;">&#41;</span>:
    <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: black;">&#40;</span>n==<span style="color: #ff4500;">0</span><span style="color: black;">&#41;</span>: c<span style="color: black;">&#40;</span>r<span style="color: black;">&#41;</span>
    <span style="color: #ff7700;font-weight:bold;">else</span>:
        sub n, <span style="color: #ff4500;">1</span>, <span style="color: black;">&#40;</span>\x1 -<span style="color: #66cc66;">&gt;</span>
        add r, n, <span style="color: black;">&#40;</span>\x2 -<span style="color: #66cc66;">&gt;</span>
        c_iter_sum<span style="color: black;">&#40;</span>x1, x2, c<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span> <span style="color: #808080; font-style: italic;">#尾递归</span></pre></div></div>

<p>可以看出，cps中引入了些自由变量，把函数求值的结果放在堆里而非栈中，于是就可以实现不限深度的递归。不过这样貌似增加了垃圾收集的负担，没有银弹哇。</p>
<p>contiuation中只有“延续”而没有“返回”，每一步“延续”都是对后面函数的调用，通过一条函数与函数的链构成了顺序结构。ShiningRay老师貌似说过，一个函数调用就是一个状态。callcc貌似就是把“延续”的下一个函数保存，从而保存了状态。Smalltalk的那个Seaside框架貌似就是把contiuation作为对象持久化，在下次访问时找到这个持久化的contiuation将状态还原，从而模拟出仿桌面程序开发的效果。貌似要比asp.net那WebForm的实现更加自然些。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fleurer-lee.com/2009/06/06/%e7%90%86%e8%a7%a3continuation/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
