Почему эта программа работает на схеме Chez, но не работает на схеме Chicken? - PullRequest
0 голосов
/ 07 октября 2019

Когда я запускаю эту программу на 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)    <--

Может кто-нибудь объяснить, что идет не так? И как это исправить?

1 Ответ

1 голос
/ 07 октября 2019

Эта программа генерирует очень большие целые числа. Похоже, что Ideone использует CHICKEN 4, который не поддерживает произвольно большие целые числа ("bignums" на языке Схемы).

Когда вы получаете слишком большие числа, чтобы уместиться в машинное слово (минус 2 бита), CHICKEN 4поместил бы число в число с плавающей запятой, чтобы аккуратно переполниться. Вот почему вы получаете ошибку vector-ref.

Если ideone поддерживает это, вы можете попробовать добавить (use numbers) в начале вашей программы. Это число яйцо добавляет поддержку для полной числовой башни (с несколькими оговорками) в CHICKEN 4.

CHICKEN 5 поддерживает полную числовую башню из коробки, и программа работает там нормально, без изменений.

...