<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1825468319952057680</id><updated>2024-10-24T16:41:52.503-07:00</updated><category term="Haskell"/><category term="parsec參考"/><category term="一致化"/><category term="參考資料"/><category term="字碼處理"/><category term="推論程序"/><category term="流程控制"/><category term="語法"/><title type='text'>墨辯：中文邏輯語言</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-8647872528609990702</id><published>2016-06-28T23:12:00.000-07:00</published><updated>2016-06-28T23:12:25.187-07:00</updated><title type='text'>墨辨主架構</title><content type='html'>墨辨直譯器&lt;br /&gt;
墨辨IDE</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/8647872528609990702/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2016/06/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/8647872528609990702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/8647872528609990702'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2016/06/blog-post.html' title='墨辨主架構'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-1836394211961809495</id><published>2016-03-08T01:47:00.000-08:00</published><updated>2016-03-08T01:47:12.606-08:00</updated><title type='text'>被動式</title><content type='html'>語言為何要有被動式，動作是句子述語的主要部分，動作有發動者及接受者之分，若發動者不重要，我們使用被動式省略發動者，強調動作接受都。&lt;br /&gt;
&lt;br /&gt;
我被親了。被誰親不重要。</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/1836394211961809495/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2016/03/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/1836394211961809495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/1836394211961809495'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2016/03/blog-post.html' title='被動式'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-2996579382335067590</id><published>2014-01-01T16:32:00.002-08:00</published><updated>2014-01-01T16:50:12.492-08:00</updated><title type='text'>Scheme 語言概要</title><content type='html'>简介： Scheme语言是LISP语言的一个方言(或说成变种)，它诞生于1975年的MIT，对于这个有近三十年历史的编程语言来说，它并没有象C++，java，C#那样受到商业领域的青睐，在国内更是显为人知。但它在国外的计算机教育领域内却是有着广泛应用的，有很多人学的第一门计算机语言就是Scheme语言。&lt;br /&gt;
&lt;br /&gt;
作为Lisp 变体，Scheme 是一门非常简洁的计算语言，使用它的编程人员可以摆脱语言本身的复杂性，把注意力集中到更重要的问题上，从而使语言真正成为解决问题的工具。本文分为上、 &lt;a href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html&quot;&gt;下&lt;/a&gt;两部分来介绍 scheme 语言。&lt;br /&gt;
&lt;div id=&quot;ibm-content-body&quot; style=&quot;background-attachment: scroll; background-image: none; background-position: 0px 0px; background-repeat: no-repeat no-repeat; clear: both; padding: 15px 0px; width: 930px;&quot;&gt;
&lt;div id=&quot;ibm-content-main&quot; style=&quot;clear: left; float: left; padding-left: 10px; width: 710px;&quot;&gt;
&lt;div class=&quot;ibm-container&quot; style=&quot;margin: 0px 0px 1.2em; width: 710px;&quot;&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;1&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;一．Scheme语言的特点&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言是LISP语言的一个方言(或说成变种)，它诞生于1975年的MIT，对于这个有近三十年历史的编程语言来说，它并没有象C++，java，C#那样受到商业领域的青睐，在国内更是显为人知。但它在国外的计算机教育领域内却是有着广泛应用的，有很多人学的第一门计算机语言就是Scheme语言。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
它是一个小巧而又强大的语言，作为一个多用途的编程语言，它可以作为脚本语言使用，也可以作为应用软件的扩展语言来使用，它具有元语言特性，还有很多独到的特色,以致于它被称为编程语言中的&quot;皇后&quot;。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面是洪峰对Scheme语言的编程特色的归纳：&lt;/div&gt;
&lt;ul style=&quot;background-color: white; font-size: 0.76em; margin-bottom: 0px; margin-top: 0px; padding-bottom: 5px; padding-right: 5px; padding-top: 0px;&quot;&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;词法定界（Lexical Scoping）&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;动态类型（Dynamic Typing）&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;良好的可扩展性&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;尾递归（Tail Recursive）&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;函数可以作为值返回&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;支持一流的计算连续&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;传值调用（passing-by-value）&lt;/li&gt;
&lt;li style=&quot;font-family: arial, nsimsun, sans-serif; margin-bottom: 0px; margin-top: 0px; padding-bottom: 3px; padding-right: 5px; padding-top: 0px;&quot;&gt;算术运算相对独立&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
本文的目的是让有编程基础（那怕是一点点）的朋友能尽快的掌握Scheme语言的语法规则，如果您在读完本文后，发现自己已经会用Scheme语言了，那么我的目的就达到了。&lt;/div&gt;
&lt;div class=&quot;ibm-alternate-rule&quot; style=&quot;background-color: white; background-image: url(http://1.www.s81c.com/i/solid.gif); clear: both; height: 1px;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;ibm-ind-link ibm-back-to-top&quot; style=&quot;background-color: white; clear: both; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; height: 15px; padding: 5px; text-align: right;&quot;&gt;
&lt;a class=&quot;ibm-anchor-up-link&quot; href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index1.html#ibm-pcon&quot; style=&quot;background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-position: 0px -1px; background-repeat: no-repeat no-repeat; color: #996699; display: inline; font-weight: bold; margin: 0px; padding: 0px 0px 0px 18px; text-decoration: none;&quot;&gt;回页首&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;2&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;二．Scheme语言的标准与实现&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;N10071&quot;&gt;&lt;span class=&quot;smalltitle&quot; style=&quot;font-size: 1.2em; font-weight: bold;&quot;&gt;R5RS (Revised(5) Report on the Algorithmic Language Scheme)&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言的语法规则的第5次修正稿，1998年制定，即Scheme语言的现行标准，目前大多数Scheme语言的实现都将达到或遵循此标准，并且几乎都加入了一些属于自己的扩展特色。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;N1007A&quot;&gt;&lt;span class=&quot;smalltitle&quot; style=&quot;font-size: 1.2em; font-weight: bold;&quot;&gt;Guile (GNU&#39;s extension language)&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Guile是GNU工程的一个项目，它是GNU扩展语言库，它也是Scheme语言的一个具体实现；如果你将它作为一个库打包，可以把它链接到你的应用程序中去，使你的应用程序具有自己的脚本语言，这个脚本语言目前就是Scheme语言。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Guile可以在LINUX和一些UNIX系统上运行，下面是简单的安装过程：&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下载guile-1.6.4版，文件名为guile-1.6.4.tar.gz，执行下面的命令：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;tar xvfz guile-1.6.4.tar.gz
cd guile-1.6.4
./configure
make
make install
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如此，即可以执行命令guile，进入guile&amp;gt;提示符状态，输入调试Scheme程序代码了，本文的所有代码都是在guile下调试通过。&lt;br /&gt;
&lt;br /&gt;
其它实现&lt;br /&gt;
&lt;br /&gt;
除了Guile外，Scheme语言的实现还有很多，如：GNU/MIT-Scheme， SCI，Scheme48，DrScheme等，它们大多是开源的，可以自由下载安装使用，并且跨平台的实现也很多。你会发现既有象basic的Scheme语言解释器，也有将Scheme语言编译成C语言的编译器，也有象JAVA那样将Scheme语言代码编译成虚拟机代码的编译器。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;三．基本概念&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;注释&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Scheme语言中的注释是单行注释，以分号[;]开始一直到行尾结束，其中间的内容为注释，在程序运行时不做处理，如：&lt;/div&gt;
&lt;div class=&quot;ibm-container&quot; style=&quot;margin: 0px 0px 1.2em; width: 710px;&quot;&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  ; this is a scheme comment line.
  &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
标准的Scheme语言定义中没有多行注释，不过在它的实现中几乎都有。在Guile中就有多行注释，以符号组合&quot;#!&quot;开始，以相反的另一符号组合&quot;!#&quot;结束，其中内容为注释，如：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;#!
there are scheme comment area.
you can write mulity lines here . 
!#
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
注意的是，符号组合&quot;#!&quot;和&quot;!#&quot;一定分做两行来写。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Scheme用做脚本语言&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Scheme语言可以象sh，perl，python等语言那样作为一种脚本语言来使用，用它来编写可执行脚本，在Linux中如果通过Guile用Scheme语言写可执行脚本，它的第一行和第二行一般是类似下面的内容：&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;#! /usr/local/bin/guile -s
!#&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这样的话代码在运行时会自动调用Guile来解释执行，标准的文件尾缀是&quot;.scm&quot;。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;块(form)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
块(form)是Scheme语言中的最小程序单元，一个Scheme语言程序是由一个或多个form构成。没有特殊说明的情况下 form 都由小括号括起来，形如：&lt;/div&gt;
&lt;div class=&quot;ibm-container&quot; style=&quot;margin: 0px 0px 1.2em; width: 710px;&quot;&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define x 123)
(+ 1 2)
(* 4 5 6)
(display &quot;hello world&quot;)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
一个 form 也可以是一个表达式，一个变量定义，也可以是一个过程。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;form嵌套&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Scheme语言中允许form的嵌套，这使它可以轻松的实现复杂的表达式，同时也是一种非常有自己特色的表达式。 下图示意了嵌套的稍复杂一点的表达式的运算过程：&lt;span style=&quot;background-color: white; padding-bottom: 0.7em; padding-top: 0.3em;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;283&quot; src=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/images/image001.png&quot; style=&quot;border: 0px; padding: 0.3em 5px 0.7em;&quot; width=&quot;336&quot; /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;变量定义&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
可以用define来定义一个变量，形式如下： &lt;br /&gt;
(define 变量名 值)&lt;br /&gt;
&lt;br /&gt;
如： (define x 123) ，定义一个变量x，其值为123。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;更改变量的值&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
可以用set!来改变变量的值，格式如下： &lt;br /&gt;
(set! 变量名 值)&lt;br /&gt;
&lt;br /&gt;
如： (set! x &quot;hello&quot;) ，将变量x的值改为&quot;hello&quot; 。&lt;br /&gt;
&lt;br /&gt;
Scheme语言是一种高级语言，和很多高级语言(如python，perl)一样，它的变量类型不是固定的，可以随时改变。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;四．数据类型&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;N10113&quot;&gt;&lt;span class=&quot;smalltitle&quot; style=&quot;font-size: 1.2em; font-weight: bold;&quot;&gt;1. 简单数据类型&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;逻辑型(boolean)&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
最基本的数据类型，也是很多计算机语言中都支持的最简单的数据类型，只能取两个值：#t，相当于其它计算机语言中的 TRUE；#f，相当于其它计算机语言中的 FALSE。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中的boolean类型只有一种操作：not。其意为取相反的值，即：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  (not #f) =&amp;gt; #t
  (not #t) =&amp;gt; #f
  &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
not的引用，与逻辑非运算操作类似&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (not 1)
#f
guile&amp;gt; (not (list 1 2 3))
#f
guile&amp;gt; (not &#39;a)
#f
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
从上面的操作中可以看出来，只要not后面的参数不是逻辑型，其返回值均为#f。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;数字型(number)&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
它又分为四种子类型：整型(integer)，有理数型(rational)，实型(real)，复数型(complex)；它们又被统一称为数字类型(number)。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
如：复数型(complex) 可以定义为 (define c 3+2i)&lt;br /&gt;
实数型（real）可以定义为 (define f 22/7)&lt;br /&gt;
有理数型（rational）可以定义为 (define p 3.1415)&lt;br /&gt;
整数型(integer) 可以定义为 (define i 123)&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中，数字类型的数据还可以按照进制分类，即二进制，八进制，十进制和十六进制，在外观形式上它们分别以符号组合 #b、 #o、 #d、 #x 来作为表示数字进制类型的前缀，其中表示十进制的#d可以省略不写，如：二进制的 #b1010 ，八进制的 #o567，十进制的123或 #d123，十六进制的 #x1afc 。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言的这种严格按照数学定理来为数字类型进行分类的方法可以看出Scheme语言里面渗透着很深的数学思想，Scheme语言是由数学家们创造出来的，在这方面表现得也比较鲜明。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;字符型(char)&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中的字符型数据均以符号组合 &quot;#\&quot; 开始，表示单个字符，可以是字母、数字或&quot;[ ! $ % &amp;amp; * + - . / : %lt; = &amp;gt; ? @ ^ _ ~ ]&quot;等等其它字符，如：&lt;br /&gt;
#\A 表示大写字母A，#\0表示字符0，&lt;br /&gt;
其中特殊字符有：#\space 表示空格符和 #\newline 表示换行符。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;符号型(symbol)&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
符号类型是Scheme语言中有多种用途的符号名称，它可以是单词，用括号括起来的多个单词，也可以是无意义的字母组合或符号组合，它在某种意义上可以理解为C中的枚举类型。看下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define a (quote xyz))  ;  定义变量a为符号类型，值为xyz
guile&amp;gt; a
xyz
guile&amp;gt; (define xyz &#39;a)  ; 定义变量xyz为符号类型，值为a
guile&amp;gt; xyz
a
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
此处也说明单引号&#39; 与quote是等价的，并且更简单一些。符号类型与字符串不同的是符号类型不能象字符串那样可以取得长度或改变其中某一成员字符的值，但二者之间可以互相转换。&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot;&gt;2. 复合数据类型&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
可以说复合数据类型是由基本的简单数据类型通过某种方式加以组合形成的数据类型，特点是可以容纳多种或多个单一的简单数据类型的数据，多数是基于某一种数学模型创建的。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
字符串(string) 由多个字符组成的数据类型，可以直接写成由双引号括起的内容，如：&quot;hello&quot; 。下面是Guile中的字符串定义和相关操作：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define name &quot;tomson&quot;)
guile&amp;gt; name
&quot;tomson&quot;
guile&amp;gt; (string-length name)  ; 取字符串的长度
6
guile&amp;gt; (string-set! name 0 #\g)  ; 更改字符串首字母(第0个字符)为小写字母g (#\g)
guile&amp;gt; name
&quot;gomson&quot;
guile&amp;gt; (string-ref name 3)  ; 取得字符串左侧第3个字符（从0开始）
#\s
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;br /&gt;
&lt;br /&gt;
字符串还可以用下面的形式定义：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.8em;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define other (string #\h #\e #\l #\l #\o ))
guile&amp;gt; other
&quot;hello&quot;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
字符串中出现引号时用反斜线加引号代替，如：&quot;abc\&quot;def&quot; 。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;点对(pair)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
我把它译成&quot;点对&quot;，它是一种非常有趣的类型，也是一些其它类型的基础类型，它是由一个点和被它分隔开的两个所值组成的。形如： (1 . 2) 或 (a . b) ，注意的是点的两边有空格。&lt;br /&gt;
&lt;br /&gt;
这是最简单的复合数据类型，同是它也是其它复合数据类型的基础类型，如列表类型（list）就是由它来实现的。&lt;br /&gt;
&lt;br /&gt;
按照Scheme语言说明中的惯例，以下我们用符号组合 &quot;=&amp;gt;&quot; 来表示表达式的值。&lt;br /&gt;
&lt;br /&gt;
它用cons来定义，如： (cons 8 9) =&amp;gt;(8 . 9)&lt;br /&gt;
&lt;br /&gt;
其中在点前面的值被称为 car ，在点后面的值被称为 cdr ，car和cdr同时又成为取pair的这两个值的过程，如：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define p (cons 4 5)) =&amp;gt; (4 . 5)
(car p)   =&amp;gt; 4
(cdr p)   =&amp;gt; 5
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
还可以用set-car! 和 set-cdr! 来分别设定这两个值：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(set-car! p &quot;hello&quot;)
(set-cdr! p &quot;good&quot;)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
如此，以前定义的 p 又变成了 (&quot;hello&quot; . &quot;good&quot;) 这个样子了。&lt;br /&gt;
&lt;br /&gt;
列表(list)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
列表是由多个相同或不同的数据连续组成的数据类型，它是编程中最常用的复合数据类型之一，很多过程操作都与它相关。下面是在Guile中列表的定义和相关操作：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define la (list 1 2 3 4 ))
guile&amp;gt; la
(1 2 3 4)
guile&amp;gt; (length la)  ; 取得列表的长度
4
guile&amp;gt; (list-ref la 3)  ; 取得列表第3项的值（从0开始）
4
guile&amp;gt; (list-set! la 2 99)  ; 设定列表第2项的值为99
99
guile&amp;gt; la
(1 2 99 4)
guile&amp;gt; (define y (make-list 5 6))  ;创建列表
guile&amp;gt; y
(6 6 6 6 6)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
make-list用来创建列表，第一个参数是列表的长度，第二个参数是列表中添充的内容；还可以实现多重列表，即列表的元素也是列表，如：(list (list 1 2 3) (list 4 5 6))。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;列表与pair的关系&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
回过头来，我们再看看下面的定义：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define a (cons 1 (cons 2 (cons 3 &#39;()))))
guile&amp;gt; a
(1 2 3)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
由上可见，a本来是我们上面定义的点对，最后形成的却是列表。事实上列表是在点对的基础上形成的一种特殊格式。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
再看下面的代码：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define ls (list 1 2 3 4))
guile&amp;gt; ls
(1 2 3 4)
guile&amp;gt; (list? ls)
#t
guile&amp;gt; (pair? ls)
#t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
由此可见，list是pair的子类型，list一定是一个pair，而pair不是list。&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (car ls)
1
guile&amp;gt; (cdr ls)
(2 3 4)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
其cdr又是一个列表，可见用于pair的操作过程大多可以用于list。&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt; guile&amp;gt; (cadr ls)   ; 此&quot;点对&quot;对象的cdr的car
2
guile&amp;gt; (cddr ls)   ; 此&quot;点对&quot;对象的cdr的cdr
(3 4)
guile&amp;gt; (caddr ls)   ; 此&quot;点对&quot;对象的cdr的cdr的car
3
guile&amp;gt; (cdddr ls)   ; 此&quot;点对&quot;对象的cdr的cdr的cdr
(4)
 &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
上在的操作中用到的cadr，cdddr等过程是专门对PAIR型数据再复合形成的数据操作的过程，最多可以支持在中间加四位a或d，如cdddr，caaddr等。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
下图表示了由pairs定义形成的列表：&lt;br /&gt;
&lt;span style=&quot;background-color: white; padding-bottom: 0.7em; padding-top: 0.3em;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;178&quot; src=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/images/image003.png&quot; style=&quot;border: 0px; padding: 0.3em 5px 0.7em;&quot; width=&quot;506&quot; /&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
这个列表可以由pair定义为如下形式：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define x (cons &#39;a (cons &#39;b (cons &#39;c (cons &#39;d &#39;())))))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
而列表的实际内容则为：(a b c d)&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
由pair类型还可以看出它可以轻松的表示树型结构，尤其是标准的二叉树。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;向量（vector）&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
可以说是一个非常好用的类型 ，是一种元素按整数来索引的对象，异源的数据结构，在占用空间上比同样元素的列表要少，在外观上：&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
列表示为： (1 2 3 4)&lt;br /&gt;
VECTOR表示为： #(1 2 3 4)&lt;br /&gt;
可以正常定义：(define v (vector 3 4 5))&lt;br /&gt;
也可以直接定义：(define v #(3 4 5))&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
vector是一种比较常用的复合类型，它的元素索引从0开始，至第 n-1 结束，这一点有点类似C语言中的数组。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
关于向量表（vector）的常用操作过程：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define v (vector 1 2 3 4 5))
guile&amp;gt; v
#(1 2 3 4 5)
guile&amp;gt; (vector-ref v 0) ; 求第n个变量的值
1
guile&amp;gt; (vector-length v)  ; 求vector的长度
5
guile&amp;gt; (vector-set! v 2 &quot;abc&quot;)  ; 设定vector第n个元素的值
guile&amp;gt; v
#(1 2 &quot;abc&quot; 4 5)
guile&amp;gt; (define x (make-vector 5 6))  ; 创建向量表
guile&amp;gt; x
#(6 6 6 6 6)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
make-vector用来创建一个向量表，第一个参数是数量，后一个参数是添充的值，这和列表中的make-list非常相似。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
我们可以看出，在Scheme语言中，每种数据类型都有一些基本的和它相关的操作过程，如字符串，列表等相关的操作，这些操作过程都很有规律，过程名的单词之间都用-号隔开，很容易理解。对于学过C++的朋友来说，更类似于某个对象的方法，只不过表现的形式不同了。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;N1021E&quot;&gt;&lt;span class=&quot;smalltitle&quot; style=&quot;font-size: 1.2em; font-weight: bold;&quot;&gt;3. 类型的判断、比较、运算、转换与方法&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;类型判断&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中所有判断都是用类型名加问号再加相应的常量或变量构成，形如：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(类型? 变量)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言在类型定义中有比较严格的界定，如在C语言等一些语言中数字0来代替逻辑类型数据False，在Scheme语言中是不允许的。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以下为常见的类型判断和附加说明：&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
逻辑型：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(boolean? #t) =&amp;gt; #t
(boolean? #f) =&amp;gt; #t 因为#t和#f都是boolean类型，所以其值为#t
(boolean? 2)  =&amp;gt; #f 因为2是数字类型，所以其值为 #f
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
字符型&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(char? #\space) =&amp;gt; #t
(char? #\newline) =&amp;gt; #t 以上两个特殊字符：空格和换行
(char? #\f)  =&amp;gt; #t 小写字母 f
(char? #\;)  =&amp;gt; #t 分号 ;
(char? #\5)  =&amp;gt; #t 字符 5 ，以上这些都是正确的，所以返回值都是 #t
(char? 5)  =&amp;gt; #f 这是数字 5 ，不是字符类型，所以返回 #f
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
数字型&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(integer? 1)  =&amp;gt; #t
(integer? 2345) =&amp;gt; #t
(integer? -90)  =&amp;gt; #t 以上三个数均为整数
(integer? 8.9)  =&amp;gt; #f   8.9不整数
(rational? 22/7) =&amp;gt; #t
(rational? 2.3)  =&amp;gt; #t
(real? 1.2)  =&amp;gt; #t
(real? 3.14159) =&amp;gt; #t
(real? -198.34)  =&amp;gt; #t 以上三个数均为实数型
(real? 23)  =&amp;gt; #t   因为整型属于实型
(number? 5) =&amp;gt; #t
(number? 2.345) =&amp;gt; #t
(number? 22/7) =&amp;gt; #t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
其它型&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(null? &#39;())  =&amp;gt; #t  ; null意为空类型，它表示为 &#39;() ，即括号里什么都没有的符号
(null? 5)  =&amp;gt; #f
(define x 123)  定义变量x其值为123
(symbol? x)  =&amp;gt; #f
(symbol? &#39;x)  =&amp;gt; #t  ; 此时 &#39;x 为符号x，并不表示变量x的值
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme语言中如此众多的类型判断功能，使得Scheme语言有着非常好的自省功能。即在判断过程的参数是否附合过程的要求。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;比较运算&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中可以用&amp;lt;，&amp;gt;，&amp;lt;=，&amp;gt;=，= 来判断数字类型值或表达式的关系，如判断变量x是否等于零，它的形式是这样的：(= x 0) ，如x的值为0则表达式的值为#t，否则为#f。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
还有下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(eqv? 34 34)   =&amp;gt;  #t
(= 34 34)      =&amp;gt;  #t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以上两个form功能相同，说明 eqv? 也可以用于数字的判断。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme语言中有三种相等的定义，两个变量正好是同一个对象；两个对象具有相同的值；两个对象具有相同的结构并且结构中的内容相同。除了上面提到的符号判断过程和eqv?外，还有eq?和equal?也是判断是否相等的过程。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;eq?，eqv?，equal?&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
eq?，eqv?和equal?是三个判断两个参数是否相等的过程，其中eq?和eqv?的功能基本是相同的，只在不同的Scheme语言中表现不一样。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
eq?是判断两个参数是否指向同一个对象，如果是才返回#t；equal?则是判断两个对象是否具有相同的结构并且结构中的内容是否相同，它用eq?来比较结构中成员的数量；equal?多用来判断点对，列表，向量表，字符串等复合结构数据类型。&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define v (vector 3 4 5))
guile&amp;gt; (define w #(3 4 5))  ; w和v都是vector类型，具有相同的值#(3 4 5)
guile&amp;gt; (eq? v w)
#f     ; 此时w和v是两个对象
guile&amp;gt; (equal? v w)
#t                  ; 符合equal?的判断要求
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以上操作说明了eq? 和equal? 的不同之处，下面的操作更是证明了这一点：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define x (make-vector 5 6))
guile&amp;gt; x
#(6 6 6 6 6)
guile&amp;gt; (eq? x x)    ; 是同一个对象，所以返回#t
#t
guile&amp;gt; (define z (make-vector 5 6))
guile&amp;gt; z
#(6 6 6 6 6)
guile&amp;gt; (eq? x z)    ; 不是同一个对象
#f
guile&amp;gt; (equal? x z)  ; 结构相同，内容相同，所以返回#t
#t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;算术运算&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中的运算符有：&lt;br /&gt;
+ , - , * , / 和 expt (指数运算)&lt;br /&gt;
其中 - 和 / 还可以用于单目运算，如：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(- 4)  =&amp;gt; -4
(/ 4)  =&amp;gt; 1/4
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
此外还有许多扩展的库提供了很多有用的过程，&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;max 求最大 (max 8 89 90 213)  =&amp;gt; 213
min 求最小 (min 3 4 5 6 7)  =&amp;gt; 3
abs 求绝对值 (abs -7) ==&amp;gt; 7
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
除了max，min，abs外，还有很多数学运算过程，这要根据你用的Scheme语言的运行环境有关，不过它们大多是相同的。在R5RS中规定了很多运算过程，在R5RS的参考资料中可以很容易找到。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;转换&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中用符号组合&quot;-&amp;gt;&quot;来标明类型间的转换（很象C语言中的指针）的过程，就象用问号来标明类型判断过程一样。下面是一些常见的类型转换过程：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (number-&amp;gt;string 123)  ; 数字转换为字符串
&quot;123&quot;
guile&amp;gt; (string-&amp;gt;number &quot;456&quot;)  ; 字符串转换为数字
456
guile&amp;gt; (char-&amp;gt;integer #\a)   ;字符转换为整型数，小写字母a的ASCII码值为96
97
guile&amp;gt; (char-&amp;gt;integer #\A)  ;大写字母A的值为65
65
guile&amp;gt; (integer-&amp;gt;char 97)  ;整型数转换为字符
#\a
guile&amp;gt; (string-&amp;gt;list &quot;hello&quot;)   ;字符串转换为列表
(#\h #\e #\l #\l #\o) 
guile&amp;gt; (list-&amp;gt;string (make-list 4 #\a)) ; 列表转换为字符串
&quot;aaaa&quot;
guile&amp;gt; (string-&amp;gt;symbol &quot;good&quot;)  ;字符串转换为符号类型
good
guile&amp;gt; (symbol-&amp;gt;string &#39;better)  ;符号类型转换为字符串
&quot;better&quot;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
五．过程定义&lt;br /&gt;
过程（Procedure）&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
在Scheme语言中，过程相当于C语言中的函数，不同的是Scheme语言过程是一种数据类型，这也是为什么Scheme语言将程序和数据作为同一对象处理的原因。如果我们在Guile提示符下输入加号然后回车，会出现下面的情况：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; +
#&amp;lt;primitive-procedure +&amp;gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
这告诉我们&quot;+&quot;是一个过程，而且是一个原始的过程，即Scheme语言中最基础的过程，在GUILE中内部已经实现的过程，这和类型判断一样，如boolean?等，它们都是Scheme语言中最基本的定义。注意：不同的Scheme语言实现环境，出现的提示信息可能不尽相同，但意义是一样的。&lt;br /&gt;
define不仅可以定义变量，还可以定义过程，因在Scheme语言中过程（或函数）都是一种数据类型，所以都可以通过define来定义。不同的是标准的过程定义要使用lambda这一关键字来标识。&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot;&gt;Lambda关键字&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Scheme语言中可以用lambda来定义过程，其格式如下：&lt;br /&gt;
&lt;br /&gt;
(define 过程名 ( lambda (参数 ...) (操作过程 ...)))&lt;br /&gt;
&lt;br /&gt;
我们可以自定义一个简单的过程，如下：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  (define add5 (lambda (x) (+ x 5)))
  &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;div style=&quot;padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;br /&gt;
此过程需要一个参数，其功能为返回此参数加5 的值，如：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.8em;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;     (add5 11) =&amp;gt; 16
     &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
下面是简单的求平方过程square的定义：&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt; (define square (lambda (x)  (* x x)))
 &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;与lambda相同的另一种方式&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
在Scheme语言中，也可以不用lambda，而直接用define来定义过程，它的格式为：&lt;br /&gt;
(define (过程名 参数) (过程内容 …))&lt;br /&gt;
如下面操作：&lt;/div&gt;
&lt;div class=&quot;ibm-container&quot; style=&quot;margin: 0px 0px 1.2em; width: 710px;&quot;&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  (define (add6 x) (+ x 6))
  add6
  #&amp;lt;procedure: add6 (x)&amp;gt; 说明add6是一个过程，它有一个参数x
  (add6 23)    =&amp;gt; 29
  &lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
再看下面的操作：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define fun
                (lambda(proc x y)
                        (proc x y)))
guile&amp;gt; fun
#&amp;lt;procedure fun (proc x y)&amp;gt;
guile&amp;gt; (fun * 5 6)
30
guile&amp;gt; (fun / 30 3)
10
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot;&gt;更多的过程定义&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
上面定义的过程fun有三个参数，其中第一个参数proc也是一个操作过程（因为在Scheme语言中过程也是一种数据，可以作为过程的参数），另外两个参数是数值，所以会出现上面的调用结果。&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define add
                (lambda (x y)
                        (+ x y)))
guile&amp;gt; add
#&amp;lt;procedure add (x y)&amp;gt;
guile&amp;gt; (fun add 100 200)
300
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
继续上面操作，我们定义一个过程add，将add作为参数传递给fun过程，得出和(fun + 100 200)相同的结果。&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; ((lambda (x) (+ x x)) 5)
10
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
上面的 (lambda(x) (+ x x)) 事实上是简单的过程定义，在后面直接加上操作参数5，得出结果10，这样实现了匿名过程，直接用过程定义来操作参数，得出运算结果。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
通过上面的操作，相信你已初步了解了过程的用法。 既然过程是一种数据类型，所以将过程作为过程的参数是完全可以的。以下过程为判断参数是否为过程，给出一个参数，用 procedure? 来判断参数是否为过程，采用if结构（关于if结构见下面的介绍）：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define isp
            (lambda (x)
                     (if (procedure? x) &#39;isaprocedure &#39;notaprocedure)))
guile&amp;gt; isp
#&amp;lt;procedure isp (x)&amp;gt;
guile&amp;gt; (isp 0)
notaprocedure
guile&amp;gt; (isp +)
isaprocedure
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
上面的过程就体现了Scheme语言的参数自省（辨别）能力，&#39;0&#39;是数字型，所以返回notaprocedure；而&#39;+&#39;是一个最基础的操作过程，所以返回isaprocedure。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;N1031E&quot;&gt;&lt;span class=&quot;smalltitle&quot; style=&quot;font-size: 1.2em; font-weight: bold;&quot;&gt;过程的嵌套定义&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme语言中，过程定义也可以嵌套，一般情况下，过程的内部过程定义只有在过程内部才有效，相当C语言中的局部变量。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
如下面的代码的最终结果是50：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define fix 
 (lambda (x y z)
  (define add 
   (lambda (a b) (+ a b)))
  (- x (add y z))))
(display (fix 100 20 30))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
此时过程add只在fix过程内部起做用，这事实上涉及了过程和变量的绑定，可以参考下面的关于过程绑定（let，let* 和letrec）的介绍。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
过程是初学者难理解的一个关键，随着过程参数的增加和功能的增强，过程的内容变得越来越复杂，小括号也会更多，如果不写出清晰的代码的话，读代码也会成为一个难题。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
熟悉了 scheme 基本概念、数据类型和过程（函数）后，&amp;nbsp;&lt;a href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html&quot; style=&quot;color: #996699;&quot;&gt;下一部分&lt;/a&gt;我们来学习 scheme 的结构、递归调用和其他扩展功能。&lt;/div&gt;
&lt;div style=&quot;background-color: white;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
谈完了 &lt;a href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index1.html&quot;&gt;scheme 的基本概念、数据类型和过程&lt;/a&gt;，我们接着介绍 scheme 的结构、递归调用、变量和过程的绑定、输入输出等功能。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot;&gt;一．常用结构&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;顺序结构&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
也可以说成由多个form组成的form，用begin来将多个form放在一对小括号内，最终形成一个form。格式为：(begin form1 form2 …)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如用Scheme语言写成的经典的helloworld程序是如下样子的：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 500px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(begin 
 (display &quot;Hello world!&quot;)  ; 输出&quot;Hello world!&quot;
 (newline))    ; 换行
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;b&gt;if结构&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Scheme语言的if结构有两种格式，一种格式为：(if 测试 过程1 过程2)，即测试条件成立则执行过程1，否则执行过程2。例如下面代码：&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(if (= x 0) 
(display &quot;is zero&quot;)
(display &quot;not zero&quot;))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
还有另一种格式：(if 测试 过程) ，即测试条件成立则执行过程。例如下面代码：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  (if (&amp;lt; x 100) (display &quot;lower than 100&quot;))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
根据类型判断来实现自省功能，下面代码判断给定的参数是否为字符串：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define fun 
 (lambda ( x )
  (if (string? x)
   (display &quot;is a string&quot;)
   (display &quot;not a string&quot;))))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;br /&gt;
&lt;br /&gt;
如执行 (fun 123) 则返回值为&quot;not a string&quot;，这样的功能在C++或JAVA中实现的话可能会很费力气。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;cond结构&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Scheme语言中的cond结构类似于C语言中的switch结构，cond的格式为：&lt;br /&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  (cond ((测试) 操作) … (else 操作))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
如下是在Guile中的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define w (lambda (x)
      (cond ((&amp;lt; x 0) &#39;lower)
           ((&amp;gt; x 0) &#39;upper)
           (else &#39;equal))))
guile&amp;gt; w
#&amp;lt;procedure w (x)&amp;gt;
guile&amp;gt; (w 9)
upper
guile&amp;gt; (w -8)
lower
guile&amp;gt; (w 0)
equal
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
上面程序代码中，我们定义了过程w，它有一个参数x，如果x的值大于0，则返回符号upper，如x的值小于0则返回符号lower，如x 的值为0则返回符号equal。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下载已做成可执行脚本的&amp;nbsp;&lt;a href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/tc.scm&quot; style=&quot;color: #996699;&quot;&gt;例程&lt;/a&gt;。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
cond可以用if形式来写，上面的过程可以如下定义：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define ff
       (lambda (x)
                    (if (&amp;lt; x 0) &#39;lower
                            (if (&amp;gt; x 0) &#39;upper &#39;zero))))
guile&amp;gt; ff
#&amp;lt;procedure ff (x)&amp;gt;
guile&amp;gt; (ff 9)
upper
guile&amp;gt; (ff -9)
lower
guile&amp;gt; (ff 0)
zero
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
这在功能上是和cond一样的，可以看出cond实际上是实现了if的一种多重嵌套。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;case结构&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
case结构和cond结构有点类似，它的格式为：&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
(case (表达式) ((值) 操作)) ... (else 操作)))&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
case结构中的值可以是复合类型数据，如列表，向量表等，只要列表中含有表达式的这个结果，则进行相应的操作，如下面的代码：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt; (case (* 2 3)
  ((2 3 5 7) &#39;prime)
  ((1 4 6 8 9) &#39;composite))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
上面的例子返回结果是composite，因为列表(1 4 6 8 9)中含有表达式(* 2 3)的结果6；下面是在Guile中定义的func过程，用到了case结构：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define func
                (lambda (x y)
                        (case (* x y)
                                ((0) &#39;zero)
                                (else &#39;nozero))))
guile&amp;gt; func
#&amp;lt;procedure func (x y)&amp;gt;
guile&amp;gt; (func 2 3)
nozero
guile&amp;gt; (func 2 0)
zero
guile&amp;gt; (func 0 9)
zero
guile&amp;gt; (func 2 9)
nozero
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
可以下载另一个脚本文件&amp;nbsp;&lt;a href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/te.scm&quot; style=&quot;color: #996699;&quot;&gt;te.scm&lt;/a&gt;，参考一下。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;and结构&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
and结构与逻辑与运算操作类似，and后可以有多个参数，只有它后面的参数的表达式的值都为#t时，它的返回值才为#t，否则为#f。看下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (and (boolean? #f) (&amp;lt; 8 12))
#t
guile&amp;gt; (and (boolean? 2) (&amp;lt; 8 12))
#f
guile&amp;gt; (and (boolean? 2) (&amp;gt; 8 12))
#f
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
如果表达式的值都不是boolean型的话，返回最后一个表达式的值，如下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (and (list 1 2 3) (vector &#39;a &#39;b &#39;c))
#(a b c)
guile&amp;gt; (and 1 2 3 4 )
4
guile&amp;gt; (and &#39;e &#39;d &#39;c &#39;b &#39;a)
a
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;or结构&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
or结构与逻辑或运算操作类似，or后可以有多个参数，只要其中有一个参数的表达式值为#t，其结果就为#t，只有全为#f时其结果才为#f。如下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (or #f #t)
#t
guile&amp;gt; (or #f #f)
#f
guile&amp;gt; (or (rational? 22/7) (&amp;lt; 8 12))
#t
guile&amp;gt; (rational? 22/7)
#t
guile&amp;gt; (real? 22/7)
#t
guile&amp;gt; (or (real? 4+5i) (integer? 3.22))
#f
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
我们还可以用and和or结构来实现较复杂的判断表达式，如在C语言中的表达式：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;((x &amp;gt; 100) &amp;amp;&amp;amp; (y &amp;lt; 100)) 和 ((x &amp;gt; 100) || (y &amp;gt; 100))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme中可以表示为：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define x 123)
guile&amp;gt; (define y 80)
guile&amp;gt; (and (&amp;gt; x 100) (&amp;lt; y 100))
#t
guile&amp;gt; (or (&amp;gt; x 100) (&amp;gt; y 100))
#t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中只有if结构是系统原始提供的，其它的cond，case，and，or，另外还有do，when，unless等都是可以用宏定义的方式来定义的，这一点充分体现了Scheme的元语言特性，关于do，when等结构的使用可以参考R5RS。&lt;/div&gt;
&lt;div class=&quot;ibm-alternate-rule&quot; style=&quot;background-color: white; background-image: url(http://1.www.s81c.com/i/solid.gif); background-repeat: repeat no-repeat; clear: both; height: 1px;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;ibm-ind-link ibm-back-to-top&quot; style=&quot;background-color: white; clear: both; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; height: 15px; padding: 5px; text-align: right;&quot;&gt;
&lt;a class=&quot;ibm-anchor-up-link&quot; href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html#ibm-pcon&quot; style=&quot;background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-position: 0px -1px; background-repeat: no-repeat no-repeat; color: #996699; display: inline; font-weight: bold; margin: 0px; padding: 0px 0px 0px 18px; text-decoration: none;&quot;&gt;回页首&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;1&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;二．递归调用&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;用递归实现阶乘&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme语言中，递归是一个非常重要的概念，可以编写简单的代码很轻松的实现递归调用，如下面的阶乘过程定义：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define  factoral (lambda (x)
    (if (&amp;lt;= x 1) 1
        (* x (factoral (- x 1))))))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
我们可以将下面的调用(factoral 4)，即4的阶乘的运算过程图示如下：&lt;/div&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;273&quot; src=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/images/image002.jpg&quot; style=&quot;background-color: white; border: 0px; padding: 0.3em 5px 0.7em;&quot; width=&quot;384&quot; /&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以下为factoral过程在Guile中的运行情况：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define factoral (lambda (x) (if (&amp;lt;= x 1) 1 (* x (factoral (- x 1))))))
guile&amp;gt; factoral
#&amp;lt;procedure factoral (x)&amp;gt;
guile&amp;gt; (factoral 4)
24
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;另一种递归方式&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面是一另一种递归方式的定义：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define (factoral n)
 (define (iter product counter)
  (if (&amp;gt; counter n)
   product
   (iter (* counter product) (+ counter 1))))
 (iter 1 1))
(display (factoral 4))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
这个定义的功能和上面的完全相同，只是实现的方法不一样了，我们在过程内部实现了一个过程iter，它用counter参数来计数，调用时从1开始累计，这样它的展开过程正好和我们上面的递归过程的从4到1相反，而是从1到4。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;循环的实现&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme语言中没有循环结构，不过循环结构可以用递归来很轻松的实现（在Scheme语言中只有通过递归才能实现循环）。对于用惯了C语言循环的朋友，在Scheme中可以用递归简单实现：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define loop
      (lambda(x y)
          (if (&amp;lt;= x y)
              (begin (display x) (display #\\space) (set! x (+ x 1))
                 (loop x y)))))
guile&amp;gt; loop
#&amp;lt;procedure loop (x y)&amp;gt;
guile&amp;gt; (loop 1 10)
1 2 3 4 5 6 7 8 9 10
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
这只是一种简单的循环定义，过程有两个参数，第一个参数是循环的初始值，第二个参数是循环终止值，每次增加1。相信读者朋友一定会写出更漂亮更实用的循环操作来的。&lt;/div&gt;
&lt;div class=&quot;ibm-alternate-rule&quot; style=&quot;background-color: white; background-image: url(http://1.www.s81c.com/i/solid.gif); background-repeat: repeat no-repeat; clear: both; height: 1px;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;ibm-ind-link ibm-back-to-top&quot; style=&quot;background-color: white; clear: both; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; height: 15px; padding: 5px; text-align: right;&quot;&gt;
&lt;a class=&quot;ibm-anchor-up-link&quot; href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html#ibm-pcon&quot; style=&quot;background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-position: 0px -1px; background-repeat: no-repeat no-repeat; color: #996699; display: inline; font-weight: bold; margin: 0px; padding: 0px 0px 0px 18px; text-decoration: none;&quot;&gt;回页首&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;2&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;三．变量和过程的绑定&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;let，let*，letrec&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在多数编程语言中都有关于变量的存在的时限问题，Scheme语言中用let，let*和letrec来确定变量的存在的时限问题，即局部变量和全局变量，一般情况下，全局变量都用define来定义，并放在过程代码的外部；而局部变量则用let等绑定到过程内部使用。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
用let可以将变量或过程绑定在过程的内部，即实现局部变量：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; let
#&amp;lt;primitive-macro! let&amp;gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
从上面的操作可以看出let是一个原始的宏，即guile内部已经实现的宏定义。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面的代码显示了let的用法（注意多了一层括号）：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (let ((x 2) (y 5)) (* x y))
10
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
它的格式是：(let ((…)…) …)，下面是稍复杂的用法：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (let ((x 5))
         (define foo (lambda (y) (bar x y)))
         (define bar (lambda (a b) (+ (* a b) a)))
         (foo (+ x 3)))
45
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以上是Guile中的代码实现情况。它的实现过程大致是：(foo 8) 展开后形成 (bar 5 8)，再展开后形成 (+ (* 5 8) 5) ，最后其值为45。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
再看下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (let ((iszero?
                (lambda(x)
                (if (= x 0) #t #f))))
        (iszero? 9))
#f
guile&amp;gt; (iszero? 0)  ;此时会显示出错信息
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
let的绑定在过程内有效，过程外则无效，这和上面提到的过程的嵌套定是一样的，上面的iszero?过程在操作过程内定义并使用的，操作结束后再另行引用则无效，显示过程未定义出错信息。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面操作演示了let*的用法：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (let ((x 2) (y 5))
       (let* ((x 6)(z (+ x y)))  ;此时x的值已为6，所以z的值应为11，如此最后的值为66
       (* z x)))
66
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
还有letrec，看下面的操作过程：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (letrec ((even?
                (lambda(x)
                (if (= x 0) #t
                        (odd? (- x 1)))))
            (odd?
                (lambda(x)
                (if (= x 0) #f
                        (even? (- x 1))))))
        (even? 88))
#t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
上面的操作过程中，内部定义了两个判断过程even?和odd?，这两个过程是互相递归引用的，如果将letrec换成let或let*都会不正常，因为letrec是将内部定义的过程或变量间进行相互引用的。看下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (letrec ((countdown
                (lambda (i)
                (if (= i 0) &#39;listoff
                        (begin (display i) (display &quot;,&quot;)
                                (countdown (- i 1)))))))
        (countdown 10))
10,9,8,7,6,5,4,3,2,1,listoff
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
letrec帮助局部过程实现递归的操作，这不仅在letrec绑定的过程内，而且还包括所有初始化的东西，这使得在编写较复杂的过程中经常用到letrec，也成了理解它的一个难点。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;apply&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
apply的功能是为数据赋予某一操作过程，它的第一个参数必需是一个过程，随后的其它参数必需是列表，如：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (apply + (list 2 3 4))
9
guile&amp;gt; (define sum
           (lambda (x )
                  (apply + x)))  ; 定义求和过程
guile&amp;gt; sum
#&amp;lt;procedure sum (x)&amp;gt;
guile&amp;gt; (define ls (list 2 3 4 5 6))
guile&amp;gt; ls
(2 3 4 5 6)
guile&amp;gt; (sum ls)
20
guile&amp;gt; (define avg
          (lambda(x)
                 (/ (sum x) (length x))))   ; 定义求平均过程
guile&amp;gt; avg
#&amp;lt;procedure avg (x)&amp;gt;
guile&amp;gt; (avg ls)
4
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以上定义了求和过程sum和求平均的过程avg，其中求和的过程sum中用到了apply来绑定&quot;+&quot;过程操作到列表，结果返回列表中所有数的总和。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;map&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
map的功能和apply有些相似，它的第一个参数也必需是一个过程，随后的参数必需是多个列表，返回的结果是此过程来操作列表后的值，如下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (map + (list 1 2 3) (list 4 5 6))
(5 7 9)
guile&amp;gt; (map car &#39;((a . b)(c . d)(e . f)))
(a c e)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
除了apply，map以外，Scheme语言中还有很多，诸如：eval，delay，for-each，force，call-with-current-continuation等过程绑定的操作定义，它们都无一例外的提供了相当灵活的数据处理能力，也就是另初学者望而生畏的算法，当你仔细的体会了运算过程中用到的简直妙不可言的算法后，你就会发现Scheme语言设计者的思想是多么伟大。&lt;/div&gt;
&lt;div class=&quot;ibm-alternate-rule&quot; style=&quot;background-color: white; background-image: url(http://1.www.s81c.com/i/solid.gif); background-repeat: repeat no-repeat; clear: both; height: 1px;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;ibm-ind-link ibm-back-to-top&quot; style=&quot;background-color: white; clear: both; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; height: 15px; padding: 5px; text-align: right;&quot;&gt;
&lt;a class=&quot;ibm-anchor-up-link&quot; href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html#ibm-pcon&quot; style=&quot;background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-position: 0px -1px; background-repeat: no-repeat no-repeat; color: #996699; display: inline; font-weight: bold; margin: 0px; padding: 0px 0px 0px 18px; text-decoration: none;&quot;&gt;回页首&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;3&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;四．输入输出&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中也提供了相应的输入输出功能，是在C基础上的一种封装。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;端口&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言中输入输出中用到了端口的概念，相当于C中的文件指针，也就是Linux中的设备文件，请看下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (current-input-port)
#&amp;lt;input: standard input /dev/pts/0&amp;gt; ;当前的输入端口
guile&amp;gt; (current-output-port)
#&amp;lt;output: standard output /dev/pts/0&amp;gt; ;当前的输出端口
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
判断是否为输入输出端口，可以用下面两个过程：input-port? 和output-port? ，其中input-port?用来判断是否为输入端口，output-port?用来判断是否为输出端口。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
open-input-file，open-output-file，close-input-port，close-output-port这四个过程用来打开和关闭输入输出文件，其中打开文件的参数是文件名字符串，关闭文件的参数是打开的端口。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;输入&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
打开一个输入文件后，返回的是输入端口，可以用read过程来输入文件的内容：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define port (open-input-file &quot;readme&quot;))
guile&amp;gt; port
#&amp;lt;input: readme 4&amp;gt;
guile&amp;gt; (read port)
GUILE语言
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
上面的操作打开了readme文件，并读出了它的第一行内容。此外还可以直接用read过程来接收键盘输入，如下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (read)  ; 执行后即等待键盘输入
12345
12345
guile&amp;gt; (define x (read))  ; 等待键盘输入并赋值给x
12345
guile&amp;gt; x
12345
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
以上为用read来读取键入的数字，还可以输入字符串等其它类型数据：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define name (read))
tomson
guile&amp;gt; name
tomson
guile&amp;gt; (string? name)
#f
guile&amp;gt; (symbol? name)
#t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
此时输入的tomson是一个符号类型，因为字符串是用引号引起来的，所以出现上面的情况。下面因为用引号了，所以(string? str)返回值为#t 。&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (define str (read))
&quot;Johnson&quot;
guile&amp;gt; str
&quot;Johnson&quot;
guile&amp;gt; (string? str)
#t
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
还可以用load过程来直接调用Scheme语言源文件并执行它，格式为：(load &quot;filename&quot;)，还有read-char过程来读单个字符等等。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;输出&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
常用的输出过程是display，还有write，它的格式是：(write 对象 端口)，这里的对象是指字符串等常量或变量，端口是指输出端口或打开的文件。下面的操作过程演示了向输出文件temp中写入字符串&quot;helloworld&quot;，并分行的实现。&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;[root@toymouse test]# guile
guile&amp;gt; (define port1 (open-output-file &quot;temp&quot;))  ; 打开文件端口赋于port1
guile&amp;gt; port1
#&amp;lt;output: temp 3&amp;gt; 
guile&amp;gt; (output-port? port1)
#t                     ; 此时证明port1为输出端口
guile&amp;gt; (write &quot;hello\\nworld&quot; port1)
guile&amp;gt; (close-output-port port1)
guile&amp;gt; (exit)               ; 写入数据并关闭退出
[root@toymouse test]# more temp          显示文件的内容，达到测试目的
&quot;hello
world&quot;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在输入输出操作方面，还有很多相关操作，读者可以参考R5RS的文档。&lt;/div&gt;
&lt;div class=&quot;ibm-alternate-rule&quot; style=&quot;background-color: white; background-image: url(http://1.www.s81c.com/i/solid.gif); background-repeat: repeat no-repeat; clear: both; height: 1px;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;ibm-ind-link ibm-back-to-top&quot; style=&quot;background-color: white; clear: both; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; height: 15px; padding: 5px; text-align: right;&quot;&gt;
&lt;a class=&quot;ibm-anchor-up-link&quot; href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html#ibm-pcon&quot; style=&quot;background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-position: 0px -1px; background-repeat: no-repeat no-repeat; color: #996699; display: inline; font-weight: bold; margin: 0px; padding: 0px 0px 0px 18px; text-decoration: none;&quot;&gt;回页首&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;4&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;五．语法扩展&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
Scheme语言可以自己定义象cond，let等功能一样的宏关键字。标准的Scheme语言定义中用define-syntax和syntax-rules来定义，它的格式如下：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;  (define-syntax 宏名
   (syntax-rules()
    ((模板) 操作))
    . . . ))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面定义的宏start的功能和begin相同，可以用它来开始多个块的组合：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;(define-syntax start
        (syntax-rules ()
                ((start exp1)
                        exp1)
                ((start exp1 exp2 ...)
                        (let ((temp exp1)) (start exp2 ...))) ))
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
这是一个比较简单的宏定义，但对理解宏定义来说是比较重要的，理解了他你才会进一步应用宏定义。在规则 ((start exp1) exp1) 中，(start exp1) 是一个参数时的模板，exp1是如何处理，也就是原样搬出，不做处理。这样 (start form1) 和 (form1) 的功能就相同了。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在规则 ((start exp1 exp2 ...) (let ((temp exp1)) (start exp2 ...))) 中，(start exp1 exp2 …) 是多个参数时的模板，首先用let来绑定局部变量temp为exp1，然后用递归实现处理多个参数，注意这里说的是宏定义中的递归，并不是过程调用中的递归。另外在宏定义中可以用省略号（三个点）来代表多个参数。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在Scheme的规范当中，将表达式分为原始表达式和有源表达式，Scheme语言的标准定义中只有原始的if分支结构，其它均为有源型，即是用后来的宏定义成的，由此可见宏定义的重要性。附上面的定义在GUILE中实现的&amp;nbsp;&lt;a href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/tx.scm&quot; style=&quot;color: #996699;&quot;&gt;代码&lt;/a&gt;。&lt;/div&gt;
&lt;div class=&quot;ibm-alternate-rule&quot; style=&quot;background-color: white; background-image: url(http://1.www.s81c.com/i/solid.gif); background-repeat: repeat no-repeat; clear: both; height: 1px;&quot;&gt;
&lt;/div&gt;
&lt;div class=&quot;ibm-ind-link ibm-back-to-top&quot; style=&quot;background-color: white; clear: both; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; height: 15px; padding: 5px; text-align: right;&quot;&gt;
&lt;a class=&quot;ibm-anchor-up-link&quot; href=&quot;http://www.ibm.com/developerworks/cn/linux/l-schm/index2.html#ibm-pcon&quot; style=&quot;background-image: url(http://1.www.s81c.com/i/v16/icons/u_bold.gif); background-position: 0px -1px; background-repeat: no-repeat no-repeat; color: #996699; display: inline; font-weight: bold; margin: 0px; padding: 0px 0px 0px 18px; text-decoration: none;&quot;&gt;回页首&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;a href=&quot;http://www.blogger.com/blogger.g?blogID=1825468319952057680&quot; name=&quot;5&quot;&gt;&lt;span class=&quot;atitle&quot; style=&quot;font-size: 1.5em; font-weight: bold;&quot;&gt;六. 其它功能&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;1. 模块扩展&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在R5RS中并未对如何编写模块进行说明，在诸多的Scheme语言的实现当中，几乎无一例外的实现了模块的加载功能。所谓模块，实际就是一些变量、宏定义和已命名的过程的集合，多数情况下它都绑定在一个Scheme语言的符号下（也就是名称）。在Guile中提供了基础的ice-9模块，其中包括POSIX系统调用和网络操作、正则表达式、线程支持等等众多功能，此外还有著名的SFRI模块。引用模块用use-modules过程，它后面的参数指定了模块名和我们要调用的功能名，如：(use-modules (ice-9 popen))，如此后，就可以应用popen这一系统调用了。如果你想要定义自己的模块，最好看看ice-9目录中的那些tcm文件，它们是最原始的定义。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
另外Guile在面向对象编程方面，开发了GOOPS（Guile Object-Oriented Programming System），对于喜欢OO朋友可以研究一下它，从中可能会有新的发现。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;2. 如何输出漂亮的代码&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
如何编写输出漂亮的Scheme语言代码应该是初学者的第一个问题，这在Guile中可以用ice-9扩展包中提供的pretty-print过程来实现，看下面的操作：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;guile&amp;gt; (use-modules (ice-9 pretty-print))    ; 引用漂亮输出模块
guile&amp;gt; (pretty-print &#39;(define fix (lambda (n)
        (cond ((= n 0) &#39;iszero)
                ((&amp;lt; n 0) &#39;lower)
                (else &#39;upper)))))   ; 此处是我们输入的不规则代码
(define fix
  (lambda (n)
    (cond ((= n 0) &#39;iszero)
          ((&amp;lt; n 0) &#39;lower)
          (else &#39;upper))))     ; 输出的规则代码
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;3. 命令行参数的实现&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
在把Scheme用做shell语言时，经常用到命令行参数的处理，下面是关于命令行参数的一种处理方法：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;#! /usr/local/bin/guile -s
!#
(define cmm (command-line))
(display &quot;应用程序名称：&quot;)
(display (car cmm))  
(newline)
(define args (cdr cmm))
(define long (length args))
(define loop (lambda (count len obj)
 (if (&amp;lt;= count len)
  (begin
   (display &quot;参数 &quot;)
   (display count)
   (display &quot; 是：&quot;)
   (display (list-ref obj (- count 1)))
   (newline)
   (set! count (+ count 1))
   (loop count len obj)))))
(loop 1 long args)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面是运行后的输出结果：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;[root@toymouse doc]# ./tz.scm abc 123 ghi
应用程序名称：./tz.scm
参数 1 是：abc
参数 2 是：123
参数 3 是：ghi
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
其中最主要的是用到了command-line过程，它的返回结果是命令参数的列表，列表的第一个成员是程序名称，其后为我们要的参数，定义loop递归调用形成读参数的循环，显示出参数值，达到我们要的结果。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;4. 特殊之处&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;一些精确的自己计算自己的符号&lt;/strong&gt;&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt;数字 Numbers  2 ==&amp;gt; 2
字符串 Strings  &quot;hello&quot; ==&amp;gt; &quot;hello&quot;
字符 Charactors #\\g ==&amp;gt; #\\g
辑值    Booleans #t ==&amp;gt; #t
量表 Vectors  #(a 2 5/2) ==&amp;gt; #(a 2 5/2)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;通过变量计算来求值的符号&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
如：&lt;/div&gt;
&lt;table border=&quot;0&quot; cellpadding=&quot;0&quot; cellspacing=&quot;0&quot; style=&quot;background-color: white; color: black; font-size: 0.8em; width: 100%px;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td class=&quot;code-outline&quot; style=&quot;background-color: rgb(247, 247, 247) !important; border: 1px solid rgb(204, 204, 204); font-family: arial, nsimsun, sans-serif; padding: 2px 2px 5px;&quot;&gt;&lt;pre class=&quot;displaycode&quot; style=&quot;font-family: &#39;Andale Mono&#39;, &#39;Lucida Console&#39;, Monaco, Liberation, fixed, monospace; font-size: 11px; overflow: auto; width: 694px;&quot;&gt; 
 
 x ==&amp;gt; 9
    -list ==&amp;gt; (&quot;tom&quot; &quot;bob&quot; &quot;jim&quot;)
 factoral ==&amp;gt; #&amp;lt;procedure: factoral&amp;gt;
   ==&amp;gt; #&amp;lt;primitive: +&amp;gt;
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br style=&quot;background-color: white;&quot; /&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;define 特殊的form&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
(define x 9) ，define不是一个过程， 它是一个不用求所有参数值的特殊的form，它的操作步骤是，初始化空间，绑定符号x到此空间，然后初始此变量。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
&lt;strong&gt;必须记住的东西&lt;/strong&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
下面的这些定义、过程和宏等是必须记住的：&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
define，lambda，let，lets，letrec，quote，set!，if，case，cond，begin，and，or等等，当然还有其它宏，必需学习，还有一些未介绍，可参考有关资料。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: arial, nsimsun, sans-serif; font-size: 0.76em; padding: 0.3em 5px 0.7em;&quot;&gt;
走进Scheme语言的世界，你就发现算法和数据结构的妙用随处可见，可以充分的检验你对算法和数据结构的理解。Scheme语言虽然是古老的函数型语言的继续，但是它的里面有很多是在其它语言中学不到的东西，我想这也是为什么用它作为计算机语言教学的首选的原因吧。&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/2996579382335067590/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2014/01/scheme.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2996579382335067590'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2996579382335067590'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2014/01/scheme.html' title='Scheme 語言概要'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-4212772825833928925</id><published>2014-01-01T03:31:00.004-08:00</published><updated>2014-01-01T23:03:39.788-08:00</updated><title type='text'>不完備定理</title><content type='html'>Die Grundzeichen des Systems P sind die folgenden:&lt;br /&gt;
I.Konstante: &quot;~&quot;(nicht), &quot;v&quot;(oder), &quot;Π&quot; (fuer alle), &quot;0&quot; (null), &quot;f&quot; (der Nachfolger von), &quot;(&quot;, &quot;)&quot;, (Klammern).&lt;br /&gt;
&lt;br /&gt;
II.Variable ersten Typs(fuer Individuen, d. h. natuerliche Zahlen inklusive 0)):&lt;br /&gt;
&lt;br /&gt;
下列為P系統之基本符：&lt;br /&gt;
I.常符:&lt;br /&gt;
~ : 非&lt;br /&gt;
v : 或&lt;br /&gt;
Π : 對所有&lt;br /&gt;
0 : 零&lt;br /&gt;
f : 後繼函數，命名源自德文後繼 Nachfolger&lt;br /&gt;
( ) :括號 &lt;br /&gt;
&lt;br /&gt;
II.第一型變數(對個體，即自然數包含零)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;陣列操作&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;哥德爾數定義&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
17.Z(n) ≡ nN[R(1)]&lt;br /&gt;
Z(n) ist das Zahlzeichen für die Zahl n.&lt;br /&gt;
Z(n) 是整數 n 的整數符號表示。&lt;br /&gt;
&lt;br /&gt;
命名源自德文整數 Zahl。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Satz V. Zu Jeder rekursiven Relation R(x1...xn)&amp;nbsp;&amp;nbsp;gibt es ein n-stelliges Relationenszeichen r (mit den freien Variablen) (u1, u2...un), so daß für alle Zahlen-n-tuple (x1, x2,...xn) gilt:&lt;br /&gt;
&lt;br /&gt;
定理V. 對每個遞迴關係 R(x1...xn) 均有一個 n 元關係符號 r(帶有自由變數)(u1,u2...un)，且對所有n元整數序對(x1,x2...xn)滿足下式：&lt;br /&gt;
&lt;br /&gt;
R(x1...xn) =&amp;gt; Bew[Sb(r u1 &amp;nbsp; &amp;nbsp; ...un &amp;nbsp; &amp;nbsp;)] &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (3)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Z(x1)...Z(xn)&lt;br /&gt;
&lt;br /&gt;
~R(x1...xn) =&amp;gt; Bew[Neg Sb(r u1 &amp;nbsp; &amp;nbsp; ...un &amp;nbsp; &amp;nbsp;)] &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(4)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Z(x1)...Z(xn)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/4212772825833928925/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2014/01/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/4212772825833928925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/4212772825833928925'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2014/01/blog-post.html' title='不完備定理'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-537081504833751967</id><published>2013-12-03T17:45:00.000-08:00</published><updated>2013-12-03T17:45:04.102-08:00</updated><title type='text'>monad 函數用法</title><content type='html'>&lt;pre class=&quot;lang-hs prettyprint prettyprinted&quot; style=&quot;border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto; word-wrap: normal;&quot;&gt;&lt;span class=&quot;pln&quot; style=&quot;border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;forM_&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre class=&quot;lang-hs prettyprint prettyprinted&quot; style=&quot;border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto; word-wrap: normal;&quot;&gt;&lt;span style=&quot;font-family: Consolas, Menlo, Monaco, &#39;Lucida Console&#39;, &#39;Liberation Mono&#39;, &#39;DejaVu Sans Mono&#39;, &#39;Bitstream Vera Sans Mono&#39;, &#39;Courier New&#39;, monospace, serif; line-height: 17.600000381469727px;&quot;&gt;模擬一般程式語言 for 建構子&lt;/span&gt;&lt;/pre&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt; forM_ xs $ \s -&amp;gt; do&lt;br /&gt;&amp;nbsp; &amp;nbsp; putStrLn &quot;Here&#39;s a string:&quot;&amp;nbsp;&lt;/span&gt;&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; forM_ s print&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; putStrLn &quot;Now it&#39;s done.&quot;&lt;/span&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/537081504833751967/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2013/12/monad.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/537081504833751967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/537081504833751967'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2013/12/monad.html' title='monad 函數用法'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-2062119211427788648</id><published>2013-11-27T16:46:00.000-08:00</published><updated>2013-12-02T19:46:19.428-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="parsec參考"/><title type='text'>parsec 剖析器組合子語義</title><content type='html'>&lt;b&gt;字元剖析器&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;a = char &#39;a&#39;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
a 剖析器會消化 a 字元，並傳回字元 a，若為其它字元則會剖析失敗。&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;b&gt;序列剖析&lt;/b&gt;&lt;b&gt;器&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
序列剖析器可組合數個剖析器，這些剖析器以do區塊組合，並依序應用這些剖析器分析，若序列中某個剖析器失敗，則整個剖析器便失敗，如下例：&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;openClose = do{ &lt;a href=&quot;http://legacy.cs.uu.nl/daan/download/parsec/parsec.html#char&quot;&gt;char&lt;/a&gt; &#39;(&#39;
              ; &lt;a href=&quot;http://legacy.cs.uu.nl/daan/download/parsec/parsec.html#char&quot;&gt;char&lt;/a&gt; &#39;)&#39;
              }&lt;/span&gt;&lt;/pre&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;
openClose 會先剖析 ( 字元，若剖析成功，則再剖析 ) 字元。&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;預測剖析器&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
預測剖析器依掃描之首字元來選擇子剖析器，子剖析器以 &amp;lt;|&amp;gt; 運算子組合，此掃描首字元會被消化掉。&lt;br /&gt;
&lt;br /&gt;
任何一個子剖析器成功，則傳回該子剖析器之值。&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;aORb = &amp;nbsp; char &#39;a&#39;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;|&amp;gt; char &#39;b&#39;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;b&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;aORb 可剖析 a 字元或 b 字元。&lt;/span&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;try 剖析器&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
預測剖析器可利用 &amp;lt;|&amp;gt; 運算子來建構。&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;testOr  =   &lt;a href=&quot;http://legacy.cs.uu.nl/daan/download/parsec/parsec.html#string&quot;&gt;string&lt;/a&gt; &quot;(a)&quot;
        &amp;lt;|&amp;gt; string &quot;(b)&quot;
&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;testOr&amp;nbsp;&lt;/span&gt;剖析器因只依掃描之首字元來選擇剖析器，而上例首字元均為 (，故無法明確選擇用那個剖析器，會出現下列錯誤。&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Main&amp;gt; run testOr &quot;(b)&quot;      
parse error at (line 1, column 2):
unexpected &#39;b&#39;
expecting &#39;a&#39;
&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;必須用左因子分解法修改剖析器才可，如下：&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;testOr1 = do{ char &#39;(&#39;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;            ; char &#39;a&#39; &amp;lt;|&amp;gt; char &#39;b&#39;
            ; char &#39;)&#39;
            }
&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;若不想用左因子分解法，則可使用&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;try 剖析器，&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;try 剖析器&lt;/span&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;若&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;剖析&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;失敗，則會把消化的輸入復原。&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;testOr2 =   try (string &quot;(a)&quot;)
        &amp;lt;|&amp;gt; string &quot;(b)&quot;
&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;br /&gt;
&lt;pre style=&quot;color: #202050;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;testOr3 =   do{ try (string &quot;(a&quot;); char &#39;)&#39;; return &quot;(a)&quot; }
        &amp;lt;|&amp;gt; string &quot;(b)&quot;&lt;/span&gt;
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
空條件剖析指若沒有任何剖析器可選擇，則會在沒有消化任何輸入下，成功傳回值。&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;parens :: Parser ()&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;parens = do{&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; char &#39;(&#39;
 ;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; parens
 ;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; char &#39;)&#39;
 ;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; parens&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;|&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;return ()&lt;/span&gt;&lt;br /&gt;
上述剖析器可剖析以下字串&lt;br /&gt;
()&lt;br /&gt;
(())&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;分隔字串處理(sepBy, endBy, sepEndBy)&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
parsec 提供2個剖析組合子，sepBy 及 endBy，用來處理實體由分隔字串區分之串列，最常見的格式應該是csv(comma seperated values)逗號分隔值組。&lt;br /&gt;
&lt;br /&gt;
這些組合子均接受兩個參數，第一個是剖析實體之組合子，另一個是剖析分隔字串之組合子，最後在無法繼續剖析時，傳回實體值之串列。&lt;br /&gt;
簡單的語義如下例：&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;x endBy _ &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;x_x_x_x_x_ &amp;nbsp;-&amp;gt; [x,x,x,x,x]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;x sepBy _&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;x_x_x_x_x &amp;nbsp; -&amp;gt; [x,x,x,x,x]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;x sepEndBy _&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;x_x_x_x_x_ &amp;nbsp;-&amp;gt; [x,x,x,x,x]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;x_x_x_x_x &amp;nbsp; -&amp;gt; [x,x,x,x,x]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;xa_ &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;-&amp;gt; [x] &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;a 並非 x 可剖析，故傳回一個 a。&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;num endBy . 接受下列字串並傳回：&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;1. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; [1]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;1.1. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-&amp;gt; [1,1]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;1.1.2. &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; -&amp;gt; [1,1,2]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;letter sepEndBy ,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&quot;&quot; &amp;nbsp; -&amp;gt; &amp;nbsp;[]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a &amp;nbsp; &amp;nbsp;-&amp;gt; &amp;nbsp;[a]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a, &amp;nbsp; -&amp;gt; &amp;nbsp;[a]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a,b &amp;nbsp;-&amp;gt; &amp;nbsp;[a,b]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;a,b, -&amp;gt; &amp;nbsp;[a,b]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ab &amp;nbsp; -&amp;gt; &amp;nbsp;[a]&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/2062119211427788648/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2013/11/sepby-endby.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2062119211427788648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2062119211427788648'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2013/11/sepby-endby.html' title='parsec 剖析器組合子語義'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-5949638776461791115</id><published>2012-06-26T01:25:00.001-07:00</published><updated>2014-01-01T23:06:51.293-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="流程控制"/><title type='text'>Continuation</title><content type='html'>&lt;b&gt;call/cc 語義&lt;/b&gt;&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: sans-serif; font-size: 12.800000190734863px; line-height: 19.200000762939453px; margin-bottom: 0.5em; margin-top: 0.4em;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;mw-geshi mw-code mw-content-ltr&quot; dir=&quot;ltr&quot; style=&quot;background-color: #f9f9f9; border: 1px solid rgb(221, 221, 221); direction: ltr; font-family: monospace, Courier; font-size: 12.800000190734863px; line-height: 1.3em; padding: 1em;&quot;&gt;
&lt;div class=&quot;scheme source-scheme&quot; style=&quot;font-family: monospace; line-height: normal;&quot;&gt;
&lt;pre class=&quot;de1&quot; style=&quot;background-image: none; border: 0px none white; font-family: monospace, monospace; font-size: 1em; line-height: 1.2em; padding: 0px; vertical-align: top;&quot;&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nu0&quot; style=&quot;color: #cc66cc;&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nu0&quot; style=&quot;color: #cc66cc;&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt;
 
&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt; x&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co1&quot; style=&quot;color: grey; font-style: italic;&quot;&gt;; displays 3&lt;/span&gt;
 
&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;call-with-current-continuation&lt;/span&gt; &lt;span class=&quot;kw1&quot; style=&quot;color: #b1b100;&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;br0&quot; style=&quot;color: #66cc66;&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;co1&quot; style=&quot;color: grey; font-style: italic;&quot;&gt;; displays 2&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: sans-serif; font-size: 12.800000190734863px; line-height: 19.200000762939453px; margin-bottom: 0.5em; margin-top: 0.4em;&quot;&gt;
Calling&amp;nbsp;&lt;i&gt;f&lt;/i&gt;&amp;nbsp;with a regular function argument first applies this function to the value 2, then returns 3. However, when&amp;nbsp;&lt;i&gt;f&lt;/i&gt;&amp;nbsp;is passed to call/cc (as in the last line of the example), applying the parameter (the continuation) to 2 forces execution of the program to jump to the point where call/cc was called, and causes call/cc to return the value 2. This is then printed by the display function.&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
这个很难理解，而且几乎找不到解说资料。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
1.什么是current-constitution？&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
The current continuation at any point in the executionof a program is an abstraction of the&lt;em&gt;rest of theprogram&lt;/em&gt;.&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
current-constitution就是运行到目前，剩余的程序的抽象。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
2.怎么去call？&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
就是用call/cc这个过程来调用。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; call/cc参数必须为一个单参数的过程pro，call/cc 构造一个具体的“目前继续”的代表传递给pro，而“目前继续”由过程kont来表示。每一次kont被传递一个值，它返回该值给call/cc的目前继续，这个值本质上就变为call/cc的值。如果pro没有引用kont，pro的返回值变成call/cc的值。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
被翻译成汉语了还是这么难以理解啊！&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
大概的意思就是：call/cc会以一个单参数的过程(设为pro)为参数，pro的参数(设为kont)会夺取pro的目前继续，那pro没有“目前继续”怎么办？放心，call/cc会为其构造一个（不过当然是山寨货了），而kont有了pro的”目前继续“也变成了一个过程(procedure)。每当kont被传递一个值，它会把她送给call/cc。如果没有传递值给kont，pro会把返回值送给call/cc。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
说的再简单点的话：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;kont想出人头地，抢了大哥pro的东西”current-constitution“，自己地位提高了，大哥却很伤心，kont虽然觉得对不起大哥，但是地位的诱惑还是很大的，不愿意把东西还给大哥。call/cc看到了，自己造了一个山寨货给pro，kont为感谢call/cc凡是自己收到的东西（地位提高了嘛，自然就有人1414），都送给call/cc，pro为了感谢call/cc，凡是别人送的东西（当然和kont的东西相比不值什么钱）也都送给call/cc。这么看来call/cc真是好奸啊！&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
例子：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(+ &amp;nbsp; &amp;nbsp;2&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (call/cc&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (lambda (kont)&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (+ &amp;nbsp; &amp;nbsp;3 &amp;nbsp; &amp;nbsp;(kont &amp;nbsp; 5))))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
kont收到礼物了，所以会返回：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(+ &amp;nbsp; 2 &amp;nbsp; &amp;nbsp; 5)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; =&amp;gt;&amp;nbsp;7&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(+ &amp;nbsp; 2&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; (call/cc&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(lambda &amp;nbsp;(kont)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (+3 &amp;nbsp; &amp;nbsp;5))))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
看来还有人恋旧情，pro收到礼物：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(+ &amp;nbsp; 2 &amp;nbsp; &amp;nbsp; &amp;nbsp;8)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; =&amp;gt; 10&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;b&gt;用法一：退出循环&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
定义一个函数list-product，该函数接受一个列表，返回列表中所有元素的积。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
法一：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(define &amp;nbsp; list-product&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(lambda &amp;nbsp; (s)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (let &amp;nbsp; &amp;nbsp; recur &amp;nbsp; ((s &amp;nbsp; &amp;nbsp;s))&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (if &amp;nbsp; &amp;nbsp; (null? &amp;nbsp;s) &amp;nbsp; 1&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(* &amp;nbsp; &amp;nbsp; (car &amp;nbsp; &amp;nbsp; s) &amp;nbsp; (recur &amp;nbsp; &amp;nbsp; (cdr &amp;nbsp; &amp;nbsp;s)))))))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
这样定义可行，但是如果有一个列表有几百个元素，而第二个元素就是零会怎么样？&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
结果这个程序会一个劲的傻算，浪费大家时间，还有我的电费。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
用call/cc会怎么样呢？&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(define &amp;nbsp; &amp;nbsp; &amp;nbsp;list-product&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (lambda &amp;nbsp; &amp;nbsp; (s)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(call/cc&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (lambda &amp;nbsp;&amp;nbsp;(exit)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (let &amp;nbsp; &amp;nbsp; recur &amp;nbsp; &amp;nbsp; ((s &amp;nbsp; &amp;nbsp;s))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;(if &amp;nbsp; &amp;nbsp;(null? &amp;nbsp; s) 1)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;(if &amp;nbsp; &amp;nbsp;(= &amp;nbsp; &amp;nbsp;(car &amp;nbsp; s) &amp;nbsp;0) &amp;nbsp;(exit &amp;nbsp; &amp;nbsp;0)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(* &amp;nbsp; &amp;nbsp; &amp;nbsp;(car &amp;nbsp; &amp;nbsp;s) &amp;nbsp; &amp;nbsp;(recur &amp;nbsp; (cdr &amp;nbsp; &amp;nbsp;s)))))))))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
程序突然变长了不少，这个就是代价吧！ 我们只用分析很色部分，其余的和上边的那个一样。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
红色部分：如果在某一步（程序是从左到右一步一步算）发现出现了0，那个2B kont——现在是exit，就会收到礼物0，他立马返回该值给call/cc，而程序的结果就是call/cc的返回值kont送的0。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
用法二：树的匹配&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
定义一个谓词same-fringe?匹配列表的展开是否相同&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: sans-serif; font-size: 12.800000190734863px; line-height: 19.200000762939453px; margin-bottom: 0.5em; margin-top: 0.4em;&quot;&gt;
&lt;span style=&quot;color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px;&quot;&gt;如：(same-fringe? &#39;(1 (2 3)) &#39;((1 2) 3))&lt;/span&gt;&lt;tt style=&quot;color: #454545; font-size: 14px; line-height: 21px;&quot;&gt;&lt;strong&gt;=&amp;gt;&lt;/strong&gt;&lt;/tt&gt;&lt;span style=&quot;color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px;&quot;&gt;#t(same-fringe? &#39;(1 2 3 4) &#39;(1 (3 2) 4 ))&lt;/span&gt;&lt;tt style=&quot;color: #454545; font-size: 14px; line-height: 21px;&quot;&gt;&lt;strong&gt;=&amp;gt;&lt;/strong&gt;&lt;/tt&gt;&lt;span style=&quot;color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px;&quot;&gt;#f&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
定义：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(define &amp;nbsp; same-fringe?&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; (lambda &amp;nbsp; (tree1 &amp;nbsp; tree2)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (let &amp;nbsp; loop &amp;nbsp; &amp;nbsp; ((ftree1 &amp;nbsp; (flatten &amp;nbsp; tree1))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (ftree2 &amp;nbsp; &amp;nbsp; (flatten &amp;nbsp;tree2)))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (cond &amp;nbsp; &amp;nbsp; ((and &amp;nbsp; &amp;nbsp;(null? &amp;nbsp; ftree1) &amp;nbsp;(null? &amp;nbsp; ftree2)) &amp;nbsp;#t)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ((or &amp;nbsp; (null? &amp;nbsp; &amp;nbsp; &amp;nbsp;ftree1) &amp;nbsp;(null? &amp;nbsp; ftree2)) &amp;nbsp; #f)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;((eqv? &amp;nbsp; (car &amp;nbsp; ftree1) &amp;nbsp; (car &amp;nbsp; &amp;nbsp;ftree2))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(loop &amp;nbsp;(cdr &amp;nbsp;ftree1) &amp;nbsp; &amp;nbsp;(cdr &amp;nbsp; ftree2))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (else &amp;nbsp; #f)))))&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
其中函数flatten的作用为将tree展开，使之只含最外面一对括号。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
例如：(1 &amp;nbsp; (2 &amp;nbsp; 3) &amp;nbsp;4)展开为(1 &amp;nbsp; &amp;nbsp;2 &amp;nbsp; 3 &amp;nbsp; 4)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
faltten的定义：&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
(define &amp;nbsp; flatten&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(lambda &amp;nbsp; (tree)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(cond &amp;nbsp; &amp;nbsp; ((null? &amp;nbsp; &amp;nbsp;tree) &amp;nbsp;&amp;nbsp;&#39;())&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;((pair? &amp;nbsp; &amp;nbsp; (car &amp;nbsp; tree))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(append &amp;nbsp; &amp;nbsp; (flatten &amp;nbsp; &amp;nbsp; (car &amp;nbsp; &amp;nbsp; tree))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(flatten &amp;nbsp; &amp;nbsp; (cdr &amp;nbsp; &amp;nbsp;tree))))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(else&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(cons &amp;nbsp; &amp;nbsp;(car &amp;nbsp; &amp;nbsp;tree)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; (flatten &amp;nbsp; &amp;nbsp; &amp;nbsp;(cdr &amp;nbsp; &amp;nbsp; tree)))))))&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
我们先看一下这个faltten的定义是不是能满足我们的要求。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
1.如果要展开的列表为空，返回空表。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
2.如果第一个元素是一个pair，我们就把它看作是列表吧，因为列表也是pair。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
就是说这种情况：((2 &amp;nbsp; &amp;nbsp;4) &amp;nbsp; &amp;nbsp;6)，它会把剩余的展开附加到(2 &amp;nbsp; 4)的展开，结果就为：(2 &amp;nbsp;4 &amp;nbsp;6).&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
3.如果第一个元素不为pair，会把第一个元素之外的剩余部分的展开附加到第一个元素后。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
这样：(2 &amp;nbsp;(4 &amp;nbsp; 5)) &amp;nbsp; =&amp;gt; &amp;nbsp;(2 &amp;nbsp; 4 &amp;nbsp; 5)&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
flatten确实能达到我们的要求。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
再来看same-fringe?&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
它会先用flatten把两棵树整个展开，然后从左到有依次比较各个元素。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
and部分：如果最后两棵树的元素都为空了，那么结果为真。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
or部分：如果最后其中一个为空而另一个不为空（不可能两者都为空，因为or字句在and字句后），那么结果为假。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
eqv?部分：如果这一步两者相同，就进入下一步循环。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
否则(else部分)：就为假。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
在这里我们终于说明same-fringe?可以达到我们的目地。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
但是肯定是有问题的呀，我们的call/cc还没出马呢，举一些极端情形下的例子，问题就出来了。&lt;/div&gt;
&lt;div style=&quot;background-color: white; color: #454545; font-family: Tahoma, Helvetica, Arial, STHeiti; font-size: 14px; line-height: 21px; padding: 0px;&quot;&gt;
假设：两颗树都很长很长，比如几千个元素，而它们的展开第二个元素就不同。那我们就没必要把他们全堵展开。&lt;/div&gt;
&lt;div style=&quot;background-color: white; font-family: sans-serif; font-size: 12.800000190734863px; line-height: 19.200000762939453px; margin-bottom: 0.5em; margin-top: 0.4em;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;函數調用與continuation&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
一般函數調用方法都是使用堆棧，用Activation record或Stack frame來記錄從最頂層函數到當前函數的所有context。&lt;br /&gt;
&lt;br /&gt;
一個frame/record就是函數的局部上下文信息，包括所有局部變量的值和SP, PC指針的值（通過靜態分析，某些局部變量的信息是不必保存的，特殊的如尾調用的情況則不需要任何stack frame。不過，邏輯上，我們認爲所有信息都被保存了）。&lt;br /&gt;
&lt;br /&gt;
函數的調用前往往伴隨著一些push來保存context信息，函數退出時則是取消當前的record/frame，恢複上一個調用者的record/frame。&lt;br /&gt;
&lt;br /&gt;
象pascal這樣的支持嵌套函數的，則需要一個額外的指針來保存父函數的frame地址。不過，無論如何，在任何時候，系統保存的就是一個後入先出的堆棧，一個函數一旦退出，它的frame就被刪除了。&lt;br /&gt;
&lt;br /&gt;
Continuation則是另一種函數調用方式。它不采用堆棧來保存上下文，而是把這些信息保存在continuation record中。這些continuation record和堆棧的activation record的區別在于，它不采用後入先出的線性方式，所有record被組成一棵樹（或者圖），從一個函數調用另一個函數就等于給當前節點生成一個子節點，然後把系統寄存器移動到這個子節點。一個函數的退出等于從當前節點退回到父節點。&lt;br /&gt;
&lt;br /&gt;
這些節點的刪除是由garbage collection來管理。如果沒有引用這個record，則它就是可以被刪除的。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;這樣的調用方式和堆棧方式相比的好處在哪裏呢？&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
最大的好處就是，它可以讓從任意一個節點跳到另一個節點。而不必遵循堆棧方式的一層一層的return方式。比如說，在當前的函數內，只要有一個其它函數的節點信息，完全可以選擇return到那個函數，而不是循規蹈矩地返回到自己的調用者。也可以在一個函數的任何位置儲存自己的上下文信息，然後，在以後某個適當的時刻，從其它的任何一個函數裏面返回到自己現在的位置。&lt;br /&gt;
&lt;br /&gt;
Scheme語言有一個CallCC (call with current continuation)的機制，也就是說：&lt;br /&gt;
取得當前的continuation，傳遞給要call的這個函數，這個函數可以選擇在適當的時候直接return到當前的continuation。&lt;br /&gt;
&lt;br /&gt;
經典的應用有：exception，back-tracking算法, coroutine等。&lt;br /&gt;
&lt;br /&gt;
應用continuation對付exception是很明顯的，只要給可能抛出異常的函數一個外面try的地方的continuation record，這個函數就可以在需要的時候直接返回到try語句的地方。&lt;br /&gt;
&lt;br /&gt;
　　Exception-handling也可以利用continuation。c++等語言普遍采用的是遇到exception就直接中止當前函數的策略，但是，還有一種策略是允許resume，也就是說，出現了異常之後，有可能異常處理模塊修複了錯誤發生的地方然後選擇恢複執行被異常中斷了的代碼。被異常中斷的代碼可以取得當前的continuation，傳遞給異常處理模塊，這樣當resume的時候可以直接跳到出現異常的地方。&lt;br /&gt;
&lt;br /&gt;
　　Back-tracking算法也可以用類似的方法，在某些地方保存當前的continuation，然後以後就可以從其它的函數跳回當前的語句。&lt;br /&gt;
&lt;br /&gt;
　　Coroutine是一個並行計算的模型。它讓兩個進程可以交替執行。典型的coroutine的應用例子如consumer-producer。比如說：&lt;br /&gt;
&lt;br /&gt;
　　Code:Producer ( c ):&lt;br /&gt;
&lt;br /&gt;
　　Loop:&lt;br /&gt;
&lt;br /&gt;
　　Produce;&lt;br /&gt;
&lt;br /&gt;
　　CallCC c&lt;br /&gt;
&lt;br /&gt;
　　Consumer( p ):&lt;br /&gt;
&lt;br /&gt;
　　Loop:&lt;br /&gt;
&lt;br /&gt;
　　Consume;&lt;br /&gt;
&lt;br /&gt;
　　Callcc p&lt;br /&gt;
&lt;br /&gt;
　　這兩個線程接受對方的continuation，在需要交出控制的時候，就把自己的continuation傳遞給對方。如此，兩者就可以交替執行，而不需要返回。&lt;br /&gt;
&lt;br /&gt;
　　Continuation機制的優化始終不是一個trivial的問題，實際上采取continuation的語言不多。而且，continuation調用方式依賴垃圾收集，也不是c/c++這類中低級的語言所願意采用的。&lt;br /&gt;
&lt;br /&gt;
　　不過，continuation的思想仍然是有其用武之地的。有一種設計的風格叫做continuation-passing-style。它的基本思想是：當需要返回某些數據的時候，不是直接把它當作函數的返回值，而是接受一個叫做continuation的參數，這個參數就是一個call-back函數, 它接受這個數據，並做需要做的事情。&lt;br /&gt;
&lt;br /&gt;
　　舉個例子：&lt;br /&gt;
&lt;br /&gt;
　　Code:X = f();&lt;br /&gt;
&lt;br /&gt;
　　Print x;&lt;br /&gt;
&lt;br /&gt;
　　把它變成continuation-passing-style, 則是：&lt;br /&gt;
&lt;br /&gt;
　　f(print)；&lt;br /&gt;
&lt;br /&gt;
　　F()函數不再返回x, 而是接受一個函數，然後把本來要返回的x傳遞給這個函數。&lt;br /&gt;
&lt;br /&gt;
　　這個例子也許看上去有點莫名其妙：爲什麽這麽做呢？對Haskell這樣的語言，一個原因是：&lt;br /&gt;
&lt;br /&gt;
　　當函數根據不同的輸入可能返回不同類型的值時，用返回值的話就必須設計一個額外的數據結構來處理這種不同的可能性。比如：&lt;br /&gt;
&lt;br /&gt;
一個函數f(int)的返回值可能是一個int, 兩個float或者三個complex，那麽，我們可以這樣設計我們的函數f.&lt;br /&gt;
&lt;br /&gt;
　　Code:F:: Int - (Int-a) - (Float-Float-a) - (Complex-Complex-Complex-a) - a&lt;br /&gt;
&lt;br /&gt;
這個函數接受一個整形參數，三個continuation回調用來處理三種不同的返回情況，最後返回這三個回調所返回的類型。&lt;br /&gt;
&lt;br /&gt;
另一個原因：對模擬imperative風格的monad，可以在函數中間迅速返回（類似于C裏面的return或者throw)&lt;br /&gt;
&lt;br /&gt;
對于C++，我想，除了處理不同返回類型的問題，另一個應用可以是避免返回值的不必要拷貝。雖然c++現在有NRV優化，但是這個優化本身就很含混，各個編譯器對NRV的實現也不同。C++中的拷貝構造很多時候是具有副作用的，作爲程序員，不知道自己寫的的副作用到底是否被執行了，被執行了幾次，總不是一個舒服事。&lt;br /&gt;
&lt;br /&gt;
而continuation-passing-style，不依賴于任何偏僻的語言特性，也不會引入任何的模棱兩可，也許可以作爲一個設計時的選擇。舉個例子, 對于字符串的拼接，如果使用continuation-passing-style如下：&lt;br /&gt;
&lt;br /&gt;
　　Code:Template&amp;lt;class F&lt;br /&gt;
&lt;br /&gt;
　　Void concat(const string&amp;amp; s1, const string&amp;amp; s2, F ret){&lt;br /&gt;
&lt;br /&gt;
　　String s(s1);&lt;br /&gt;
&lt;br /&gt;
　　S.append(s2);&lt;br /&gt;
&lt;br /&gt;
　　ret(s);//此處，本來應該是return(s)，但是我們把它變成ret(s)。&lt;br /&gt;
&lt;br /&gt;
　　}&lt;br /&gt;
&lt;br /&gt;
　　我們就可以很安心地說，我們此處沒有引入任何不必要的拷貝，不論什麽編譯器。&lt;br /&gt;
&lt;br /&gt;
當然，continuation style的問題是，它不如直接返回值直觀，類型系統也無法保證你確實調用了ret(s)。而且，它需要一個function object，c++又不支持lamda，定義很多trivial的functor也會讓程序變得很難看。&lt;br /&gt;
&lt;br /&gt;
　　利弊如何，還要自己權衡。&lt;br /&gt;
&lt;br /&gt;
Scheme 是一門神奇的編程語言，它不僅是世界上第一個完整支持閉包（closure）的語言，也是世界上第一個提供continuation 的語言。你可以看到wiki 上幾個關於Continuation 的條目全部用Scheme 作為示例語言。如無特指，本文以及接下來的兩篇文章中凡是提到continuation 的地方，均是指Scheme 中的continuation。&lt;br /&gt;
&lt;br /&gt;
During the evaluation of a Scheme expression, the implementation must keep track of two things: (1) what to evaluate and (2) what to do with the value. ... We call &quot;what to do with the value&quot; the continuation of a computation.&lt;br /&gt;
&lt;br /&gt;
Continuation 就是一個表達式被求值之後，接下來要做的事情。描述很簡單，但是Scheme continuation 的用法比較奇葩，導致我在學習continuation 的過程中被幾個問題困擾了很久，不過沒關係，哥現在終於搞清楚了。寫下這篇文章不是為了說明continuation 是什麼，而是想能幫助其他人更好地理解這個東西。下面我們通過幾個小實驗全面了解continuation 的各個特性，在看每一個例子的時候，希望你先思考一下“這段代碼的結果是什麼？”、或者“為什麼是這個結果？”，然後再看我的解說。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;I. 非本地退出&amp;nbsp;&lt;/b&gt;Non-local exit&lt;br /&gt;
&lt;div&gt;
非本地退出是初學continuation 很好的例子，因為它邏輯簡單，並且體現了continuation 的三個特性，：&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
continuation as first-class，簡單地說就是continuation 也可以視為一等公民，可以當做參數被傳遞和返回；&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
continuation is represented by procedure，也就是說可以視continuation 為過程，可以調用它，本來也應該如此，因為continuation 表示的正是“將來要做的事情；&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
假設call/cc 捕捉了當前的continuation，並綁定到lambda 的參數cc，那麼在lambda 函數體內，一旦cc 被直接或間接的作為過程調用，那麼call/cc 會立即返回，並且提供給cc 的參數即為call/cc 的返回值。&lt;/div&gt;
&lt;br /&gt;
請看下面這段程序：&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;text-indent: 28px;&quot;&gt;&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;(define (test element cc)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; (if (zero? element)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; (cc &#39;found-zero) ; non-local exit&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; (void)))&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;(define (search-zero test lst)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; (call/cc&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp;(lambda (return)&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;(for-each (lambda (element)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(test element return)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;(printf &quot;~a~%&quot; element)) ; print&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;lst)&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;#f)))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;(search-zero test &#39;(-3 -2 -1 0 1 2 3))&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;span style=&quot;color: #494949; font-family: Courier New, Courier, monospace;&quot;&gt;&lt;span style=&quot;line-height: 20.99431800842285px; white-space: normal;&quot;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/pre&gt;
運行結果：&lt;br /&gt;
-3&lt;br /&gt;
-2&lt;br /&gt;
-1&lt;br /&gt;
&#39;found-zero&lt;br /&gt;
&lt;br /&gt;
函數search-zero 遍歷表中所有的元素，每一次都把當前的continuation 取出來然後傳給test，一旦遇到0，就立即終止並返回&#39;found-zero。本來for-each 應當遍歷了整個表，但是test發現0的時候，就把&#39;found-zero 傳給cc，並調用之，由此search-zero 在這時直接返回，而不會執行下剩下的迭代。&lt;br /&gt;
&lt;div style=&quot;border: 0px; list-style: none; margin-bottom: 5px; padding: 0px; word-break: normal; word-wrap: normal;&quot;&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://photo.blog.sina.com.cn/showpic.html#blogid=4dff871201018wtz&amp;amp;url=http://s15.sinaimg.cn/orignal/4dff8712tc8226db92c8e&quot;&gt;&lt;/a&gt;&lt;span style=&quot;list-style-image: initial; list-style-position: initial; margin: 0pt auto;&quot;&gt;&lt;img action-data=&quot;http%3A%2F%2Fs15.sinaimg.cn%2Fmiddle%2F4dff8712tc8226db92c8e%26690&quot; action-type=&quot;show-slide&quot; alt=&quot;Scheme &amp;lt;wbr&amp;gt;Continuation &amp;lt;wbr&amp;gt;三部曲（一）鈥斺斏钊肜斫 &amp;lt;wbr&amp;gt;Continuation&quot; height=&quot;282&quot; name=&quot;image_operate_77221345951105924&quot; real_src=&quot;http://s15.sinaimg.cn/middle/4dff8712tc8226db92c8e&amp;amp;690&quot; src=&quot;http://s15.sinaimg.cn/middle/4dff8712tc8226db92c8e&amp;amp;690&quot; style=&quot;border: 0px; display: block; list-style: none; margin: 0pt auto; padding: 0px;&quot; title=&quot;Scheme &amp;lt;wbr&amp;gt;Continuation &amp;lt;wbr&amp;gt;三部曲（一）鈥斺斏钊肜斫 &amp;lt;wbr&amp;gt;Continuation&quot; width=&quot;400&quot; /&gt;&lt;/span&gt;&lt;/div&gt;
我把函數的一次次求值畫成一段段的箭頭，當test 遇到0的時候，它利用cc 執行了一次非本地退出，跳到了cc 定義的continuation，怎麼知道這個continuation 是什麼呢？分析一下它的值被用來做什麼了。由於search-zero 的整個函數體都被call/cc 包起來了，所以call/cc 的返回值剛好就是search-zero的返回值，而這個值接下來被用來執行的操作就是輸出到屏幕——這就是cc 的內容，test 利用cc 令search-zero 中的call/cc 返回&#39;found-zero，隨後這個結果被輸出到了屏幕上。&lt;br /&gt;
&lt;br /&gt;
實際上還沒完，R5RS描述道，“ The continuation represents an entire (default) future for the computation”。 continuation 不僅保存了這個表達式的值被求出來後拿去做了什麼，還保存著這個值被求出來後，對後序表達式的求值操作。 sea​​rch-zero 是在頂層被調用的，所以cc 還包括“提示下一個輸入，執行輸入的表達式，如此永不停歇”。也就是說， cc 中包含著一個無限的操作—— 一時難以理解是吧，但事實就是如此，哈哈哈。&lt;br /&gt;
&lt;br /&gt;
再看一個生成器，它接收一個列表作為參數，每次被調用的時候就返回一個元素，有點像python 的yield：&lt;br /&gt;
&lt;pre style=&quot;background-color: #eb735a; color: #494949; font-size: 14px; line-height: 21px; text-indent: 28px; white-space: normal;&quot;&gt;&lt;code&gt;
(define (generate-one-element-at-a-time lst)
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;;; Hand the next item from a-list to &quot;return&quot; or an end-of-list marker
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(define (control-state return)
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(for-each&amp;nbsp;
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(lambda (element)
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(call/cc
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(lambda (resume-here)
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;;; Grab the current continuation
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(set! control-state resume-here) ;; !!!
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(return element))))
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;lst)
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(return &#39;end))

&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(define (generator)
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(call/cc control-state))&amp;nbsp;

&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;;; Return the generator&amp;nbsp;
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;generator)

(define generate-digit
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;(generate-one-element-at-a-time &#39;(0 1 2)))

&amp;gt; (generate-digit)
0
&amp;gt; (generate-digit)
1
&amp;gt; (generate-digit)
2
&amp;gt; (generate-digit)
&#39;end
&amp;gt; (generate-digit)
&#39;end&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
又是一个非本地退出的例子，值得注意的是 control-state，这个函数第一次被调用的时候它还是个函数，但是看注释“!!!”的这一行，经过第一次调用后， control-state 就把自己改成了一个 continuation，随后借助 generator 传进来的 return，完成一次非本地退出（在 control-state 里退出generator）。第一次看这个可能有点晕，因为这里有两个 call/cc，而且还是嵌套的。这两个 call/cc 各司其职，generator 里的 call/cc 是为了非本地退出，第二个 call/cc 则是为了记录遍历列表的状态——这样下一次调用 generator 的时候，通过 control-state（它是个 continuation），就能直接从上次修改 continuation 的地方继续运行，从而跳了回去，达到生成器的效果。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
通过在 call/cc 内 apply continuation，我们可以在任意时刻从函数中跳出来；通过修改中途获取的 continuation，我们还可以跳回去。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
II. 非引用透明性&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
我们知道，引用透明性（Referential Transparent）是纯函数式语言的重要特征，但通过 call/cc，我们能定义出一个不具有引用透明性的函数：&lt;br /&gt;
&lt;div style=&quot;border: 0px; color: #494949; font-size: 14px; line-height: 21px; list-style: none; margin-bottom: 5px; padding: 0px; text-indent: 28px; word-break: normal; word-wrap: normal;&quot;&gt;
&lt;code&gt;&lt;span style=&quot;background-color: white; font-family: Courier New, Courier, monospace;&quot;&gt;(define (get-cc) (call/cc (lambda (c) c)))&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
看出 get-cc 做了什么吗？它捕捉到当前的 continuation 然后返回，显然这个函数的返回值受到上下文——准确地说是下文，的影响，所以它其实很不透明= = 但正是它的不透明性能帮助我们更好地了解 continuation。来看下面这段代码：&lt;br /&gt;
&lt;pre style=&quot;background-color: #eb735a; color: #494949; font-size: 14px; line-height: 21px; text-indent: 28px; white-space: normal;&quot;&gt;&lt;code&gt;
&amp;gt; (define x (get-cc))
&amp;gt; x
#&amp;lt; continuation&amp;gt;
&amp;gt; (x 10)
&amp;gt; x
10
&amp;gt; (number? x)
#t
&amp;gt; ((get-cc) 10)
. . a application: not a procedure;
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;expected a procedure that can be applied to arguments
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;given: 10
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;arguments...:
&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;&lt;wbr&gt;&lt;/wbr&gt;&amp;nbsp;10
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
你明白上面发生了什么吗？ x 明明是个 continuation，怎么变成10了？？为什么 (get-cc) define 成 x可以被调用，却不能被直接调用？？？&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
我曾经被这几个“奇怪的现象”困扰了好一阵子。但是想清楚 get-cc 的不透明性及其缘由就明白了。实际上，经过 define 之后， x 获得了一个 continuation，这个 continuation 是什么呢？……是获取一个值，然后绑定到 x —— 恰好就是 define 所做的事情。所以再以10为参数调用 x 的时候， continuation 把10绑定到 x，x 又被绑定了一次，就变成数字10了。但是直接对 (get-cc) apply 10的时候，却提示错误，这是因为这个 (get-cc) 接下来被用来当成函数调用了，所以给它传一个10之后，这个10就被当做函数执行，显然这是不对的。get-cc 是个神奇的函数，就是获取它这个位置上的 continuation， (get-cc) 自己被用来做了什么事，它返回的 continuation 就对别人做同样的事，以彼之道，还施彼身。如果你感到有点晕，别急着往下看，先消化一下。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
接下来这个表达式，你能看出它的返回值是什么吗？(let ([x (get-cc)]) (x (lambda (unused) &quot;我擦&quot;)))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
也许你能马上猜到结果，但是不一定能马上明白。我们仍然从 (get-cc) 开始分析。我们看到 (get-cc)被用来绑定到 x上，随后以 (lambda (unused) &quot;我擦&quot;)) 为参数调用 x。现在开始还施彼身。于是，接下来(lambda (unused) &quot;我擦&quot;)) 也被绑定到 x 上，然后用参数 (lambda (unused) &quot;我擦&quot;)) 调用新的 x，显然这个参数没有用上，所以 x 直接返回了“我擦”。真是我擦啊……&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
这是最后一个关于 get-cc 的例子。&lt;br /&gt;
&lt;pre style=&quot;background-color: #eb735a; color: #494949; font-size: 14px; line-height: 21px; text-indent: 28px; white-space: normal;&quot;&gt;&lt;code&gt;(((get-cc) (lambda (x) x)) &quot;我又擦&quot;)&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
你应该马上就能猜到，这个表达式返回了“我又擦”，but why?&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
沿用刚才的思路，先分析 (get-cc) 自己被用来做了什么？它被当成函数，以 (lambda (x) x) 为参数进行调用，调用的返回值又被当成函数，以“我又擦”为参数执行调用。好，(get-cc) 的参数是 (lambda (x) x)——一个恒等函数，于是 (lambda (x) x) 被当成了函数，以 (lambda (x) x)（没错，就是它自己）为参数执行调用，返回值当然还是它自己，又一个恒等函数；最后，这个恒等函数接收参数“我又擦”，当然也就返回“我又擦”。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
(get-cc) 的非引用透明性来源于它的语义，它总是捕捉当前的 continuation 并返回之。可以这么理解call/cc，它可以出现在任何一个本应是表达式的地方（它占了表达式的位置）。凡是表达式都要求值，并且还要求它的后续表达式的值，程序员通过call/cc，可以在该表达式出现的地方捕捉（catch）到该表达式的后续操作。被捕捉到的后续操作即为 continuation，某种程度上说，它就像个时光机，调用捕捉到的 continuation 可以回到过去。但是注意调用 continuation 和非本地退出的区别，后者是在 call/cc 的函数体内（直接或间接）调用捕捉到的 cc，这是 continuation 的特殊用法，它能立即退出，而且可以在非本地退出；而前者是在相应 continuation 的 call/cc 之外调用，它的作用就是重复后续操作。&lt;br /&gt;
&lt;br /&gt;
III. 移花接木&lt;br /&gt;
这一部分只讲解一个例子，不过这个例子更绕~ &lt;a href=&quot;http://www.cppblog.com/vczh/&quot;&gt;V神&lt;/a&gt;跟我说，monad 就是给一个函数打很多个孔，然后灵活地组合，我觉得 continuation 也是给函数打孔，而且不同函数打的孔还可以对接起来。&lt;br /&gt;
&lt;br /&gt;
生产者-消费者问题是检验多任务机制的经典问题，我们可以用 continuation 模拟这个过程，即生成-消费-再生产-再消费-...
(define dish #f)

(define (put! fruit) (set! dish fruit))
(define (get!) (let ([fruit dish]) (set! dish #f) fruit))

(define (consumer do-other-stuff)
  (let loop ()
    (when dish
      (printf &quot;C: get a ~a~%&quot; (get!))
      (set! do-other-stuff (call/cc do-other-stuff))
      (loop))))

(define (producer do-other-stuff)
  (for-each (lambda (fruit)
              (put! fruit)
              (printf &quot;P: put a ~a~%&quot; fruit)
              (set! do-other-stuff (call/cc do-other-stuff)))
            &#39;(&quot;apple&quot; &quot;strawberry&quot; &quot;peach&quot;  &quot;grape&quot;)))

(producer consumer)
&lt;br /&gt;
&lt;br /&gt;
producer 通过 for-each “生产”了几个水果，每生成一个就放进盘子里，并通过 call/cc 把控制权交给 consumer，consumer 先看看盘子里有没有水果，如果有就取。运行结果不难预科：
&amp;gt; (producer consumer)
P: put a apple
C: get a apple
P: put a strawberry
C: get a strawberry
P: put a peach
C: get a peach
P: put a grape
C: get a grape&lt;br /&gt;
&lt;br /&gt;
实际上这段程序有两个过程交替运行，我们知道多任务控制流的一个关键就是，保存每个任务的上下文，让它切出去再返回的时候能接着执行，就像没有发生过切换一样。这个任务，continuation 完全胜任。How does it works?&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
producer 往盘子里放水果之后，通过 call/cc 调用 consumer，它的 continuation 就传进 consumer了（consumer 的 do-other-stuff 就是 producer 的 continuation）， consumer 取出水果之后，就能通过这个 continuation 回到 producer，同时它也把自己的 continuation 传给了 producer。两个函数通过互传 continuation 的方式实现切换和恢复。&lt;br /&gt;
&lt;br /&gt;
IV. 模拟多任务&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
最后，我们看看如何用 continuation 模拟多任务。刚才的例子已经模拟了一个很简单的多任务过程，即producer 和 conmuser 两个过程“同时”运行，但那是两个任务都知道对方的存在从而实现精确的同步。如果是几个独立的进程，如何并发执行呢？
(define lwp-list &#39;())
(define lwp
  (lambda (thunk)
    (set! lwp-list (append lwp-list (list thunk)))))

(define start
  (lambda ()
    (let ([p (car lwp-list)])
      (set! lwp-list (cdr lwp-list))
      (p))))

(define pause
  (lambda ()
    (call/cc
      (lambda (k)
        (lwp (lambda () (k #f)))
        (start)))))

(lwp (lambda () (let f () (pause) (display &quot;h&quot;) (f))))
(lwp (lambda () (let f () (pause) (display &quot;e&quot;) (f))))
(lwp (lambda () (let f () (pause) (display &quot;y&quot;) (f))))
(lwp (lambda () (let f () (pause) (display &quot;!&quot;) (f))))
(lwp (lambda () (let f () (pause) (newline) (f))))
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
lwp 即 ligth-weight process, lwp-list 是进程表，不难看出 lwp 和 start 的作用分别是添加一进程到进程表、和从进程表里取出一个进程并执行，理解这段程序的关键在于 pause。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
pause 是这些进程真正的调度者，它不仅有副作用，而且也不具有引用透明性，所以难以理解，我们分析一下。(lwp (lambda () (k #f))) 把 pause 的 continuation 添加到进程表尾，以备将来恢复。但注意，call/cc 能取出一个函数的全部未来，当然也包括这个函数执行完毕后的后续操作——每一个 lwp 调用pause 之后的操作是“输出一个字符，然后再递归调用自己”，这些操作当然也在 pause 的 continuation 里面——&lt;br /&gt;
&lt;div style=&quot;background-color: #eb735a; border: 0px; color: #494949; font-family: simsun; font-size: 14px; line-height: 21px; list-style: none; margin-bottom: 5px; padding: 0px; text-indent: 28px; word-break: normal; word-wrap: normal;&quot;&gt;
&lt;img action-data=&quot;http%3A%2F%2Fs10.sinaimg.cn%2Fmiddle%2F4dff8712tc8226f220879%26690&quot; action-type=&quot;show-slide&quot; alt=&quot;oh no&quot; name=&quot;image_operate_49491345950662697&quot; real_src=&quot;http://s10.sinaimg.cn/middle/4dff8712tc8226f220879&amp;amp;690&quot; src=&quot;http://s10.sinaimg.cn/middle/4dff8712tc8226f220879&amp;amp;690&quot; style=&quot;border: 0px; list-style: none; margin: 0px; padding: 0px;&quot; title=&quot;&quot; /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
你看出来了吗？这些进程第一次被执行时不输出任何信息，因为它们到达 (pause) 的时候，pause 把剩余操作打包成 continuation 放到进程表尾，然后就执行下一个进程了。最后的执行结果就是不停的打印 &quot;hey!&quot;：
&amp;gt; (start)
hey!
hey!
hey!
hey!
hey!
 &lt;br /&gt;
&lt;br /&gt;
V. 总结一下&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
如果充分理解的上面所有的例子，那也就相当程度地掌握了 continuation。说了那么多，continuation 有什么用呢？这篇文章举的例子已展示了一些使用 continuation 的模式，如非本地退出、保存上下文等。在第三篇文章中我们还会看到如何用 continuation 消除非尾递归。continuation 为程序员提供了一种强大、灵活、近乎随心所欲的控制流（Tom 言：时光机），但是它太锋利，而且很多时候还要涉及一些带副作用的操作，另外想必你也发现带 call/cc 的代码非常难读= =，综上所述，除非你已经非常非常熟悉 continuation， 否则不建议轻易使用。其实我仍然有一些小细节没有讲，有些是连自己也没明白透，有些是特意留着让你自己去发现。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
下一篇文章，我们将领略 continuation 的终极奥义，真·阴阳谜题，敬请期待。&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/5949638776461791115/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/06/continuation.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/5949638776461791115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/5949638776461791115'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/06/continuation.html' title='Continuation'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-4525438886861761372</id><published>2012-06-03T19:15:00.000-07:00</published><updated>2013-11-27T17:23:28.551-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="字碼處理"/><title type='text'>Unicode與Big5轉換</title><content type='html'>&lt;b&gt;Unicode&lt;/b&gt;&lt;br /&gt;
大五碼 ( BIG5 )，是用一個數字來表示英文字母及一些符號的數碼。對歐美國家的文字來說，只需約一～兩百個就已足夠，這是因為他們的文字都是以字母拼成，而每種語言的字母個數不多，例如英文字母僅 26 個，再加上空白、標點符號、阿拉伯數字等等，不超過一百個。&lt;br /&gt;
一個位元組 ( byte ) 有 8 個位元，可以表示 0～255 之間的數值，也就是說可以表示 256 種 ( 28=256 ) 不同的數字，若一個數表示一個字母或符號，那麼 ASCII 碼用一個位元組的長度就已經夠了，後來 ASCII 果真以 7 個位元表示，而 IBM 推出 PC/XT 時，把 ASCII 擴充為 8 個位元寬，即為一個位元組的大小。像 ASCII 這種系統，我們稱之為『單位元組編碼系統』( SBCS，Single Byte Code System。也有人稱為『單位元組字集』，Single Byte Character Set )。&lt;br /&gt;
但對於中文，就嫌不夠了。常用的中文字保守估計也有數千個，因此得用兩個位元組來表示文字，2 個位元組共有 16 個位元，最多可以表示 216，亦即 65536 個數，像這種以 2 個位元組編碼的方式稱為『雙位元組編碼系統』( DBCS，Double Byte Code System，也有人稱為『雙位元組字集』，Double Byte Character Set )。早期中文電腦發展時，並沒有強而有力的國家標準編碼，所以造成每一家公司或機構所發展的編碼不同而不相容。到了中華民國 73 年，中華民國財團法人資訊工業策進會和五間電腦公司，宏碁、神通、佳佳、零壹及大眾，所共同發展一套中文的編碼系統，這五家電腦公司在當時是數一數二的大公司，其影響力可謂舉足輕重，而他們所發展的編碼系統就稱為大五碼 ( Big5 )。詳情見維基百科有關&lt;a href=&quot;http://zh.wikipedia.org/wiki/%E5%A4%A7%E4%BA%94%E7%A2%BC&quot;&gt; Big5 &lt;/a&gt;的說明。&lt;br /&gt;
由於大五碼的誕生，使得中文編碼有依循的標準，後來在 DOS 系統中的倚天中文，Windows 3.1 以及 Windows 95/98/Me 都採用這先後採用這套編碼來處理正體中文。但是 Big5 碼所收錄的字太少，許多人名、地名並沒有包括在內。因此後來有許多機構在 Big5 的基礎上加以擴充。現今 ( 民國 80～95 年 )，使用正體中文的國家或地區，像中華民國、香港、新加坡以及海外華人的中文電腦，大多使用 Big5 碼。&lt;br /&gt;
&lt;br /&gt;
倚天中文系統在 DOS 系統下執行的倚天中文，採用的就是 Big5 碼。倚天中文系統執行後，會常駐於記憶體裏。倚天中文顯示文字的原理與英文類似，請參考&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ch30.html#VGA_memory&quot;&gt;第三十章&lt;/a&gt;顯示記憶體的說明。倚天中文也是把 B800:0000 開始的記憶體當成顯示記憶體，偶數位址是存放 Big5 碼，奇數位址是存放顏色，例如假設在螢幕上左上角顯示綠色的『我學 ASSEMBLY。』這句話，那麼用 DEBUG.EXE 觀察位址 B800:0000，您會看見：&lt;br /&gt;
B800:0000 A7 02 DA 02 BE 02 C7 02 20 02 41 02 53 02 53 02 ........ .A.S.S.
B800:0010 45 02 4D 02 42 02 4C 02 59 02 A1 02 43 02 20 00 E.M.B.L.Y...C. .&lt;br /&gt;
的記憶體內容，其中以白色標起來的 A7DA、BEC7 和 A143 分別是『我』、『學』和『。』的 Big5 碼，而位址 B800:0001、B800:0003、B800:0005、B800:0007 等內容為 02 的位元組是綠字黑底的顏色號碼 ( 參考附錄七的&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ap07.html#note1&quot;&gt;表一&lt;/a&gt; )。或許您會問，如果改變 B800:0001 或 B800:0003 的內容，使它們不一樣，這樣是不是會變成同一個字，但左半部和右半部顏色不同？的確如此，您可以試試看。底下以列表方式說明：&lt;br /&gt;
&lt;br /&gt;
當倚天中文常駐於記憶體後，如果它發現螢幕上的資料屬於 Big5 碼，倚天中文會以這個 Big5 碼查出字形檔中該字的字形，最後再依據字形把字顯示於螢光幕上，這一點與 ASCII 的碼是一樣的。&lt;br /&gt;
在倚天中文採用 Big-Endian 的方式存入記憶體。此外在 Big5 的純文字檔案裏，也是以 Big-Endian 方式存入磁碟，這點和 PC 的習慣不同。有關什麼是 Big-Endian？什麼是 Little-Enddian？請參閱後面的&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ap10.html#byte_order&quot;&gt;說明&lt;/a&gt;。&lt;br /&gt;
在這種以 Big5 編碼系統中，如果遇到中英文混合資料時，有兩種選擇，一是像上面的例子，ASCII 與 Big5 混合使用，但這樣一個字元可能佔用一個位元組也可能兩個位元組，在計算字串長度時有點困難；另一種是完全採用 Big5 碼，遇到英文時也採用&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ap10.html#note1&quot;&gt;全形字體&lt;/a&gt;。&lt;br /&gt;
&lt;a href=&quot;http://mo-bian.blogspot.tw/2012/06/google-httphome.html&quot;&gt;&lt;/a&gt;Big5 碼的編碼方式是以筆畫順序為依據，若筆畫相同則依其部首的筆畫排序。您可以到&lt;a href=&quot;http://i18n.linux.org.tw/openi18n/big5/code/&quot;&gt; Openi18n 台灣網頁&lt;/a&gt;去查詢每個 Big5 碼所代表的中文字。&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;萬國碼 ( UNICODE )&lt;/b&gt;&lt;br /&gt;
緣起隨著網際網路的發達，電腦已不是一座座的孤島，常常需要藉由網路與外界相連，讀取國外的資料，而這些資料不一定是本國語言或英文，像是日文、泰文、阿拉伯文、俄文……等等。甚至有時希望能在同一份文件中，能包含數種文字。要達到這目標，就不能靠一種語文一種編碼的方式了。&lt;br /&gt;
為了解決這個難題，自民國 73 年開始，有兩個組織著手研究這個問題。其中一個是國際標準組織 ( ISO，International Organization for Standardization ) 與聯合國下屬的國際電氣技術委員會 ( IEC，International Electro-technical Commission ) 合組的工作小組，該小組草擬提出的 ISO 10646 標準草案。另一個組織是由 IBM、DEC、Sun、Xerox、Apple、MicroSoft、Novell 公司，共同出資成立的 Unicode 協會，該協會設立非營利的 Unicode 公司，並由該公司設計出適用全球的萬國碼 ( Universal Code；簡稱 Unicode，亦有人稱統一碼、單一碼或萬國碼 )。雖然一開始，這兩個組織的工作是各自發展的，但是最後他們體認到世界不需要有兩套編碼，否則豈不是陷於當初的困境？於是在民國 80 年左右，他們合併了雙方的成果變成 ISO 10646/Unicode 標準，提供全世界語言文字與符號的顯示、儲存、傳送等，不但避免了資源的浪費，也能落實統一全球文字交換標準的理想。&lt;br /&gt;
要把全球所有文字編碼，不是一件簡單的事情。據估計全世界約有不到七千種語言，但是有些語言只有聲音沒有文字，扣除這些語言，只算有文字的語言約有兩千多種。要把這些語言的每個字都編成碼也不是簡單的工作，因為到底有多少個文字或字母，誰也說不準。但編碼工作總是要繼續的，經過數十年的努力，辛勤的工作總算有的結果，在民國 82 年發表的 ISO 10646。&lt;br /&gt;
&lt;br /&gt;
UCS-4在 ISO 10646 裏用四個位元組來編碼，因此稱為 UCS-4，UCS 是 Universal Multiple-Octet Coded Character Set 的縮寫，意義為多個八位元編碼的廣用文字集，4 代表 4 個位元組。ISO 10646 依位元組高低次序把每一位元組稱為群組 ( group )、字面 ( plane )、列 ( row )、格 ( cell )。群組的最高位元不使用，僅剩七個位元，由 00H～07FH 共 128 個，可分成 128 群組；次高位元組代表字面，所以每一群都有 256 個字面 ( 00～0FFH )，每個字面本應有 216，即 65536 個空間可容納文字 ( 每個文字得佔用一個空間，或稱一個碼位 )，但 ISO 10646 裏規定最後兩格不用，所以每個字面變成 65534 個字。依據這個規則，最多可以把 65534×128×256 ＝2,147,418,112，約二十一億個文字編成碼。有關群組、字面的說明，請參考下圖所示 ( 下圖參考 &lt;a href=&quot;http://61.60.106.73/web/word.jsp#iso10646&quot;&gt;CNS11643 中文全字庫&lt;/a&gt;繪製而成 )：&lt;br /&gt;
&lt;br /&gt;
UCS-2 與 BMP雖然 ISO 10646 裏用四個位元組來編碼，但是實際上，全球重要的語言已經有九成五以上都包含在第 00 群組的第 00 字面。所以為了考慮效率，在 ISO 10646 也特別規定第 00 群組的第 00 字面稱為『基本多語文字面』( Basic Multilingual Plane，簡稱 BMP )，如果所使用的文字都在 BMP 內，那麼就可以用兩個位元組來表示，以節省空間增進效率，像這種字集稱為 UCS-2，也因為效率，世界各國莫不想讓本國文字擠進 BMP 裏。說了這麼多，小木偶整理一下：在實際使用上，萬國碼可分為 UCS-2 與 UCS-4 兩種編碼方式，如果所使用的文字都在 BMP 上，那麼使用 UCS-2 就可以了，否則就必須使用 UCS-4。同一份文件或檔案裏只能選擇其中一種，不是 UCS-2 就是 UCS-4，不能混用，以免造成一個字不定長度的缺點。&lt;br /&gt;
&lt;br /&gt;
世界最重要的幾種語言，如北京話 ( 約 八億六千萬人使用 )、英語 ( 約四億三千萬人使用 )、印地語 ( 印度所使用的語言，約三億兩千萬人使用 ) 等語言都已被編入 BMP 中。各語文所佔編碼範圍可以參考維基百科有關&lt;a href=&quot;http://zh.wikipedia.org/w/index.php?title=%E5%9F%BA%E6%9C%AC%E5%A4%9A%E6%96%87%E7%A8%AE%E5%B9%B3%E9%9D%A2&amp;amp;variant=zh-tw&quot;&gt;基本多語文字面&lt;/a&gt;與曾士熊先生所著 &lt;a href=&quot;http://www.ascc.sinica.edu.tw/nl/89/1610/02.txt&quot;&gt;Unicode 與 ISO10646&lt;/a&gt; 的描述，而各字的編碼可到 &lt;a href=&quot;http://www.unicode.org/charts/&quot;&gt;www.unicode.org&lt;/a&gt; 檢閱。底下是依熊先生的文章所作的介紹：&lt;br /&gt;
&lt;br /&gt;
0000～007Fh： C0 控制碼與基本拉丁字母區。其中 0000～001Fh 為 C0 控制碼，0020h 為空格 ( space )，0021～007Eh 為 ASCII 圖形字元……事實上，這 128 個字元碼只要把前 8 個位元去掉就是 ASCII 碼。&lt;br /&gt;
&lt;br /&gt;
0080～00A0h： 控制碼區。0080～009Fh 為 C1 控制碼，00A0h 為不中斷空格 ( no-break space )&lt;br /&gt;
00A1～1FFFh： 拼音文字區。收容除基本拉丁字母以外的各種拼音文字字元，包括歐洲各國語言、希臘文、斯拉夫語文、希伯來文、阿拉伯文、亞美尼亞文、印度各地方言、馬來文、泰文、寮文、柬普寨文、滿文、蒙文、藏文、印地安語文等。&lt;br /&gt;
2000～2BFFh： 符號區。收容各種符號，包括標點符號、上下標、錢幣符號、數字、箭頭、數學符號、工程符號、光學辨識符號、帶圈或帶括符的文數字、表格繪製符號、地理圖示、盲用點字、裝飾圖形等。&lt;br /&gt;
2C00～2E7Fh： 拼音文字區，包含格拉哥里字母、古埃及文、衣索匹亞語等…&lt;br /&gt;
2E80～33FFh： 中日韓符號區。收容康熙字典部首、中日韓輔助部首、注音符號、日本假名、韓文音符，中日韓的符號、標點、帶圈或帶括符文數字、月份，以及日本的假名組合、單位、年號、月份、日期、時間等。&lt;br /&gt;
3400～4DFFh： 中日韓認同表意文字擴充 A 區，總計收容 6582 個中日韓漢字。表義文字是指文字像是一種圖形符號，只代表語素，而不代表音節，例如中、日、韓、越等文字即屬表義文字。與表義文字相對的是拼音文字，如英語即是拼音文字。&lt;br /&gt;
4E00～9FFFh： 中日韓認同表意文字區，總計收容 20902 個中日韓漢字。可到 &lt;a href=&quot;http://www.unicode.org/charts/PDF/U4E00.pdf&quot;&gt;www.unicode.org&lt;/a&gt; 下載各字的編碼。&lt;br /&gt;
A000～A4FFh： 彝族文字區，收容中國南方彝族文字和字根。&lt;br /&gt;
A500～ABFFh： 包含加拿大土著語、聲調修飾字母、八思巴字、爪哇語、越南傣語等。&lt;br /&gt;
AC00～D7FFh： 韓文拼音組合字區，收容以韓文音符拼成的文字。&lt;br /&gt;
D800～DFFFh： S 區，專用於 &lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ap10.html#note2&quot;&gt;UTF-16&lt;/a&gt;。&lt;br /&gt;
E000～F8FFh： 專用字區，其內容沒有規定，保留供使用者自行添加 ISO 10646 未收容的字元。&lt;br /&gt;
F900～FAFFh： 中日韓相容表意文字區，總計收容 302 個中日韓漢字。&lt;br /&gt;
FB00～FFFDh： 文字表現形式區，收容組合拉丁文字、希伯來文、阿拉伯文、中日韓直式標點、小符號、半形符號、全形符號等。&lt;br /&gt;
&lt;br /&gt;
輔助字面除了基本多語文字面以外的字面都稱為『輔助字面』，輔助字面多存放罕用的文字。當使用輔助字面的文字時，就得用 4 個位元組來表示一個字了。第一輔助字面 ( Supplementary Multilingual Plane，簡稱 SMP )，擺放拼音文字，主要為現時已不再使用的文字及符號。範圍在 00010000～0001FFDh。&lt;br /&gt;
&lt;br /&gt;
第二輔助字面，又稱為表意文字補充字面 ( Supplementary Ideographic Plane，簡稱 SIP )，整個範圍在 00020000～0002FFFDh。擺放「中日韓統一表意文字擴展 B 區」，共 43253 個漢字，以及中日韓相容表意文字增補 ( CJK Compatibility Ideographs Supplement )。這些文字主要康熙字典、漢語大字典為基礎，扣除已編入 BMP 的文字，再加上各國所提字集，進行整理。其他字面有些是尚未編入文字，有些對我們而言是幾乎不會用到，所以就不介紹了。不過您應當可以參考上面的 UCS-4 全部編碼空間知道尚有許多空間尚未編碼。&lt;br /&gt;
&lt;br /&gt;
UNICODE 轉換成 BIG5在這一章的例子裏，小木偶打算製作一個程式，使其能把 Unicode 轉換成 Big5 碼。還記得 FAT32 裏的 FDB 中，長檔名格式的檔名是以 Unicode 記錄嗎？此章小木偶打算延續&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ch34.html&quot;&gt;第三十四章&lt;/a&gt;的內容，針對 DFC.EXE 的缺點改進使其能顯示長檔名。在 Win 9x/Me 的『DOS 視窗』裏的中文是以 Big5 碼顯示中文，因此長檔名必須轉換成 Big5 碼才能正確顯示，否則是一堆亂碼。&lt;br /&gt;
&lt;br /&gt;
轉換表格︰cp950-u2b.txt要撰寫一個可以把 Unicode 轉換成 Big5 的程式，最大的困難在於製作一張上萬個字的萬國碼轉換成大五碼對照表，幸好在網際網路上已經有人製作好了這張表，在&lt;a href=&quot;http://www.moztw.org/docs/big5/&quot;&gt; Mozilla Taiwan：Mozilla 系列與 Big5 中文字碼&lt;/a&gt;有這樣的一張表。在眾多 Big5 版本裏，小木偶選擇了微軟的 CP950 版本，原因有兩個，一是為了配合底下的例子，DFC3.EXE，DFC3.EXE 是讀取 Win 9x/Me 系統長檔名，眾所皆知，Win 9x/Me 是微軟的產品，自己所改進的 Big5 碼應該會支援吧？；二是該網頁也建議用這一張表。&lt;br /&gt;
&lt;br /&gt;
在該網頁中下載 &lt;a href=&quot;http://www.moztw.org/docs/big5/table/cp950-u2b.txt&quot;&gt;cp950-u2b.txt&lt;/a&gt; 檔案，它就是把萬國碼轉換成 Big5 的表格。cp950-u2b.txt 是純文字檔，底下是前面幾行的內容︰&lt;br /&gt;
# big5 unicode
0x0021 0x00A1
0xA246 0x00A2
0xA247 0x00A3
0xA244 0x00A5
0x007C 0x00A6
0xA1B1 0x00A7
0xA14C 0x00A8
0x0063 0x00A9
0x0061 0x00AA
0x002D 0x00AD
0x0052 0x00AE
0xA1C2 0x00AF
……&lt;br /&gt;
由上面可以看出，cp950-u2b.txt 是按照第二列的 Unicode 由小至大排列，而 Unicode 前的十六進位數值就是相對應的 Big5 碼，例如第一行的 Unicode 的 0x00A1 換成 Big5 碼就是 0x0021。因此有了這張表，要把 Unicode 轉換成 Big5 就非常容易了，在此特別感謝這張表格的作者。儘管如此，cp950-u2b.txt 對組合語言的設計者來說，還是有兩點不太方便：&lt;br /&gt;
&lt;br /&gt;
cp950-u2b.txt 所有的資料是按照 C/C++ 的十六進位格式製作的表格，並非按照組合語言十六進位格式記錄。&lt;br /&gt;
cp950-u2b.txt 檔案裏共收集了 20192 個中文字，每個中文字必須用 Unicode 及 Big5 碼各記錄一次，這兩種編碼都佔用兩個位元組，所以每個中文字佔用 4 個位元組，因此共用去 80768 個位元組，超過一個區段 64KB 的限制。為了解決這個問題，小木偶先撰寫一程式，U2B_2ASM.ASM，這個程式會製造出一個 CP950-U2B_ASM.INC 檔案，這個檔案是一個組合語言包含檔，他把 cp950-u2b.txt 的資料分成兩個區段，big5 與 ucode，big5 區段只存放 Big5 碼資料而 ucode 區段只存放 Unicode 區段。這兩個區段相同偏移位址的資料是對應的，也就是說 big5:0000 位址是 00021h，而 ucode:0000 則是 000a1h。因此 CP950-U2B_ASM.INC 的內容是像這樣的：&lt;br /&gt;
big5 segment
 dw 00021h,0a246h,0a247h,0a244h,0007ch,0a1b1h,0a14ch,00063h
 dw 00061h,0002dh,00052h,0a1c2h,0a258h,0a1d3h,00032h,00033h
 …………
 dw 0a155h,0a162h,0a1e3h,0a14eh,0a246h,0a247h,0a1c3h,0a244h
big5 ends
ucode segment
 dw 000a1h,000a2h,000a3h,000a5h,000a6h,000a7h,000a8h,000a9h
 dw 000aah,000adh,000aeh,000afh,000b0h,000b1h,000b2h,000b3h
 …………
 dw 0ff5ch,0ff5dh,0ff5eh,0ff64h,0ffe0h,0ffe1h,0ffe3h,0ffe5h
ucode ends&lt;br /&gt;
當要把 Unicode 轉換成Big5 碼時，只要找出 Unicode 的偏移位址，再切換成 Big5 碼的區段位址，就可取得相對應的 Big5 碼。例如：&lt;br /&gt;
;把 AX 內的 UNICDODE 轉換成 BIG-5
;輸入：AX－UNICDODE
;輸出：NC：轉換成功，此時 AX=BIG-5
; CY：轉換失敗，此時 AX=『？』
convert_u2big5 proc near uses bx
 mov bx,ucode
 mov gs,bx
 sub bx,bx ;由 ucode:0000 開始搜尋存於 AX 中的 Unicode 位址
next_code:
 cmp ax,gs:[bx]
 je find_out
 add bx,2
 or bx,bx ;如果到 BX=0 ( 搜尋完整個 ucode 區段 ) 都還沒找到，
 jnz next_code ;，表示沒有相對應的 Big5 碼，轉換失敗
 stc ;設定進位旗標
 mov ax,35a1h ;Big5 的 0a135h=『？』
 jmp short u2b_exit
find_out:
 mov ax,big5
 mov gs,ax
 mov ax,gs:[bx] ;取得 Big5
 xchg al,ah ;換成 Big-Endian
 clc ;清除進位旗標
u2b_exit:
 ret ;返回主程式
convert_u2big5 endp&lt;br /&gt;
&lt;a href=&quot;http://mo-bian.blogspot.tw/2012/06/google-httphome.html&quot;&gt;&lt;/a&gt;&lt;br /&gt;
Big-Endian 與 Little-Endian&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ch33.html#vfat&quot;&gt;第三十三章&lt;/a&gt;裏提過，FAT32 分割是利用 VFAT 實現長檔名，不管是中文或英文檔名全都採用萬國碼的方式儲存，而非 Big5 碼。例如，上面例子中有一個檔案名為『費玉清－蘆花州.TXT』在目錄磁區裏的儲存方式如下︰&lt;br /&gt;
0000 41 BB 8C 89 73 05 6E 0D-FF 06 86 0F 00 0C B1 82 A;..s.n.......1.
0010 1F 82 4C 6B 5E 8A 2E 00-54 00 00 00 58 00 54 00 ..Lk^...T...X.T.
0020 B6 4F A5 C9 B2 4D 7E 31-54 58 54 20 00 0D 38 77 6O%I2M~1TXT ..8w
0030 68 35 68 35 00 00 AB 1B-4A 33 E1 50 1B 03 00 00 h5h5..+.J3aP....&lt;br /&gt;
要注意的是用粉紅色標出來的是萬國碼的『費』字，他的代碼是 8CBBH，而其大五碼是 0B64FH，並非 4FB6H。這一點很奇怪，小木偶也不知為什麼要這樣排。一般在 PC 及其相容機種的資料幾乎以 Little-Endian 的方式排列，但在 FDB 中的 Big5 卻是以 Big-Endian 的方式排列。&lt;br /&gt;
所謂 Little-Endian 或 Big-Endian 的排列是指數值存放在記憶體的排列方式。當記憶體位址由低位址開始向高位址排好時，先把較小的位數存入的這種方式稱為 Little-Endian，例如上面的 Unicode 的『費』字，其十六進位為『8CBBH』，『BB』分別是個位、十位數，『8C』分別是千位、百位數，所以『BB』填入較低位址而『8C』填入較高位址。因此在傾印時，常常是低位址先印出來，於是變得顛倒了，但是在記憶體裏的排列卻是正常。有關 Little-Endian 或 Big-Endian 可以參考&lt;a href=&quot;http://libai.math.ncu.edu.tw/bcc16/pool/1.33.shtml&quot;&gt;用 C 語言窺探記憶體&lt;/a&gt;。&lt;br /&gt;
&lt;br /&gt;
DFC3.EXE：檢查檔案所佔磁區是否連續DFC3.EXE 用法與 DFC.EXE 相同，它也只能用在 Win 9x/Me 系列，無法在 Windows NT/2k/XP 裏。其執行結果如下圖︰&lt;br /&gt;
&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/dfc3.png&quot; /&gt;為了讓 DFC3.EXE 能夠顯示中文長檔名，修改了 DFC.ASM 裏的 get_filename 副程式，使具有長檔名的檔案能夠呼叫 convert_u2big5 副程式，convert_u2big5 副程式的功用就是把 Unicode 碼轉變成 Big5 碼。&lt;br /&gt;
&lt;br /&gt;
組譯方法因為 DFC3.ASM 原始碼幾乎與 DFC.ASM 一樣，且加上一個轉換 cp950-u2b.txt 變成符合組合語言格式及區段的程式，U2B_2ASM.ASM，所以此處不列出整個內容，請&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/AP10.RAR&quot;&gt;下載 AP10.RAR &lt;/a&gt;後解壓縮。&lt;br /&gt;
&lt;br /&gt;
解壓縮後，在 XP 的命令提示字元或 Win 9x/Me 的 MS-DOS 模式中組譯都可成功。組譯時先把 AP10.RAR 裏所有檔案放於同一子目錄，例如 D:\AP10，再把 &lt;a href=&quot;http://www.moztw.org/docs/big5/table/cp950-u2b.txt&quot;&gt;cp950-u2b.txt&lt;/a&gt; 檔案拷貝到這個子目錄，然後切換到此子目錄，並設定 ML.EXE 的路徑，底下是在 Win XP 系統之下以命令提示字元為例子說明：&lt;br /&gt;
D:\AP10&amp;gt;dir [Enter]
 Volume in drive D is FAT32DATA
 Volume Serial Number is DC74-CCE3

 Directory of D:\AP10

2006/11/21 ?? 10:49 6,499 U2B_2ASM.ASM → AP10.RAR 內的檔案
2006/10/22 ?? 05:37 282,703 CP950-U2B.TXT → 自&lt;a href=&quot;http://www.moztw.org/docs/big5/table/cp950-u2b.txt&quot;&gt; Mozilla Taiwan &lt;/a&gt;下載
2006/11/17 ?? 09:44 29,551 DFC3.ASM → AP10.RAR 內的檔案
2006/04/05 ?? 04:49 4,881 MYASMINC.INC → AP10.RAR 內的檔案
 4 File(s) 323,634 bytes
 2 Dir(s) 1,489,784,832 bytes free

D:\AP10&amp;gt;path D:\HomePage\MASM611\BIN;%path% [Enter]

D:\AP10&amp;gt;ml /AT U2B_2ASM.ASM [Enter]
Microsoft (R) Macro Assembler Version 6.11
Copyright (C) Microsoft Corp 1981-1993. All rights reserved.

 Assembling: U2B_2ASM.ASM

Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992
Copyright (C) Microsoft Corp 1984-1992. All rights reserved.

Object Modules [.obj]: U2B_2ASM.obj/t
Run File [U2B_2ASM.com]: &quot;U2B_2ASM.com&quot;
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:&lt;br /&gt;
在組譯時，須下選項『/AT』，這是為了組譯成 U2B_2ASM.COM 檔，而不是 U2B_2ASM.EXE 檔。接下來就可以利用 U2B_2ASM.COM 把 cp950-u2b.txt 轉換成符合組合語言格式及區段的包含檔，CP950-U2B_ASM.INC 了。&lt;br /&gt;
D:\AP10&amp;gt;U2B_2ASM [Enter]

D:\AP10&amp;gt;dir [Enter]
 Volume in drive D is FAT32DATA
 Volume Serial Number is DC74-CCE3

 Directory of D:\AP10

2006/11/21 ?? 10:05 &amp;lt;DIR&amp;gt; .
2006/11/21 ?? 10:05 &amp;lt;DIR&amp;gt; ..
2006/11/21 ?? 10:49 6,499 U2B_2ASM.ASM
2006/10/22 ?? 05:37 282,703 CP950-U2B.TXT
2006/11/17 ?? 09:44 29,551 DFC3.ASM
2006/04/05 ?? 04:49 4,881 MYASMINC.INC
2006/11/21 ?? 10:21 775 u2b_2asm.obj
2006/11/21 ?? 10:21 445 U2B_2ASM.COM
2006/11/21 ?? 10:21 368,566 CP950-U2B_ASM.INC
 7 File(s) 693,420 bytes
 2 Dir(s) 1,489,408,000 bytes free&lt;br /&gt;
接下來組譯 DFC3.ASM：&lt;br /&gt;
D:\AP10&amp;gt;&amp;gt;ml dfc3.asm [Enter]
Microsoft (R) Macro Assembler Version 6.11
Copyright (C) Microsoft Corp 1981-1993. All rights reserved.

 Assembling: dfc3.asm

Microsoft (R) Segmented Executable Linker Version 5.31.009 Jul 13 1992
Copyright (C) Microsoft Corp 1984-1992. All rights reserved.

Object Modules [.obj]: dfc3.obj
Run File [dfc3.exe]: &quot;dfc3.exe&quot;
List File [nul.map]: NUL
Libraries [.lib]:
Definitions File [nul.def]:&lt;br /&gt;
如此就得到 DFC3.EXE，檔案僅 84368 個位元組。不過 DFC3.EXE 只能在 Win 9x/Me 系統中執行，在 Win NT/2k/XP 中無法執行。&lt;br /&gt;
&lt;a href=&quot;http://mo-bian.blogspot.tw/2012/06/google-httphome.html&quot;&gt;註一：&lt;/a&gt;在 DOS 系統裏，每個字在螢幕上顯示的寬度都是相同的，但載入倚天中文後，中文字不僅佔用兩個位元組，在螢幕顯示時的寬度也是英文字的兩倍，故稱全形字，而原來的英文自稱為半形字體。不過，在 Big5 碼裏，也有全形字體的英文字母，在 A2CF～A343，同樣的，阿拉伯數字、希臘字母也都有全形字體。&lt;br /&gt;
&lt;a href=&quot;http://mo-bian.blogspot.tw/2012/06/google-httphome.html&quot;&gt;&lt;/a&gt;註二：&lt;br /&gt;
&lt;br /&gt;
UTF-16 與 UTF-8UCS-4 字集雖然能容納古今中外全球人類所書寫過的文字及符號，但是其實有九成五以上的文字及符號都編入 UCS-2 字集 ( 即 BMP )。很明顯的 UCS-2 要比 UCS-4 有效率得多，不說別的，單只比較儲存空間，UCS-2 就只有 UCS-4 的一半。設想如果一篇數千字或數萬字的文件裏，就只有十幾個字在 BMP 以外的字面，若只為了這幾個字就得採用 UCS-4 字集，顯然是很不符合經濟效率。因此 ISO 10646 特別規定在 BMP 以外的字可以轉換成兩個或多個 16 位元的 UCS-2 表示，這種表示或轉換方式稱為 UCS-16，即 UCS Transformation Format 之縮寫。&lt;br /&gt;
現在已經被使用的字面，只有第 00 群組前十四個字面用到，因此只需考慮第 00 群組的第 00 字面到第 0E 字面即可。其轉換方式是把 32 位元的 UCS-4 的第 10 個位元到第 15 個位元變成轉換後第一個字組的低 6 位元，UCS-4 的第 16 個位元到第 19 個位元所組成的二進位數減 1，變成轉換後第一個字組的第 6 到第 9 位元，而轉換後的最高 6 位元則固定是 110110；UCS-4 的第 0 位元到第 9 位元變成第二個字組的低 10 位元，高 6 位元固定是 110111。因此 UCS-4 經過 UTF-16 轉換後的高位元組落在 D800～DBFF 之間，低位元組則落在 DC00～DFFF 之間。如下圖：&lt;br /&gt;
&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-16.png&quot; /&gt;現在網路傳輸的資料仍大多以 ASCII 編碼的方式傳輸。也就是說，在網路設備如路由器等會去檢查傳輸的資料是否包含 C0 等 ASCII 控制字元，如果有的話，會依狀況處理。因此不管是 UCS-2 或 UCS-4 字元在網路傳輸時，只要含有 C0 控制字元都會被誤認。為了讓 UCS-2 或 UCS-4 字元能安然通過網路設備的檢查，於是 ISO 10646 也規定了 UTF-8 轉換方式。&lt;br /&gt;
UTF-8 轉換規則很簡單，如果 USC-4 字元是等於 7F 或小於 7F 以下，則不轉換直接取最低八位元傳送。如果超過 7F 時，則轉換成數個位元組，第一個位元組前面有幾個 1，就代表轉換成幾個位元組，之後接上一個 0，然後從原來的 UCS-4 開始逐一把位元由高而低填上，直到滿了 8 個位元，轉換後的第二個位元組以後前兩個位元必是 10，然後其餘的 6 個位元就是剩餘的 UCS-4 位元依次填上。方法如下：&lt;br /&gt;
&lt;br /&gt;
原來的 UCS-4&lt;br /&gt;
字元範圍 位元結構 經 UTF-8 轉換後&lt;br /&gt;
00000000&lt;br /&gt;
到&lt;br /&gt;
0000007F 第一個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-0.png&quot; /&gt;&lt;br /&gt;
第二個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-1.png&quot; /&gt; 第一個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to00.png&quot; /&gt;&lt;br /&gt;
00000080&lt;br /&gt;
到&lt;br /&gt;
000007FF 第一個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-0.png&quot; /&gt;&lt;br /&gt;
第二個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-2.png&quot; /&gt; 第一個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to10.png&quot; /&gt;&lt;br /&gt;
第二個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to11.png&quot; /&gt;&lt;br /&gt;
00000800&lt;br /&gt;
到&lt;br /&gt;
0000FFFF 第一個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-0.png&quot; /&gt;&lt;br /&gt;
第二個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-3.png&quot; /&gt; 第一個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to20.png&quot; /&gt;&lt;br /&gt;
第二個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to21.png&quot; /&gt;&lt;br /&gt;
第三個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to22.png&quot; /&gt;&lt;br /&gt;
00010000&lt;br /&gt;
到&lt;br /&gt;
001FFFFF 第一個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-4.png&quot; /&gt;&lt;br /&gt;
第二個字組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8-5.png&quot; /&gt; 第一個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to30.png&quot; /&gt;&lt;br /&gt;
第二個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to31.png&quot; /&gt;&lt;br /&gt;
第三個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to32.png&quot; /&gt;&lt;br /&gt;
第四個位元組：&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/utf-8to33.png&quot; /&gt;&lt;br /&gt;
上表說明 UCS-4 轉換後的結果，如果是 UCS-2 的話，就不考慮第一個字組，結果一樣。例如『中』的萬國碼是 4E2D，轉換成二進位是：&lt;br /&gt;
0100 1110 0010 1101&lt;br /&gt;
4E2D 在 0800 與 FFFF 之間，因此會轉換成 3 個位元組，轉換如下：&lt;br /&gt;
第一個位元組：1110 0100 →E4
第二個位元組：1011 1000 →B8
第三個位元組：1010 1101 →AD&lt;br /&gt;
第一個位元組的黃色部份有 3 個一，表示 UTF-8 轉換後有三個位元組，其後所接黃色的零表示分隔記號；第二、三最前面黃色的『10』也表示 UTF-8 轉換後的記號。而中的萬國碼的前四個位元是紅色的『0100』就接在 UTF-8 轉換後的第一個位元組後四個位元；而藍色的『1110 00』也就接在第二個位元組之後的 6 個位元；UCS-2 最後的 6 個位元組，就接在第三個位元組的最後 6 個位元。&lt;br /&gt;
在 Win XP 的記事本裏，要儲存檔案時，會出現一個『另存新檔』的對話盒，其中『編碼：』複合框就是可以選擇以不同的四種編碼方式存入檔案。如下圖：&lt;br /&gt;
&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;http://home.educities.edu.tw/wanker742126/asm/note_save_as.png&quot; /&gt;其中，ANSI 編碼指的就是以 ASCII 或 Big5 碼方式存入。例如在記事本中有一句『我學Assembly。』字，存檔時，存入的是 ASCII 與 Big5 碼 ( 英文半形字用 ASCII 碼，中文或全形字用 Big5 碼 )，內容如下：&lt;br /&gt;
A7 DA BE C7 41 73 73 65 6D 62 6c 79 A1 43&lt;br /&gt;
您可以自行到&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ap10.html#openi18n&quot;&gt;前面提到&lt;/a&gt;的地方查『我』、『學』這兩字的 Big5 碼和到&lt;a href=&quot;http://home.educities.edu.tw/wanker742126/asm/ap04.html&quot;&gt;附錄四&lt;/a&gt;查這些英文字的 ASCII 碼是否符合上面的十六進位數。如果用 Unicode 方式存，則會以 UCS-2 Little-Endian 方式存入，所存入內容為&lt;br /&gt;
FF FE 11 62 78 5B 41 00 73 00 73 00 65 00 6D 00
62 00 6C 00 79 00 02 30&lt;br /&gt;
最前面兩個位元組是 FF FE，這兩位元組的目的是用來分辨 Big-Endian 還是 Little-Endian。在萬國碼裏，FEFF 是無寬度不中斷空格 ( zero width no-break space )，其 Little-Endian 是 FF FE，而 FFFE 在萬國碼沒有編碼，因此萬國碼是不會出現 FFFE 這種碼的，萬一出現，那就表示是 Little-Endian 編碼。所以 UCS 中建議我們在傳送或儲存萬國碼時，最先傳送、儲存 FEFF 字元，表示 Big-Endian，或者傳送、儲存 FFFE 表示 Little-Endian。而 FEFF 字元經 UTF-8 轉換後變成 EF BB BF，所以前三個位元組是 EF BB BF 的就是 UTF-8 編碼。&lt;br /&gt;
接下來的十六進位數，6211、5B78、0041…等分別是『我學A…』的萬國碼，以 UCS-2 Little-Endian 編碼。&lt;br /&gt;
如果以 Big-Endian 方式存入時，也是以 UCS-2 編碼方式編碼，但是以大數在前方式排列，因此您會看見與 Unicode 方式存檔時兩兩一組且前後互換，所存內容為&lt;br /&gt;
FE FF 62 11 5B 78 00 41 00 73 00 73 00 65 00 6D
00 62 00 6C 00 79 30 02&lt;br /&gt;
如果以 UTF-8 方式存檔時，內容就變成：&lt;br /&gt;
EF BB BF E6 88 91 E5 AD B8 41 73 73 65 6D 62 6C
79 E3 80 82&lt;br /&gt;
您可自行驗證。</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/4525438886861761372/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/06/unicodebig5.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/4525438886861761372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/4525438886861761372'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/06/unicodebig5.html' title='Unicode與Big5轉換'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-443309661726676066</id><published>2012-05-02T19:06:00.001-07:00</published><updated>2013-10-26T20:24:30.304-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="推論程序"/><title type='text'>SLD歸結法</title><content type='html'>1.給定一個目標句 G: &amp;nbsp;-: L1,!L2,...,!Li,...,!Ln&lt;br /&gt;
2.選定一個詞 Li&lt;br /&gt;
3.選擇一個子句 C: L -: &amp;nbsp;K1,...,Km 使得 Li 及 L 可以一致化，其一致子為 S。&lt;br /&gt;
4.將給定子句之尾&amp;nbsp;K1,...,Km&amp;nbsp;取代目標句之 Li 部份，並應用一致子 S，&lt;br /&gt;
&amp;nbsp; &amp;nbsp;產生新目標句&amp;nbsp;&amp;nbsp; G1: -: (L1,L2,...,K1,...,Km,...,Ln)S</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/443309661726676066/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/05/sld.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/443309661726676066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/443309661726676066'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/05/sld.html' title='SLD歸結法'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-2372701489425245752</id><published>2012-03-27T19:31:00.003-07:00</published><updated>2012-03-27T19:53:18.855-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Haskell"/><title type='text'>How to install HDBC-sqlite3 on windows.</title><content type='html'>&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4e4e4e; font-family: &#39;Myriad Pro&#39;, &#39;Trebuchet MS&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 21px; margin-bottom: 1em; margin-top: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;&lt;br /&gt;
&lt;div class=&quot;post-text&quot; style=&quot;background-attachment: initial; background-clip: initial; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: black; font-family: Arial, &#39;Liberation Sans&#39;, &#39;DejaVu Sans&#39;, sans-serif; font-size: 14px; line-height: 17px; margin-bottom: 5px; margin-left: 0px; margin-right: 5px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-align: left; vertical-align: baseline; width: 660px;&quot;&gt;&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; font-size: 14px; margin-bottom: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;&quot;&gt;&lt;span style=&quot;background-color: transparent; font-size: 14px;&quot;&gt;I downloaded sqlite3.dll and sqlite3.h from source zip.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; font-size: 14px; margin-bottom: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;&quot;&gt;then I inserted sqlite3.dll in system32 dir and in setup configure i used&lt;/div&gt;&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; clear: both; font-size: 14px; margin-bottom: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline; word-wrap: break-word;&quot;&gt;--extra-lib-dirs=... --extra-include-dirs=... parameters with correct paths to header and dll.&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
You have a problem it seems. You want to install the Haskell&amp;nbsp;&lt;a href=&quot;http://hackage.haskell.org/package/HDBC-sqlite3&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #0071bb; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: none; outline-width: initial; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;HDBC-sqlite3&lt;/a&gt;&amp;nbsp;library on Windows but you seem to be&amp;nbsp;&lt;a href=&quot;http://stackoverflow.com/questions/2795737/installation-hdbc-sqlite3-haskell&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #7b9d14; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: none; outline-width: initial; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; text-decoration: none; vertical-align: baseline;&quot;&gt;getting these error messages telling you that it cannot find the required sqlite3 library&lt;/a&gt;. The way that you solve this kind of problem is by simply getting your hands on the sqlite3.dll and sqlite3.h files,&amp;nbsp;&lt;a href=&quot;http://www.sqlite.org/download.html&quot; style=&quot;background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #0071bb; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; outline-color: initial; outline-style: none; outline-width: initial; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;from here&lt;/a&gt;, and putting them in locations that you can then add to the cabal install command later. The ultimate install command should look really simple, something like this:&lt;/div&gt;&lt;pre style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-color: initial; border-image: initial; border-left-color: rgb(221, 221, 221); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(221, 221, 221); border-right-style: solid; border-right-width: 1px; border-style: initial; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; color: #4e4e4e; font-family: &#39;Courier 10 Pitch&#39;, Courier, monospace; font-size: 12px; line-height: 1.7; margin-bottom: 1.7em; padding-bottom: 0.85em; padding-left: 1.7em; padding-right: 1.7em; padding-top: 0.85em; vertical-align: baseline;&quot;&gt;cabal install HDBC-sqlite3 \
--extra-lib-dirs=&#39;C:\some\path\to\sqlite\lib&#39; \
--extra-include-dirs=&#39;C:\some\path\to\sqlite\include&#39;&lt;/pre&gt;&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4e4e4e; font-family: &#39;Myriad Pro&#39;, &#39;Trebuchet MS&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 21px; margin-bottom: 1em; margin-top: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;Where you obviously need to set what actual paths get given to those variables.&lt;/div&gt;&lt;div style=&quot;background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-image: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; color: #4e4e4e; font-family: &#39;Myriad Pro&#39;, &#39;Trebuchet MS&#39;, Helvetica, Arial, sans-serif; font-size: 14px; line-height: 21px; margin-bottom: 1em; margin-top: 1em; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;&quot;&gt;The only other gotcha that you will need to look out for it to make sure that the sqlite3.dll is always in the path of any program that you make that depends on HDBC-sqlite3 because otherwise it will complain about not being able to find the required dll. Just so that you know, the current directory of any program is always in the current library path.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/2372701489425245752/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/03/how-to-install-hdbc-sqlite3-on-windows.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2372701489425245752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2372701489425245752'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/03/how-to-install-hdbc-sqlite3-on-windows.html' title='How to install HDBC-sqlite3 on windows.'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-2938152527740989900</id><published>2012-01-24T22:48:00.003-08:00</published><updated>2013-10-26T20:27:38.627-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="一致化"/><title type='text'>一致化</title><content type='html'>&lt;h3 style=&quot;background-color: ghostwhite;&quot;&gt;



&lt;/h3&gt;
&lt;b&gt;替換：&lt;/b&gt;&lt;br /&gt;
替換為將變數對映到詞的一對一函數，其表示如下：&lt;br /&gt;
{X1/t1, X2/t2,...,Xn/tn}&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;一致化&lt;/b&gt;：&lt;br /&gt;
令 s 及 t 為式，若存在替換 T 使得 sT = tT&amp;nbsp;語義相等，則 s 及 t可以一致化，而該替換 T 稱為 s 及 t 之一致子。&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;
&lt;b&gt;形式一致化問題：&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
找出可使一組等式集合 ES 之合取 t0 = u0 &amp;amp; t1 = u 1 &amp;amp;...&amp;amp; tn = un 語義相等之替換 S。&lt;br /&gt;
此替換稱為該等式集合之一致子。&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;解式&lt;/b&gt;：&lt;br /&gt;
為一組等式，等式左側均為不同變數，且不會出現在右側中。&lt;br /&gt;
[$x=x,$f=f(x o),$q=q,$s=s]&lt;br /&gt;
即為一組解式。&lt;br /&gt;
&lt;br /&gt;
一致化為給定一組等式，並將其轉換成解式之過程。&lt;br /&gt;
&lt;br /&gt;
1.下面形式則表示無法一致化&lt;br /&gt;
1.1. f = g 其中f及g 是相異原子。&lt;br /&gt;
1.2. f = g 其中f為複合子及g是原子，f為原子及g是複合子。&lt;br /&gt;
1.3. f(...) = g(...) 其中f及g 是相異函子。&lt;br /&gt;
1.4. f(a1, a2, ..., aN) = g(b1, b2, ..., bM) 其中N及M數目不同。&lt;br /&gt;
2.$X=$X 其中$X均為變數，則刪除此等式&lt;br /&gt;
3.a=a 其中a均為元式，則刪除此等式4. f(a1, a2, ..., aN) = f(b1, b2, ..., bN) 則用 ai = bi 等式組取代&lt;br /&gt;
5.t = X 其中 X 為變數而 t為非變數，則以 X = t取代6.X = t 其中 X 為變數而 t為非變數，且 X 未在 t 中，而存在其它等式中，後把其它等式出現的X 以 t 取代。&lt;br /&gt;
7.X = t 其中 X 為變數而 t為非變數，且 X 在 t 中，則因正向變數檢查而無法一致化。&lt;br /&gt;
8.若無其它步驟可套用，則一致化成功。</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/2938152527740989900/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/01/mguherbrand.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2938152527740989900'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/2938152527740989900'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/01/mguherbrand.html' title='一致化'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-5947132082837252323</id><published>2012-01-24T22:36:00.000-08:00</published><updated>2012-01-24T22:36:07.576-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="參考資料"/><title type='text'>參考資料</title><content type='html'>&lt;a href=&quot;http://pauillac.inria.fr/~deransar/prolog/bips.html&quot;&gt;ISO Prolog 語意&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/5947132082837252323/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/01/blog-post_24.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/5947132082837252323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/5947132082837252323'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/01/blog-post_24.html' title='參考資料'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1825468319952057680.post-8795807943755476066</id><published>2012-01-24T22:34:00.000-08:00</published><updated>2012-01-24T22:37:52.142-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="語法"/><title type='text'>前置 &#39;$&#39; 字元之詞視為變數</title><content type='html'>前置 &#39;$&#39; 字元之詞視為變數，這是墨辯與Prolog以大寫字元前置視為變數最大之不同。&lt;br /&gt;
此項語法參考Perl之用法。</content><link rel='replies' type='application/atom+xml' href='http://mo-bian.blogspot.com/feeds/8795807943755476066/comments/default' title='張貼留言'/><link rel='replies' type='text/html' href='http://mo-bian.blogspot.com/2012/01/blog-post.html#comment-form' title='0 個意見'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/8795807943755476066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1825468319952057680/posts/default/8795807943755476066'/><link rel='alternate' type='text/html' href='http://mo-bian.blogspot.com/2012/01/blog-post.html' title='前置 &#39;$&#39; 字元之詞視為變數'/><author><name>leng</name><uri>http://www.blogger.com/profile/12871080801434660933</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>