[racket] Making a Racket function "recallable"
On Mon, Feb 13, 2012 at 11:52 PM, Joe Gilray <jgilray at gmail.com> wrote:
> Warning: extreme newbie question ahead.
>
> I wrote the following fibonacci function:
>
> ; function that returns the next fibonacci number each time it is called
> ; invoke as (fib)
> (define fib
> (let ([n0 -1] [n1 1])
> (lambda ()
> (let ([next (+ n0 n1)])
> (set! n0 n1)
> (set! n1 next))
> n1)))
One thing you can do is turn fib into a "sequence", and then from a
sequence into a stream that knows how to remember its previous values.
Here's what it might look like:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
#lang racket
(require racket/sequence)
(define fib
(let ([n0 -1] [n1 1])
(lambda ()
(let ([next (+ n0 n1)])
(set! n0 n1)
(set! n1 next))
n1)))
(define fib-stream
;; Here's a sequence of the function:
(let ([fib-sequence (in-producer fib 'donttellmecauseithurts)])
;; Let's wrap it and turn it into a stream that remembers...
(sequence->stream fib-sequence)))
;; Ok, we've got a stream. Let's look at its first few elements.
(define (peek-fibs n)
(for ([elt fib-stream]
[i (in-range n)])
(displayln elt)))
(peek-fibs 10)
(printf "-----\n")
(peek-fibs 20)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;