{"componentChunkName":"component---src-templates-blog-post-js","path":"/the-little-schemer-summary-5/","result":{"data":{"site":{"siteMetadata":{"title":"星雨之夜"}},"markdownRemark":{"id":"4e04c6af-3ae7-59ad-9959-715c0d5cb7e8","excerpt":"准备知识 所有 * 函数所处理的列表，都满足以下情况中的一种： 空列表。 一个原子 cons 在一个列表上。 一个列表 cons 在另一个列表上。  第一个参数为 false 则直接返回 false； 第一个参数为 true 则直接返回 true。所以它们的问题可能不会全部问到。 一个 S…","html":"<h2>准备知识</h2>\n<ol>\n<li>\n<p>所有 * 函数所处理的列表，都满足以下情况中的一种：</p>\n<ul>\n<li>空列表。</li>\n<li>一个原子 cons 在一个列表上。</li>\n<li>一个列表 cons 在另一个列表上。</li>\n</ul>\n</li>\n<li><code class=\"language-text\">(and ...)</code> 第一个参数为 false 则直接返回 false；<code class=\"language-text\">(or ...)</code> 第一个参数为 true 则直接返回 true。所以它们的问题可能不会全部问到。</li>\n<li>一个 S-表达式要么是一个原子，要么是一个 S-表达式列表（也可以是空列表）。</li>\n<li>注意区分 <code class=\"language-text\">eq?</code>、<code class=\"language-text\">=</code>、<code class=\"language-text\">eqan?</code> 和 <code class=\"language-text\">equal?</code>。</li>\n</ol>\n<h2>Scheme 十诫之第一诫（终极式）</h2>\n<ul>\n<li>当对一个原子列表 <code class=\"language-text\">lat</code> 进行递归调用时，询问两个有关 <code class=\"language-text\">lat</code> 的问题：<code class=\"language-text\">(null? lat)</code> 和 <code class=\"language-text\">else</code>。</li>\n<li>当对一个数字 <code class=\"language-text\">n</code> 进行递归调用时，询问两个有关 <code class=\"language-text\">n</code> 的问题：<code class=\"language-text\">(zero? n)</code> 和 <code class=\"language-text\">else</code>。</li>\n<li>当对一个 S-表达式列表 <code class=\"language-text\">l</code> 进行递归调用时，询问三个有关 <code class=\"language-text\">l</code> 的问题：<code class=\"language-text\">null? l</code>、<code class=\"language-text\">(atom? (car l))</code> 和 <code class=\"language-text\">else</code>。</li>\n</ul>\n<h2>Scheme 十诫之第四诫（终极式）</h2>\n<p>在递归时总是改变至少一个参数：</p>\n<ul>\n<li>当对一个原子列表 <code class=\"language-text\">lat</code> 进行递归调用时，使用 <code class=\"language-text\">(car lat)</code>。</li>\n<li>当对数字 <code class=\"language-text\">n</code> 进行递归调用时，使用 <code class=\"language-text\">(sub1 n)</code>。</li>\n<li>当对一个 S-表达式进行递归调用时，只要 <code class=\"language-text\">(null? lat)</code> 和 <code class=\"language-text\">(atom? (car l))</code> 都不为 true，那么就同时使用 <code class=\"language-text\">(car lat)</code> 和 <code class=\"language-text\">(cdr lat)</code>。</li>\n</ul>\n<p>在递归时改变的参数，必须向着不断接近结束条件而改变。改变的参数必须在结束条件中得以测试：</p>\n<ul>\n<li>当使用 <code class=\"language-text\">cdr</code> 时，用 <code class=\"language-text\">null?</code> 测试是否结束。</li>\n<li>当使用 <code class=\"language-text\">sub1</code> 时，用 <code class=\"language-text\">zero?</code> 测试是否结束。</li>\n</ul>\n<h2>Scheme 十诫之第六诫</h2>\n<p>简化工作只在功能正确之后开展。</p>\n<h2>自定义函数</h2>\n<h3>(rember* a l)</h3>\n<p>定义：移除列表 <code class=\"language-text\">l</code> 中的全部原子 <code class=\"language-text\">a</code>，以此类推。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> rember*\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">a</span> l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">quote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> a<span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n          <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">eq?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> a<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">rember*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span>\n                      <span class=\"token punctuation\">(</span><span class=\"token function\">rember*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token function\">rember*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">rember*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(insertR* new old l)</h3>\n<p>定义：在列表 <code class=\"language-text\">l</code> 中的所有原子 <code class=\"language-text\">old</code> 后面插入原子 <code class=\"language-text\">new</code>。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> insertR*\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">new</span> old l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">quote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n          <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">eq?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> old<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> old\n                  <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> new\n                        <span class=\"token punctuation\">(</span><span class=\"token function\">insertR*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span>\n                      <span class=\"token punctuation\">(</span><span class=\"token function\">insertR*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token function\">insertR*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">insertR*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>比较 <code class=\"language-text\">rember*</code> 和 <code class=\"language-text\">insertR*</code> 两个函数，看看是怎么问问题的。</p>\n<h3>(occur* a l)</h3>\n<p>定义：统计列表 <code class=\"language-text\">l</code> 中原子 <code class=\"language-text\">a</code> 出现的所有次数。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> occur*\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">a</span> l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token number\">0</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n          <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">eq?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> a<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">(</span><span class=\"token function\">add1</span> <span class=\"token punctuation\">(</span><span class=\"token function\">occur*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">occur*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">plus</span> <span class=\"token punctuation\">(</span><span class=\"token function\">occur*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">occur*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(subst* new old l)</h3>\n<p>定义：把列表 <code class=\"language-text\">l</code> 中的所有原子 <code class=\"language-text\">old</code> 都替换为原子 <code class=\"language-text\">new</code>。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> subst*\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">new</span> old l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">quote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n          <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">eq?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> old<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> new\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">subst*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> old\n                      <span class=\"token punctuation\">(</span><span class=\"token function\">subst*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token function\">subst*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">subst*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(insertL* new old l)</h3>\n<p>定义：在列表 <code class=\"language-text\">l</code> 中的所有原子 <code class=\"language-text\">old</code> 前面插入原子 <code class=\"language-text\">new</code>。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> insertL*\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">new</span> old l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">quote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n          <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">eq?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> old<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> new\n                  <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> old\n                        <span class=\"token punctuation\">(</span><span class=\"token function\">insertL*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n          <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> old\n                      <span class=\"token punctuation\">(</span><span class=\"token function\">insertL*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token function\">insertL*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">insertL*</span> new old <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(member* a l)</h3>\n<p>定义：判断原子 <code class=\"language-text\">a</code> 是否出现在列表 <code class=\"language-text\">l</code> 中。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> member*\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">a</span> l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token function\">or</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eq?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> a<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">(</span><span class=\"token function\">member*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">or</span> <span class=\"token punctuation\">(</span><span class=\"token function\">member*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                <span class=\"token punctuation\">(</span><span class=\"token function\">member*</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>回忆一下 <code class=\"language-text\">or</code> 的用法。</p>\n<h3>(leftmost l)</h3>\n<p>定义：找出非空 S-表达式列表 <code class=\"language-text\">l</code> 中最左边的原子。同时该列表不包含空列表元素。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> leftmost\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">l</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">leftmost</span> a <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(eqlist? l1 l2)</h3>\n<p>定义：判断两个列表是否相等。</p>\n<p>思考：需要问 9 个问题，因为处理列表有 3 种情况，两个列表就是 9 种情况。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> eqlist?\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">l1</span> l2<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#t</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eqan?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n             <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                 <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><code class=\"language-text\">(and (null? l1) (null? l2))</code> 和 <code class=\"language-text\">(or (null? l1) (null?l2))</code> 可以确定 3 种情况，以此简化一下：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> eqlist?\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">l1</span> l2<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#t</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">or</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eqan?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n             <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">or</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                 <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(equal? s1 s2)</h3>\n<p>定义：判断两个 S-表达式是否相同。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> equal?\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">s1</span> s2<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token function\">eqan?</span> s1 s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s1<span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s2<span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> s1 s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>同上，第二第三个问题可以归纳为 <code class=\"language-text\">(or (atom? s1) (atom? s2))</code>，简化版：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> equal?\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">s1</span> s2<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token punctuation\">(</span><span class=\"token function\">eqan?</span> s1 s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">or</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token function\">atom?</span> s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> s1 s2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>接下来用 <code class=\"language-text\">equal?</code> 重写 <code class=\"language-text\">eqlist?</code>：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> eqlist?\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">l1</span> l2<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#t</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">or</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token boolean\">#f</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token function\">and</span> <span class=\"token punctuation\">(</span><span class=\"token function\">equal?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n                 <span class=\"token punctuation\">(</span><span class=\"token function\">eqlist?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l1<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>\n<h3>(rember s l)</h3>\n<p>定义：详见<a href=\"/the-little-schemer-summary-3\">第三篇</a>，这里是用任意 S-表达式列表 <code class=\"language-text\">l</code> 替代 <code class=\"language-text\">lat</code>，任意 S-表达式 <code class=\"language-text\">s</code> 替代原子 <code class=\"language-text\">a</code> 之后的版本。用到了上述的 <code class=\"language-text\">equal?</code>。</p>\n<p>实现：</p>\n<div class=\"gatsby-highlight\" data-language=\"scheme\"><pre class=\"language-scheme\"><code class=\"language-scheme\"><span class=\"token punctuation\">(</span><span class=\"token keyword\">define</span> rember\n  <span class=\"token punctuation\">(</span><span class=\"token keyword\">lambda</span> <span class=\"token punctuation\">(</span><span class=\"token function\">s</span> l<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">(</span><span class=\"token keyword\">cond</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token builtin\">null?</span> l<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token keyword\">quote</span> <span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token punctuation\">(</span><span class=\"token function\">equal?</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span> s<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n      <span class=\"token punctuation\">(</span><span class=\"token keyword\">else</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">cons</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">car</span> l<span class=\"token punctuation\">)</span>\n                  <span class=\"token punctuation\">(</span><span class=\"token function\">rember</span> s <span class=\"token punctuation\">(</span><span class=\"token builtin\">cdr</span> l<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span></code></pre></div>","frontmatter":{"title":"The Little Schemer 知识点整理（五）：我得天！都是星星","date":"2018 年 12 月 13 日","description":"前面几篇介绍完基础类型和基础知识后，这一章开始写星星函数（*）。在以前的基础上，完善了其中几个函数的语义。同时还强调，如果要对代码做简化或者优化，需要先保证功能的正确性，用我们学到的来描述就是要把每个问题都问完。"}}},"pageContext":{"slug":"/the-little-schemer-summary-5/","previous":{"fields":{"slug":"/how-to-contribute-to-open-source-project/"},"frontmatter":{"title":"如何向开源项目贡献代码"}},"next":{"fields":{"slug":"/the-little-schemer-summary-6/"},"frontmatter":{"title":"The Little Schemer 知识点整理（六）：如影随形"}}}}}