1

なぜこの再帰が終了するのかわかりません:

In[27]:= MyFunc[n_] := MyFunc[n] = 2;
MyFunc[3]

Out[28]= 2

エンドレスじゃないかな

MyFunc[3]
MyFunc[3] = 2
(MyFunc[3] = 2) = 2

等々?

なぜこれは

MyFunc[n_] := MyFunc[n];
MyFunc[3]

During evaluation of In[31]:= $IterationLimit::itlim: Iteration limit of 4096 exceeded. >>

Out[33]= Hold[MyFunc[3]]

再帰制限ではなく、「反復」制限エラーを引き起こしますか?

4

1 に答える 1

1

私の他の答えは、いくつかの重要な詳細を見逃していました。これが 2 番目の例です。

SetDelayedは属性HoldAllSet持ち、属性は持ちますHoldFirst。だから、あなたの定義

MyFunc[n_] := MyFunc[n] = 2;

部分は評価されずに保存されます。それを呼び出したときのみ、たとえば MyFunc[3]rhs が評価されます。この場合は、 , を含む式SetですMyFunc[3] = 2Sethas 属性であるためHoldFirst、このルールは最初の引数 (つまり、lhs) が評価されずに格納されます。この段階MyFunc[3]では、式の左辺はSet再評価されません。しかし、そうである場合、 Mathematica はルールを見つけて、そのルールを lhs で使用せずMyFunc[3] = 2に に評価MyFunc[3]します。2MyFunc[n_]

あなたの2番目の定義、つまり

MyFunc[n_] := MyFunc[n];

も評価されずに保存されます。ただし、関数を呼び出すと、たとえば myFunc[3]、rhs が評価されます。rhs は に評価されるMyFunc[3]か、必要に応じて別の呼び出しに評価されますMyFuncMyFunc[3]Mathematicaの評価中に、格納された書き換え規則が検出されMyFunc[n_] := MyFunc[n]、適用されます。繰り返します。Mathematica はこれを再帰ではなく反復と見なすことに注意してください.

式の左辺を評価することが実際に何を意味するのかは、私には完全には明らかではありません。もちろん、Mathematica は関数呼び出しの引数を貪欲に評価するため 、 のような呼び出しMyFunc[3+4]は実際に評価されることになります。MyFunc[7]

実際、ここで何が起こっているのかを理解しようとすると、代入と左辺と右辺を忘れて、すべてが式であり、たとえば、

MyFunc[n_] := MyFunc[n] = 2;

単なる書き方です

SetDelayed[MyFunc[n_], MyFunc[n] = 2]
于 2013-01-22T15:42:17.017 に答える