diagonal.scm 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. #!/usr/bin/env guile
  2. # -*- scheme -*-
  3. !#
  4. (use-modules (ice-9 match)
  5. (fibers)
  6. (fibers channels))
  7. (define (make-squarer in)
  8. (let ((out (make-channel)))
  9. (spawn-fiber (lambda ()
  10. (let lp ()
  11. (let ((x (get-message in)))
  12. (put-message out (* x x))
  13. (lp))))
  14. #:parallel? #t)
  15. out))
  16. (define (make-sqrter in)
  17. (let ((out (make-channel)))
  18. (spawn-fiber (lambda ()
  19. (let lp ()
  20. (let ((x (get-message in)))
  21. (put-message out (sqrt x))
  22. (lp))))
  23. #:parallel? #t)
  24. out))
  25. (define (make-broadcaster in dimensions)
  26. (let ((out (map (lambda (_) (make-channel))
  27. (iota dimensions))))
  28. (spawn-fiber (lambda ()
  29. (let lp ()
  30. (let ((x (get-message in)))
  31. (for-each (lambda (ch) (put-message ch x))
  32. out)
  33. (lp))))
  34. #:parallel? #t)
  35. out))
  36. (define (make-summer in)
  37. (let ((out (make-channel)))
  38. (spawn-fiber (lambda ()
  39. (let lp ()
  40. (let lp ((sum 0) (in in))
  41. (match in
  42. (() (put-message out sum))
  43. ((ch . in) (lp (+ sum (get-message ch)) in))))
  44. (lp)))
  45. #:parallel? #t)
  46. out))
  47. (define (make-counter)
  48. (let ((out (make-channel)))
  49. (spawn-fiber (lambda ()
  50. (let lp ((n 0))
  51. (put-message out n)
  52. (lp (1+ n))))
  53. #:parallel? #t)
  54. out))
  55. (define (make-diagonal dimensions make-head make-tail)
  56. (let ((ch (make-head)))
  57. (let lp ((dimensions dimensions))
  58. (when (positive? dimensions)
  59. (make-tail ch)
  60. (lp (1- dimensions))))))
  61. (define (test dimensions message-count)
  62. (let* ((ints (make-counter))
  63. (dims (make-broadcaster ints dimensions))
  64. (squares (map make-squarer dims))
  65. (sums (make-summer squares))
  66. (lens (make-sqrter sums)))
  67. (let lp ((n 0))
  68. (when (< n message-count)
  69. (get-message lens)
  70. (lp (1+ n))))))
  71. (define (main args)
  72. (match args
  73. ((_ dimensions message-count)
  74. (let ((dimensions (string->number dimensions))
  75. (message-count (string->number message-count)))
  76. (run-fibers (lambda () (test dimensions message-count)))))))
  77. (when (batch-mode?) (main (program-arguments)))