为什么这个程序在 Chez Scheme 上运行但在 Chicken Scheme 上失败?

Why does this program work on Chez Scheme but fail on Chicken Scheme?

当我 运行 这个程序在 Ideone:

; scrambled words

(define rand ; knuth random number generator with shuffle box
  (let* ((a 69069) (c 1234567) (m 4294967296) (k 32) ; 32-bit
         ; (a 6364136223846793005) (c 1442695040888963407)
         ; (m 18446744073709551616) (k 256) ; 64-bit
         (seed 19380110) ; happy birthday knuth
         (next (lambda ()
           (set! seed (modulo (+ (* a seed) c) m)) seed))
         (init (lambda (seed) (let ((box (make-vector k)))
           (do ((j 0 (+ j 1))) ((= j k) box)
             (vector-set! box j (next))))))
         (box (init seed)))
    (lambda args
      (if (pair? args)
        (set! seed (modulo (car args) m)) (set! box (init seed)))
      (let* ((j (quotient (* k seed) m)) (n (vector-ref box j)))
        (set! seed (next)) (vector-set! box j seed) (/ n m)))))

(define (randint . args)
  (let ((lo (if (pair? (cdr args)) (car args) 0))
        (hi (if (pair? (cdr args)) (cadr args) (car args))))
    (+ lo (floor (* (rand) (- hi lo))))))

(define (shuffle x)
  (do ((v (list->vector x)) (n (length x) (- n 1)))
      ((zero? n) (vector->list v))
    (let* ((r (randint n)) (t (vector-ref v r)))
      (vector-set! v r (vector-ref v (- n 1)))
      (vector-set! v (- n 1) t))))

(define (scramble str)
  (let* ((cs (string->list str))
         (upper (map char-upper-case? cs))
         (cs (map char-downcase cs)))
    (let loop ((cs cs) (word (list)) (zs (list)))
      (cond ((null? cs) ; end of input
              (list->string
                (map (lambda (u? c)
                       (if u? (char-upcase c) c))
                     upper (reverse zs))))
            ((char-alphabetic? (car cs)) ; in a word
              (loop (cdr cs) (cons (car cs) word) zs))
            ((pair? word) ; end of word
              (loop cs (list) (append (shuffle word) zs)))
            (else ; not in a word
              (loop (cdr cs) word (cons (car cs) zs)))))))

(display (scramble "Programming Praxis is fun!")) (newline)
(display (scramble "Programming Praxis is fun!")) (newline)
(display (scramble "Programming Praxis is fun!")) (newline)

我得到这个错误输出:

Error: (vector-ref) bad argument type: 1.0

    Call history:

    <eval>    [next] (+ (* a seed) c)
    <eval>    [next] (* a seed)
    <eval>    [init] (doloop14 (+ j 1))
    <eval>    [init] (+ j 1)
    <eval>    [init] (= j k)
    <eval>    (quotient (* k seed) m)
    <eval>    (* k seed)
    <eval>    (vector-ref box j)
    <eval>    (next)
    <eval>    [next] (modulo (+ (* a seed) c) m)
    <eval>    [next] (+ (* a seed) c)
    <eval>    [next] (* a seed)
    <eval>    (vector-set! box j seed)
    <eval>    (/ n m)
    <eval>    [randint] (- hi lo)
    <eval>    [shuffle] (vector-ref v r)    <--

有人可以解释一下出了什么问题吗?以及如何修复它?

这个程序生成非常大的整数。看起来 Ideone 使用的是 CHICKEN 4,它不支持任意大的整数("bignums" 用 Scheme 的说法)。

当你得到的数字太大而无法容纳一个机器字(负 2 位)时,CHICKEN 4 会将数字填充为浮点数以便整齐地溢出。这就是为什么您会收到矢量引用错误的原因。

如果ideone支持的话,你可以试试在你程序的开头加上(use numbers)numbers egg 在 CHICKEN 4 中添加了对完整数字塔的支持(有几个注意事项)。

CHICKEN 5 支持开箱即用的完整数字塔,程序在那里运行良好,无需修改。