廣島です.
1つ前のパズルの問題ですが...,
> 中村 のりつぐ です。
>
> In article <20030228.095745.03648286.tsutomu@...>
> Tsutomu Hiroshima <tsutomu@...> wrote:
> > guile で動かして下さい.
> >
> > (let foo ((a 2003) (x 100000))
> > (if (zero? (modulo x a))
> > (write (list a (/ x a))))
> > (if (> a 1001) (foo (- a 1) (- x 1))))
>
> Gauche でも動きました!
>
> # GCL で動かそうとして挫折中…
Common Lisp で同じアルゴリズムを書いてみました.
;; 始まり
(defun foo (a x)
(multiple-value-bind (q r) (floor x a)
(if (zerop r)
(print (list a q)))
(if (> a 1001)
(foo (1- a) (1- x)))))
(compile 'foo) ; これがミソ
(foo 2003 100000)
;; 終り
今目の前にあるシステムには clisp しか無いのですが,
家で試したところ,gcl では (compile 'foo) をコメントアウトすると
スタックオーバーフローします.
;; もっともその前に答が出力されますが...
秘密は,gcl のメッセージに有ります.
Compiling gazonk0.lsp.
End of Pass 1.
;; Note: Tail-recursive call of FOO was replaced by iteration.
End of Pass 2.
Common Lisp ではインタープリタとしては,末尾再帰は関数呼び出しで,
コンパイルの際に末尾再帰を繰り返しに置き換えるわけです.
Scheme はインタープリタだけど,末尾再帰は常に繰り返しに置き換えられます.
ではでは.
-----------------------------
廣島 勉
(tsutomu@...)