(do ((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
((= 10 n) cur)))
这是一段来自Lisp教科书的示例,介绍了关键字"do"
"do"的基本模板如下:
(do (variable-definitions*)
(end-test-form result-form*)
statement*)
然而,对于这个例子,我不清楚哪部分是哪部分。还有,中间的两行代码是做什么的?
谢谢!
(do ((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
((= 10 n) cur)))
这是一段来自Lisp教科书的示例,介绍了关键字"do"
"do"的基本模板如下:
(do (variable-definitions*)
(end-test-form result-form*)
statement*)
然而,对于这个例子,我不清楚哪部分是哪部分。还有,中间的两行代码是做什么的?
谢谢!
(do ((n 0 (1+ n)) ;declares n, initially 0, n+1 each subsequent iteration)
(cur 0 next) ;declares cur, initially 0, then old value of next
(next 1 (+ cur next))) ;declares next, initially 1, then the sum of (the old) cur and next
((= 10 n) ;end condition (ends when n = 10)
cur) ; return value
;empty body
)
翻译成类C代码
for(n=0, cur=0, next=1 ;
!(n == 10) ;
n=old_n+1, cur=old_next, next = old_cur + old_next)
{
//do nothing
old_n = n;
old_cur = cur;
old_next = next;
}
return cur;
顺带一提,你应该能够看到这段代码返回第10个斐波那契数。
可选的EBNF/正式语法:
根据Hyperspec的语法是:
(do ({var | (var [init-form [step-form]])}*)
(end-test-form result-form*)
declaration*
{tag | statement}*)
理解这需要对EBNF有一定的了解,并对Hyperspec掌握相当多的知识
您良好的缩进清晰地显示了每个部分:
(do ((n 0 (1+ n))
^(cur 0 next)
|(next 1 (+ cur next)))
|
+-- first argument of do
((= 10 n) cur)))
^
|
+-- start of second argument of do
看,它们排列得很整齐,内部材料也有缩进:
((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
^
|
+- inner material of argument: three forms which are
indented by 1 character and aligned together.
你的do
语句没有第三个参数:循环体中没有语句(空循环)。
(do
;; varlist
((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
;; endlist
((= 10 n) cur)
;; body
(print (list n cur next)))
这将打印
(0 0 1)
(1 1 1)
(2 1 2)
(3 2 3)
(4 3 5)
(5 5 8)
(6 8 13)
(7 13 21)
(8 21 34)
(9 34 55)
55
(do ((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
((= 10 n) cur))
do有3个部分。
在这个特定的例子中,没有主体。所有真正的工作都由1和2完成。首先它设置了3个变量并给出了初始值和步骤形式。例如,n
设置为0,在每次迭代期间它会进一步步进:(1+n)
,这将增加n
终止条件是((= n 10) cur)
:当n
等于10时。然后将cur
作为此do
表达式的整个返回值返回。
将所有这些组合起来,在这个do
示例中,它将从1加到10,得到55。
result-form-n
而不是action-n
,另外你的第二个代码块缩进得很糟糕。 - tobyodavies(cur,next) = (0,1) (1,1) (1,2) (2,3) (3,5) (5,8) (8,13) ...
的斐波那契数,而不仅仅是部分和。 - Will Ness
(if (> (this-fib-loop) 10) 'gt-10 'lte-10)
),这更具有函数式的特点。 - tobyodavies