Closed gambiteer closed 1 year ago
A Scheme system is allowed to delimit continuations at the REPL prompt.
Can you run your test as a top-level program instead?
How do I do that? I tried
heine:~/programs/chibi-scheme> cat test-cont1.scm
(import (srfi 231))
(define (pp arg) (display arg) (newline))
(pp 'array-copy)
(let* ((cont #f)
(call-cont #t)
(domain (make-interval '#(2 2)))
(A_ (lambda (i j)
(call-with-current-continuation
(lambda (c)
(if (= i j 0)
(set! cont c))
1))))
(A (make-array domain A_))
(array-list '()))
(set! array-list (cons (array-copy A) array-list))
(pp 'printing)
(for-each (lambda (A) (pp (array->list* A))) array-list)
(if call-cont
(begin
(set! call-cont #f)
(cont 4)))
#;(pp (apply eq? array-list)))
and
heine:~/programs/chibi-scheme> env LD_LIBRARY_PATH=/usr/local/chibi/lib /usr/local/chibi/bin/chibi-scheme test-cont1.scm
ERROR on line 3 of file test-cont1.scm: undefined variable: newline
called from <anonymous> on line 1268 of file /usr/local/chibi/share/chibi/init-7.scm
called from <anonymous> on line 800 of file /usr/local/chibi/share/chibi/init-7.scm
Searching for modules exporting newline ...
newline is exported by:
(chibi)
(scheme base)
(scheme r5rs)
(scheme red)
(scheme small)
You have to import at least (scheme base)
and (scheme write)
.
Thanks, I added
(import (scheme base)
(scheme write)
(srfi 231))
at the top of the file and got
heine:~/programs/chibi-scheme> env LD_LIBRARY_PATH=/usr/local/chibi/lib /usr/local/chibi/bin/chibi-scheme test-cont1.scm
array-copy
printing
((1 1) (1 1))
printing
((4 1) (1 1))
FYI if you want to demonstrate that Chibi's array iterators are not call/cc reentrant you need a dimension 3 or higher array.
It appears to have nothing to do with arrays, here's another example:
heine:~/programs/chibi-scheme> env LD_LIBRARY_PATH=/usr/local/chibi/lib /usr/local/chibi/bin/chibi-scheme test-cont2.scm
map
printing
(1 2 3 4)
printing
(4 2 3 4)
heine:~/programs/chibi-scheme> cat test-cont2.scm
(import (scheme base)
(scheme write))
(define (pp arg) (display arg) (newline))
(pp 'map)
(let* ((cont #f)
(call-cont #t)
(arg '(1 2 3 4))
(f (lambda (x)
(call-with-current-continuation
(lambda (c)
(if (eqv? x 1)
(set! cont c))
x))))
(lists '()))
(set! lists (cons (map f arg) lists))
(pp 'printing)
(for-each pp lists)
(if call-cont
(begin
(set! call-cont #f)
(cont 4)))
#;(pp (apply eq? array-list)))
Gambit gives:
heine:~/programs/chibi-scheme> gsi test-cont2.scm
map
printing
(1 2 3 4)
printing
(4 2 3 4)
(1 2 3 4)
Running in the interpreter, mzscheme gives:
> (define (pp arg) (display arg) (newline))
> (pp 'map)
map
> (let* ((cont #f)
(call-cont #t)
(arg '(1 2 3 4))
(f (lambda (x)
(call-with-current-continuation
(lambda (c)
(if (eqv? x 1)
(set! cont c)
'die)
x))))
(lists '()))
(set! lists (cons (map f arg) lists))
(pp 'printing)
(for-each pp lists)
(if call-cont
(begin
(set! call-cont #f)
(cont 4))
'die)
#;(pp (apply eq? array-list)))
printing
(1 2 3 4)
printing
(4 2 3 4)
(1 2 3 4)
die
I don't really know how to run this as a file in Racket, sorry. Edit: Forgot the last line of output from the Racket version, which needed two-arm ifs.
You don't need map
to see the problem:
heine:~/programs/chibi-scheme> cat test-cont3.scm
(import (scheme base)
(scheme write))
(define (pp arg) (display arg) (newline))
(pp 'function-call)
(let* ((cont #f)
(call-cont #t)
(f (lambda (x)
(call-with-current-continuation
(lambda (c)
(if (eqv? x 'first-entry)
(set! cont c)
'die)
x))))
(list '()))
(set! list (cons (f 'first-entry) list))
(pp 'printing)
(pp list)
(if call-cont
(begin
(set! call-cont #f)
(cont 're-entry))
'die)
#;(pp (apply eq? array-list)))
Chibi runs this as
heine:~/programs/chibi-scheme> env LD_LIBRARY_PATH=/usr/local/chibi/lib /usr/local/chibi/bin/chibi-scheme test-cont3.scm
function-call
printing
(first-entry)
printing
(re-entry)
Gambit gives
heine:~/programs/chibi-scheme> gsi test-cont3.scm
function-call
printing
(first-entry)
printing
(re-entry first-entry)
It appears to be something to do with the direct continuation of a set!
clause. Change the set! to
(let ((tmp (f 'first-entry)))
(set! list (cons tmp list)))
and it works as expected.
Ah, mystery solved. This is just a matter of the order of evaluation - Chibi is one of the few implementations which evaluate args right-to-left rather than left-to-right.
Since this continuation is caught in the middle of an application call, it's not defined whether the other arguments (here list
) are evaluated before or after the continuation is captured. The rewrite above forces an ordering, making it behave like Gambit, but more simply we can flip the order of args to make it agree:
(set! list (xcons list (f 'first-entry)))
Since the order of evaluation is undefined this is not a bug.
Thanks for your explanation, I'm really a beginner at continuations.
When I try the program
heine:~/programs/chibi-scheme> cat test-cont4.scm
(import (scheme base)
(scheme write))
(define (pp arg) (display arg) (newline))
(pp 'function-call)
(let* ((cont #f)
(call-cont 4)
(f (lambda (x)
(call-with-current-continuation
(lambda (c)
(if (eqv? x 'first-entry)
(set! cont c)
'die)
x))))
(list '()))
(set! list (cons (f 'first-entry) list))
(pp 'printing)
(pp list)
(if (not (zero? call-cont))
(begin
(set! call-cont (- call-cont 1))
(cont 're-entry))
'die)
#;(pp (apply eq? array-list)))
I see
heine:~/programs/chibi-scheme> env LD_LIBRARY_PATH=/usr/local/chibi/lib /usr/local/chibi/bin/chibi-scheme test-cont4.scm
function-call
printing
(first-entry)
printing
(re-entry)
printing
(re-entry)
printing
(re-entry)
printing
(re-entry)
So does that mean the list passed to the set!
is always '()
, no matter how many times the set!
is called?
And, does that mean that the value of list at the initial call, '()
, is stored in the continuation, rather than the "box" that contains the value?
I guess I still find this counterintuitive.
I get it now, thanks.
Message ID: @.***>
For easier understanding you can use the xcons
version in Gambit and see it print out:
printing
(first-entry)
printing
(re-entry)
I tried to test some of the SRFI 231 routines in chibi, and found
I was expecting
array-list
to end up with two elements, as in Gambit:This may have something more to do with continuations than with SRFI 231.