sieve.scm 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. #!/usr/bin/env guile
  2. # -*- scheme -*-
  3. !#
  4. (use-modules (ice-9 match)
  5. (fibers)
  6. (fibers channels))
  7. (define (sieve p in)
  8. (let ((out (make-channel)))
  9. (spawn-fiber (lambda ()
  10. (let lp ()
  11. (let ((n (get-message in)))
  12. (unless (zero? (modulo n p))
  13. (put-message out n)))
  14. (lp)))
  15. #:parallel? #t)
  16. out))
  17. (define (integers-from n)
  18. (let ((out (make-channel)))
  19. (spawn-fiber (lambda ()
  20. (let lp ((n n))
  21. (put-message out n)
  22. (lp (1+ n))))
  23. #:parallel? #t)
  24. out))
  25. (define (take ch n)
  26. (let lp ((n n))
  27. (unless (zero? n)
  28. (get-message ch)
  29. (lp (1- n)))))
  30. (define (primes)
  31. (let ((out (make-channel)))
  32. (spawn-fiber (lambda ()
  33. (let lp ((ch (integers-from 2)))
  34. (let ((p (get-message ch)))
  35. (put-message out p)
  36. (lp (sieve p ch)))))
  37. #:parallel? #t)
  38. out))
  39. (define (main args)
  40. (match args
  41. ((_ count)
  42. (let ((count (string->number count)))
  43. (run-fibers (lambda () (take (primes) count)))))))
  44. (when (batch-mode?) (main (program-arguments)))