ソースコード:Reduce(object, object)

ファイル Builtin.cs には、別の関数 reduce の定義が含まれます。

# IronPython-1.1.2/Src/IronPython/Modules/Builtin.cs
[PythonType("__builtin__")]
public static partial class Builtin {
...
[PythonName("reduce")]
public static object Reduce(object func, object seq) {
IEnumerator i = Ops.GetEnumerator(seq);
if (!i.MoveNext()) {
throw Ops.TypeError("reduce() of empty sequence with no initial value");
}
object ret = i.Current;
while (i.MoveNext()) {
ret = Ops.Call(func, ret, i.Current);
}
return ret;
}


静的メソッド Reduce のヘッダーを見ると、関数 reduce の第3引数を省略したものに相当するのが分かります。メソッド本体には、前述したイディオムの変形版が記述してあります。

    IEnumerator e = ...
if (!e.MoveNext()) {
...
}
... e.Current ...

次のテストケースを試すと、このコードの意味を理解するのに役立ちます。

>>> reduce(lambda acc,e: e+acc, "")
Traceback (most recent call last):
File "", line 1, in
reduce(lambda acc,e: e+acc, "")
TypeError: reduce() of empty sequence with no initial value>>> reduce(lambda acc,e: acc+e, [])
Traceback (most recent call last):
File "", line 1, in
reduce(lambda acc,e: acc+e, [])
TypeError: reduce() of empty sequence with no initial value
ここでは、例外 TypeError が発生して、エラーメッセージが出力されます。これは、メソッド本体にある、Ops.TypeError の引数と同じ文字列です。例外 TypeError を生成してメッセージを表示したいときに、Ops.TypeError を利用するだけです。
    if (!i.MoveNext()) {
throw Ops.TypeError(...);
}

この条件式から、次の要素が得られないときに、例外を生成しているのが分かります。なぜなら、空文字列 "" や空リスト [] は、要素を含まないからです。
これに続くメソッド本体は、前述した Reduce(object, object, object) とほぼ同じです。これで、その動作を理解するのに必要なコードを読破したことになります。