-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlab1-functional.html
561 lines (517 loc) · 22 KB
/
lab1-functional.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2016-10-31 一 15:40 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>函数编程–实验一以及其他</title>
<meta name="generator" content="Org mode" />
<meta name="author" content="zqy767" />
<style type="text/css">
<!--/*--><![CDATA[/*><!--*/
.title { text-align: center;
margin-bottom: .2em; }
.subtitle { text-align: center;
font-size: medium;
font-weight: bold;
margin-top:0; }
.todo { font-family: monospace; color: red; }
.done { font-family: monospace; color: green; }
.priority { font-family: monospace; color: orange; }
.tag { background-color: #eee; font-family: monospace;
padding: 2px; font-size: 80%; font-weight: normal; }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
.underline { text-decoration: underline; }
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
p.verse { margin-left: 3%; }
pre {
border: 1px solid #ccc;
box-shadow: 3px 3px 3px #eee;
padding: 8pt;
font-family: monospace;
overflow: auto;
margin: 1.2em;
}
pre.src {
position: relative;
overflow: visible;
padding-top: 1.2em;
}
pre.src:before {
display: none;
position: absolute;
background-color: white;
top: -10px;
right: 10px;
padding: 3px;
border: 1px solid black;
}
pre.src:hover:before { display: inline;}
/* Languages per Org manual */
pre.src-asymptote:before { content: 'Asymptote'; }
pre.src-awk:before { content: 'Awk'; }
pre.src-C:before { content: 'C'; }
/* pre.src-C++ doesn't work in CSS */
pre.src-clojure:before { content: 'Clojure'; }
pre.src-css:before { content: 'CSS'; }
pre.src-D:before { content: 'D'; }
pre.src-ditaa:before { content: 'ditaa'; }
pre.src-dot:before { content: 'Graphviz'; }
pre.src-calc:before { content: 'Emacs Calc'; }
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
pre.src-fortran:before { content: 'Fortran'; }
pre.src-gnuplot:before { content: 'gnuplot'; }
pre.src-haskell:before { content: 'Haskell'; }
pre.src-java:before { content: 'Java'; }
pre.src-js:before { content: 'Javascript'; }
pre.src-latex:before { content: 'LaTeX'; }
pre.src-ledger:before { content: 'Ledger'; }
pre.src-lisp:before { content: 'Lisp'; }
pre.src-lilypond:before { content: 'Lilypond'; }
pre.src-lua:before { content: 'Lua'; }
pre.src-matlab:before { content: 'MATLAB'; }
pre.src-mscgen:before { content: 'Mscgen'; }
pre.src-ocaml:before { content: 'Objective Caml'; }
pre.src-octave:before { content: 'Octave'; }
pre.src-org:before { content: 'Org mode'; }
pre.src-oz:before { content: 'OZ'; }
pre.src-plantuml:before { content: 'Plantuml'; }
pre.src-processing:before { content: 'Processing.js'; }
pre.src-python:before { content: 'Python'; }
pre.src-R:before { content: 'R'; }
pre.src-ruby:before { content: 'Ruby'; }
pre.src-sass:before { content: 'Sass'; }
pre.src-scheme:before { content: 'Scheme'; }
pre.src-screen:before { content: 'Gnu Screen'; }
pre.src-sed:before { content: 'Sed'; }
pre.src-sh:before { content: 'shell'; }
pre.src-sql:before { content: 'SQL'; }
pre.src-sqlite:before { content: 'SQLite'; }
/* additional languages in org.el's org-babel-load-languages alist */
pre.src-forth:before { content: 'Forth'; }
pre.src-io:before { content: 'IO'; }
pre.src-J:before { content: 'J'; }
pre.src-makefile:before { content: 'Makefile'; }
pre.src-maxima:before { content: 'Maxima'; }
pre.src-perl:before { content: 'Perl'; }
pre.src-picolisp:before { content: 'Pico Lisp'; }
pre.src-scala:before { content: 'Scala'; }
pre.src-shell:before { content: 'Shell Script'; }
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
/* additional language identifiers per "defun org-babel-execute"
in ob-*.el */
pre.src-cpp:before { content: 'C++'; }
pre.src-abc:before { content: 'ABC'; }
pre.src-coq:before { content: 'Coq'; }
pre.src-groovy:before { content: 'Groovy'; }
/* additional language identifiers from org-babel-shell-names in
ob-shell.el: ob-shell is the only babel language using a lambda to put
the execution function name together. */
pre.src-bash:before { content: 'bash'; }
pre.src-csh:before { content: 'csh'; }
pre.src-ash:before { content: 'ash'; }
pre.src-dash:before { content: 'dash'; }
pre.src-ksh:before { content: 'ksh'; }
pre.src-mksh:before { content: 'mksh'; }
pre.src-posh:before { content: 'posh'; }
/* Additional Emacs modes also supported by the LaTeX listings package */
pre.src-ada:before { content: 'Ada'; }
pre.src-asm:before { content: 'Assembler'; }
pre.src-caml:before { content: 'Caml'; }
pre.src-delphi:before { content: 'Delphi'; }
pre.src-html:before { content: 'HTML'; }
pre.src-idl:before { content: 'IDL'; }
pre.src-mercury:before { content: 'Mercury'; }
pre.src-metapost:before { content: 'MetaPost'; }
pre.src-modula-2:before { content: 'Modula-2'; }
pre.src-pascal:before { content: 'Pascal'; }
pre.src-ps:before { content: 'PostScript'; }
pre.src-prolog:before { content: 'Prolog'; }
pre.src-simula:before { content: 'Simula'; }
pre.src-tcl:before { content: 'tcl'; }
pre.src-tex:before { content: 'TeX'; }
pre.src-plain-tex:before { content: 'Plain TeX'; }
pre.src-verilog:before { content: 'Verilog'; }
pre.src-vhdl:before { content: 'VHDL'; }
pre.src-xml:before { content: 'XML'; }
pre.src-nxml:before { content: 'XML'; }
/* add a generic configuration mode; LaTeX export needs an additional
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
pre.src-conf:before { content: 'Configuration File'; }
table { border-collapse:collapse; }
caption.t-above { caption-side: top; }
caption.t-bottom { caption-side: bottom; }
td, th { vertical-align:top; }
th.org-right { text-align: center; }
th.org-left { text-align: center; }
th.org-center { text-align: center; }
td.org-right { text-align: right; }
td.org-left { text-align: left; }
td.org-center { text-align: center; }
dt { font-weight: bold; }
.footpara { display: inline; }
.footdef { margin-bottom: 1em; }
.figure { padding: 1em; }
.figure p { text-align: center; }
.inlinetask {
padding: 10px;
border: 2px solid gray;
margin: 10px;
background: #ffffcc;
}
#org-div-home-and-up
{ text-align: right; font-size: 70%; white-space: nowrap; }
textarea { overflow-x: auto; }
.linenr { font-size: smaller }
.code-highlighted { background-color: #ffff00; }
.org-info-js_info-navigation { border-style: none; }
#org-info-js_console-label
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
.org-info-js_search-highlight
{ background-color: #ffff00; color: #000000; font-weight: bold; }
.org-svg { width: 90%; }
/*]]>*/-->
</style>
<link rel="stylesheet" type="text/css" href="css/stylesheet.css" />
<script type="text/javascript">
/*
@licstart The following is the entire license notice for the
JavaScript code in this tag.
Copyright (C) 2012-2013 Free Software Foundation, Inc.
The JavaScript code in this tag is free software: you can
redistribute it and/or modify it under the terms of the GNU
General Public License (GNU GPL) as published by the Free Software
Foundation, either version 3 of the License, or (at your option)
any later version. The code is distributed WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
As additional permission under GNU GPL version 3 section 7, you
may distribute non-source (e.g., minimized or compacted) forms of
that code without the copy of the GNU GPL normally required by
section 4, provided you include this license notice and a URL
through which recipients can access the Corresponding Source.
@licend The above is the entire license notice
for the JavaScript code in this tag.
*/
<!--/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*///-->
</script>
</head>
<body>
<div id="org-div-home-and-up">
<a accesskey="h" href=""> UP </a>
|
<a accesskey="H" href="https://zqy767.github.io"> HOME </a>
</div><div id="content">
<h1 class="title">函数编程–实验一以及其他</h1>
<div id="table-of-contents">
<h2>Table of Contents</h2>
<div id="text-table-of-contents">
<ul>
<li><a href="#orgc36ca8c">1. 引子</a></li>
<li><a href="#orgb8dcfb3">2. 题目</a></li>
<li><a href="#org7aaf8d2">3. 函数式编程之基本思想</a>
<ul>
<li><a href="#orgf433941">3.1. 函数式编程的特性</a>
<ul>
<li><a href="#org4a40948">3.1.1. 函数是一等公民</a></li>
<li><a href="#org7563bb5">3.1.2. 无副作用</a>
<ul>
<li><a href="#orge05856b">3.1.2.1. 函数式编程中不许出现全局变量</a></li>
<li><a href="#org5461c3e">3.1.2.2. 函数式编程中不许修改传入的参数</a></li>
</ul>
</li>
<li><a href="#org3560a69">3.1.3. 所有表达式都由返回值</a></li>
</ul>
</li>
<li><a href="#org16ebc38">3.2. 函数式编程与面向过程的区别</a>
<ul>
<li><a href="#org61f089f">3.2.1. 全局变量</a></li>
<li><a href="#org6808ebe">3.2.2. 对于函数的理解</a></li>
</ul>
</li>
<li><a href="#org6ac6863">3.3. 函数式编程与面对对象的区别以及联系</a></li>
</ul>
</li>
<li><a href="#org4d21bd0">4. 函数式编程之自下向上</a>
<ul>
<li><a href="#org8d8599b">4.1. 什么是自下向上编程</a></li>
</ul>
</li>
<li><a href="#org77a9c6f">5. <span class="todo TODO">TODO</span> 用滚雪球方式来理解代码</a>
<ul>
<li><a href="#orgb3374a1">5.1. 第一个雪球</a></li>
<li><a href="#orgdefad4c">5.2. <span class="todo TODO">TODO</span> 第二个雪球</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div id="outline-container-orgc36ca8c" class="outline-2">
<h2 id="orgc36ca8c"><span class="section-number-2">1</span> 引子</h2>
<div class="outline-text-2" id="text-1">
<p>
本文会以common lisp为代码基础,对实验一进行分析.本文会很长.所以希望能有一定的耐心读完.读完希望能对您有所收获,
</p>
</div>
</div>
<div id="outline-container-orgb8dcfb3" class="outline-2">
<h2 id="orgb8dcfb3"><span class="section-number-2">2</span> 题目</h2>
<div class="outline-text-2" id="text-2">
<p>
实验一特指哈工大软件工程的实验1.那么具体的题目为:
</p>
<blockquote>
<p>
给定一个表达式,可以对表达式化简,部分求值,求导.
同时表达式由字母,数字,括号,+,-,*,<sup>等符号组成</sup>.
</p>
</blockquote>
<p>
看起来是一个很简单的编译原理题目.但是仔细考虑会发现题目很有难度.比如如何处理括号是一个难点.如果用传统的自上向下编程,容易走入误区.那么,换个角度用函数式编程的思路以及方法,我们反而会有豁然开朗之感.
</p>
</div>
</div>
<div id="outline-container-org7aaf8d2" class="outline-2">
<h2 id="org7aaf8d2"><span class="section-number-2">3</span> 函数式编程之基本思想</h2>
<div class="outline-text-2" id="text-3">
<p>
首先要回答:什么是函数式编程.这个问题真的是见仁见智.我读过很多书,每本书对函数式编程的定义都不尽相同.但是在这些定义中有他们的共性.在这里我将主要分析共性,并在下面的文章中进行详细阐释.
</p>
</div>
<div id="outline-container-orgf433941" class="outline-3">
<h3 id="orgf433941"><span class="section-number-3">3.1</span> 函数式编程的特性</h3>
<div class="outline-text-3" id="text-3-1">
</div><div id="outline-container-org4a40948" class="outline-4">
<h4 id="org4a40948"><span class="section-number-4">3.1.1</span> 函数是一等公民</h4>
<div class="outline-text-4" id="text-3-1-1">
<p>
既然是函数式编程,自然离不开函数.那么什么叫函数是一等公民呢?就是说函数可以像变量一样传递.举一个很经典来自<a id="org764b5a1"></a><sup><a id="fnr.1" class="footref" href="#fn.1">1</a></sup>的例子:
</p>
<blockquote>
<p>
我们需要写一个函数,它能够生成累加器,即这个函数接受一个参数n,然后返回另一个函数,后者接受参数i,然后返回n增加(increment)了i后的值。
</p>
</blockquote>
<p>
是的,我们这里要函数的返回值就是函数.在这个情况下,函数和变量完全被当做一致看待了.这是理解函数式编程很重要的一点.平时写代码如果能强迫自己多用这种思维方式去思考,那么编程水平会有很大提高.
</p>
<p>
顺便说一句,上面这个问题用java是不可解的.有兴趣的可以加以尝试.但是在common lisp中,解决方案反而是很常见的一种模式:
</p>
<div class="org-src-container">
<pre class="src src-common-lisp">(defun acc (n)
(lambda (i) (+ i x)))
</pre>
</div>
</div>
</div>
<div id="outline-container-org7563bb5" class="outline-4">
<h4 id="org7563bb5"><span class="section-number-4">3.1.2</span> 无副作用</h4>
<div class="outline-text-4" id="text-3-1-2">
<p>
无副作用很简单的解释就是,一段代码无论在什么时候,在什么地点,对于相同的输入都会产生相同的结果.并且输入不会被改变.比如下面这段代码:
</p>
<div class="org-src-container">
<pre class="src src-common-lisp">(defun (x)
(+ 1 x))
</pre>
</div>
<p>
很明显的,不论我现在运行这段代码,还是1000万年以后运行这段代码,不论我在我电脑上运行这段代码,还是在实验室运行这段代码.x的数值不会变,返回的数据也不会变.
</p>
<p>
那么,我们可以得到非常有趣的两个结论:
</p>
</div>
<div id="outline-container-orge05856b" class="outline-5">
<h5 id="orge05856b"><span class="section-number-5">3.1.2.1</span> 函数式编程中不许出现全局变量</h5>
<div class="outline-text-5" id="text-3-1-2-1">
<p>
因为一旦出现了全局变量,将会导致在不同两次对函数的调用中,相同的输入导致不同的输出.这是函数式编程不能够允许的.下面函数式编程与面对过程编程中还有更深层次的讲解.
</p>
</div>
</div>
<div id="outline-container-org5461c3e" class="outline-5">
<h5 id="org5461c3e"><span class="section-number-5">3.1.2.2</span> 函数式编程中不许修改传入的参数</h5>
<div class="outline-text-5" id="text-3-1-2-2">
<p>
既然数据不许改变,那么c/c++中传递引用还是传值还是传地址就失去了意义.正确的做法是传数据传递的是地址,但是在函数内部不许改变参数.这种情况下代码清晰度才是最高的.
</p>
</div>
</div>
</div>
<div id="outline-container-org3560a69" class="outline-4">
<h4 id="org3560a69"><span class="section-number-4">3.1.3</span> 所有表达式都由返回值</h4>
<div class="outline-text-4" id="text-3-1-3">
<p>
当你习惯了函数式编程,在看到没有返回值的调用会觉得不舒服.在SICP中,函数式编程是不许使用变量的,一切的数据改变都必须通过返回值来完成.对于我们编程来说可能会有局限性,每个表达式都要油返回值的概念就此建立.
</p>
</div>
</div>
</div>
<div id="outline-container-org16ebc38" class="outline-3">
<h3 id="org16ebc38"><span class="section-number-3">3.2</span> 函数式编程与面向过程的区别</h3>
<div class="outline-text-3" id="text-3-2">
<p>
刚一接触函数式编程,可能会分不清函数式编程和面向过程编程之间的关系.并且有可能会以为他们之间区别不大.其实他们之间区别反而比函数式编程和面对对象之间的区别更大.
</p>
</div>
<div id="outline-container-org61f089f" class="outline-4">
<h4 id="org61f089f"><span class="section-number-4">3.2.1</span> 全局变量</h4>
<div class="outline-text-4" id="text-3-2-1">
<p>
上文已经说过,全局变量在函数式编程中是被禁止的.其实在严格的函数式编程语言中(比如SICP)连变量都是禁止使用的,而在面对过程中,全局变量是很重要的一个方面.全局变量可以提高效率,但是会降低代码的可读性甚至于正确性.这是我们要尽力避免的.
</p>
</div>
</div>
<div id="outline-container-org6808ebe" class="outline-4">
<h4 id="org6808ebe"><span class="section-number-4">3.2.2</span> 对于函数的理解</h4>
<div class="outline-text-4" id="text-3-2-2">
<p>
面对过程把函数(function)理解为了一个过程(procedure).对于他们而言,函数不过是代码模块,而面对对象则是把函数理解为了变量.可传递函数,可赋值.这从起始点就完全不同
</p>
</div>
</div>
</div>
<div id="outline-container-org6ac6863" class="outline-3">
<h3 id="org6ac6863"><span class="section-number-3">3.3</span> 函数式编程与面对对象的区别以及联系</h3>
<div class="outline-text-3" id="text-3-3">
<p>
对于common lisp语言来说,虽然他被"公认"为函数式编程语言(虽然我不这么认为),但是他依然有最先进的面对对象系统clos(这可不是我自己封的).面对对象和函数式编程区别看起来很大,但是在思想上却有着共同之处:把代码封装,从而提高效率以及提高正确率.
</p>
<p>
提到函数式编程和面对对象联系,不能不提到闭包这个数据结构:在很多著作中,闭包起到了面对对象中封装代码的作用,并且更加灵活.在学习闭包的时候如果能联系类的定义,一定会事半功倍.
</p>
</div>
</div>
</div>
<div id="outline-container-org4d21bd0" class="outline-2">
<h2 id="org4d21bd0"><span class="section-number-2">4</span> 函数式编程之自下向上</h2>
<div class="outline-text-2" id="text-4">
</div><div id="outline-container-org8d8599b" class="outline-3">
<h3 id="org8d8599b"><span class="section-number-3">4.1</span> 什么是自下向上编程</h3>
<div class="outline-text-3" id="text-4-1">
<p>
函数式编程和面对对象很大区别在于:面对对象一般自上向下编程,通过接口抽象出代码结构,然后逐步完善.函数式则一般采取子下向上编程.也就是 "the end is up".
</p>
<p>
现在工程一般采取的方法,是自上向下分析.可以简单的理解为先有图纸然后建造大楼.而自下向上则可以理解为滚雪球.通过一个个小雪球让雪球越滚越大.两种方法各有利弊.在下面我会用自己的代码,去阐述函数式编程和自下向上方法.
</p>
</div>
</div>
</div>
<div id="outline-container-org77a9c6f" class="outline-2">
<h2 id="org77a9c6f"><span class="section-number-2">5</span> <span class="todo TODO">TODO</span> 用滚雪球方式来理解代码</h2>
<div class="outline-text-2" id="text-5">
</div><div id="outline-container-orgb3374a1" class="outline-3">
<h3 id="orgb3374a1"><span class="section-number-3">5.1</span> 第一个雪球</h3>
<div class="outline-text-3" id="text-5-1">
<p>
按照我们这个思路去解决这题目的话,首先我们要建立合适的数据结构.在common lisp中,广义表是最常用的数据结构,在本题中也不例外.对表达式进行分析的话.发现一个表达式基础就是:
</p>
<blockquote>
<p>
number * symol<sub>1</sub> ^ number<sub>1</sub> … symbol<sub>n</sub> ^ number<sub>n</sub>
</p>
</blockquote>
<p>
那么我们广义表也就可以定义为:
</p>
<div class="org-src-container">
<pre class="src src-common-lisp">'(系数 ( sym_1 . num_1 ) ( sym_2 . num_2 ) ...)
</pre>
</div>
<p>
那么我们就可以开始滚第一个雪球–对数据结构进行操作的函数了:
</p>
<div class="org-src-container">
<pre class="src src-common-lisp">;;WARNNING!!!
;;all those macro should be applied to cdrs.
;; the two ended with car should be deleted later.
(defmacro get-^ (x)
`(cadar ,x))
(defmacro get-name (x)
`(caar ,x))
(defmacro get-prenum-car (x)
`(car ,x))
(defmacro get-prenum (x)
`(caar ,x))
(defmacro get-var-list (x)
`(cadar ,x))
(defmacro get-var-list-car (x)
`(cadr ,x))
</pre>
</div>
<p>
因为今后为了统一,我们默认采取的是传输cdr的形式.所以在上面没有说明的传输的都是list的cdr数据
</p>
</div>
</div>
<div id="outline-container-orgdefad4c" class="outline-3">
<h3 id="orgdefad4c"><span class="section-number-3">5.2</span> <span class="todo TODO">TODO</span> 第二个雪球</h3>
<div class="outline-text-3" id="text-5-2">
<p>
显然,为了处理系数,以及合并同类项,我们需要第二个雪球:
</p>
<div class="org-src-container">
<pre class="src src-common-lisp"> ;;warning
;;no side affect here
;;all functional programming
(defun create-var (var exp varlist)
(if (null varlist)
(list (list var exp))
(append1 varlist (list var exp))))
(defun change-exp (var exp varlist)
(if (find-variable var varlist)
(let ((cpvarlist varlist))
(incf (get-^ (find-variable var cpvarlist)) exp)
cpvarlist)
(create-var var exp varlist)))
</pre>
</div>
<p>
至于注释里面提到的side effect,我们已经在上文陈述过了.
</p>
</div>
</div>
</div>
<div id="footnotes">
<h2 class="footnotes">Footnotes: </h2>
<div id="text-footnotes">
<div class="footdef"><sup><a id="fn.1" class="footnum" href="#fnr.1">1</a></sup> <div class="footpara"><p class="footpara">
<a href="http://www.cnblogs.com/syeerzy/articles/3548899.html">http://www.cnblogs.com/syeerzy/articles/3548899.html</a>
</p></div></div>
</div>
</div></div>
<div id="postamble" class="status">
<p class="author">Author: zqy767</p>
<p class="date">Created: 2016-10-31 一 15:40</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
</body>
</html>