2008-08-20

Scheme笔记 -- 5

偶尔看到一篇文章,The Swine Before PERL[pdf|ppt],来自MIT的lightweight language workshop,相当精彩,读了数遍仍然意犹未尽。其中有一段代码,放在Chez Scheme, MzScheme,UCB STk,MIT-Scheme以及Guile 1.6下都能跑,唯独Guile 1.8总是报错,让我开始怀疑这是否是它的bug,结果却出乎意料:只有Guile 1.8才是做了该做的事 -- 从源代码eval.c的997到1003行可以看出端倪。

这里是各种Scheme解释器中运行的结果:
;; STk interpreter version 4.0.1-ucb1.3.6
(case 'x (x 1) (else 0)) ;; 1
(case 'x ((x) 1) (else 0)) ;; 1
(case 'x ('x 1) (else 0)) ;; 1
(case 'x ('x 1) ('y 2) (else 0)) ;; 1

;; MzScheme v4.0
(case 'x (x 1) (else 0)) ;; bad syntax
(case 'x ((x) 1) (else 0)) ;; 1
(case 'x ('x 1) (else 0)) ;; 1
(case 'x ('x 1) ('y 2) (else 0)) ;; 1

;; MIT-Scheme 7.7.90.+
(case 'x (x 1) (else 0)) ;; Ill-formed clause
(case 'x ((x) 1) (else 0)) ;; 1
(case 'x ('x 1) (else 0)) ;; 1
(case 'x ('x 1) ('y 2) (else 0)) ;; 1

;; Guile 1.6.7
(case 'x (x 1) (else 0)) ;; bad or missing clauses
(case 'x ((x) 1) (else 0)) ;; 1
(case 'x ('x 1) (else 0)) ;; 1
(case 'x ('x 1) ('y 2) (else 0)) ;; 1

;; Guile 1.8.3
(case 'x (x 1) (else 0)) ;; bad or missing clauses
(case 'x ((x) 1) (else 0)) ;; 1
(case 'x ('x 1) (else 0)) ;; 1
(case 'x ('x 1) ('y 2) (else 0)) ;; Duplicate case label

因为Scheme中'x等价于(quote x),于是最后一个语句等价于:
(case (quote x)
((quote x) 1) ;; A
((quote y) 2) ;; B
(else 0))
显然分支A和B中含有相同标号quote,这就是错误的根源。改成:
(case 'x ((x) 1) ((y) 2) (else 0))
就行了。

早晨搜到一个难兄难弟:链接

标签:

0 Comments:

发表评论

<< Home