2006-10-27 [長年日記]

[Q3] マクロの変数と再帰呼び出し

例えば、階乗を求めるために、

@Defun('Fact',
       @If(@Equal($1, 0),
           0,
           @Add($1, @Fact(@Subtract($1, 1)))))

のように再帰呼び出しをすることができますが、再帰された関数の中で@Setを使って変数を設定すると正しく動かなくなります。

これは、変数のスタックがないので、同じ名前の変数はどこで設定しても一番外側の変数を上書きしてしまうためです。@Defunで定義した関数を呼び出すときにはちゃんと変数のフレームを作った方が良いかもしれません。

もっとも、そこまでやるならスクリプトを使ったほうが楽なんですが…

@Progn(
 @Defun('Fact',
        @Script(<<END
result.value = fact(arguments(0));

function fact(n) {
  return n == 0 ? 0 : n + fact(n - 1);
}
END
, 'JScript', $1))
[]