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

Popular posts from this blog

linux - Does gcc have any options to add version info in ELF binary file? -

android - send complex objects as post php java -

charts - What graph/dashboard product is facebook using in Dashboard: PUE & WUE -