[racket] static variables question
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)