無駄な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をガン食いしているようですね.

残念.

やはり末尾最適化を考えなければいけない.

続く...