[racket] Making a Racket function "recallable"

From: Erik Silkensen (eriksilkensen at gmail.com)
Date: Tue Feb 14 00:51:07 EST 2012

Instead of calling fib-less-than-n recursively, you could add a loop inside, for example something like,

(define (fib-less-than-n n)
  (define fib (mk-fib))
  (let loop ([vs '()])
    (let ([fib-val (fib)])
      (if (>= fib-val n)
          (reverse vs)
          (loop (cons fib-val vs))))))

- Erik

On Feb 13, 2012, at 10:41 PM, Joe Gilray wrote:

> Erik,
> 
> Intriguing idea and it works "flat", but if I write the following I end up with an infinite loop:
> 
> (define (fib-less-than-n n)
>   (let ([f1 (mk-fib)])
>     (let ([fib-val (f1)])
>       (if (>= fib-val n) '() (cons fib-val (fib-less-than-n n))))))
> 
> How would I use your idea in this case?
> 
> thanks!
> -joe
> 
> On Mon, Feb 13, 2012 at 9:18 PM, Erik Silkensen <eriksilkensen at gmail.com> wrote:
> Another option is you could turn change your fib function to be 'mk-fib' that returns a new instance of the fib function each time it's called:
> 
> (define (mk-fib)
>  (let ([n0 -1] [n1 1])
>    (lambda ()
>      (let ([next (+ n0 n1)])
>        (set! n0 n1)
>        (set! n1 next))
>      n1)))
> 
> - Erik
> 
> On Feb 13, 2012, at 10:10 PM, Danny Yoo wrote:
> 
> > 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)
> > ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> >
> > ____________________
> >  Racket Users list:
> >  http://lists.racket-lang.org/users
> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20120213/dc9d411b/attachment.html>

Posted on the users mailing list.