[plt-scheme] Hash-tables and call/cc
Hello Jens,
I am not certian, but I think the problem resides in the fact that you're
capturing the entire escape-path which now includes the 'list' bit. This
means that you're calling a separate list on each item. I remember having
similar issues when I wanted to lazify a structure, and I had to jump through
quite a few hoops to do it with continuations.
But, this seems to be a perfect place to use delimited continuations:
(module foo
(require (lib "control.ss"))
(define (hash-table->generator ht)
(let ([*pair*
(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 ()
(if *pair*
(let ([temp *pair*])
;; The #f is just a bogus parameter, reset continuations
;; require 1 parameter
(set! *pair* ((car temp) #f))
(cdr temp)
)
#f))))
(define g (hash-table->generator
(make-immutable-hash-table
'(("1" . 1) ("2" . 2) ("3" . 3)))))
)
Cheers,
Christophe
Jens Axel Søgaard wrote:
> Hi all,
>
> I'd like to iterate through the keys in a hash-table
> with srfi-42. In order to do that I'd like a function:
>
> hash-table->generator : hash-table -> thunk
>
> which takes a hash-table as input and returns a
> thunk g as output. The first invocation of g
> returns the first element, the second invocation
> returns the seconc, and so on. When there is no
> left, g simply return #f.
>
> Here is an attempt do just that:
>
> (define (hash-table->generator ht)
> (let ([continue 'start])
> (lambda ()
> (case continue
> [(done) #f]
> [(start) (let/ec return
> (hash-table-for-each
> ht
> (lambda (x v)
> (call/cc
> (lambda (k)
> (set! continue k)
> (return x)))))
> (set! continue 'done)
> #f)]
> [else (continue)]))))
>
> It almost work - but only almost.
>
> Here is a session in the REPL:
>
>> (define g (hash-table->generator
> (make-immutable-hash-table
> '(("1" . 1) ("2" . 2) ("3" . 3)))))
>> (g)
> "2"
>> (g)
> "3"
>> (g)
> "1"
>> (g)
> #f
>
> But now the fun begins:
>
>> (define g (hash-table->generator
> (make-immutable-hash-table
> '(("1" . 1) ("2" . 2) ("3" . 3)))))
>> (list (g) (g))
> (#f done)
>
> I have missed /something/ in hash-table->generator,
> but what?
>
--
christophe poucet
phd. student
nes - mpsoc ltr
phone:+32 16 28 87 20
e-mail: christophe (dot) poucet (at) imec (dot) be
--------------------------------------------------------------------------------
IMEC vzw – Register of Legal Entities Leuven VAT BE 0425.260.668
– Kapeldreef 75, B-3001 Leuven, Belgium
– http://www.imec.be
--------------------------------------------------------------------------------