無駄なlambda再帰no.1
前にも書いたけど,あれ,かいたっけか?
ま,とにかく,pythonは普通に使う限りは,lambda式の再帰を書けないし,レキシカル変数をlambda式の中で定義できない訳だ.
で,今回は前者を考えてみた.
lambdaの再帰を書く.
キーワードは引数.
def lambdaLoop (fun, *arg): return fun (fun, arg)
というlambdaLoop関数を定義する.
この関数は第一引数に関数オブジェクトの参照funを持つ.
このfunはfun (fun, arg)からわかる通り,自分自身を代入している.
つまり,自分自身を自分の内側から参照するためのシンボルとなる.
第二引数には可変長のargをわたす.
これはそのままfunに渡す可変長引数でfunの内側からはリストとしてアクセス可能である.
で,例
lambdaLoop (lambda x, y: (len (y) == 1) and y[0] or y[0] + x(x, y[1:]), 3, 4, 5) # 12
ちなみにschemeで同様に書くとこう.
(let loop ((lst '(3 4 5))) (if (= (length lst) 1) (car lst) (loop (cdr lst)))) # 12
というわけだ.
これもどういう訳か深いネストを実行すると"maximum recursion depth exceeded"が返ってきてしまうため注意が必要.
どうやらheapをガン食いしているようですね.
残念.
やはり末尾最適化を考えなければいけない.
続く...