作者: Tsutomu Hiroshima
日時: 2003/3/18(15:17)
廣島です.
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@...)