久野です。

hata@iname.comさん:
> ただ、この場合の両者の違いとして、while ループは外側に関数(ループ内の
> ルーチン)の呼出が並べられて展開されるが、再帰呼出は内側に入れ子状に関数
> の呼出が展開される、というようなイメージでいいのでしょうか?

  それは何の話? 計算モデル? 実装?

  計算モデル的には「埋め込まれる」と考えてもいいんでしょうけど、
実装上は関数は「戻り番地と引数をスタックに積んでジャンプし、内部
を実行し、戻る時はスタックから戻り番地を取り降ろして戻る」という
形になります。

> という風に階乗の計算と代入が逐次的に行われていくイメージがありますが、
> 再帰呼出だと、
> n! = n * (n - 1)!
> n! = n * (n - 1) * (n - 2)!
> (……)
> n! = n * (n - 1) * (n - 2)! * (……) * 2 * 1

  それで正しいですね。

  5!
  5 * 4!
  5 * 4 * 3!
  5 * 4 * 3 * 2!
  5 * 4 * 3 * 2 * 1!
  5 * 4 * 3 * 2 * 1 * 0!
  5 * 4 * 3 * 2 * 1 * 1
  5 * 4 * 3 * 2 * 1
  5 * 4 * 3 * 2
  5 * 4 * 6
  5 * 24
  120

> 処理系(ちなみに自分が親しんでいる言語は Perl です)によって違いがあるの
> かもしれませんが、同じことをやるのなら、while ループの方が効率は良さそう
> な気がします(それに再帰の場合はコンパイラ側のスタック(?)の管理が大変
> そうに思える)が、実際のところどうなのでしょう?

  別に大変じゃないです。単にそういうコード出せばいいだけだから。

               人間が実装を追うのが面倒なだけで。            久野

P.S. そして最適化によってスタックを使わずにwhileと同等に計算する
     ようなコンパイラもあると思う。