1 名前:デフォルトの名無しさん [2014/11/08(土) 13:11:47.84 ID:6V2MLUHb.net] 関数型言語に必ずくっついてるこれ いらんでしょ?匿名クラスで充分でしょ
232 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 00:01:22.20 ID:Gw1grNBM.net] Rubyのブロックの中に副作用をジャンジャン書いて それを繋げるスタイルを関数型と言われても困るわ 文推奨の時点で関数型とは言い難いわけだし
233 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 00:38:38.65 ID:iRnVJ1/v.net] オレオレクロージャ君は言葉が通じないし、 必死でググった的外れで糞長い引用でしか反応しないし、 相手するだけ無駄。
234 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 02:05:45.83 ID:sl2oQCLD.net] うん、ただのPythonアンチでしか無いと思うよ。 Ruby好きでPython嫌いな俺は、Pythonのlambdaが使いにくいのには同意するが そのためにクロージャの定義のほうを捻じ曲げるのは、ありえないと感じるよ。 そもそも、その定義だとRubyどーなんねん、と思うし。 Rubyには「他言語の関数」に相当するものがなく、 一定の条件を満たし、見かけ上、関数のような呼び出しが可能なメソッドを 便宜的に「関数」と呼んでいるだけだし。 クロージャはブロックという形で存在はしているが、 彼の言う定義に従うならブロックはファーストクラスでなければならない。 でもRubyのブロックはファーストクラスとは言い難い。 lambda関数(実際はもちろんメソッド)が返すのはProcクラスのインスタンスだけれども、 ブロック.is_a? Procインスタンス では無い。そしてメソッドや、ましてや関数でもない。 そもそもブロック単体では値としては取り回せないからProcクラスがあるんだし。
235 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/14(日) 10:29:16.99 ID:63H3dBz7.net] オレオレクロージャ君って少し前に某スレでPython disってた人にそっくり
236 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/14(日) 14:05:17.21 ID:2A/iPobJ.net] lambda ラ…ランバダ…
237 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/14(日) 14:52:29.83 ID:VBy2GaOL.net] >>236 もっと勇気をもって! ランバダ!
238 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/14(日) 15:49:06.80 ID:hNeAViIY.net] ,-----、 / ヽ. | (・) (・) | /ヽ ̄  ̄ノヽ / ヽ_____/ ヽ | / l | |\ | | 。ノ ヽ。 .|___| \ ヽ___ヽ + ノ,、_、_、_ヽ \ | ヽ| ̄ ̄ ̄ ̄ | ;;;;;;;;;;;;;;;\_ ノ < ````/\ /\;;;;;;;;;;;;;;;;;/ ヽ;;;;;;| \_/ ヽ;;;;;;;;;;;ノ  ̄.|___/ \__) ̄ .____ / | | | \ / (___| |__)===⊃ 勇者の父 ランバダ
239 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/14(日) 15:54:41.51 ID:KqwrXZGg.net] 無駄にMP消費していざという時に足りなくなって犬死にする無能
240 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 20:48:34.17 ID:lkA9lgpO.net] >>231 >Rubyのブロックはラムダじゃないしファーストクラスでもないよね? Python や JavaScript のクロージャは、(名前が宣言された)関数と同様に クロージャへ引数を渡すだけで評価される closure = function(x) { return x + 1 } # クロージャを生成して名前に束縛 succ_of_one = closure(1) # クロージャを評価 それに対して Ruby だと、メソッド Proc#call を呼ばなければ評価されない block = lambda { |x| x + 1 } # ブロックを生成して名前に束縛 succ_of_1 = block.call(1) # ブロックを評価 従って >>4 (>>201 ) の関数型言語におけるクロージャ定義に当てはめれば 「Ruby のブロックは(本物の)クロージャではない」あるいは「....はクロージャもどきである」 またRuby のブロックの意味はオブジェクト(Procクラスのインスタンス)だからファーストクラスである >メソッドにラムダを渡すこともできるけど、不格好なんだが? たしかに不格好だ def foo(x, y, &block); .... ; end # メソッドを定義 foo(x, y, lambda { |z| .... }) # メソッドの呼び出し だから Ruby には「ブロック付きメソッド呼び出し」という構文糖が最初から用意されている def foo(x, y); .... ; end # メソッドを定義 foo(x, y) { |z| .... } # メソッドの呼び出し >Pythonの仕様をあげつらうためだけにオレオレ定義をこねくって >>4 のクロージャ定義の引用元(ソース)は >>201 で示したが、まともな反論はない むしろオレオレ定義と騒ぎ立てていた連中がSICP本を読んだ事もないお馬鹿達だったのでは? あるいはSICP本を読んでいなくても、関数型言語の操作的意味論や処理系実装の知識があれば >>4 がオレオレ定義でないことは直ぐに理解できていたはず
241 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 21:10:51.70 ID:Gw1grNBM.net] >>240 後から言い逃れようとしても、掲示板にはログが残ってるから無駄ですよ >>99 に対する>>103 の返答の時点で、何も分かってなかったのは明らか
242 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 21:42:31.25 ID:k3gK/GUJ.net] >>240 RubyのブロックはProcクラスのインスタンスではないよ ブロックそのものは、メソッド呼び出し文法の一部でしかない そのブロックを、それのみで値として扱うためのラッパがProc
243 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 21:59:53.72 ID:Y1wljoB2.net] Rubyistは全員クロージャを間違った解釈してるのか? それとも、奴だけなのか? そこが気になるな。
244 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 22:03:54.59 ID:lkA9lgpO.net] >>232 残念ながら Ruby の関数型プログラミングというスタイルは、 全世界の Ruby コミュニティですでに認知されている ・Functional programming with Ruby code.google.com/p/tokland/wiki/RubyFunctionalProgramming ・Rubyによる関数型プログラミング(上記文書の日本語訳) www.h6.dion.ne.jp/~machan/misc/FPwithRuby.html また Ruby の「ブロック付きメソッド呼び出し」とそれらを並べる(=チェーンさせる)スタイルは、 Apple の新言語である Swift にそのまま採用された 他の言語、たとえばラムダ式が導入された Java 8 だと、このスタイルをストリームと呼んでいる ・ラムダ式で本領を発揮する関数型インターフェースとStream APIの基礎知識 (2/3) -- @IT www.atmarkit.co.jp/ait/articles/1404/30/news017_2.html 個人的には、Ruby と多くのOOP言語で採用されているメソッドチェーン・スタイルは: ・データの流れ(いわゆるデータフロー)とメソッドの並びが一致し、 ・カッコが入れ子にならない から、可読性が高いと思う table.select { |r| .... }.map { |r| .... }.inject(0) { |n, r| .... } # >>191 を参照 それに対して、Python 伝統的な関数適用スタイルでは: ・データの流れ(いわゆるデータフロー)とメソッドの並びが逆転し、 ・カッコが入れ子になる reduce(lambda n, r: ...., 0, map(lambda r: ...., filter(lambda r: ...., table))) どちらを優れているか?という評価は主観だから、各自で判断してもらいたい (まだ続くので、ここで切る)
245 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 22:48:49.10 ID:lkA9lgpO.net] >>241 次に、関数型プログラミングと(文の評価によって起こる)副作用との関連について まず関数型プログラミングで副作用は推奨されていない 基本的には map/filter/reduce (Ruby では map/select/inject) といった高階関数を使った (副作用の無い)参照透明性のあるコードが推奨されている これは >>244 の文書「Rubyによる関数型プログラミング」で具体的なコード例を使って解説されている おそらく誤解したのは >>191 の Swift/Ruby/JavaScript コードで while 文と ローカル変数への破壊的代入を用いていたのを見たからだと思うけど、 これは、「わざわざ」副作用を使った手続き型プログラミングほうが簡潔になる「お題」を選んだからだ 実際、副作用の代わりに再帰を使った Python コード >>208 は「普通のプログラマ」には分かりにくい (Python だけでなく、この「お題」は Ruby であっても再帰を使えば同じく分かりにくいコードになる) また(Ruby を含む)大半の手続き型言語処理系だと、TCO(末尾再帰最適化)は実装されていないか不完全である だから手続き型言語における関数型プログラミングにおいて、 再帰プログラミングには(分かりづらいだけでなく)実用上の制限があるから ツリーのような再帰的データ構造の探索問題などに限定して利用すべき(上記文書の節「再帰」を参照) これらの判断について、上記の文書では以下のように記述されている(節「おわりに」から引用): 「Rubyは基本的には命令型言語であるけれど、 関数型プログラミングへの際立った潜在能力があるのだから、 それらをいつどのように使うか(そして、いつ使わないか)を知っておくべきである。 」
246 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 22:59:19.75 ID:iRnVJ1/v.net] もうみんなgaucheに改宗しようぜ
247 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 23:34:55.92 ID:lkA9lgpO.net] >>234 >Rubyには「他言語の関数」に相当するものがなく、...... これは(>>240 に書いたけど)、まったくそのとおり >でもRubyのブロックはファーストクラスとは言い難い。 ここの「....とは言い難い」という文章表現は曖昧だね (なぜ「....ではない」と断定的に言い切れなかったのだろうか?) まず >>240 で書いたように、Ruby の「ブロック付きメソッド呼び出し」は構文糖だ (対して、簡潔な構文を追求した Smalltalk では、常にブロックはオブジェクトである) これを構文糖にした理由の一つはメソッド呼び出しコードを簡潔にする目的(>>240 )であるが、 ブロックを多用する Ruby のプログラミングスタイルでは、ブロックを評価するたびに Procオブジェクトを生成していたのでは実行効率の面でオーバヘッドが大きいという理由がある このためRubyインタプリタの内部だと、 ブロックは(重いオブジェクトを表すC構造体ではなく)専用の軽量なC構造体で表現されている ただし、(たとえ内部表現が Proc オブジェクトと異なっていても)プログラマから見れば問題にならない なぜなら、渡されたブロックをいつでも Proc オブジェクトへ変換できる構文糖が最初から用意されているから.... たとえば foo(x, y) { |z| .... } という「ブロック付きメソッド呼び出し」に対して(>>240 ): ・def foo(x, y); .... ; end ・def foo(x, y, &block); .... ; end という2つのメソッド定義は「いつでも」交換できる まとめると: Ruby のブロックは内部表現だと Proc オブジェクトではないが、 プログラマ目線ではファーストクラスのオブジェクトとして扱うことができる
248 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 23:42:14.32 ID:NejhiS1a.net] gaucheいいよね
249 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 23:49:27.85 ID:lkA9lgpO.net] >>241 つまり「Ruby のブロックはクロージャである」という初歩的なミスについて、 >>103 をレスした時点から数えて >>231 が指摘するまでの間には 誰一人気付けなかった事実が「掲示板にはログが残ってるから明らか」になるわけですね た い へ ん わ か り や す い で す
250 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 23:57:54.55 ID:pRYhwT4i.net] 最近はほぼgaucheでしかプログラム書いてない。 もう止められない体になってしまった。。。
251 名前:デフォルトの名無しさん mailto:sage [2014/12/14(日) 23:58:44.82 ID:iRnVJ1/v.net] 俺、numpyとscipyとopencvのサポートがgaucheにくっ付いたら、python捨てるんだ!(遠い目
252 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 00:02:02.47 ID:wtT+wvpm.net] common lisp処理系の方が速いのあるしライブラリも充実してるし良いよ
253 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 00:07:51.10 ID:G9R+2lJx.net] ループしないで全部再帰で書きたい
254 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 00:08:50.51 ID:YlFhPVoF.net] lisp-2なのが何となく嫌
255 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 00:31:53.12 ID:K7E8QpHY.net] >>253 いいよ
256 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 08:42:12.40 ID:J0ddkTzC.net] >>249 だってRubyなんてマイナー言語どうでも良いし?
257 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 11:24:34.16 ID:yMEZ5G45.net] >>243 こいつだけです。と言うかRubyに対しての知見も怪しい >>247 Rubyのブロック付きメソッド呼び出しのほうを構文糖と。またオレオレ定義? 「ブロック付きメソッド呼び出し」は文法だ、これはlambdaより先に実装されてる そのブロック部分のみを扱うためにProcクラスもlambdaより先に実装されていて、 そのProcを簡便に扱うためにlambdaと言う構文糖が後から出来た と言うか「ブロック付きメソッド呼び出し」、昔は「イテレータ呼び出し」だった イテレータ呼び出しを汎化した結果生まれたのが、ブロック付きメソッド呼び出し その時代からmapやselectなどの 今で言う関数型的なメソッド群を実装するモジュールEnumerableは 「これをincludeするクラスにはeachメソッドを実装すること」としていた もしRubyが関数型として設計されていてProcが主なら call必須なんてことにはしなかっただろうし 関数がメソッドの一種なんてことにはなってない そしてEnumerableはeachではなく、Array辺りを要求する高階関数群だっただろう RubyはOOPLとして設計され、それが主で 関数型プログラミングは結果として付いてきた そこでProcに関数型のラムダ的な挙動を付加し生成するlambdaも出来たんだよ
258 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 20:13:34.89 ID:AoWRRy2d.net] >>244 > また Ruby の「ブロック付きメソッド呼び出し」とそれらを並べる(=チェーンさせる)スタイルは、 > Apple の新言語である Swift にそのまま採用された Obj-C が inline Smalltalk が書ける C なのに、Swift が Ruby をまねたみたいなデマはやめてくれる? それと、 Ruby で関数型スタイルのプログラムを書けるということを、Ruby で書いたら関数型プログラムになるかのように書くのもやめてくれる?
259 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 21:18:41.61 ID:QjagSoag.net] 主観を事実であるかのように語る客観性の無さ オレオレ定義の根拠を問われて自身の過去の書き込みを引用するコミュニケーション不全 完全に論破されると、自分の間違った主張を相手が言い出したと歴史歪曲しようとする卑怯さ 全てを兼ね備えると>>244 みたいな奴になる
260 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 22:27:41.97 ID:eMlPsgxM.net] >>257 >そのブロック部分のみを扱うためにProcクラスもlambdaより先に実装されていて、 >そのProcを簡便に扱うためにlambdaと言う構文糖が後から出来た lambda はメソッドであって、構文糖ではない >>234 では「もちろん(lamda は)メソッド」と主張しているから、もしも同一人物のカキコなら矛盾している いったいどちらが正しいの? >イテレータ呼び出しを汎化した結果生まれたのが、ブロック付きメソッド呼び出し その「汎化」とは具体的には何を指しているのかな? もともとイテレータという概念と用語は手続き型言語 CLU で生まれ、Ruby でも採用された ただし CLU のイテレータは for ... in 構文というループ処理での利用に制限されたのに対して、 (クロージャとしての)ブロックを備えた Ruby ではループ処理以外にも利用できる形で「最初から設計された」 ・Rubyist のための他言語探訪 【第 2 回】 CLU magazine.rubyist.net/?0009-Legwork このためループ処理でもないのにイテレータ(iterator, 反復子)という用語は紛らわしいという声が挙り、 用語「イテレータ呼び出し」は「ブロック付きメソッド呼び出し」へと名称が「後から変更された」 つまり単に用語の命名が「後から」改められだけで、言語仕様の基本は「最初から」何も変わっていないはずです >RubyはOOPLとして設計され、それが主で関数型プログラミングは結果として付いてきた スマンが、いいかげん説明は面倒なので以下を読んでください ・Lisp から Ruby への設計ステップ yohshiy.blog.fc2.com/blog-entry-250.html ただし、もともとメソッド lambda は proc の別名で同じ意味でしたが、 1.8 の時代に lambda の挙動が変更されメソッドとして独立しました その変更の理由は関数型プログラミングと関連する可能性はありますが、詳しい背景を自分は知りません 言語仕様として「関数型プログラミング向けに後から追加/変更」されたのは、自分の記憶だとコレくらいしかありません
261 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 22:40:54.50 ID:G9R+2lJx.net] 俺が平安時代に読んだ本だと、iteratorはアイテレータって書かれてたな。 あとhierarchyはハイアラーキだった。
262 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 22:46:59.52 ID:G9R+2lJx.net] そんなにlispに憧れてるなら、lispを使えばいいのに。
263 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 22:47:19.92 ID:BuhXHDiL.net] > 1.8 の時代に lambda の挙動が変更されメソッドとして独立しました > その変更の理由は関数型プログラミングと関連する可能性はありますが、詳しい背景を自分は知りません RubyのProc.newで作られるオブジェクトは returnの挙動が普通の関数と違ってキモすぎるので lambdaの方だけでも普通に直したんでしょう
264 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 23:02:52.91 ID:BuhXHDiL.net] さらに言えば、Rubyのブロック変数のスコープの扱いが1.9で仕様変更されてるけど、 それについてmatz自身が > それは、Rubyが最初から関数型言語としてスタートしてないからであって、言語が違うからですよね。 と語っているね www.atmarkit.co.jp/news/200907/24/ruby.html
265 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 23:10:49.42 ID:eMlPsgxM.net] >>258 >Obj-C が inline Smalltalk が書ける C なのに、Swift が Ruby をまねたみたいなデマはやめてくれる? スマン、ここは説明が足りなかった、Tailing Closure のことを言いたかった Objective-C を含むほとんどの言語では、引数をカッコで囲んで関数(or メソッド)へ渡す文法になる 基本的には Swift も同じですが、引数リストの最後がクロージャである場合に限り、 そのクロージャ引数を閉じカッコの直後に置く事ができます ・collection.map({ ..... }) // 一般的(常識的?)な書き方 ・collection.map() { ..... } // クロージャを引数リストの直後へ移動できる ・collection.map { ..... } // さらには丸カッコ () も省略できる これを Ruby で書くと、以下のようになります ・collection.map(lambda { ..... }) # Ruby だと一般的ではない ・collection.map() { ..... } # ブロックを引数リストの直後へ移動できる(ブロック付きメソッド呼び出し) ・collection.map { ..... } # さらには丸カッコ () も省略できる(これが普通の Ruby らしい書き方) これと同じ書き方ができる言語を Swift と Ruby の他に自分は知りません そして発表時期的に Ruby の後に Swift が生まれたから、ここは Ruby の影響ではないかと「推測」しました Tailing Closure の由来に関するソースは持っていないので、デマと言われてもしかたがありませんね.... >それと、 Ruby で関数型スタイルのプログラムを書けるということを、Ruby で書いたら関数型プログラムになるかのように書くのもやめてくれる? Ruby は手続き型言語なのだから、プログラマが意識しなければ関数型プログラミングのスタイルにならないのは当たり前 いいかげん説明は面倒なので、以下の文書をよく読んでください: ・Rubyによる関数型プログラミング www.h6.dion.ne.jp/~machan/misc/FPwithRuby.html もし具体的な疑問/質問があれば、個別に返答します
266 名前:デフォルトの名無しさん mailto:sage [2014/12/15(月) 23:24:28.86 ID:eMlPsgxM.net] >>263 おそらくその通りだと思います >>264 もしも Matz が Lisper ではなく Schemer であったなら、 違った結果になっていたかもしれませんね
267 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 00:31:08.98 ID:IiuX/rSM.net] 自己レスになりますが、>>245 では: > (Python だけでなく、この「お題(>>191 )」は Ruby であっても再帰を使えば同じく分かりにくいコードになる) とカキコしました で、後から考え直して「手続き型のループ&破壊的代入」ではなく、しかも「関数再帰」も使わずに、 参照透明性がある関数型プログラミングのコードを考えてみました ideone.com/UrfbuL ポイントは「反復に組み込みメソッド loop」を「ブロック脱出に引数付のbreak文」を使った2点です なおメソッド loop は一般に loop do .... end という手続き型のスタイルで書かれることが多いために ループ構文の一種と誤解されがちですが、(lambda を構文糖であると >>257 が 勘違いしたように....) loop はメソッドですので(コードで示したように) inject へチェーンさせることができます また「参照透明性はあっても、手続き型の制御構造であるbreak文の利用は反則ではないか?」という 指摘を予測して、 同じスタイルで(break文の代わりに)組み込みメソッド catch と throw を使ったコードも書きました ideone.com/SaCAFi ただし、この catch/throw は大域脱出のために用意されたメソッドですから、 今回の「お題」のように単一ブロックを脱出するだけならbreak文を使うのが素直だと考えます ついでに(catch/throw の代わりに)Scheme 由来の継続(continuation)を使ったコードも書きました ideone.com/5t1VEq
268 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 02:54:32.21 ID:178msYck.net] こんな無駄に遠回しなコード沢山書いてどんだけオナニー好きなんだよ。
269 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 02:58:06.18 ID:178msYck.net] >>200 の爪の垢でも煎じて飲めよ。
270 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 07:18:26.71 ID:/LiRSDzk.net] >>260 もちろん、本当はただのメソッドであってlambdaは文法要素ではない あたかも「ブロックはlambdaの構文糖」であるかのような主張をするから、その対比としてそう書いたまでだよ 分かりにくかったね、「構文糖のような存在のメソッド」と修正しておくよ
271 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 07:24:54.85 ID:/LiRSDzk.net] まあ、「構文糖のような存在のメソッド」って用語がおかしいというなら 「真のクロージャ」って用語もおかしいのだと気付いて欲しいな
272 名前:1 mailto:sage [2014/12/16(火) 07:48:21.23 ID:PApLEh59.net] なんか知らんけど伸びてて嬉しいです 目標はGCスレ超えです
273 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 08:02:21.01 ID:/LiRSDzk.net] 一応lambdaというメソッドの実装された時期について調べてみたら、結構昔から存在自体はしてたのね 元々procと同じなのに字数多い&Procなのにlambdaって覚えにくいのと1.4当時は関数型とか知らんかったからスルーしてたのかな そこは俺の記憶違いだったわ
274 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 08:45:33.81 ID:7mh816Ug.net] クロージャがなければ参照カウント型のGCで済むんじゃないか説があるし ワンチャンあるよ
275 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 08:47:53.04 ID:7mh816Ug.net] 構文糖衣とかいいながら ラムダって名前から甘そうな印象をうけない 名前が悪いよ考え直すべき
276 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 08:56:24.06 ID:7mh816Ug.net] クロージャって名前も固いし 意味わかんねえから 貝殻のclamを頑張ってもじって クリームって名前にするくらいの 努力はあってよかった
277 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 09:58:24.78 ID:/LiRSDzk.net] >>275 そういう意味ではfunctionを名前ありの関数にもラムダにも使ったJavaScriptは上手いと思う らむだ何ソレ?な人にも「関数名書かないで使うと無名の関数も作れるよ」って説明で事足りるもんね
278 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 10:58:59.39 ID:gf3D6lb/.net] ブロックとProc.newとprocとlambdaと->があるRubyはやり過ぎ
279 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 11:12:47.94 ID:/LiRSDzk.net] >>278 まあ、Rubyは他の組み込みライブラリでも エイリアスや似たようなメソッド、所属モジュールが違う同様のメソッドとか持つのは普通だからね 俺は昔からproc派、RubyのProcとλ算法は別物だと思うからあの挙動でいいし、早く書けるし
280 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 22:27:19.26 ID:IiuX/rSM.net] >>270 >あたかも「ブロックはlambdaの構文糖」であるかのような主張をするから、 いや「あるかのよう」ではない、>>247 で以下のように、断定的に明記したとおり: > まず >>240 で書いたように、Ruby の「ブロック付きメソッド呼び出し」は構文糖だ Ruby インタブリタの内部では「ブロック付きメソッド呼び出し」と 「値渡しされた Proc オブジェクト」とは別の表現(C構造体)が用いられ、それらを相互変換している ただし Ruby プログラマの視点では、値渡しされたProc オブジェクトで「あるかのように」 (すなわちファーストクラスとして)ブロックを扱う事ができる、だから「ブロックは構文糖」になる ブロックを評価するのにメソッド Proc#call が必須(>>257 )なのは、また別の理由.... それらをごっちゃにすべきではない >>271 >まあ、「構文糖のような存在のメソッド」って用語がおかしいというなら いや「構文糖のような」という比喩表現であれば、何の問題も無い >「真のクロージャ」って用語もおかしいのだと気付いて欲しいな >>4 でクロージャ定義を示してから >>201 までソースを明かすのを遅らせたのは意図的だったけど、 「真のクロージャ」という曖昧な表現でいらぬ混乱を与えたことは余計だったと反省している 最初からストレートに「関数型言語のクロージャ」とすべきだったね
281 名前:デフォルトの名無しさん mailto:sage [2014/12/16(火) 23:35:24.13 ID:178msYck.net] 関数型言語のクロージャと非関数型言語のクロージャはナニが違うですか。
282 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 00:34:28.88 ID:NwnPjzlT.net] 結局、Pythonのクロージャは本物で、Rubyのブロックは偽物って結論になったんか?
283 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 06:09:12.08 ID:4QPsGplH.net] >>282 彼の中だけではそういうことらしい
284 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 06:10:48.27 ID:HxoNcsla.net] 環境もちこしてる関数っぽいやつならクロージャでいいじゃん
285 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 06:13:43.20 ID:4QPsGplH.net] って彼の中だけでは逆か >>284 と言うか元々環境持ち越すのがクロージャの要件でしょ
286 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 06:16:00.02 ID:HxoNcsla.net] なんで突っ込まれてるのかさっぱりわからん
287 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 06:21:06.36 ID:4QPsGplH.net] >>286 突っ込んでないよ、超同意してんだよ
288 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 07:54:17.64 ID:HxoNcsla.net] まじかよ世界は平和だった
289 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 20:35:47.86 ID:JUumI3zm.net] >>281 もともとクロージャの概念/用語は関数型言語で生まれたものだから、 「非関数型言語のクロージャ」とは: 「関数型言語のクロージャ」の定義に対して、どれくらい忠実に実装されているか? という相対的な評価になるね
290 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 21:10:46.15 ID:cFsqVLS5.net] そして、オリジナルのクロージャーが 一番優れているとかいう信者が現れるわけかw 普通はオリジナルを改良した方が 優れているんだがな。
291 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 21:39:32.52 ID:JUumI3zm.net] >>282 でれでは、ここまでの結論をまとめてみる まず最初は。>>289 の評価結果から: [Python:X] Python の lambda 構文は式しか書けないという制限があるから、 クロージャ固有の局所環境を持つことができない したがって、Python の lambda 構文は「関数型言語のクロージャ」ではない [Ruby:X] Ruby のブロックはオブジェクトであるから、 その評価にはメソッド Proc#call をコールしなければならない したがって、Ruby のブロックは「関数型言語のクロージャ」ではない [JavaScript:O] JavaScript の関数リテラルは任意の書けるからクロージャ固有の局所環境を持てるし、 なおかつ引数に適用するだけで評価できる したがって、JavaScript の関数リテラルは「関数型言語のクロージャ」である 結果として、最も忠実に「関数型言語のクロージャ」が実装されている(>>277 )、と言える 続けて、この評価結果が現実のプログラミングに与える影響をまとめる ここでは Apple 公式リファレンスに含まれる Swift クロージャのサンプルコードを「お題」とした(>>191 ) ・高階関数 map に与えるクロージャをインラインで書ける [Python:X] ・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>208 ) ・このため、一般には(インラインで書くのはあきらめて)関数定義を使わざるをえない [Ruby & JavaScript:O] ・インラインで自然な while ループを使った(ふつうのプログラマにとって)分かりやすいコードが書ける ・参照透明性のある関数型プログラミングで書ける [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>208 ) [Ruby:O] (関数再帰の代わりに)組み込みの高階関数風メソッドを使うことで、可読性の高いコードが書ける(>>267 ) [JavaScript:?] (書けるか否か、現時点では不明)
292 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 21:47:14.69 ID:JUumI3zm.net] >>282 を一部訂正 X:JavaScript の関数リテラルは任意の書けるから O:JavaScript の関数リテラルは任意の文が書けるから
293 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 22:23:00.08 ID:NwnPjzlT.net] >>291 再帰関数よりwhileループが読みやすいレベルの人間が 関数型プログラミングについて語るなんて滑稽すぎる
294 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 22:32:56.00 ID:NwnPjzlT.net] >>291 あと、>>208 じゃなくて>>203 を評価すべきだと思うんだけど、 なんでワザワザ可読性を落としてる方を評価してるの? まさか、Rubyでinjectは使って良いけど、Pythonでapplyfは使っちゃダメとでも言うつもり?
295 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 22:42:41.33 ID:KZ4YaCx1.net] 可読性の良し悪しなんて定量的ではないものを評価対象にするとか
296 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 22:47:17.42 ID:ffqYUKYZ.net] > Python の lambda 構文は式しか書けないという制限があるから、 > クロージャ固有の局所環境を持つことができない def make_f(n): return lambda x: x + n f = make_f(1) n = 1000 f(1) #=> 2 こういう風に、(引数以外の変数を)実行時の環境じゃなくて 自身が定義された環境で解決できればクロージャだよ。 この場合は変数nのことね。
297 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 23:03:51.76 ID:dyHF3Jr0.net] >>289 レキシカルクロージャってSchemeが最初だと思うけど、 Schemeって純粋な関数型言語じゃないよね。
298 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 23:50:33.95 ID:JUumI3zm.net] >>294 お題に対して「Python だけがわざわざ関数 applyf をユーザ定義しなければならない」ことを問題視している >>203 のコードは「お題を(勝手に改変せず)インラインで書ける」という観点だと(評価以前に)失格だ もしも Python コミュニティにおいて関数 applyf が常識的に認知されていたならば、 (map/filter/reduce 等と同様に) applyf は組み込み関数として実装されていたはず なお、組込み関数の実装レベルは言語によって差異があるものだから、 公平性を考慮して functools のような標準ライブラリを import するのは認める また Ruby のメソッド Enumerable#inject に対応する Python の関数は reduce だよ Python で組込み関数 reduce を使うのは、まったく問題無い
299 名前:デフォルトの名無しさん mailto:sage [2014/12/17(水) 23:55:13.45 ID:dyHF3Jr0.net] ていうか、さらっと1個の式で書けないような処理はインラインに書こうとするなよ っていうのがpythonの求めるところなんじゃないの?
300 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:12:23.41 ID:SaitqfQN.net] >>203 はインラインでは書けていないけど、>>208 と比べれば可読性の高いコードであると思うから、 >>294 の主張を受け入れて >>291 を以下のように一部改訂する(* で始まる行を変更している) 改定前: ・高階関数 map に与えるクロージャをインラインで書ける [Python:X] ・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>208 ) * ・このため、一般には(インラインで書くのはあきらめて)関数定義を使わざるをえない ・参照透明性のある関数型プログラミングで書ける * [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>208 ) 改訂後: ・高階関数 map に与えるクロージャをインラインで書ける [Python:X] ・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>208 ) * ・このため、一般には(インラインで書くのはあきらめて)関数定義または変数宣言(>>203 )を使わざるをえない ・参照透明性のある関数型プログラミングで書ける * [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>203 ,205)
301 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:16:28.27 ID:5LPNbvYA.net] むしろ標準で用意されてなくてもユーザ定義で拡張できるのは 言語として筋が良いといえる
302 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:18:19.46 ID:wQzGbOYd.net] 謎の標準ライブラリ縛りが入りましたw
303 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:22:42.78 ID:Xu+bpXu3.net] 1個の式で済む以上の事をやろうとする処理に名前を付ける事が、なぜ可読性の低下につながるの?
304 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:29:24.93 ID:wQzGbOYd.net] 再帰は可読性低いって連呼しててワロタ Rubyユーザって、ブロック使ってるだけで関数型だと思ってるの?
305 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:35:38.77 ID:Xu+bpXu3.net] Schemeは普通ならループで済むような事まで再帰で書くぜ
306 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:44:04.09 ID:4kRgXtNb.net] 再帰よりnamed let使おう
307 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 00:52:42.96 ID:Xu+bpXu3.net] named let は再帰でしょ?
308 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 01:28:37.32 ID:4kRgXtNb.net] 書いた後に思った
309 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 08:20:12.81 ID:ETi/Ct7F.net] >>304 彼だけだよ
310 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 08:27:40.63 ID:9iQd+rLQ.net] lispおじさんに言わせれば 全部lispのパクりだから 全部クロージャで問題ないよ
311 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 09:21:04.09 ID:f+DPSsFx.net] なんでクロージャスレでClojureを話題にしないの?
312 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 09:50:43.10 ID:ZOTu6c+H.net] >>311 若いときは買ってでもするものなあ〜んだ?
313 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 12:49:08.51 ID:nVA5J83n.net] >>312 ゲーム
314 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 19:33:48.97 ID:Xo1YvlzDq] ClosureCL…(ボソッ
315 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 19:41:50.11 ID:5ReW54RD.net] >>191 流れをナナメ読みかつ関数型言語素人なんだけど、 関数型言語だとそのアップルサイトの例はどういうふうに書くもんなの? let digitNames = [0,"Zero"; 1,"One"; 2,"Two"; 3,"Three"; 4,"Four"; 5,"Five"; 6,"Six"; 7,"Seven"; 8,"Eight"; 9,"Nine"];; let numbers = [16; 58; 510; 0];; let strings = List.map (fun n -> let rec f n acc = match (n, n / 10) with (0, 0) -> List.assoc 0 digitNames | (_, 0) -> List.assoc (n mod 10) digitNames ^ acc | (_, _) -> f (n / 10) (List.assoc (n mod 10) digitNames ^ acc) in f n "") numbers;; List.iter (fun s -> print_endline s) strings;; 言語はOCaml。三つの変数名はオリジナル版を採用。 dictionaryは諸事情でめんどいのでタプルのリストで代用。 関数型言語のことはまったくわからないw
316 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 22:22:25.63 ID:2b1ZQukZ.net] >>312 SEX
317 名前:デフォルトの名無しさん mailto:sage [2014/12/18(木) 23:09:02.06 ID:SaitqfQN.net] >>315 Standard ML で素直に末尾再帰を使って書いてみた ideone.com/WpChMC
318 名前:デフォルトの名無しさん mailto:sage [2014/12/19(金) 00:07:27.38 ID:lMWP4GlC.net] >>317 おおっ!わざわざどうも! SMLとOCamlの関係だからこういう似たような感じになるのかな? それともループを再帰に置き換えたらどうせどの言語でもこんな感じかな? それにしても関数型言語なるものを知るにつれて思うのは、 再帰についてはすがすがしいが、 それ以外についてはタイプ量が増えがちってこと。 ハッシュテーブルひとつ準備するのにもウダウダ。 関数型どうのというより、個別の言語によるのかもしれないけど…。
319 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 00:24:39.20 ID:0cpPf2uS.net] >>318 >SMLとOCamlの関係だからこういう似たような感じになるのかな? SML も OCaml も同じML族の一員ですから、そんな感じになるのも不思議じゃないと思いますね >それともループを再帰に置き換えたらどうせどの言語でもこんな感じかな? SML 以外の関数型言語は触った程度のレベルなので、以下はあくまで私見です: ・Lisp でも似た感じの再帰になる ただし Lisp は TCO が保証されていないから、一般的な反復処理であれば loop や while マクロ(または、その相当品)で手続き的なループで書く ・Scheme は TCO が言語仕様で保証されているので、普通は再帰で書く(>>305 ) また継続(call/cc)があるので、loop や while の相当品を関数として自前で定義することも可能 ・Haskell の場合、初めのうちは(ML や Scheme と同様に)再帰で書く ただし Haskell だと文字列は文字型のリストであり、標準ライブラリの unfoldl を使う事を学ぶようになる ・関数プログラミングの楽しみ www.amazon.co.jp//dp/4274068056 第3章「おりがみプログラミング」で詳しく解説されています ということで Haskell の定義を参考にして、SML でも関数 unfoldl で再帰を抽象化したコードを書きました: ideone.com/o5JM86 ここで unfold とは、よく知られている fold の双対な概念です (fold は、Ruby だと inject、Lisp や JavaScript では reduce と呼ばれています) fold xs が「あるリスト xs を畳んだ値 y」を返すのに対し、 unfold y は「ある値 y を広げたリスト xs」を返します なお、「畳む/広げる」という言葉よりも「分解する(destruct)/組立てる(construct)」のほうが直感的かもしれません (* 長いので、続く *)
320 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 00:32:09.09 ID:0cpPf2uS.net] (* >>319 の続き *) なお、map や filter といった高階関数を一般化したものが fold であることは よく知られていますが、ここでリストを代数(群)に見立てた圏論の視点で再構成すると: ・fold を(更に)一般化したものがカタモルフィズム(catamorphism)である ・unfold を(更に)一般化したものがアナモルフィズム(anamorphism)である という、本質的な形でリスト処理を定義できるようになります (モナドとは関連しない)圏論を応用したプログラミングについては、以下のプレゼンがお薦めです ・Introduction to Categorical Programming (Revised) www.slideshare.net/sakai/introduction-to-categorical-programming-revised p.18 の図式を使った「圏論でのリスト型の定義」が直感的です 詳細については、以下の記事で紹介されている論文(英語)が分かりやすかったです ・Haskellと圏論を学んできて、そのまとめとしてちょうどよい論文を見つけたのでメモ。 https://plus.google.com/+OsamuNagano/posts/7cPfAQ145Yi >それにしても関数型言語なるものを知るにつれて思うのは、.... ML や Haskell は静的型付けによる安全性と高速化を主眼に設計された言語ですから、 Ruby や Python といったスクリプト言語の置き換えには成り得ないと考えます これに関しては、以前に別スレ「LLにおける関数型プログラミング」で説明しています peace.2ch.net/test/read.cgi/tech/1345123070/28 また ML や Haskell の強力な型推論は、データ型に関する矛盾(=バグ)が存在しないことを(実行の前に)証明しますが、 動かしては書き直す(いわゆるトライ&エラー)が一般的なスクリプトプログラミングには不向きだと考えます (* これで終わり *)
321 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 07:17:42.63 ID:tzPxF8Oh.net] 長い 3行でまとめろ
322 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 12:12:13.43 ID:PEBuGla8.net] 珍しく普通に相手にしてもらって うれしくてたまらない オレオレクロージャくんであった
323 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 16:08:48.96 ID:5dXZUu33.net] >>319-320 > Lisp は TCO が保証されていないから TCOが保証されての末尾再帰。何がすがすがしいって、これですよね。 これがあるから書いていける。 保証なしで気軽に再帰なんかしてもスタックオーバーフローでげんなりだし。 > Haskell だと文字列は文字型のリストであり、標準ライブラリの unfoldl を おったまげですね。初めてunfoldなるもんを知りました。 Rubyでinject、OCamlでfold_left/fold_rightは馴染みがあったんですが。 何かHaskellって…グイグイ来てますよね!(小学生並みの感想)。 > cata, ana, 圏論, 圏論でのリスト型の定義 リンク先拝見しましたが現時点でどうも1ミリも理解できていません。半笑いです。 > ideone.com/o5JM86 ありがとうございます。よく考えると37行目の「 ^ output」が不要にも見えますね。
324 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 16:23:01.32 ID:a9XjC0LN.net] 源クロウジャ義経
325 名前:デフォルトの名無しさん mailto:sage [2014/12/20(土) 19:01:20.98 ID:tzPxF8Oh.net] >>322 分かりやすいですー
326 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 00:04:04.16 ID:YWufr8fT.net] >>323 >よく考えると37行目の「 ^ output」が不要にも見えますね。 バグ指摘ありがとうございます、変数 output そのものが不要でした 対策を以下へ反映し、ついでに Ruby と Python でも unfold を使って書いてみました ・Standard ML ideone.com/3L6yJ0 ・Ruby ideone.com/4OzC0s ・Python ideone.com/8TouzI >おったまげですね。初めてunfoldなるもんを知りました。 「unfold は fold の双対な概念」であることを知れば、応用範囲は広がります 今回は文字列の unfold でしたが、リスト/配列/辞書/集合/スタック/キューといった 「コレクション・オブジェクトにおける fold/unfold」を考えることから始めませう
327 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 09:15:25.48 ID:KrmABo99.net] TCO無くて正格評価なPythonでは unfoldはループ&ジェネレータで実装した方が良いね それと文字列に限定する意味って無いよね ideone.com/e1fKAL
328 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 16:48:41.14 ID:MvQSKDIW.net] この話題クロージャとか特に関係なく、Pythonの無名関数には文を書けず式しか書けないという単純な事実の指摘でOK? 関数型プログラミングのラムダとしては困らないが、手続き型言語における無名関数としては不便だろうな 自分はPythonを使わないので、Pythonでの「普通の」プログラミングスタイルがどっちなのかは知らん
329 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 17:05:17.75 ID:MvQSKDIW.net] Hackで適当に書いてみたら本体は一行だった。PHPの緩さにラムダ加わるの最強 $strings = array_map($n ==> array_reduce(str_split($n), ($s, $d) ==> $s . $digitNames[$d]), $numbers);
330 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 17:15:45.30 ID:KrmABo99.net] そんなので良ければPythonでも一行 strings = [''.join(digitNames[x] for x in str(n)) for n in numbers]
331 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 17:21:26.20 ID:MvQSKDIW.net] あれ、それdigitNames[x]のxに文字列で渡ると思うけど、Pythonも勝手に数値に変換してくれるんだっけ? 整数に変換してやらないと駄目な記憶があっていちいち面倒くさいと思ってた
332 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 18:11:16.63 ID:axFrURca.net] digitnames = { "0": "Zero" ... } なら>>331 digitnames = { 0: "Zero" ... } なら digitNames[int(x)]になるだけだろ。 Perlなら my @string = map{ join '', @digit_names{split //, $_} } @numbers; Javascriptなら var strings = numbers.map(function(number) { return number.toString().split("").map(function(x) { return digitNames[x] }).join(""); }); Javascriptはアロー演算子が欲しいところだ。
333 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 18:21:39.18 ID:MvQSKDIW.net] 最強言ったから気に食わなかったならスマンカッタ PHPの緩さは、こういうのが動くところ。>>329 でそのまま動く $digitNames = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','.'=>'Point','-'=>'Minus']; $numbers = [1.234, -5.4321];
334 名前:デフォルトの名無しさん mailto:sage [2014/12/21(日) 23:04:35.55 ID:YWufr8fT.net] >>327 >>326 と比較すると: ・わざわざジェネレータで「組立てた」シーケンスを reduce で「畳み込んで」いて、二重のループになっているから処理効率(=性能)が悪く、 なおかつ reduce へ渡すラムダ式が増えているからコードも複雑化してしまっている ・そもそも「Haskell の unfold 定義」に従って関数定義していないから その関数の命名 unfold は不適切であり、別の名前を考案すべき 念の為に「Haskell の unfold 定義」を以下に示す(ただし末尾再帰ではなく一般再帰): unfold :: (B -> Maybe (A, B)) -> B -> [A] unfold f u = case f u of Nothing -> [] Just (x, v) -> x : (unfold f v) この「Haskell の unfold 定義」に従った unfold の Python 実装を以下に書いた: ideone.com/vpTBlR ・__unfoldl_string_rec__:一般再帰による実装(>>326 と同じ) ・__unfoldl_string_while__:while 文と破壊的代入を使った手続き型実装 あわせて Ruby の実装コードも更新した: ideone.com/9x6s0h コードの要点を示す: ・Python のジェネレータを Ruby では外部イテレータ Enumerator と呼ぶが、 (Ruby 1.9 以降のメソッド定義マナーに従い)ブロックが渡されていない場合には (組込みメソッド Object#to_enum を使って)外部イテレータを返すようにした ・3種類のメソッド定義を示した ・String#__unfoldl_rec__:一般再帰による実装(>>326 と同じ) ・String#__unfoldl_until__:until 文と破壊的代入を使った手続き型実装 ・String#__unfoldl_loop__:メソッド loop を使った参照透明性のある関数型実装(>>267 ) 最後に、Ruby と同様な「Haskell の unfold 定義」に従った Python のジェネレータ実装については、>>327 への宿題としておく (ML や Haskell といった静的型付け関数型言語に慣れていないと、難しいかもしれないが....)
335 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 08:52:28.54 ID:6avCYBJ9.net] Pythonの場合リストを返したかったら list(unfold(f, x)) で良くね? 毎回 s += a 等やって組み立てるよりも速いぞ
336 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 09:03:18.85 ID:6avCYBJ9.net] あ、もしかしてunfoldlじゃないからダメって言ってんの? unfoldには unfoldr と unfoldl の二種類あって、HaskellではPreludeにあるのはunfoldrだけだぞ
337 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 09:04:46.38 ID:6avCYBJ9.net] ちなみに>>334 が自信満々に貼ってる方のHaskellのunfoldの定義はunfoldrの方なw
338 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 09:07:58.19 ID:ZCDWZl5G.net] unfold :: (B -> Maybe (A, B)) -> B -> [A] じゃないから駄目とか言っといて、なんで出してる実装はことごとく unfold :: (B -> Maybe (A, B)) -> B -> A なの? バカなの?
339 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 14:26:58.64 ID:51sTiTTJ.net] またオレオレ定義君がやらかしちゃったかー
340 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 21:08:27.40 ID:8h2AGQmm.net] cにクロージャくれよっておもってたけど 今ならgoがあるんだよな
341 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 21:10:47.28 ID:VRBNRD9f.net] C++使ったら?スコープ抜けた際どうなるか、必要ならコピーを持たせよう、とかスマポにするかーとか、考える必要はあるけど
342 名前:デフォルトの名無しさん mailto:sage [2014/12/22(月) 21:16:46.96 ID:6skO2mFq.net] >>340 clangならblocksが使えるんじゃないかしら
343 名前:デフォルトの名無しさん mailto:sage [2014/12/23(火) 06:28:08.32 ID:pszL50YR.net] ほー objc じゃなくても使えるのか。 まあ objc に c のソースだけ食わせて使ってもいいんだけど。
344 名前:デフォルトの名無しさん mailto:sage [2014/12/23(火) 11:28:17.27 ID:St4HMSPr.net] boost lambdaで怖い思いしたから c++はng コンパイルエラーから黒魔術なコード出されてもこまる
345 名前:デフォルトの名無しさん mailto:sage [2014/12/23(火) 11:30:55.43 ID:0dLhalMI.net] そういうのはreplで対話的に書けたほうがいいな
346 名前:デフォルトの名無しさん mailto:sage [2014/12/23(火) 14:09:04.60 ID:Og1JN7U7.net] このスレのおかげでクロージャの良さと Ruby信者のキモさが分かりました ありがとうございました
347 名前:デフォルトの名無しさん mailto:sage [2014/12/27(土) 00:25:14.89 ID:randw1SU.net] クロージャなんて最近の言語は大抵あるからね 次に関数型言語からパクって欲しいのはパターンマッチ
348 名前:デフォルトの名無しさん mailto:sage [2014/12/29(月) 07:25:36.12 ID:Br8mMuyh.net] disると公開される
349 名前:デフォルトの名無しさん mailto:sage [2014/12/29(月) 16:50:56.24 ID:9aAL2Pj2.net] まぁ別にいらないっちゃいらないな。 最近の言語はいろいろ付けすぎだわ。 もっと仕様単純でいいよ。
350 名前:デフォルトの名無しさん mailto:sage [2014/12/29(月) 17:19:30.86 ID:LxjJzYoX.net] パターンマッチの無い言語にパターンマッチを付けられるような言語がいい
351 名前:デフォルトの名無しさん mailto:sage [2014/12/29(月) 19:45:55.93 ID:NKff8BVB.net] >>350 プリプロセッサを使えば、どんな言語でも なんだって出来るんじゃね?
352 名前:デフォルトの名無しさん mailto:sage [2014/12/30(火) 17:09:02.43 ID:AU/nggqJ.net] その万能プリプロセッサがあればいいんだけど
353 名前:デフォルトの名無しさん mailto:sage [2014/12/30(火) 18:06:56.67 ID:mxKZGqd3.net] m4通すとか?
354 名前:デフォルトの名無しさん mailto:sage [2014/12/30(火) 18:40:21.70 ID:AU/nggqJ.net] その言語処理系を書かた言語のコードを直接書き変えるような書き方じゃなくて その言語自体で新しい表現(パターンマッチとか)を定義出来るようにするってこと
355 名前:デフォルトの名無しさん mailto:sage [2014/12/30(火) 19:32:00.99 ID:tU/2zS2Z.net] >>350 lispおじさんだ!
356 名前:デフォルトの名無しさん mailto:sage [2014/12/30(火) 20:40:47.63 ID:LKC757rT.net] lispでマクロ使えばおk
357 名前:デフォルトの名無しさん mailto:sage [2014/12/31(水) 23:19:03.80 ID:tqgvohnx.net] >>354 たぶんschemeにドハマリするタイプ
358 名前:デフォルトの名無しさん mailto:sage [2015/01/01(木) 00:15:11.77 ID:6s4ScpeL.net] on lispとかlet over lambdaがあるcommon lispの方がいいんじゃね
359 名前:デフォルトの名無しさん mailto:sage [2015/01/01(木) 08:49:44.48 ID:Vz2QaCIS.net] あなほりマクロ怖い
360 名前:デフォルトの名無しさん mailto:sage [2015/01/01(木) 19:26:59.51 ID:LWrX8qsS.net] やっぱりpythonとかhaskellのコードと比べると 専用の構文があった方がスッキリ書ける でもそうすると自由度が無くなってマクロがうまく使えないジレンマ
361 名前:デフォルトの名無しさん mailto:sage [2015/01/01(木) 19:31:53.89 ID:LWrX8qsS.net] 一応リーダマクロを使えば解決するんだけど結局使わなくなる
362 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 09:58:20.63 ID:ie8IusfS.net] lispおじさんのせいで すっかりマクロ談義スレになったな
363 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 10:14:10.05 ID:PL75YfkA.net] 真のクロージャとマクロ、どっちがマシか難しいところだな
364 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 11:28:56.61 ID:Ur5QsT6D.net] 二つのいいところを組み合わせたものが最強ではないだろうか? つまりマクロージャー
365 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 12:10:26.52 ID:ie8IusfS.net] マクロにコンテクストが付いて回るclの事だよねそれ
366 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 15:30:32.04 ID:/upm+g4t.net] マクロとクロージャを組み合わせればOOPも継続も後から付けられる
367 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 15:37:48.79 ID:Ur5QsT6D.net] いろんなことができる。そうマクロージャならね!
368 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 20:00:41.84 ID:ZuY3pBgY.net] >>366 継続渡しではないですよね? マクロとクロージャーで継続をどう実装するか ぱっとは思いつかなかったのでよかったら教えてください。
369 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 20:28:34.80 ID:UWr+Udi0.net] onlispでは継続を表わすクロージャを引数で渡してそれをマクロで包んでる これだと使う側が末尾呼出的に書かないといけない縛りがある cl-contは式をwithマクロで包んでその式をcodewalkしてcps変換してる
370 名前:デフォルトの名無しさん mailto:sage [2015/01/02(金) 21:04:50.09 ID:ZuY3pBgY.net] ありがとうございます。On Lisp 読んでみます。
371 名前:1 mailto:sage [2015/01/09(金) 13:33:15.35 ID:3m5OEfmN.net] そもそも関数が一級オブジェクトである必要があるのかどうか疑問が出てきました ifelse( aaa, xxx, ifelse( bbb, yyy, ifelse( ccc, zzz, iii ))) ↑死ね IDE使えってことなんでしょうけど認知に負荷をかける言語仕様は間違ってると思うんですよね これよりはメソッドチェーンの方がかなりスマートだと思う foo(aaa){xxx}.bar(bbb){yyyy}.baz(ccc){zzz}
372 名前:デフォルトの名無しさん mailto:sage [2015/01/11(日) 21:16:33.98 ID:8HLn7hr5.net] それだと全てのメソッドで条件分岐を想定した実装にしなくちゃいけなくなるのでは
373 名前:デフォルトの名無しさん mailto:sage [2015/01/16(金) 01:40:03.14 ID:U7RTYgR7.net] Pythonはパターンマッチ以前にSwichtすらない
374 名前:デフォルトの名無しさん mailto:sage [2015/01/16(金) 08:39:36.86 ID:oLGQ6wLb.net] >>373 そんなもんがある言語を見たことないが
375 名前:デフォルトの名無しさん mailto:sage [2015/01/16(金) 23:23:44.50 ID:obgM8cFp.net] なんかドイツ語?みたいな切り方だな
376 名前:デフォルトの名無しさん mailto:sage [2015/01/21(水) 16:33:15.48 ID:Out9u5nx.net] ゲルマンおじさんこわい!
377 名前:デフォルトの名無しさん mailto:sage [2015/01/22(木) 01:37:45.45 ID:8pwMw7VT.net] スウィヒトとか読むの?ドイツ語ってよくわからんタイミングで濁るイメージあ?からジットとかかな
378 名前:デフォルトの名無しさん mailto:sage [2015/01/22(木) 08:08:05.98 ID:VatMjg6z.net] スヴィヒトだな、あえてカタカナを当てれば
379 名前:デフォルトの名無しさん mailto:sage [2015/01/24(土) 00:56:47.04 ID:hSO7J5Oj.net] 中二病みたい
380 名前:デフォルトの名無しさん mailto:sage [2015/01/27(火) 21:37:55.87 ID:x1TLH4fz.net] ここまでnonlocalなし
381 名前:デフォルトの名無しさん mailto:sage [2015/11/26(木) 03:43:18.04 ID:9L/RhMYwv] 関数を返す関数を定義するときにはいる
382 名前:デフォルトの名無しさん mailto:sage [2016/01/10(日) 19:01:54.47 ID:sdj7zt3O.net] Objective-Cのblocksが便利だというからいろいろ読んでみたが 使い道がよーわからん。他言語のクロージャやラムダだということで 他言語のクロージャやラムダについて読んでたらもっと混迷が深まった。
383 名前:デフォルトの名無しさん [2016/03/29(火) 09:21:36.23 ID:/c8bAcK4.net] サッカーブッシュ日本代表日程ぷあたん(しゅっちょうまいくろ教育長交代)春文執行40代売上差額シュガーチョコ https://www.youtube.com/watch?v=NDq1QoJY0nY宇ドナルドアナリストパワーストーンコーチングとしまえん サッカーブッシュ日本代表日程古本屋よしたけしゅっちょうちょこしゅがー ディーラー税務署天才開発者死亡詰みヨミドクターマイクロサービス不足 サッカーブッシュ日本代表日程ぷあたんシフト光金さかい強制バイト人権侵害問題 春分資源執行ニューヨーク低原価ぼったステーキソルトレイク福岡横浜新橋奴隷課金パチシフト強制バイト問題新潟米センター生残 コスメ24チャリティー隠れ40代生活保護プレイボーイバイトレードいたりあん接待問題 マスコミKARDローンケーオーサービス不足婚活パーティー寄付金執行原発ビジネス FBIチャイニーズタイホテル売上事務所ガチャ決算ガチャキャンペーン(販売報道陣過激派組織向携帯最新情報提供終了 校長発言細心注意ノートン産廃エラー(著作権クレーム中国反応融資高額教育費)(中国捕鯨団体40代社員サッカーコメント 高額入学金ヤフウ新橋大学ヤフウ新橋理事長FX経費 おじや50代資産ガリバズフィード40代エリート
384 名前:デフォルトの名無しさん [2016/05/01(日) 14:33:24.76 ID:tKi6j9CT.net] 匿名通信(Tor、i2p等)ができるファイル共有ソフトBitComet(ビットコメット)みたいな、 BitTorrentがオープンソースで開発されています 言語は何でも大丈夫だそうなので、P2P書きたい!って人居ませんか? Covenantの作者(Lyrise)がそういう人と話したいそうなので、よろしければツイートお願いします https://twitter.com/Lyrise_al ちなみにオイラはCovenantの完成が待ち遠しいプログラミングできないアスペルガーw The Covenant Project 概要 Covenantは、純粋P2Pのファイル共有ソフトです 目的 インターネットにおける権力による抑圧を排除することが最終的な目標です。 そのためにCovenantでは、中央に依存しない、高効率で検索能力の高いファイル共有の機能をユーザーに提供します 特徴 Covenant = Bittorrent + Abstract Network + DHT + (Search = WoT + PoW) 接続は抽象化されているので、I2P, Tor, TCP, Proxy, その他を利用可能です DHTにはKademlia + コネクションプールを使用します UPnPによってポートを解放することができますが、Port0でも利用可能です(接続数は少なくなります) 検索リクエスト、アップロード、ダウンロードなどのすべての通信はDHT的に分散され、特定のサーバーに依存しません い