scheme - Weird thing happening with call/cc, Why? -


i simulated state-programming solution on lisp solve tree-flatten:

#lang racket  (define (flat-tree-generator tr)     (define initial? #t)     (define state '())     (define (resume)         (if (null? state)             '()             (let ((cont (car state)))                 (set! state (cdr state))                 (cont))))     (define (recur tr)          (cond              ((null? tr) (resume))             ((not (pair? tr)) tr)             (else (call/cc                      (lambda (k)                         (set! state                              (cons                                (lambda () (k (recur (cdr tr))))                                state))                         (recur (car tr)))))))     (define (dispatch)         (if initial?             (begin (set! initial? #f) (recur tr))             (resume)))     dispatch)   (define g1 (flat-tree-generator '((0 (1 2)) (3 4)))) (define g2 (flat-tree-generator '(0 1 2 3 4))) 

ok, if try:

(g1)(g2)(g1)(g2)(g1)(g2)(g1)(g2)(g1)(g2) 

it work expected (output lines 0011223344). however, if try this:

(for ([e1 (in-producer g1 '())]       [e2 (in-producer g2 '())])     (printf "e1: ~a  e2: ~a\n" e1 e2)) 

you get:

e1: 0  e2: 0 e1: 0  e2: 1 e1: 0  e2: 2 e1: 0  e2: 3 e1: 0  e2: 4 

or try:

(define (test)     (g1)(g2)(g1)(g2)(g1)(g2)(g1)(g2)(g1)(g2)) (test) 

you get:

'() 

i confused.. why?

when call-with-current-continuation in repl have guards between each statement while in test end after first (g2) after executing second unless tr null. eg. execute second (g2) , (g1) in loop since end before code executed until hit (not (pair? tr)) g2 , g1 3 times emty list.

you don't need call/cc @ all. it's enough closures:

(define (flat-tree-generator tr)   (define initial? #t)   (define state '())   (define (resume)     (if (null? state)         '()         (let ((cont (car state)))           (set! state (cdr state))           (cont))))   (define (recur tr)      (cond        ((null? tr) (resume))       ((not (pair? tr)) tr)       (else (set! state                       (cons                        (lambda () (recur (cdr tr)))                        state))                (recur (car tr)))))   (define (dispatch)     (if initial?         (begin (set! initial? #f) (recur tr))         (resume)))   dispatch) 

or can use rackets generator features. code works in same manner:

(require racket/generator) (define (flat-tree-generator tr)   (generator ()     (let rec ((tr tr))       (cond ((null? tr) tr)             ((pair? (car tr)) (rec (car tr))                               (rec (cdr tr)))             (else (yield (car tr))                   (rec (cdr tr))))))) 

in both expected behaviour:

(for ([e1 (in-producer g1 '())]       [e2 (in-producer g2 '())])     (printf "e1: ~a  e2: ~a\n" e1 e2))  ; ==> void, side effect prints: e1: 0  e2: 0 e1: 1  e2: 1 e1: 2  e2: 2 e1: 3  e2: 3 e1: 4  e2: 4 

Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -