[racket] static variables question

From: Gary Baumgartner (gfb at cs.toronto.edu)
Date: Sun Feb 19 15:50:21 EST 2012

Applying a lot of what Neil said:

; function to create a list of prime factors of a number
; invoke as (factor n)
(define (factor n)
  (let loop-factors ([facts '()] [x n] [start 2] [end 1000]
                                 [candidate-primes (primes-from-to 2 1000)])
    (cond [(and (empty? candidate-primes) (>= end (integer-sqrt x)))
           (if (= 1 x) facts (append facts (list x)))]
          [else (cond [(empty? candidate-primes)
                       ; attempt to pull in more primes in an efficient manner
                       (set! start end)
                       (set! end (* 2 end))
                       (when (> (* 1.25 end) (integer-sqrt x))
                         (set! end (integer-sqrt x)))
                       (set! candidate-primes (primes-from-to start end))
                       (loop-factors facts x start end candidate-primes)]
                      [else (define candidate (first candidate-primes))
                            (cond [(zero? (remainder x candidate))
                                   (set! facts (append facts (list candidate)))
                                   (loop-factors facts (quotient x candidate) start end
                                                 candidate-primes)]
                                  [else
                                   (loop-factors facts x start end (rest candidate-primes))])])])))

When you're using a lot of 'begin's in 'if's, consider 'cond' which has imlicit 'begin'.
 And for single-branch 'if's [which must be for side-effect], 'when' or 'unless'.

As for the 'set!'ing: notice, e.g., that
                                   (set! facts (append facts (list candidate)))
                                   (loop-factors facts (quotient x candidate) start end
                                                 candidate-primes)
 is just
                                   (loop-factors (append facts (list candidate))
                                                 (quotient x candidate) start end
                                                 candidate-primes)

Posted on the users mailing list.