callcc - Scheme call/cc issue - implementing exit. -
i writing program needs recursively analyze list of "commands" , "programs" (it interpreter of "robotic language" invented our professor robot living in maze). because initial implementation slow, decided use call-with-current-continuation.
i know how call/cc works, have read this , this explanation.
my call/cc based on part of tutorial:
often want use call-with-current-continuation call procedure takes arguments other escape procedure. example, might have procedure takes 2 arguments besides escape procedure, thus:
(define (foo x y escape) ... (if (= x 0) (escape 'error)) ...)) can fix currying procedure, making procedure of 1 argument.
[ earlier chapter should have discussion of currying! ]
suppose want pass 0 , 1 values of x , y, handing foo escape procedure. rather saying
(call-with-current-continuation foo) doesn't pass enough arguments call foo, say
(call-with-current-continuation (lambda (escape) (foo 0 1 escape))) lambda expression creates closure want. call foo arguments 0, 1, , escape procedure created call-with-current-continuation.
however, reason doesn't work , throws exception:
call-with-current-continuation: contract violation expected: (any/c . -> . any) given: #<procedure:...mazesimulator.ss:301:34>
i me find mistake , explain why occurs...
here part of code relevant question:
; main program (define (simulate state expression-list program limit) ; read input , set global variables (set! current-orientation (list-ref state 2)) (set! current-coordinates (list-ref state 1)) (set! current-maze (list-ref state 0)) ; call inner function (call-with-current-continuation (lambda (exit) (command state expression-list program limit exit))) ; output (list list-of-executed-commands (list current-maze current-coordinates current-orientation)) ) ;; main recursive function ;; analyses expression-list parameter ;; evaluates elements ;; , calls on cdr of espression-list (define (command state expression-list program limit exit) (if (and (not (null? expression-list))(equal? stop-command #f)) ; recursion end condition, whole procedure done ; if list still not empty (if (atom? expression-list) ;if list consists of 1 command (if (equal? stop-command #f) ;positive branch - if there no erros before (atomic-command state expression-list program limit exit) ;call atomic-command on element ;when flag set #t (exit)) ; here comes problem "inner ifs" (if (atom? (car expression-list)) ;negative branch - if first element "if" (if (equal? (car expression-list) 'if) ;if list consisits of if-clause, no other commands ((if ...)) (if ((name->function (list-ref expression-list 1))) ;evaluate boolean - wall? north? , choose corresponding branch (command state (list-ref expression-list 2) program limit exit) (command state (list-ref expression-list 3) program limit exit)) (evaluate-first-and-call-command-on-rest expression-list program limit exit)) (if (equal? (car(car expression-list)) 'if) ;if if-clause not element in list - "inner if" ((if ...) turn-left put-mark) (begin ;not evaluate if-clause, (if ((name->function (list-ref (car expression-list) 1))) (command state (list-ref (car expression-list) 2) program limit exit) (command state (list-ref (car expression-list) 3) program limit exit)) (command state (cdr expression-list) program limit exit)) ;but call command on cdr! (evaluate-first-and-call-command-on-rest expression-list program limit exit)))) ;when limit exceeded or when flag set #t (exit) ))
new follow-up: @ point puzzled poster's question. gozoner has pointed out continuation passed call/cc
may require actual parameter when invoked, not true in racket (which, based on poster's error message, language implementation assume under discussion).
furthermore, code snippet original poster put in question incomplete, 1 cannot directly execute code in attempt replicate problem. (my informal analysis hasn't revealed obvious bug in use of call-with-current-continuation
presented original poster.) useful if original poster derive minimal (or @ least smaller) test case exposes same issue.
it 1 of specific languages or language levels within racket uses more restrictive form of call/cc
, have not found evidence of such language level. pose question original poster.
edit: chris-jester young has pointed out commentary may not apply here (see comments on answer). need more investigate racket's handling of continuations in imperative code; notes below may leading asker down incorrect path. (i plan delete answer if can confirm notes below bogus.)
follow-up edit: appears racket's handling of call/cc
indeed pass along continuation accept 0 values when invoked context discards value. example:
(define global 7) (define (goner exit) (set! global 11) (exit) (set! global 13) (* 2 3)) (define (hi) (define x global) (call-with-current-continuation goner) (* 5 x global)) (* 5 7 11) (hi)
the above prints 385 (twice); once (* 5 7 11)
, , once (hi)
.
(original commentary follows)
the fact invoking (exit)
0 arguments leads me think not understand how call/cc
works (as in observable behavior), despite claim contrary.
i recommend play small examples, independently of professor's robot maze infrastructure, before try incorporate call/cc
solution.
for example, can readily reproduce error message way:
(define (goner) (* 2 3)) (define (hi) (let ((x (call-with-current-continuation goner))) (* 5 x))) (hi)
from above, get:
call-with-current-continuation: contract violation expected: (any/c . -> . any) given: #<procedure:goner>
which quite similar error message, no? (though honest, might coincidence).
compare output run above outputs runs of:
(define (goner exit) (* 2 3)) (define (hi) (let ((x (call-with-current-continuation goner))) (* 5 x))) (hi)
and:
(define (goner exit) (* 2 (exit))) (define (hi) (let ((x (call-with-current-continuation goner))) (* 5 x))) (hi)
and:
(define (goner exit) (* 2 (exit 3))) (define (hi) (let ((x (call-with-current-continuation goner))) (* 5 x))) (hi)
and:
(define (goner exit) (* (exit 2) 3)) (define (hi) (let ((x (call-with-current-continuation goner))) (* 5 x))) (hi)
give careful thought each illustrating, , think how might matter in case of program.
Comments
Post a Comment