1 ;;;; r5rs_pitfall.test --- tests some pitfalls in R5RS -*- scheme -*-
2 ;;;; Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
4 ;;;; This library is free software; you can redistribute it and/or
5 ;;;; modify it under the terms of the GNU Lesser General Public
6 ;;;; License as published by the Free Software Foundation; either
7 ;;;; version 2.1 of the License, or (at your option) any later version.
9 ;;;; This library is distributed in the hope that it will be useful,
10 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ;;;; Lesser General Public License for more details.
14 ;;;; You should have received a copy of the GNU Lesser General Public
15 ;;;; License along with this library; if not, write to the Free Software
16 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 ;; These tests have been copied from
19 ;; http://sisc.sourceforge.net/r5rs_pitfall.scm and the 'should-be'
20 ;; macro has been modified to fit into our test suite machinery.
22 (define-module (test-suite test-r5rs-pitfall)
23 :use-syntax (ice-9 syncase)
24 :use-module (test-suite lib))
26 (define-syntax should-be
28 ((_ test-id value expression)
29 (run-test test-id #t (lambda ()
31 (equal? expression value)))))))
33 (define-syntax should-be-but-isnt
35 ((_ test-id value expression)
36 (run-test test-id #f (lambda ()
38 (equal? expression value)))))))
40 (define call/cc call-with-current-continuation)
42 ;; Section 1: Proper letrec implementation
44 ;;Credits to Al Petrofsky
46 ;; defines in letrec body
47 ;; http://groups.google.com/groups?selm=87bsoq0wfk.fsf%40app.dial.idiom.com
51 (letrec ((x (call-with-current-continuation (lambda (c) (set! cont c) 0)))
52 (y (call-with-current-continuation (lambda (c) (set! cont c) 0))))
61 ;;Credits to Al Petrofsky
63 ;; Widespread bug (arguably) in letrec when an initializer returns twice
64 ;; http://groups.google.com/groups?selm=87d793aacz.fsf_-_%40app.dial.idiom.com
66 (letrec ((x (call/cc list)) (y (call/cc list)))
67 (cond ((procedure? x) (x (pair? y)))
68 ((procedure? y) (y (pair? x))))
69 (let ((x (car x)) (y (car y)))
70 (and (call/cc x) (call/cc y) (call/cc x)))))
72 ;;Credits to Alan Bawden
74 ;; LETREC + CALL/CC = SET! even in a limited setting
75 ;; http://groups.google.com/groups?selm=19890302162742.4.ALAN%40PIGPEN.AI.MIT.EDU
77 (letrec ((x (call-with-current-continuation
81 ((cadr x) (list #F (lambda () x)))
84 ;; Section 2: Proper call/cc and procedure application
86 ;;Credits to Al Petrofsky, (and a wink to Matthias Blume)
88 ;; Widespread bug in handling (call/cc (lambda (c) (0 (c 1)))) => 1
89 ;; http://groups.google.com/groups?selm=87g00y4b6l.fsf%40radish.petrofsky.org
91 (call/cc (lambda (c) (0 (c 1)))))
93 ;; Section 3: Hygienic macros
98 ;; http://groups.google.com/groups?selm=skitsdqjq3.fsf%40tulare.cs.cornell.edu
102 ((_ expr) (+ expr 1)))))
107 ;; Al Petrofsky again
109 ;; Buggy use of begin in r5rs cond and case macros.
110 ;; http://groups.google.com/groups?selm=87bse3bznr.fsf%40radish.petrofsky.org
112 (let-syntax ((foo (syntax-rules ()
113 ((_ var) (define var 1)))))
115 (begin (define foo +))
116 (cond (else (foo x)))
121 ;; An Advanced syntax-rules Primer for the Mildly Insane
122 ;; http://groups.google.com/groups?selm=87it8db0um.fsf@radish.petrofsky.org
127 ((foo (syntax-rules ()
129 ((bar (syntax-rules ()
130 ((_) (let ((x 2)) y)))))
135 ;; Contributed directly
137 (let-syntax ((x (syntax-rules ()))) 1))
139 ;; Setion 4: No identifiers are reserved
143 ;; shadowing syntatic keywords, bug in MIT Scheme?
144 ;; http://groups.google.com/groups?selm=6e6n88%248qf%241%40news.cc.ukans.edu
146 ((lambda lambda lambda) 'x))
148 (should-be 4.2 '(1 2 3)
149 ((lambda (begin) (begin 1 2 3)) (lambda lambda lambda)))
152 (let ((quote -)) (eqv? '1 1)))
153 ;; Section 5: #f/() distinctness
163 ;; Section 6: string->symbol case sensitivity
167 ;; Symbols in DrScheme - bug?
168 ;; http://groups.google.com/groups?selm=3be55b4f%240%24358%24edfadb0f%40dspool01.news.tele.dk
170 (eq? (string->symbol "f") (string->symbol "F")))
172 ;; Section 7: First class continuations
175 ;; No newsgroup posting associated. The jist of this test and 7.2
176 ;; is that once captured, a continuation should be unmodified by the
177 ;; invocation of other continuations. This test determines that this is
178 ;; the case by capturing a continuation and setting it aside in a temporary
179 ;; variable while it invokes that and another continuation, trying to
180 ;; side effect the first continuation. This test case was developed when
181 ;; testing SISC 1.7's lazy CallFrame unzipping code.
189 (set! r (+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! a k) 4))))
190 (+ 5 (+ 6 (call/cc (lambda (k) (set! b k) 7))))))
201 ;; Same test, but in reverse order
209 (set! r (+ 1 (+ 2 (+ 3 (call/cc (lambda (k) (set! a k) 4))))
210 (+ 5 (+ 6 (call/cc (lambda (k) (set! b k) 7))))))
221 ;; Credits to Matthias Radestock
222 ;; Another test case used to test SISC's lazy CallFrame routines.
223 (should-be 7.3 '((-1 4 5 3)
233 (define (identity x) x)
235 ((identity (if (= state 0)
236 (call/cc (lambda (k) (set! k1 k) +))
238 (identity (if (= state 0)
239 (call/cc (lambda (k) (set! k2 k) 1))
241 (identity (if (= state 0)
242 (call/cc (lambda (k) (set! k3 k) 2))
244 (define (check states)
248 (set! res (cons r res))
251 (begin (set! state (car states))
252 (set! states (cdr states))
257 (map check '((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)))))
259 ;; Modification of the yin-yang puzzle so that it terminates and produces
260 ;; a value as a result. (Scott G. Miller)
261 (should-be 7.4 '(10 9 8 7 6 5 4 3 2 1 0)
266 (let* ((yin ((lambda (foo)
273 (call/cc (lambda (bar) bar))))
277 (call/cc (lambda (baz) baz)))))
284 ;; R5RS Implementors Pitfalls
285 ;; http://groups.google.com/groups?selm=871zemtmd4.fsf@app.dial.idiom.com
287 (let - ((n (- 1))) n))
289 (should-be 8.2 '(1 2 3 4 1 2 3 4 5)
290 (let ((ls (list 1 2 3 4)))
291 (append ls ls '(5))))
293 ;;Not really an error to fail this (Matthias Radestock)
294 ;;If this returns (0 1 0), your map isn't call/cc safe, but is probably
295 ;;tail-recursive. If its (0 0 0), the opposite is true.
296 (should-be 8.3 '(0 1 0)
298 (define executed-k #f)
302 (set! res1 (map (lambda (x)
304 (call/cc (lambda (k) (set! cont k) 0))
308 (begin (set! executed-k #t)