クロージャって何がいいの? [転載禁止]©2ch.net

■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
垢版 |
2014/11/08(土) 13:11:47.84ID:6V2MLUHb
関数型言語に必ずくっついてるこれ
いらんでしょ?匿名クラスで充分でしょ
2014/11/10(月) 07:14:42.95ID:0mRy26rG
Pythonの不自由さ(関数型のクロージャに近いの)はGuidoの方針じゃないの?
嫌なら、おとなしくジェネレータ使えばいいじゃん。
2014/11/10(月) 08:48:39.72ID:PWSP4TjP
クロージャは何がいいんだよ!
https://i.imgur.com/fTQTEYN.gif
2014/11/10(月) 09:04:03.39ID:HTkQymog
引数に別名付けたくなる程に中身が長いなら
関数にも名前付けろってのがGuidoの方針なんだろ
文法的に拡張可能なのに、あえてリジェクトしてるくらいだし
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
2014/11/10(月) 10:20:30.55ID:CeTPRNSr
>>106
Martin Fowlerは字面だけを見てないから、ちゃんとPythonにもクロージャがあると思ってるよ

お前が張ったリンク先の「他の言語」を見てみろ
1151
垢版 |
2014/11/10(月) 11:39:28.98ID:rdbd3Lyi
何がクロージャかよりどこが好きかでクロージャを語れよ!!(ドンッ
2014/11/10(月) 20:33:09.35ID:AR7BQCkT
クロージャとメソッドで f[x] と f(x) を使い分けなきゃダメなRubyが
一番ウンコだと思う
2014/11/10(月) 20:39:42.07ID:5eyjbk6/
>>116
それはクロージャとメソッドではなく、Procとメソッドだと思う
Rubyのクロージャはブロックのほうの機能と考えたほうが良いんじゃないかな
118デフォルトの名無しさん
垢版 |
2014/11/10(月) 21:34:09.37ID:Xzn5T3EF
>>115

俺の財宝か?欲しけりゃくれてやる。
探せ!この世の全てをそこに置いてきた。
2014/11/10(月) 22:47:25.14ID:oQ75X8QG
文系出身プログラマ「クロージャ?なにそれ?服入れるとこ??」
ってやつに対してドヤ顔ができる
2014/11/11(火) 06:32:45.68ID:G8l0apNf
クロー系の最強魔法です 消費MP60
121118
垢版 |
2014/11/11(火) 21:00:28.44ID:UknPa1bY
レスお願いします
2014/11/11(火) 22:06:02.40ID:3gT2I0NB
若い時に買ってでもすることは?

苦労じゃ!くろうじゃ!クロージャ!
2014/11/12(水) 01:25:01.41ID:G1/eYMX4
クロージャの良さを、クロージャを使うことで劇的に
簡潔になる例を使って説明してください
2014/11/12(水) 07:27:28.43ID:ptlTHlgg
コールバック関数を別途書かなくて良くなります。
もしコールバック関数の為だけにインスタンス変数を定義していたなら、
それも必要が無くなります。

消費MP 5
2014/11/12(水) 08:10:30.04ID:G1/eYMX4
コールバック関数地獄のJSのコードは
可読性が悪い上に簡潔でも無いので、失格です
2014/11/12(水) 08:13:15.39ID:/hly7+iy
オールバックって額からハゲるだろ?
2014/11/12(水) 08:27:11.27ID:cKuXIrT/
>>125
そんなあなたにClojureScript。
core.asyncのチャネルでスッキリしますよ(Go由来のようだけど)
2014/11/12(水) 20:27:05.24ID:3VJGATlA
>>127
コールバック自体がダメなんだよ。
例えば、addEventLisnerの引数にコールバックを指定する。
これだけでも可読性悪いだろ。
2014/11/12(水) 20:37:53.49ID:L8labB6g
見慣れてるかどうかだと思うけどな
2014/11/12(水) 20:38:24.71ID:5GyhUZuz
>>128
代案も出さずに批判だけするなら、幼稚園児にだってできるよ
2014/11/12(水) 20:52:00.80ID:UPi6O5bX
リスナーI/Fをインプリメントしたオブジェクト渡せばいいのでは
2014/11/12(水) 21:14:25.68ID:ptlTHlgg
それではそのオブジェクトを定義しなくてはならなくなります。
クロージャはそのようなデリゲートオブジェクトやコールバックパターンからの解放なのです。

消費MP 12
2014/11/12(水) 21:16:45.87ID:eep146vT
JavaScript(だけに限らないが)
クロージャーが見難いんじゃなくて
非同期の入れ子が見にくいんだろ。
で、それを解決するライブラリが存在する。

結局のところ、そのライブラリ
Promiseとかを使えば解決する問題。
2014/11/12(水) 21:23:36.45ID:G1/eYMX4
結局のところ、コールバックはクロージャのメリットじゃないんですね?
もっと良い方法があるのですから
2014/11/12(水) 21:36:55.56ID:ptlTHlgg
いや、クロージャ使ってそのスコープで解決しちゃえばコールバック関数要らないって話なんだが。
2014/11/12(水) 21:59:20.14ID:G1/eYMX4
Haskellのdo記法みたいなのがあれば
クロージャをチェインしていっても読み難くならないという話ですか?
2014/11/12(水) 22:58:17.02ID:L8labB6g
小規模なコールバックだったらインラインで書いた方が見通しが良いだろうし、
複雑なのだったら分けて書いた方が理解しやすいだろうし、
あれが最強他はゴミとか言ってるのが一番ダメなんじゃね?
2014/11/15(土) 12:17:49.98ID:uUcubJGq
結局クロージャの利点てコールバックが楽にかけるってだけ?
ならクロージャや匿名オブジェクトじゃなくて匿名メソッドが書ければ充分だな
2014/11/15(土) 12:25:31.04ID:u4ZMuG60
楽に書けるって事じゃなくて、そのスコープで完結できるって事じゃね?
2014/11/15(土) 12:56:58.32ID:XlhMXrhL
とりあえずコードで語れば?
大規模開発でメリットが出てくるとかの話じゃないんだし
2014/11/15(土) 14:40:16.71ID:EFct/v5k
見た目的にも変数の値の可視性的にもそこのスコープってとこが楽だよね
2014/11/15(土) 14:43:26.00ID:XlhMXrhL
つまりインラインでクラス定義できるのでも良いわけだよね
2014/11/15(土) 15:14:55.72ID:EFct/v5k
>>142
本来そうだけど 、
シンタックスはインラインだけど実際はただの内部クラスで、
生成時の環境を一切利用できない言語もあるから何とも言えない。

クロージャの代わりにクラスを用いると何となくそういう実装になる。
ローカル環境の代わりにインスタンス変数を用いる方向にいくから。


FILE *fp = fopen(..);
doHoge( ^(const char*msg){ fputs(msg,fp); });
fclose(fp);

みたいに簡便にクロージャ生成時の外部の変数(の値のコピー)を
保持し使用できるクロージャとは方向性が違う。

ローカルメソッドに至っては環境が一昨渡せない
シングルスレッド前提ならグローバル変数を使えばいいわけだけど
2014/11/15(土) 15:54:48.49ID:uUcubJGq
(擬似言語)
fw = new FileWriter();
doHoge( fw.witer );
fw.close();
こんなのをワンラインで書ければ満足なんだろ?匿名メソッドで十分じゃない
2014/11/15(土) 15:58:46.71ID:EFct/v5k
>>144
じゃ匿名メソッドで書いてごらんよ
2014/11/15(土) 23:46:47.75ID:JsFAZjCZ
with (fw, new FileWriter()) {
doHoge(fw.witer);
}
こうやって書けるほうがいい
2014/11/16(日) 10:37:06.14ID:ZMiOBdAw
じゃあこれは?

FILE *fp = fopen(..);
doHoge( ^(const char*msg){ fprintf(fp, "Hoge: %s\n", msg); });
fclose(fp);
2014/11/16(日) 11:54:54.13ID:fx2XWh+X
>>146
もはや匿名メソッドすら要らない派が出てくるしww
2014/11/18(火) 16:33:41.48ID:cuxiU0eb
Java8すら使わせてもらえない人が必死なスレにしか見えなくなってきた
2014/11/19(水) 22:27:12.37ID:eeZRz+g3
>>144,147
それだと doHoge の実行中に例外が発生するとファイルがクローズされない

たとえばクロージャを多用する Ruby のような言語だと、以下のように書く
 File.open(..) do |file|
   doHoge do
     file.puts(msg)
   end
 end
Ruby ではクロージャをブロックと呼ぶけど、ブロック実行中に例外が発生しても
ファイルは確実にクローズされるし、ユーザ定義メソッドでも同様な振る舞いを実装できる


>>146
それに対して、クロージャを持たない手続き型言語の Pascal や Python といった言語では、
同じ事をするのに(>>146 のような) with 構文を使わなければ書けない
クロージャは一級市民だから引数で渡したり呼び出すことができるという自由があるけど、
with 構文はあくまで文(statement)だからクロージャと比較すれば表現力は制限される
いわばクロージャという概念を持たない言語の代用品が with 構文である

なおJavaScript はクロージャと with 構文のどちらも持っているけど、
書籍 "JavaScript: Good Parts" だとクロージャは Good Parts に
with 構文は Bad Parts に分類されている
2014/11/19(水) 23:00:05.80ID:074lLX1H
クロージャばりばり使うlisp方言でもwith構文は使うよ
2014/11/19(水) 23:12:18.42ID:3WdraWBV
クロージャとクリーンアップ処理とは別の話じゃないの?
2014/11/19(水) 23:33:41.68ID:PA9iCB5s
Pythonが憎すぎて既知外になった人の相手をしちゃいけません
2014/11/19(水) 23:39:01.13ID:QzanlTyB
>>150
> なおJavaScript はクロージャと with 構文のどちらも持っているけど、
> 書籍 "JavaScript: Good Parts" だとクロージャは Good Parts に
> with 構文は Bad Parts に分類されている

お前バカじゃね? 大馬鹿じゃね?

ここで言ってるwithは例外が起きた時にリソースを解放する機能を持ったもの。
JavaScriptのwithはそんな機能は持っておらず、

obj.foo() を
with(obj) {
  foo()
}
と書けるようにするためでしかなく、それによる問題(詳しくは調べて)があるから
Bad Partsになってるだけ。
PascalやPythonのwithがBad Partsになってるわけじゃない

お前、ほんと、馬鹿だよね?
2014/11/19(水) 23:57:41.67ID:eeZRz+g3
クロージャと with 構文のどちらも持っている言語であれば、
ケースバイケースで可読性や好みで使い分ければいいのではないかと

問題はクロージャを持たない、あるいは
「世間一般のクロージャの要件(>>104)」を満たせない言語では、
with 構文という(クロージャと比べて)不自由な代用品を使わざるをえない
という話
2014/11/20(木) 00:02:30.91ID:fhZ8V3Hu
>>150>>155
下の(a)と(b)が等価であるようなJSのwith構文と
リソース解放のwith構文の区別もつかないような馬鹿が
何書いても説得力無いよ


// (a)
with (obj) {
    a = b;
}

// (b)
if (obj.a === undefined) {
    a = obj.b === undefined ? b : obj.b;
} else {
    obj.a = obj.b === undefined ? b : obj.b;
}


withって字面だけ見て同じだと思っちゃったの?
そんなだから構文の字面しか見てない馬鹿って言われちゃうんだよ
2014/11/20(木) 00:19:03.39ID:wJ3BgpRF
>>154
>ここで言ってるwithは例外が起きた時にリソースを解放する機能を持ったもの。

わざわざ with という構文を追加して言語の意味論を複雑にしなくても、
もし汎用的な概念であるクロージャがあれば、同じ事を実現できるってことだよ

もし Python にもクロージャがあるなら、他の言語達と同様に
with 構文を使わなくてもリソースの自動解放を簡潔に表現できるハズだけど、
手続き型言語の Python では無理だろうね

それとも、書けるかな?
2014/11/20(木) 00:20:15.54ID:7GcQ+ika
pythonでも引数にクロージャ受け取ってwithの中でそれを実行する関数つくれば、rubyのそれと等価じゃね?
pythonはlambdaが制限きついから複雑な処理はインラインには書けないけど。
2014/11/20(木) 00:29:37.23ID:wJ3BgpRF
>>158
>それを実行する関数つくれば、

もし Python が「世間一般のクロージャの要件(>>104)」を満たしていれば、
「関数をつくらなくても」クロージャだけで簡潔に書けるはず
つまり「関数をつくらなければ書けない」ということは、
Python が「世間一般のクロージャの要件」を満たしていないことを認めたってこと
2014/11/20(木) 00:36:40.77ID:ri7Qzvfi
「世間一般のクロージャの要件」が
全然世間一般の定義じゃない件
2014/11/20(木) 00:37:00.07ID:7GcQ+ika
>>159
def make_f(x):
 def f(y):
  return x * y
 return f

例えばこんなのがあったとして、このmake_f()が返すものは何?
2014/11/20(木) 00:42:39.12ID:wJ3BgpRF
>>161
「クロージャみたいなモノ」もしくは「クロージャもどき」

def make_f(x):
 return lambda(y): x * y

が返すのも同じ
2014/11/20(木) 00:44:55.24ID:7GcQ+ika
>>162
「クロージャみたいなモノ」もしくは「クロージャもどき」と、クロージャの違いは何?
2014/11/20(木) 00:45:40.70ID:ri7Qzvfi
>>162
>>31の定義だと完璧にクロージャの条件を満たしてるけど?

君はどこのローカルルールの話をしてるの?
2014/11/20(木) 00:47:27.27ID:wJ3BgpRF
>>163
>>104
2014/11/20(木) 00:52:13.60ID:7GcQ+ika
>>165
>世間一般のクロージャの要件(C#、Java8、C++11、JavaScript、Ruby 等々):
>  関数であっても無名関数であっても、局所環境を持つ(変数を束縛できる):>>52,56,77

>>161のmake_f()が返すものは局所環境をもってるし名前も付いてないよ。
2014/11/20(木) 00:58:03.79ID:wJ3BgpRF
>>164
いや、Python は関数を定義しなければ局所環境が作られないんだから、
>>31 の要件は満たしていないだろ
>>31 には「ラムダ式や無名関数で実現している」と書かれているんだけど、
日本語が不自由なんですか?

実際、もしも >>31 の定義を満たしているなら、
>>46 のゴチャゴチャしたコードは
(>>73 のようにわざわざ関数を定義しなくても)
>>83 のように「ラムダ式や無名関数で実現している」
簡潔なコードに書き直せるはずだ

さて、論よりコード、>>164 は書き直せるかな?
2014/11/20(木) 01:00:19.64ID:fhZ8V3Hu
今の議論と全然関係ないんだけど、久しぶりにTIOBEを見たら
ちょっと前までPerl, Python, Ruby, PHPで順位を争ってたのに
いつの間にかRubyだけ人気無くなっててワロタw

http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html


だからRuby信者発狂しちゃったの?


1 C
2 Java
3 Objective-C
4 C++
5 C#
6 PHP
7 Python
8 JavaScript
9 Perl
10 Visual Basic .NET
11 Visual Basic
12 R
13 Transact-SQL
14 Ruby
15 Delphi/Object Pascal
16 F#
17 PL/SQL
18 Swift
19 Pascal
20 Dart
2014/11/20(木) 01:03:38.95ID:ri7Qzvfi
>>167
>>31には「いくつかの言語では」と前置きされてるじゃん
つまりラムダ式や無名関数は必要条件ではない

そっちこそ日本語が不自由すぎるのでは?
2014/11/20(木) 01:04:53.19ID:wJ3BgpRF
>>166
それは def f(x): で関数を定義しているから、当たり前の話

「世間一般のクロージャ」であれば、わざわざ関数を定義しなくても
ラムダ式や無名関数と呼ばれる構文でクロージャを作れるんだよ
>>31 をよく読み直そうね
2014/11/20(木) 01:06:05.89ID:7GcQ+ika
>>170
じゃあさ、これが返すものは何?
(define (make_f x)
 (define (f y)
  (* x y))
  f)
2014/11/20(木) 01:07:50.18ID:fhZ8V3Hu
>>170
> >>31 をよく読み直そうね

お前が100回読み直した方が良いぜw
2014/11/20(木) 01:10:58.55ID:wJ3BgpRF
>>169
>>31 にある「いくつかの言語では」という前置きは、
後から出てくる Smalltalk や Ruby のブロック構文を指すと
考えるのが自然じゃないかな?

さすがに Wikipedia のページ著者が
「ラムダ式や無名関数」と「関数定義」との違いも
分からないほどのお馬鹿さんだとは思えないしね
2014/11/20(木) 01:11:10.32ID:7GcQ+ika
>>171
ごめん。それで (make_f 10) とか実行した時に返ってくるもの、の間違い。
2014/11/20(木) 01:15:12.19ID:wJ3BgpRF
>>171
クロージャだね

(define (make_f x)
 (lambda (x) (* x y))
)

が返すのもクロージャだね
2014/11/20(木) 01:18:52.68ID:7GcQ+ika
>>175
>>161のpythonのコードと完全に同じなんだけどw
2014/11/20(木) 01:18:56.43ID:fhZ8V3Hu
>>173
> さすがに Wikipedia のページ著者が

Wikipediaの編集者を持ち上げるのは良いけど、
お前の主張とは違う事が書いてあるぜ
読めるか?Pythonって書いてある

> クロージャを持つ言語に、C# 3.0、C++11、ECMAScript(JavaScriptを含む)、Groovy、Java 8(予定)、
> Perl、Python、Ruby、PHP(5.3以降)、Lua、Squirrelなどがある。
2014/11/20(木) 01:28:21.39ID:wJ3BgpRF
>>177
Wikipedia の記事が常に 100% 正しいと思っているのかな?

記事の冒頭にある >>31 のクロージャという用語の定義とは
矛盾していると思うけどね
(自分のクロージャという用語の定義は >>4 で書いた)

もし矛盾していないと反論したいのなら、論よりコードだ
>>46 のゴチャゴチャしたコードは
(>>73 のようにわざわざ関数を定義しなくても)
>>83 のようにラムダ式や無名関数だけで書き直せるはず

さて、>>177 は書き直せるかな?
2014/11/20(木) 01:32:42.88ID:fhZ8V3Hu
>>178
>>169が正解と考えれば全く矛盾してないので、お前が間違ってるんだよ
2014/11/20(木) 09:44:37.50ID:BfhGUngW
with構文はスコープから抜ける時にclose的な関数を必ず呼び出してくれる保証があるけど、
Rubyのブロックにはそんな保証は無い
だからRubyではウッカリcloseを忘れても分かりにくい
そういうのは良くない
2014/11/20(木) 11:08:08.37ID:nwROesTX
>>178
> Wikipedia の記事が常に 100% 正しいと思っているのかな?

思ってないけど、あんたが言っていることよりかは
正しいと思うね。

だって、あんたの言うことのほうが正しいなら
wikipediaを修正すればいいわけだから。
2014/11/20(木) 12:57:07.44ID:5gFBGGbj
なんだ、この偏執狂たちの罵り合いはw

そんなことより、問題。
若い内に買ってでもしろ、と言われるものはなぁんだ?
2014/11/20(木) 15:15:51.24ID:W3M4RtQD
ああ、let-inが無いからpythonのはクロージャじゃないって主張か。
斜め上だな。
2014/11/20(木) 16:40:50.21ID:2szoNUEC
環境と変数を手軽に包めるのは有難いけどなあ
XMLベースのジョブ管理言語とか
ちょっとしたVM作るときに
継続の表現にクロージャなしだとだるいよ
さらに無名クラスも無い言語だと
本物のVM作らなきゃいけなくなる
2014/11/20(木) 20:12:20.93ID:IqIimPum
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Closures
2014/11/21(金) 13:07:27.23ID:obtZMam2
>>182
セックス…かな
年とると立たなくなるから
2014/11/21(金) 13:13:28.47ID:zygDXSz1
>>186
ご愁傷さまです。
2014/11/29(土) 13:01:53.24ID:OX49RFg5
>>188
2014/12/10(水) 19:56:15.27ID:veDvxwge
Swift スレでクロージャの話題で荒れそうだったので、こちらへ移動しとく
 http://peace.2ch.net/test/read.cgi/tech/1415860741/153

--
Swift や Ruby を含む多くの言語では常識であるけど Python では異なるものとして、
関数型言語に由来した(無名関数やラムダ式とも呼ばれる)クロージャがある
たとえば "The Swift Programming Language" の "Closure" の章にある map メソッドを使った
サンプルコードは、Ruby でも同じスタイルの良く似たコードで書き直せる:
 http://ideone.com/TsGD6B
これは Ruby だけでなく、JavaScript でも同じ
Swift や Ruby と比べて構文が簡潔な JavaScript ではいくらか冗長にはなるけれど、
何の苦もなく Swift と同じスタイルで書き直せる:
 http://ideone.com/74oNVU

同様に、「あるテーブルから特定の行だけを抽出し、加工して、集計する処理」は、
Swift だと table.filter { .... }.map { .... }.reduce { .... } とメソッドを連結(チェイン)させた式で書ける
これは Ruby なら table.select { .... }.map { .... }.inject { .... } と書き直せる
ここで、クロージャ内の ..... の部分には、上記のサンプルのように「任意の文(statements)が書ける」

もしかすると、いやこんなの高階関数のプログラミングを知っている人なら当たり前だろ、と感じるかもしれない
ところが Python だけはクロージャの本体に(任意の文ではなく)「式(expression)しか書けない」:
 http://ideone.com/tDaDkL  # --> Syntax Error になってしまう
だから、他の言語のクロージャに相当するコードを(名前のある)関数としてわざわざ宣言しなければならない:
 http://ideone.com/R7twCQ

結果として、Python は手続き型プログラミングであれば簡潔で可読性に優れたコードが書けるスクリプト言語だけれど、
関数型プログラミングには適さず、こうした関数型プログラミングは推奨されていないらしい(これを "酸っぱい葡萄" と言ふ)
 http://peace.2ch.net/test/read.cgi/tech/1345123070/70-71

これが Swift や Ruby 等と比較すると、関数型プログラミングで Python が劣る典型的な一例になる
2014/12/10(水) 20:24:01.24ID:Q728OFWk
と言うかどう見てもこないだまでこのスレに居た俺俺定義の人ですな
2014/12/10(水) 20:43:29.64ID:Q728OFWk
よく見たら、そのスレで誘導かけてるの、話振ったお前本人じゃねーかw
俺俺定義が認められなかったから逃げて来たのか?
2014/12/10(水) 21:30:40.85ID:AwBDqpLr
クロージャの定義は>>4って書かれてたがStandard MLにラムダ式はない
けど当然SMLにはクロージャがあるわけで
ソースはThe Definition of Standard ML, revised edition
2014/12/10(水) 21:46:37.74ID:ZY5znPCs
関数型プログラミングってどういうのを指して言ってるんだろ
2014/12/10(水) 21:50:32.14ID:gkNqf6iG
>>189のサンプルが手続き型全開の書き方で笑った


>>193
関数(に名前付けたくない)型プログラミング
2014/12/11(木) 21:30:20.83ID:GpAyUabF
>>191
Swift スレの質問「Python が Swift や Ruby より劣ってるのは何か」に答えただけ
で、具体的に反論できないから罵倒を始めて Swift スレが荒れそうだったから、
こちらへ移動してきた


>>192
>>4 の定義において、局所環境やラムダ式は(クロージャという概念の構成要素であるけど)、
一般の言語だと直接的に対応する具象構文として存在していない(自分は知らない)
その書籍は読んでいないけど、おそらく Standard ML では "fn" <match> という具象構文を
「関数(function)」または「関数式(function expression)」と呼んでいると思う
>>4 だと、その具象構文 "fn" <match> はクロージャに対応する

またクロージャ(日本語では「閉包」)という用語は馴染みづらいので、
クロージャの具象構文を指して(便宜的に)無名関数/匿名関数/ラムダ関数/ラムダ式/関数式 ...etc と
別名で呼ばれることがある:
・Standard ML では、単純に「関数」や「関数式」と呼ぶ
・JavaScript では、"ECMAScript Specification" では(SML と同様に)「FunctionExpression」と呼ばれ、
 サイ本では「関数リテラル」と呼ばれている
  ・13 関数定義 (Function Definition) -- Under Translation of ECMA-262 3rd Edition
    http://www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/13_Function_Definition.html
・Python では、その言語リファレンスで「ラムダ式」と呼ばれている:
  ・6. 式 (expression) ― Python 3.4.2 ドキュメント
   http://docs.python.jp/3.4/reference/expressions.html#lambda
2014/12/11(木) 21:48:16.84ID:AENhOzwc
>>195
肝心のクロージャの定義の引用はまだですか?
俺俺定義はお腹いっぱいなんですよ
2014/12/11(木) 22:44:15.05ID:GpAyUabF
調べてみると、Python のラムダ式で任意の文が書けないという問題(>>189)は、
過去に何度もネット上で話題になっていたようだね:
・Is it possible to have multiple statements in a python lambda expression? - Stack Overflow (May 14 '09)
 http://stackoverflow.com/questions/862412/is-it-possible-to-have-multiple-statements-in-a-python-lambda-expression
・syntax - No Multiline Lambda in Python: Why not? - Stack Overflow (Aug 5 '09)
 http://stackoverflow.com/questions/1233448/no-multiline-lambda-in-python-why-not
・Why doesn't Python allow multi-line lambdas? - Programmers Stack Exchange (Aug 7 '11)
 http://programmers.stackexchange.com/questions/99243/why-doesnt-python-allow-multi-line-lambdas

そして、この問題を解決すべく数多くの提案が出された:
・AlternateLambdaSyntax - Python Wiki
 https://wiki.python.org/moin/AlternateLambdaSyntax

それら提案の中には、Ruby のブロックを真似しよう(similar to Ruby's blocks)、というものまであった
・[Python-ideas] Proposal for function expressions - Grokbase
 http://grokbase.com/t/python/python-ideas/097ccjz2c3/proposal-for-function-expressions

しかし残念ながら、これ以上続けても収束しそうもないから議論は打ち切り、とGuido氏が宣言(強権発動?)して終わった
・[Python-Dev] Let's just *keep* lambda
 https://mail.python.org/pipermail/python-dev/2006-February/060415.html
この顛末をGuido氏は「複数行のラムダは解けないパズル(unsolvable puzzle)」と語っている
・Language Design Is Not Just Solving Puzzles
 http://www.artima.com/weblogs/viewpost.jsp?thread=147358

まさに「みんなを納得させるほどの「結論」じゃない」というのは、こういう状況を指しているんだろね....
 http://peace.2ch.net/test/read.cgi/tech/1417333026/9
2014/12/11(木) 22:55:21.60ID:aWaBOmKM
>>189
普段Python書かないからPythonicではないかもしれないが、だいたいこんな感じだろう。
http://ideone.com/0vAET2

それで、何が問題なんだ?
2014/12/11(木) 23:02:23.22ID:GpAyUabF
>>196
ではクロージャ定義の引用元ソースを示そうね

答えは書籍「計算機プログラムの構造と解釈」、いわゆるSICP本だ
その中の節「3.2.1 評価の規則」に手続きオブジェクトが、いわゆるクロージャに対応する
 http://sicp.iijlab.net/fulltext/x321.html

そしてクロージャを視覚化したのが、
このページの図3.2にあるオタマジャクシの卵が2つ並んだ図形になる

単純な話だと思うけど、難しいかな?
2014/12/11(木) 23:27:50.83ID:GpAyUabF
>>198
関数を宣言せずに書くという制約の元ですから、とてもPythonらしいコードだと思います
しかもループの代わりに関数再帰を使っているのですから、より関数型プログラミングらしいとも言えます

ただし、元々 Swift で書かれていたサンプルコードを各 LL へと書き直しているのですから、
もし以下の点を改善できれば(Pythonらしさという意味では)完璧でしょう:
・中間変数 f を宣言せず、リスト内包式の中にラムダ式をインラインで書く
・Swift のコードは辞書を使っているのですから、それを(勝手に)配列 digits へ改変せず、
 Python でも(Ruby や JavaScript と同様に)辞書を使って書く
2014/12/12(金) 00:10:51.51ID:kNbqUbaQ
>>200
注文が多いな。
http://ideone.com/KWnSgA
2014/12/12(金) 09:01:50.64ID:hLblKLHb
>>199
で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?
「Schemeという特定の言語」で「クロージャはlambda式で作られる」と書いてあるだけだが?

いい加減、誤摩化して逃げ回るのは止めたら?
2014/12/12(金) 19:05:12.73ID:1wfis/cT
別にPythonのラムダに式が書けないから問題だと言うだけなら荒れねーよ
そこで「だからPythonにはクロージャが無い」って言う
決して成り立たない等式を持ち込むから「いやそのりくつはおかしい」って言われてんのに
そしたら既存のクロージャという用語の定義のほうを弄ろうとするから叩かれてんだろうが

プログラミングに例えるなら、お前は自分の書いた関数で
組み込み整数型の値にそのままリスト処理を適用しようとして例外吐かれたから、と
整数クラスのほうがリストとして振る舞うようにメソッドを書き換えようとしてる
2014/12/12(金) 22:20:24.14ID:ZYnyJXBo
>>201
お疲れさまです
中間変数 f は消えましたが、今度は中間変数 applyf が現れてしまいましたね....
2014/12/12(金) 22:38:08.46ID:hhr7pvhS
>>204
http://ideone.com/zAN4uA
2014/12/12(金) 22:42:02.66ID:hLblKLHb
>>204
とりあえずクロージャの定義を貼っておきますね
反論よろしく

https://www.princeton.edu/~achaney/tmve/wiki100k/docs/Closure_(computer_science).html


> In computer science, a closure is a first-class function with free variables that are bound in the lexical environment.


ここの文章も良く読んでね

> The term closure is often mistakenly used to mean anonymous function.
> This is probably because most languages implementing anonymous functions allow them
> to form closures and programmers are usually introduced to both concepts at the same time.
> These are, however, distinct concepts.
2014/12/12(金) 23:33:45.85ID:ZYnyJXBo
>>202
> で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?

もちろん「クロージャは無名関数でなければダメ」とは書かれていない
同時に「ラムダ式に文が書かなくともクロージャである」とも書かれていない
SICP本を理解するには、記述されている定義から類推によって解釈できる知性が必要だね


>「Schemeという特定の言語」で「クロージャはlambda式で作られる」と書いてあるだけだが?

この節で記述されているのはクロージャの一般的な概念であり、特定の言語や実装には限定されない
ここで記述されている概念に沿って設計された言語であれば、たとえば:
・Scheme なら (lambda (x) .... ) で、
・Standard ML なら fn x => .... で、
・JavaScript なら function(x) { ..... } で、
・Ruby なら proc { |x| .... } で作られる
ここで.... の部分には、破壊的代入や入出力等の副作用を伴う任意のコードが書ける
唯一、書けないのは Python だけ

で、どこに「Schemeという特定の言語」と書いてあるの?
いい加減、誤摩化して言い逃れをするのは止めたら?
2014/12/12(金) 23:54:36.75ID:ZYnyJXBo
>>205
ありがとうございます、これで完璧ですね

これで「何が問題なんだ?(>>198)」という議論を続けることができます
具体的には、>>189 の Swift/Ruby/JavaScript で書かれたコードと
>>205 の Python で書かれたコードを比較して、
「どちらがわかりやすいか/読みやすいか/書きやすいか?」という話です

で、これらは主観による評価ですから、
いくら議論しても誰もが納得できる結論へとは収束しないでしょう
すべての Pythonista にとって >>205 が読みやすく書きやすいと感じるのなら、
それはそれでいいんじゃないでしょうか
2014/12/13(土) 00:01:46.30ID:HrrHquek
一時変数を消すためにそんなパズルみたいな事やって読みやすいわけないだろw
2014/12/13(土) 00:13:09.40ID:HrrHquek
>>207
schemeではlambdaが本質的なもので(define (f x) 〜)はシンタックスシュガーだけど、
pythonではdefが本質的なものでlambdaの方がシンタックスシュガーなのでは。
2014/12/13(土) 00:39:02.24ID:gzcIElev
>>206
Wikipedia 英語版の解説と同じに見えるけど、何を言いたいのかな?
・Closure (computer programming) - Wikipedia, the free encyclopedia
 http://en.wikipedia.org/wiki/Closure_(computer_programming)
単に他人の文書をコピペして終わりにするだけでなく、引用した文書(ソース)を元に、
自分なりの意見を思考しそれを自分の文章として表現できるようになったほうがいいと思う


で、とりあえず反論しておくと、その文書(= Wikipedia)の
章「mplementation and theory」には、冒頭に以下の記述がある

> Closures are typically implemented with a special data structure that
> contains a pointer to the function code, plus a representation of
> the function's lexical environment (i.e., the set of available variables)
> at the time when the closure was created.

この理論としてのクロージャ定義は、SICP本(>>119) および >>4 のそれと矛盾していない
そして Haskell のような純粋関数型言語に限定した文脈ではないのだから、
文中の "function code" は(>>207 で書いたように)単なる式だけではなく
破壊的代入や入出力等の副作用を伴う任意のコードも書けると解釈するのが自然だと考える
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況