[plt-scheme] Hash-tables and call/cc

From: Jens Axel Søgaard (jensaxel at soegaard.net)
Date: Mon May 7 17:17:35 EDT 2007

Strange, when I test the shift/reset solution i the repl
everthing looks fine. But when I use with srfi-42 this

   (list-ec (:set x (list->set (list 1 2 3)))
            x)

evaluats to (#t #t #t) and not to (1 2 3) as
the call/cc solution did.

Any ideas?

Move the #; to try the other version.


(require (lib "42.ss" "srfi")
          (lib "string.ss")
          (lib "match.ss")
          (lib "control.ss"))

(define-struct set (ht))

(define (empty)
   (make-set (make-hash-table 'equal)))

(define (insert! x s)
   (hash-table-put! (set-ht s) x #t)
   s)

(define (list->set xs)
   (let ([s (empty)])
     (for-each (lambda (x)
                 (insert! x s))
               xs)
     s))


#;
(define (hash-table->generator ht)
   (let ([continue+x
          (reset
           (hash-table-for-each
            ht
            (lambda (x v)
              ;; Return the value and the remaining computation
              (shift f (cons f v))))
           ;; Return a final #f
           (shift f #f))])
     (lambda ()
       (match continue+x
         [(continue . x)  (set! continue+x (continue 'dummy))
                          x]
         [#f              #f]))))

(define (hash-table->generator ht)
   (let ([continue 'start]
         [return   #f])
     (lambda ()
       (let/cc ret
         (set! return ret)
         (case continue
           [(done)    (return #f)]
           [(start)   (hash-table-for-each
                       ht
                       (lambda (x v)
                         (call/cc
                          (lambda (k)
                            (set! continue k)
                            (return x)))))
                      (set! continue 'done)
                      (return #f)]
           [else      (continue)])))))


(define-syntax :set
   (syntax-rules (index)
     ((:set cc var (index i) arg)
      (:parallel cc (:set var arg) (:integers i)) )
     ((:set cc var arg)
      (:do cc
           (let ((g (hash-table->generator (set-ht arg)))))
           ((x (g)))
           x
           (let ((var x)))
           #t
           ((g))))))

(define (:set-dispatch args)
   (cond
     [(null? args)
      'set]
     [(and (= (length args) 1)
           (set? (car args)))
      (:generator-proc
       (:set (car args)))]
     [else
      #f]))

(:-dispatch-set!
  (dispatch-union (:-dispatch-ref) :set-dispatch))

(list-ec (:set x (list->set (list 1 2 3)))
          x)


-- 
Jens Axel Søgaard



Posted on the users mailing list.