(define (sieve n)
  (let ((is-prime (make-vector (+ n 1) #t)))
    (vector-set! is-prime 0 #f)
    (vector-set! is-prime 1 #f)
    (let loop ((i 2))
      (when (<= (* i i) n)
        (when (vector-ref is-prime i)
          (let inner ((j (* i i)))
            (when (<= j n)
              (vector-set! is-prime j #f)
              (inner (+ j i)))))
        (loop (+ i 1))))
    (let collect ((i 2) (primes '()))
      (if (> i n)
          (reverse primes)
          (collect (+ i 1)
                   (if (vector-ref is-prime i)
                       (cons i primes)
                       primes))))))

(display "Primes up to 100:")
(newline)
(for-each
  (lambda (p) (display p) (display " "))
  (sieve 100))
(newline)
