偶尔看到一篇文章,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))
就行了。
早晨搜到一个难兄难弟:
链接。
标签: scheme