<?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>Fan&#039;s blog &#187; Language</title>
	<atom:link href="http://fkpwolf.net/category/language/feed/" rel="self" type="application/rss+xml" />
	<link>http://fkpwolf.net</link>
	<description>无为而无不为</description>
	<lastBuildDate>Sun, 13 May 2012 13:24:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>Promise, Future, Dojo&#8230;</title>
		<link>http://fkpwolf.net/2011/07/25/promise-future-dojo/</link>
		<comments>http://fkpwolf.net/2011/07/25/promise-future-dojo/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 08:51:06 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[Language]]></category>

		<guid isPermaLink="false">http:///?p=1049</guid>
		<description><![CDATA[Dojo上一个普通的Ajax调用： var xhrHandler = dojo.xhrGet({url:this.url, handleAs:"json-comment-optional", content:serverQuery}); xhrHandler.addCallback(dojo.hitch(this, function(data){ this._xhrFetchHandler(data, request, fetchHandler, errorHandler); })); xhrHandler.addErrback(function(error){ errorHandler(error, request); }); addCallback时，如果deferred已经完成，则传入的function被立刻执行。所以如果上面的xhrGet很快执行完成，则加入的callback也会被执行（这个时候消息队列为空），如同代码顺序执行。如果xhrGet较长时间完成，则加入的callback会有异步运行的效果。 上面的代码感觉很奇特，有种时空的错觉。如果dojo.xhrGet(..).addCallback(&#8230;).addCallback(&#8230;)则好点。 这个东西叫Promise，在CommonJS有单独的列出来，写法可以这样requestData(&#8220;foo.bar.com&#8221;).then(&#8230;).then()，看上去直观了很多。新的Dojo.js语法里面也有这个东西，不算新，只是我对Promise这个词很感兴趣，还有Future。 当命名一个抽象概念时，名字很重要啊！ 后来搜了下，原来Future在java中也有这个概念，可以参考这篇中文的文章（把callback和actor鄙视了一通），大体上讲就是把一个异步的程序转为顺序的写法： ExecutorService executor = ...//copy from jdk doc ArchiveSearcher searcher = ... void showSearch(final String target) throws InterruptedException { Future&#60;String&#62; future = executor.submit(new Callable&#60;String&#62;() { public String call() { return searcher.search(target); }}); displayOtherThings(); [...]]]></description>
			<content:encoded><![CDATA[<p>Dojo上一个普通的Ajax调用：</p>
<pre>var xhrHandler = dojo.xhrGet({url:this.url,
  handleAs:"json-comment-optional", content:serverQuery});
xhrHandler.addCallback(dojo.hitch(this, function(data){
  this._xhrFetchHandler(data, request, fetchHandler, errorHandler);
}));
xhrHandler.addErrback(function(error){
  errorHandler(error, request);
});</pre>
<p>addCallback时，如果deferred已经完成，则传入的function被立刻执行。所以如果上面的xhrGet很快执行完成，则加入的callback也会被执行（这个时候消息队列为空），如同代码顺序执行。如果xhrGet较长时间完成，则加入的callback会有异步运行的效果。</p>
<p>上面的代码感觉很奇特，有种时空的错觉。如果dojo.xhrGet(..).addCallback(&#8230;).addCallback(&#8230;)则好点。</p>
<p>这个东西叫Promise，在CommonJS有单独的列出来，写法可以这样requestData(&#8220;foo.bar.com&#8221;).then(&#8230;).then()，看上去直观了很多。新的Dojo.js语法里面也有这个东西，不算新，只是我对Promise<strong>这个词</strong>很感兴趣，还有Future。</p>
<p>当命名一个抽象概念时，名字很重要啊！</p>
<p>后来搜了下，原来Future在java中也有这个<a href="http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Future.html">概念</a>，可以参考这篇<a href="http://www.cnblogs.com/uptownBoy/articles/1772483.html">中文的文章</a>（把callback和actor鄙视了一通），大体上讲就是把一个异步的程序转为顺序的写法：</p>
<pre>   ExecutorService executor = ...//copy from jdk doc
   ArchiveSearcher searcher = ...
   void showSearch(final String target)
       throws InterruptedException {
     Future&lt;String&gt; future
       = executor.submit(new Callable&lt;String&gt;() {
         public String call() {
             return searcher.search(target);
         }});
     displayOtherThings(); // do other things while searching
     try {
       displayText(future.get()); // use future 这个地方会被block
     } catch (ExecutionException ex) { cleanup(); return; }</pre>
<p>如果会被block的话，还有啥意义呢？不过代码的逻辑清楚很多。</p>
<p>正式的解释在wikipeida上面有：http://en.wikipedia.opreiki/Futures_and_promises Futures and promises.</p>
<p>看<a href="http://www.sitepen.com/blog/2010/05/03/robust-promises-with-dojo-deferred-1-5/">这篇</a>dojo tutorial，你发现原来dojo.then其实对应上面的future，也就是一个包含返回数据的对象（js不需要用<em>get</em>方法），dojo.when的用处就是使普通的数据和“将来”的数据统一使用。Wikipedia对java需要get的方式为显式的future，而dojo的为隐式的。</p>
<p>在Actor模式中也会用到future，具体参考Akka的<a href="http://akka.io/docs/akka/1.1/java/futures.html">这篇</a>文档。（Akka的文档比Scala完善很多，而且有java的版本，上手很容易。上面说Future is Monad，晕啊）</p>
<pre>Future[Object] future = actorRef.sendRequestReplyFuture[Object](msg);
Object result = future.get(); //Block until result is available, usually bad practice</pre>
<p>actor之间可以用message来访问，上面的方式方便了非actor访问actor。如果系统明确的划分成几个Actor，则future使用的地方很少。</p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2011/07/25/promise-future-dojo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>在对象集合中查找</title>
		<link>http://fkpwolf.net/2011/01/17/query-in-object-collection/</link>
		<comments>http://fkpwolf.net/2011/01/17/query-in-object-collection/#comments</comments>
		<pubDate>Mon, 17 Jan 2011 02:47:20 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[Language]]></category>

		<guid isPermaLink="false">http:///?p=888</guid>
		<description><![CDATA[最近写代码时经常遇到在一个Collection中找某个符合条件的元素。比如我要“在这些书中找到《编程之魂》”，这个简单算法在Java中得这么写： private static Book getBookByName(List&#60;Book&#62; all, String bookName){ for ( Book b : all) { String bName = b.getName(); if ( bName.equals(bookName) ){ return b; } } } 大段的代码会打断工作的“流”：你不得不停下刚才的想法而先完成这个任务，这势必会影响效率。.NET中有个先进的玩意LINQ，用类似SQL的语法来操作collectio而不是常见的关系数据库。有了SQL语法，当然可以生成比上面复杂多的查询条件。Java开发人员只能羡慕了：在函数式编程方面，C#走在了Java前面。 Javascript中也有同样的问题，看了下jQuery，它有个方法jQuery.grep： var arr = [ 1, 9, 3, 8, 6, 1, 5, 9, 4, 7, 3, 8, 6, 9, 1 ]; arr = jQuery.grep(arr, function(n, i){ [...]]]></description>
			<content:encoded><![CDATA[<p>最近写代码时经常遇到在一个Collection中找某个符合条件的元素。比如我要“在这些书中找到《编程之魂》”，这个简单算法在Java中得这么写：</p>
<pre class="brush:java">private static Book getBookByName(List&lt;Book&gt; all, String bookName){
  for ( Book b : all) {
    String bName = b.getName();
    if ( bName.equals(bookName) ){
      return b;
    }
  }
}</pre>
<p>大段的代码会打断工作的“流”：你不得不停下刚才的想法而先完成这个任务，这势必会影响效率。.NET中有个先进的玩意LINQ，用类似SQL的语法来操作collectio而不是常见的关系数据库。有了SQL语法，当然可以生成比上面复杂多的查询条件。Java开发人员只能<a href="http://stackoverflow.com/questions/346721/linq-for-java-tool">羡慕</a>了：在函数式编程方面，C#走在了Java前面。</p>
<p>Javascript中也有同样的问题，看了下jQuery，它有个方法<a href="http://api.jquery.com/jQuery.grep/">jQuery.grep</a>：</p>
<pre class="brush:javascript">var arr = [ 1, 9, 3, 8, 6, 1, 5, 9, 4, 7, 3, 8, 6, 9, 1 ];
arr = jQuery.grep(arr, function(n, i){
  return (n != 5 &amp;&amp; i &gt; 4);
});
// return 1, 9, 4, 7, 3, 8, 6, 9, 1</pre>
<p>闭包的优势就体现出来了。而Java没有闭包，所以得整匿名函数。<a href="http://code.google.com/p/guava-libraries/">Google Guava</a>扩展了JDK引以为豪的Java Collection框架（看看Guava的其他扩展，Java老矣），其中有个方法Iterables.filter(Iterable&lt;T&gt; unfiltered, Predicate&lt;? super T&gt; predicate)，实现了跟上面类似的功能。匿名函数实现起来就比闭包麻烦了。</p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2011/01/17/query-in-object-collection/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Asynchronous Javascript</title>
		<link>http://fkpwolf.net/2010/10/14/asynchronous-javascript/</link>
		<comments>http://fkpwolf.net/2010/10/14/asynchronous-javascript/#comments</comments>
		<pubDate>Thu, 14 Oct 2010 03:57:57 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Language]]></category>
		<category><![CDATA[Web Development]]></category>

		<guid isPermaLink="false">http:///?p=829</guid>
		<description><![CDATA[本来以为Javascript是有异步机制的，后来发现其实大多数的实现都是使用setTimeout + callback，单单使用callback是不能达到异步的，比如： // callback style: function renderLotsOfData(data, callback){ var success = false try{ for(var x in data){ renderDataitem(data[x]); } success = true; }catch(e){ } if(callback){ callback(success); } } // using callback style renderLotsOfData(someDataObj, function(success){ // handles success or failure if(!success){ promptUserToRecover(); } }); renderOthers(); renderOthers必须等到callback函数运行完后再触发，所以其实这里是block的，只是callback的使用有“代码段”上的异步的感觉。 dojo.Defferred乍看很神秘，其实只不过是对callback函数的管理，可以有callback函数链的效果，也使复杂的情况下的编码更容易理解。 有些地方使用Node.js的方法process.nextTick来实现异步，文档里面简单的说“This is not a simple alias to setTimeout(fn, [...]]]></description>
			<content:encoded><![CDATA[<p>本来以为Javascript是有异步机制的，后来发现其实大多数的实现都是使用setTimeout + callback，单单使用callback是不能达到异步的，比如：</p>
<pre lang="javascript">	// callback style:
	function renderLotsOfData(data, callback){
		var success = false
		try{
			for(var x in data){
				renderDataitem(data[x]);
			}
			success = true;
		}catch(e){ }
		if(callback){
			callback(success);
		}
	}
	// using callback style
	renderLotsOfData(someDataObj, function(success){
		// handles success or failure
		if(!success){
			promptUserToRecover();
		}
	});
	renderOthers();</pre>
<p>renderOthers必须等到callback函数运行完后再触发，所以其实这里是block的，只是callback的使用有“代码段”上的异步的感觉。</p>
<p><a href="http://www.dojotoolkit.org/api/dojo/Deferred.html">dojo.Defferred</a>乍看很神秘，其实只不过是对callback函数的管理，可以有callback函数链的效果，也使复杂的情况下的编码更容易理解。</p>
<p>有些<a href="http://caolanmcmahon.com/async_in_node_js.html">地方</a>使用Node.js的方法<a href="http://nodejs.org/api.html#process-nexttick-76">process.nextTick</a>来实现异步，文档里面简单的说“This is not a simple alias to setTimeout(fn, 0), it&#8217;s much more efficient.” 具体能做到多高效不得而知。而且Node.js虽然很cool，也只能在server端使用。所以感觉js中真正的异步也只有AJAX了，当然，大多数的异步要求也围绕request/response。</p>
<p>最好的方案大概是使用event的subscribe/publish模式了，这在Dojo和Node.js中都大量使用。要在Java中实现这种“异步的Observer模式”需要使用Executor的线程技术，不过由于缺少闭包，这时候模式的使用看上去更像为了弥补语言的缺陷。</p>
<p>Node.js号称任何东西都是异步的，比如I/O的操作，并以此获得Scalability。很多人对此表示怀疑，争论最后变为event和thread这两种模式的比较。<a href="http://al3x.net/2010/07/27/node.html">Node and Scaling in the Small vs Scaling in the Large</a>这篇指出scaling在大型系统上是综合的考虑，没有哪一种技术是“银弹”，或者说技术的选择已经无关紧要，架构或者设计才是重要的。当然这是冷静的思考，不过Node.js现在版本才0.48，大概没有人会用在大型系统中吧。我觉得event模式优点在于逻辑清晰，而thread代码复杂，难以维护。</p>
<p><span style="text-decoration: line-through;">感觉语法级别的异步和并发也只有java能做到了，也是久经考验的。Node.js的稳定性则依赖chrome V8引擎的c++代码，多少有点不靠谱，</span>但是javascript语法灵活，这是极大优点<span style="text-decoration: line-through;">。Ruby如果要使用异步还的靠第三方包，不过一般的web应用对这方面也不需要，php啥都没有，照样十分流行。</span></p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2010/10/14/asynchronous-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《Real World Haskell》读书笔记</title>
		<link>http://fkpwolf.net/2010/04/07/reading-notes-real-world-haskell/</link>
		<comments>http://fkpwolf.net/2010/04/07/reading-notes-real-world-haskell/#comments</comments>
		<pubDate>Wed, 07 Apr 2010 02:24:50 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[Language]]></category>

		<guid isPermaLink="false">http:///?p=712</guid>
		<description><![CDATA[这本书还是不错的，举了很多例子，学起来容易多了。 1). Lambda。书上讲的比较少，其实有个例子就很清楚。show me the code: Input: map (\x -&#62; 3*x + x/4) [1,2,3,4] Output: [3.25,6.5,9.75,13.0] Input: foldr1 (\x y -&#62; 2*x + y) [1,2,3,4] Output: 16 2. Multiple Return Value。指一个函数可以返回多个值。Haskell中使用Tuple，大小为2的tuple为pair，这比创建一个这些值的容器类更灵活，语法上更直观，比如result, ok = add(11, 22)，这里ok可以用来指示程序运行是否有异常，在Go语言这种语法用来弥补C的不足。Haskell因为是静态类型的，所以这些Tuple都是有类型约束的；Go中则还可以对参数命名，这样函数的定义更加规范。 3. Pattern Matching. Twitter.]]></description>
			<content:encoded><![CDATA[<p>这本书还是不错的，举了很多例子，学起来容易多了。</p>
<p>1). <strong>Lambda</strong>。书上讲的比较少，其实有个例子就很清楚。show me the code:</p>
<p>Input: map (\x -&gt; 3*x + x/4) [1,2,3,4]</p>
<p>Output: [3.25,6.5,9.75,13.0]</p>
<p>Input: foldr1 (\x y -&gt; 2*x + y) [1,2,3,4]</p>
<p>Output: 16</p>
<p>2. <strong>Multiple Return Value</strong>。指一个函数可以返回多个值。Haskell中使用Tuple，大小为2的tuple为pair，这比创建一个这些值的容器类更灵活，语法上更直观，比如result, ok = add(11, 22)，这里ok可以用来指示程序运行是否有异常，在Go语言这种语法用来<a href="http://www.infoq.com/cn/articles/google-go-primer">弥补C的不足</a>。Haskell因为是静态类型的，所以这些Tuple都是有类型约束的；Go中则还可以对参数命名，这样函数的定义更加规范。</p>
<p>3. <strong>Pattern Matching</strong>. Twitter.</p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2010/04/07/reading-notes-real-world-haskell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>多语言开发</title>
		<link>http://fkpwolf.net/2010/01/02/%e5%a4%9a%e8%af%ad%e8%a8%80%e5%bc%80%e5%8f%91/</link>
		<comments>http://fkpwolf.net/2010/01/02/%e5%a4%9a%e8%af%ad%e8%a8%80%e5%bc%80%e5%8f%91/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 00:44:42 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[Language]]></category>

		<guid isPermaLink="false">http:///?p=577</guid>
		<description><![CDATA[最近看Thoughworks的《软件开发沉思录》，《卓有成效的程序员》，还有一本老书：O&#8217;Reilly的《超越Java》。 这几本书都提出一个观点：Java已经老矣，是时候该用多语言来编程了，试试ruby, haskell这些语言吧。]]></description>
			<content:encoded><![CDATA[<p>最近看Thoughworks的《软件开发沉思录》，《卓有成效的程序员》，还有一本老书：O&#8217;Reilly的《超越Java》。</p>
<p>这几本书都提出一个观点：Java已经老矣，是时候该用多语言来编程了，试试ruby, haskell这些语言吧。</p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2010/01/02/%e5%a4%9a%e8%af%ad%e8%a8%80%e5%bc%80%e5%8f%91/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>实现DSL的几个例子</title>
		<link>http://fkpwolf.net/2009/12/31/example-of-dsl/</link>
		<comments>http://fkpwolf.net/2009/12/31/example-of-dsl/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 08:24:43 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[Language]]></category>

		<guid isPermaLink="false">http:///?p=552</guid>
		<description><![CDATA[所谓DSL就是能描述语言的语言，一般某些领域都有自己的专有术语，用这些术语来交流比一般的通用的语言更流畅，比如象棋的“平五进八”，这种走棋的表达比自然语言更快，DSL就是把这种领域的语言翻译成“自然语言”的模型。一般有内部和外部之分，内部指领域语言嵌入在自然语言中用自然语言表达，相当于从“古文”中进化出“普通话”的过程；外部则指全新的语言，比如Java, C等，是一个全新的描述模型，创造起来比内部要复杂。举几个例子容易明白，下面几个是内部的DSL。 使用连贯接口 这是&#8221;The productive Programmer&#8221;中的例子，要描述的领域是“食谱”。比如“recipe.add 200.grams.of Flour”。 class Numeric def gram self end alias_method :grams, :gram end Ruby可以打开一个存在的类向其中添加方法，所以可以写出200.grams这种有点恶心的句子，而且ruby中方法可以不加括号（），光这点用Java实现就够呛。不过用method chain会使用很多点点点，有点像人没有进化完全而留下点阑尾&#8230; 这种open class的做法在其他语言中也可以遇到。Javascript中是直接修改类的prototype，Objective-C中也可以，比如扩展NSString使其可以转化为Json格式。但是Open class也有问题，因为Open class直接修改了原来的类，这会蔓延到整个类型系统，违反了模块化和封装的原则，所以这个修改最后只在某个范围内有效。 下面这个例子来自&#8221;Programming Scala Tackle Multi-Core Complexity on the Java Virtual Machine&#8221;，要描述的领域为“时间”，比如“2 days ago”。 object App { def main(args : Array[String]) : Unit = { implicit def convertInt2DateHelper(number: Int) = new DateHelper(number) val [...]]]></description>
			<content:encoded><![CDATA[<p>所谓DSL就是能描述语言的语言，一般某些领域都有自己的专有术语，用这些术语来交流比一般的通用的语言更流畅，比如象棋的“平五进八”，这种走棋的表达比自然语言更快，DSL就是把这种领域的语言翻译成“自然语言”的模型。一般有内部和外部之分，内部指领域语言嵌入在自然语言中用自然语言表达，相当于从“古文”中进化出“普通话”的过程；外部则指全新的语言，比如Java, C等，是一个全新的描述模型，创造起来比内部要复杂。举几个例子容易明白，下面几个是内部的DSL。</p>
<li>使用连贯接口</li>
<p>这是&#8221;The productive Programmer&#8221;中的例子，要描述的领域是“食谱”。比如“recipe.add 200.grams.of Flour”。</p>
<pre class="brush:ruby">class Numeric
  def gram
   self
  end

  alias_method :grams, :gram
end</pre>
<p>Ruby可以打开一个存在的类向其中添加方法，所以可以写出200.grams这种有点恶心的句子，而且ruby中方法可以不加括号（），光这点用Java实现就够呛。不过用method chain会使用很多点点点，有点像人没有进化完全而留下点阑尾&#8230;</p>
<p>这种open class的做法在其他语言中也可以遇到。Javascript中是直接修改类的prototype，Objective-C中也可以，比如扩展NSString使其可以转化为Json格式。但是<a href="http://www.infoq.com/articles/ruby-open-classes-monkeypatching">Open class也有问题</a>，因为Open class直接修改了原来的类，这会蔓延到整个类型系统，违反了模块化和封装的原则，所以这个修改最后只在某个范围内有效。</p>
<li>下面这个例子来自&#8221;Programming Scala Tackle Multi-Core Complexity on the Java Virtual Machine&#8221;，要描述的领域为“<strong>时间</strong>”，比如“2 days ago”。</li>
<pre class="brush:ruby">object App
{
  def main(args : Array[String]) : Unit =
  {
    implicit def convertInt2DateHelper(number: Int) = new DateHelper(number)
	val ago = "ago"
	val from_now = "from_now"
	val past = 2 days ago
	val appointment = 5 days from_now
	println(past)
	println(appointment)
  }

	import java.util._
	class DateHelper(number: Int) {
		def days(when: String) : Date = {
			var date = Calendar.getInstance()
			when match {
				case "ago" =&gt; date.add(Calendar.DAY_OF_MONTH, -number)
				case "from_now" =&gt; date.add(Calendar.DAY_OF_MONTH, number)
				case _ =&gt; date
			}
			date.getTime()
		}
  	}
}</pre>
<p>这里面当Scala遇到Int类型的2时，会自动的选择implicit的方法把这个整数转换为DateHelper类，不清楚这是语言的功能还是VM的特征，这里并没有扩展Int类型：加上days的方法。Scala有个Traits的功能，倒是可以扩展类，暂时不大清楚。</p>
<li>计算器</li>
<p>这里有讲到：<a href="http://www.ibm.com/developerworks/cn/java/j-scala08268.html">面向 Java 开发人员的 Scala 指南: 构建计算器，第 1 部分</a> 解决如何计算如((5 * 10) + 7)这样的表达式。这倒是一个DSL的好例子，不过文章最后把核心问题交给了Becker-Naur Form（BNF），这就有点走向外部DSL的，这么简单的表达式也很难搞，看来内部DSL不能描述复杂的语法结构，高级一点的又得求助于语法解析器。</p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2009/12/31/example-of-dsl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>我对CPS的理解</title>
		<link>http://fkpwolf.net/2009/12/07/my-understanding-on-cps/</link>
		<comments>http://fkpwolf.net/2009/12/07/my-understanding-on-cps/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 09:43:37 +0000</pubDate>
		<dc:creator>Fan Fan</dc:creator>
				<category><![CDATA[Language]]></category>

		<guid isPermaLink="false">http:///?p=519</guid>
		<description><![CDATA[最近学习Haskell，我看的是Yet Another Haskell Tutorial，看到CPS，发现这本书写的很难懂，不知所云。后来看了wikibooks上面的文章，明白了一些。这里是一个总结，也还不错。 CPS到底是个啥？拿例子看比较容易。比较如下代码： add (square x) (square y) 和CAS style的： pythagoras'cps x y k = square'cps x $ \x'squared -&#62; square'cps y $ \y'squared -&#62; add'cps x'squared y'squared $ \sum'of'squares -&#62; k sum'of'squares CPS有点像倒置过来的写法，而前者则是普通的堆栈的写法。那这样CPS有什么有优点呢？ 在Java中类似的写法有stringBuffer.append(&#8220;A&#8221;).append(&#8220;B&#8221;).append(&#8220;C&#8221;)，IO API中好像也有类似的方法。（在《The Productive Programmer》里面管这个叫做连贯接口 fluent interface&#8230;） 感觉有点类似管道（pipe），前面的square把结果（这里就是k）传到下一个function，这样一个个串联起来，而k起了连接的作 用。而像add( square(x), square(y))这种方式每个func相当独立(primitive)，最后有一个组合(mash-up)的过程。 而这种方式才让“从某个点停止，然后继续执行”成为可能，因为这样没有堆栈。add( square(x), square(y))这种方式会生成临时变量，会有running context。而pipe某个节点的状态就是pipe的全部，是继续“流”下去所需的所有内容，这个function是可以“重入”的。这里“流”下去就是“延续”的意思。 这种状态保存其实很多地方都有，比如http session，比如进程上下文（进程也可以sleep后再重新载入，或者恢复），但是CPS则粒度更细，可以在代码级上的重新载入，“重入”精确到某行代码。而Spring web flow这种流程级的则是精确到了flow中的某个节点，比较代码级的天书一样的代码，流程级的引入进来还是比较好的一个折中。当然这样的话，跟CPS就关系不大了。 我很早前读过跨越边界: [...]]]></description>
			<content:encoded><![CDATA[<p>最近学习Haskell，我看的是<a href="http://darcs.haskell.org/yaht/yaht.pdf">Yet Another Haskell Tutorial</a>，看到CPS，发现这本书写的很难懂，不知所云。后来看了wikibooks上面的<a href="http://en.wikibooks.org/wiki/Haskell/Continuation_passing_style">文章</a>，明白了一些。<a href="http://www.haskell.org/haskellwiki/Continuation">这里</a>是一个总结，也还不错。</p>
<p>CPS到底是个啥？拿例子看比较容易。比较如下代码：<br />
<code>add (square x) (square y)</code><br />
和CAS style的：<br />
<code> pythagoras'cps x y k =<br />
square'cps x $ \x'squared -&gt;<br />
square'cps y $ \y'squared -&gt;<br />
add'cps x'squared y'squared $ \sum'of'squares -&gt;<br />
k sum'of'squares</code></p>
<p>CPS有点像倒置过来的写法，而前者则是普通的堆栈的写法。那这样CPS有什么有优点呢？</p>
<p>在Java中类似的写法有stringBuffer.append(&#8220;A&#8221;).append(&#8220;B&#8221;).append(&#8220;C&#8221;)，IO API中好像也有类似的方法。（在《The Productive Programmer》里面管这个叫做连贯接口 fluent interface&#8230;）</p>
<p>感觉有点类似管道（pipe），前面的square把结果（这里就是k）传到下一个function，这样一个个串联起来，而k起了连接的作 用。而像add( square(x), square(y))这种方式每个func相当独立(primitive)，最后有一个组合(mash-up)的过程。</p>
<p>而这种方式才让“从某个点停止，然后继续执行”成为可能，因为这样没有堆栈。add( square(x), square(y))这种方式会生成临时变量，会有running context。而pipe某个节点的状态就是pipe的全部，是继续“流”下去所需的所有内容，这个function是可以“重入”的。这里“流”下去就是“延续”的意思。</p>
<p>这种状态保存其实很多地方都有，比如http session，比如进程上下文（进程也可以sleep后再重新载入，或者恢复），但是CPS则粒度更细，可以在代码级上的重新载入，“重入”精确到某行代码。而Spring web flow这种流程级的则是精确到了flow中的某个节点，比较代码级的天书一样的代码，流程级的引入进来还是比较好的一个折中。当然这样的话，跟CPS就关系不大了。</p>
<p>我很早前读过<a href="http://www.ibm.com/developerworks/cn/java/j-cb03216/">跨越边界: 延续、Web 开发和 Java 编程</a>，当时不甚理解，现在拿Haskell做例子，才明白原来这里面实现起来还是很绕的。</p>
]]></content:encoded>
			<wfw:commentRss>http://fkpwolf.net/2009/12/07/my-understanding-on-cps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

