万年素人からHackerへの道

万年素人がHackerになれるまで殴り書きするぜ。

Boo Language Advent Calendar 2012 16日目 Title:「Booでクロージャ」

URL: http://atnd.org/events/34622

公式のクロージャドキュメントはここにある
URL: http://boo.codehaus.org/Closures

「Closures vs. Functions」なので関数と相反する立場だ

PHPでは、「無名関数 = クロージャ」みたいな書き方が書いてるが・・。PHPのなので信頼出来ない。
PHPの説明URL: http://php6.jp/php5-3/%E7%84%A1%E5%90%8D%E9%96%A2%E6%95%B0%EF%BC%88%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3%EF%BC%89/

たしか無名関数のスコープが外に見えないかなにかだったと思い、更に調べた

URL: http://hisasann.com/housetect/2007/12/post_44.html
「親関数の外に参照が渡される内部関数をクロージャと呼ぶ」

こっちの説明が正しそうだ。
「無名関数のスコープが外に見えるやつ」のことか?


「無名関数 = クロージャ」ではなく「無名関数 ∋ クロージャ」だな。

さっそく「Closures vs. Functions」のところにあったコードを試します。

import UnityEngine

class Closure (MonoBehaviour):

    def Start ():
        c = do(x as int):
            Debug.Log(x)
            #=> xとでる?
            c(x) if x > 0
        c(5)

→ 「Assets/Closure.boo(9,13): BCE0005: Unknown identifier: 'c'.」のエラーになる

しかし、これは「変数"c"がクロージャ内部から知られないから、実行されない(This will not work because "c" is unknown from inside the closure:)」

c = do(x as int)の無名関数が、内部にあるc(x) if x > 0では参照されず、呼べないから。
これは厳密にはクロージャではなく、無名関数と呼ぶものだと思う。

import UnityEngine

class Closure (MonoBehaviour):

    def Start ():
        d as callable
        c = do(x as int):
            Debug.Log(x)
            #=> xが出る?
            d(x) if x > 0
        d = c
        c(5)

しかし、このように「d = c」と代入すれば、「d(x) if x > 0」での無名関数の内部からでも「d(x)」が呼べるという想定らしいが、
メモリ不足になって動かなくなる(スタックオーバーフローになる)という罠・・・。

しかしよく見ると、
d(x)が条件文の「if x > 0」を永久に満たすからじゃないかな?ここは公式?なのにドキュメントは誤字があったりだと
ただでさえBooっていう名前だから馬鹿にされるんだよ・・・

ちなみにこちらの対決対象の関数もおなじくスタックオーバーフロー!!!!

import UnityEngine

class Closure (MonoBehaviour):

    def c(x as int):
        Debug.Log(x)
        c(x) if x > 0
    
    def Start():
        c(5)

ここのサンプルコードはきちんと試しましたかね・・・・
報告しよう!

これが動くようにしたかったが今日も仕事なので、次の方!