マクロでtarai回し 4回目
さらに修正したら状態数がまた少し減った。あと地味にバグがあったのを直した。
(define-syntax tarai-r/o (syntax-rules () ((_ 0 %x %y %z %k ...) (tarai-r/o "force" %x (tarai-r/o 1 %y %z) %k ...)) ((_ 1 %y %z %x-value %k ...) (tarai-r/o "force" %y (tarai-r/o 2 %z %x-value) %k ...)) ((_ 2 %z %x-value %y-value %k ...) (tarai-r/o "loop" %x-value %y-value %x-value %y-value %z %k ...)) ((_ "loop" (%x1 %x2 ...) (%y1 %y2 ...) %x-value %y-value %z %k ...) (tarai-r/o "loop" (%x2 ...) (%y2 ...) %x-value %y-value %z %k ...)) ((_ "loop" () (%y1 ...) %x-value %y-value %z %k ...) (tarai-r/o "return" %y-value %k ...)) ((_ "loop" (%x1 %x2 ...) () %x-value %y-value %z %k ...) (tarai-r/o 0 ("delay" (tarai-r/o 3 %x-value %y-value %z)) ("delay" (tarai-r/o 3 %y-value %z %x-value)) ("delay" (tarai-r/o 3 %z %x-value %y-value)) %k ...)) ((_ 3 %x %y %z %k ...) (tarai-r/o "force" %x (tarai-r/o 4 %y %z) %k ...)) ((_ 4 %y %z (%x1 %x2 ...) %k ...) (tarai-r/o 0 (%x2 ...) %y %z %k ...)) ((_ "force" ("delay" (%f ...)) %k ...) (%f ... %k ...)) ((_ "force" %val %k ...) (tarai-r/o "return" %val %k ...)) ((_ "return" %val) %val) ((_ "return" %val (%k1 ...) %k2 ...) (%k1 ... %val %k2 ...)) ((_ %x %y %z) (tarai-r/o "loop" %x %y %x %y %z)) ))
そろそろ完全形に近づいてきた。もう改善するところはないかな。
動作テスト
次のようなファイルを用意して(...には上に挙げた定義が入る)
#! /usr/bin/env gosh (define-syntax tarai-r/o ...) (define (main args) (display (macroexpand '(tarai-r/o (12 11 10 9 8 7 6 5 4 3 2 1) (6 5 4 3 2 1) (1)))) (newline))
% time ./tarai-mac.scm (12 11 10 9 8 7 6 5 4 3 2 1) real 0m0.027s user 0m0.020s sys 0m0.006s
ということで、確かに遅延評価の効果はあったようだ。