万年素人からHackerへの道

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

  • ・資産運用おすすめ
    10万円は1000円くらい利益
    資産運用ブログ アセマネ
    • ・寄付お願いします
      YENTEN:YYzNPzdsZWqr5THWAdMrKDj7GT8ietDc2W
      BitZenny:ZfpUbVya8MWQkjjGJMjA7P9pPkqaLnwPWH
      c0ban:8KG95GXdEquNpPW8xJAJf7nn5kbimQ5wj1
      Skycoin:KMqcn7x8REwwzMHPi9fV9fbNwdofYAWKRo

    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)
    

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

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