SchemeでFizzBuzz

まずは普通に。ちなみにこれは電車の中でPocket Schemeを使って書きました。

#!/usr/bin/gosh

(define (fizzbuzz)
  (let loop ((i 1) (r ()))
    (if (> i 100)
        (reverse! r)
        (loop (+ i 1)
              (cons (cond ((zero? (modulo i 15)) "FizzBuzz")
                          ((zero? (modulo i 3)) "Fizz")
                          ((zero? (modulo i 5)) "Buzz")
                          (else i))
                    r)))))

(for-each (lambda (s) (display s) (newline)) (fizzbuzz))

call/ccを使って無理矢理Schemeらしさを出してみる。

#!/usr/bin/gosh

(define (make-generator proc)
  (let ((next #f) (return #f))
    (lambda ()
      (call/cc (lambda (break)
                 (set! return break)
                 (if (not next)
                     (proc (lambda arg
                             (call/cc (lambda (cc)
                                        (set! next cc)
                                        (apply return arg)))))
                     (next)))))))

(define fizzbuzz
  (make-generator
   (lambda (yield)
     (let loop ((i 1))
       (yield (cond ((zero? (modulo i 15)) "FizzBuzz")
                    ((zero? (modulo i 3)) "Fizz")
                    ((zero? (modulo i 5)) "Buzz")
                    (else i)))
       (loop (+ i 1))))))

(let loop ((i 0))
  (if (< i 100)
      (begin (display (fizzbuzz))
             (newline)
             (loop (+ i 1)))))

make-generatorの実装はScheme:generatorとdoとwhileで公開されているものを使いました。