简体   繁体   中英

Corecursion Doesn't Terminate After Small Change

I wrote a function in Racket to produce something similar to the following fractal.

圆形分形

(define CUT-OFF 5)
(define CIRCLE-MODE "outline")

(define (circle-fractal size colour)
  (local [(define full-circle (circle size CIRCLE-MODE colour))]

    (cond [(<= size CUT-OFF) full-circle]
          [else
           (overlay/align "middle" "middle" 
                          full-circle
                          (beside (circle-fractal (/ size 2) colour)
                                  (circle-fractal (/ size 2) colour)))])))

It passes my tests.

I changed the code, thinking the below would be more readable.

(define (circle-fractal size colour)
  (local [(define full-circle (circle size CIRCLE-MODE colour))
          (define half-circle (circle-fractal (/ size 2) colour))]

    (cond [(<= size CUT-OFF) full-circle]
          [else
           (overlay/align "middle" "middle" 
                          full-circle
                          (beside half-circle half-circle))])))

Now the function doesn't terminate. Racket reaches its memory limit with no output.

Does each corecursive call somehow not approach the trivial case after this change?

In the first version (circle-fractal (/ size 2) colour) is evaluated only if size > CUT-OFF . In the second it's called regardless of size. This way you lost your recursion base case.

Try:

(define (circle-fractal size colour)
  (define full-circle (circle size CIRCLE-MODE colour))
  (cond [(<= size CUT-OFF) full-circle]
        [else
         (define half-circle (circle-fractal (/ size 2) colour))
         (overlay/align "middle" "middle" 
                        full-circle
                        (beside half-circle half-circle))]))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM