関数型言語に必ずくっついてるこれ
いらんでしょ?匿名クラスで充分でしょ
探検
クロージャって何がいいの? [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2014/11/08(土) 13:11:47.84ID:6V2MLUHb213デフォルトの名無しさん
2014/12/13(土) 02:13:23.84ID:6/3yjF6w foo = lambda bar: bar
これはクロージャである
っていうのが偽であることを定義から証明すればいいんじゃないかな
反例あげればいいだけだよね?
これはクロージャである
っていうのが偽であることを定義から証明すればいいんじゃないかな
反例あげればいいだけだよね?
214デフォルトの名無しさん
2014/12/13(土) 02:17:02.89ID:6/3yjF6w あ、まちがえたそれはクロージャじゃない
def foo():
bar = 1
これに訂正
def foo():
bar = 1
これに訂正
215デフォルトの名無しさん
2014/12/13(土) 07:14:46.97ID:toJAZvUP216デフォルトの名無しさん
2014/12/13(土) 08:00:50.00ID:1EyzOdES217デフォルトの名無しさん
2014/12/13(土) 10:42:15.83ID:ygYpq94K イデオンこわい
2014/12/13(土) 12:26:47.45ID:sGDpUYPr
>>207
> もちろん「クロージャは無名関数でなければダメ」とは書かれていない
なんだ、Pythonのdefで良かったんだ
知らないみたいだから教えてあげるけど、Pythonではdefで関数定義すると
環境を持ったクロージャになってるんだよ、勉強になったね
> もちろん「クロージャは無名関数でなければダメ」とは書かれていない
なんだ、Pythonのdefで良かったんだ
知らないみたいだから教えてあげるけど、Pythonではdefで関数定義すると
環境を持ったクロージャになってるんだよ、勉強になったね
2014/12/13(土) 12:40:53.92ID:sGDpUYPr
2014/12/13(土) 14:05:13.26ID:ZLG0O37u
>>207
書かれてない要素を勝手に追加するから
オレオレ定義って言われるんだよ
クロージャの定義には無名関数であることも、文が書けるor書けないことも、
含まれてないんたから、勝手に条件に追加すんな
書かれてない要素を勝手に追加するから
オレオレ定義って言われるんだよ
クロージャの定義には無名関数であることも、文が書けるor書けないことも、
含まれてないんたから、勝手に条件に追加すんな
2014/12/13(土) 14:39:36.41ID:1EyzOdES
2014/12/13(土) 20:13:18.59ID:gzcIElev
>>210
本質という言葉の定義が曖昧ですが、自分なりにコメントします
まず >>206(= Wikipedia, >>211)の章「2.1 First-class functions」には、
その冒頭に以下の記述があります
> Closures typically appear in languages in which functions are first-class values ―
> in other words, such languages enable functions to be passed as arguments,
> returned from function calls, bound to variable names, etc.,
> just like simpler types such as strings and integers.
つまりクロージャは「一級の値( first-class values)」であると定義しています
従って(一級市民ではない関数宣言 def よりも)一級市民であるクロージャ lambda を
本質とするのが正しいのではないかと思います
(「宣言された関数は一級市民だけど、宣言そのものはそうではない」という意味です、念の為)
(あくまで私見ですが)可能性があるのは、関数スコープ方式の手続き型言語である Python では、
関数型言語の特性を追加する際にクロージャを(lamda ではなく)宣言された関数へ実装したほうが
(開発工数や難易度の視点からは)容易だったのではないかと推測します(詳細は省略....)
一言で言えば「Python は手続き型言語だから」ということですね
本質という言葉の定義が曖昧ですが、自分なりにコメントします
まず >>206(= Wikipedia, >>211)の章「2.1 First-class functions」には、
その冒頭に以下の記述があります
> Closures typically appear in languages in which functions are first-class values ―
> in other words, such languages enable functions to be passed as arguments,
> returned from function calls, bound to variable names, etc.,
> just like simpler types such as strings and integers.
つまりクロージャは「一級の値( first-class values)」であると定義しています
従って(一級市民ではない関数宣言 def よりも)一級市民であるクロージャ lambda を
本質とするのが正しいのではないかと思います
(「宣言された関数は一級市民だけど、宣言そのものはそうではない」という意味です、念の為)
(あくまで私見ですが)可能性があるのは、関数スコープ方式の手続き型言語である Python では、
関数型言語の特性を追加する際にクロージャを(lamda ではなく)宣言された関数へ実装したほうが
(開発工数や難易度の視点からは)容易だったのではないかと推測します(詳細は省略....)
一言で言えば「Python は手続き型言語だから」ということですね
2014/12/13(土) 20:39:14.11ID:HrrHquek
>>222
本質的ってのは、よりプリミティブなものっていう意味で書いたんだよ。
first-class valueってのは、変数に代入したり、関数の引数に渡したり、
関数の値として返したりできるオブジェクトの事だよ。
def だの lambda だのっていうのはそういうオブジェクトであるクロージャを作り出すための構文だよ。
pythonは手続き型言語だっていうけど、そんなの当たり前だろw
rubyだのjavascriptだのだって手続型言語だよ。
本質的ってのは、よりプリミティブなものっていう意味で書いたんだよ。
first-class valueってのは、変数に代入したり、関数の引数に渡したり、
関数の値として返したりできるオブジェクトの事だよ。
def だの lambda だのっていうのはそういうオブジェクトであるクロージャを作り出すための構文だよ。
pythonは手続き型言語だっていうけど、そんなの当たり前だろw
rubyだのjavascriptだのだって手続型言語だよ。
2014/12/13(土) 21:42:39.17ID:gzcIElev
>>223
> 本質的ってのは、よりプリミティブなものっていう意味で書いたんだよ。
その意味であれば、関数型言語と Ruby/JavaScript だと
関数定義よりもクロージャのほうがが本質的だね
プリミティブな名前とクロージャから関数(or メソッド)が作られるという
因果関係があるのだから
ただし、Python だけは違うみたいだね
> rubyだのjavascriptだのだって手続型言語だよ。
外見は手続き型言語だけど、どちらの言語もLISPをベースに設計されている
だから最初から関数型言語と同等なクロージャを備えて誕生した
それが知られるようになったのは最近だから、知らない人は多いけどね.....
手続き型言語として生まれ、後付けで関数型を増築した Python とは違うのだよ
http://peace.2ch.net/test/read.cgi/tech/1409526637/857
--
> パクリどころか Ruby と JavaScript は、これらの作者自身が
> Lisp を基礎として言語を設計したと語っている
>
> ・Lisp から Ruby への設計ステップ
> http://yohshiy.blog.fc2.com/blog-entry-250.html
> ・JavaScript: The World's Most Misunderstood Programming Language
> http://www.crockford.com/javascript/javascript.html
> (邦訳版「JavaScriptの勉強:世界で最も誤解されたプログラミング言語」へのリンクは閉鎖)
>
> だから関数型プログラミングという土俵の上で Ruby や JavaScript に
> 手続き型言語の Python がいくら挑戦しても勝てずに負け続けているのは、
> しごく当然な結果なわけ
> 本質的ってのは、よりプリミティブなものっていう意味で書いたんだよ。
その意味であれば、関数型言語と Ruby/JavaScript だと
関数定義よりもクロージャのほうがが本質的だね
プリミティブな名前とクロージャから関数(or メソッド)が作られるという
因果関係があるのだから
ただし、Python だけは違うみたいだね
> rubyだのjavascriptだのだって手続型言語だよ。
外見は手続き型言語だけど、どちらの言語もLISPをベースに設計されている
だから最初から関数型言語と同等なクロージャを備えて誕生した
それが知られるようになったのは最近だから、知らない人は多いけどね.....
手続き型言語として生まれ、後付けで関数型を増築した Python とは違うのだよ
http://peace.2ch.net/test/read.cgi/tech/1409526637/857
--
> パクリどころか Ruby と JavaScript は、これらの作者自身が
> Lisp を基礎として言語を設計したと語っている
>
> ・Lisp から Ruby への設計ステップ
> http://yohshiy.blog.fc2.com/blog-entry-250.html
> ・JavaScript: The World's Most Misunderstood Programming Language
> http://www.crockford.com/javascript/javascript.html
> (邦訳版「JavaScriptの勉強:世界で最も誤解されたプログラミング言語」へのリンクは閉鎖)
>
> だから関数型プログラミングという土俵の上で Ruby や JavaScript に
> 手続き型言語の Python がいくら挑戦しても勝てずに負け続けているのは、
> しごく当然な結果なわけ
2014/12/13(土) 22:07:55.30ID:HrrHquek
>外見は手続き型言語だけど、どちらの言語もLISPをベースに設計されている
S式で表現されてなきゃlispじゃねえよ。
S式で表現されてなきゃlispじゃねえよ。
2014/12/13(土) 22:14:57.19ID:HrrHquek
だいたいlispが関数型言語だって言うことにも抵抗がある。
2014/12/13(土) 23:06:18.71ID:gzcIElev
>>224
>手続き型言語として生まれ、後付けで関数型を増築した Python とは違うのだよ
自己レスで補足する(すべての手続き型言語が Python と同じではない....
同じ手続き型言語に関数型の特性を追加した言語でも、
調べた範囲だと少なくとも Perl5/Java8/C++11 のクロージャは
・>>4,>>119 のクロージャ定義に沿って設計され、
・クロージャ内で任意の文が書ける
ただしそれら言語がクロージャをサポートした時期は遅かった
真面目に設計したからだろう
対して Python の関数型サポートは素早かったけど、検討が不十分だったと言うほかない
リリース後に改善要望/議論紛糾したあげく、結論を出せず現在に到る(>>197)
>手続き型言語として生まれ、後付けで関数型を増築した Python とは違うのだよ
自己レスで補足する(すべての手続き型言語が Python と同じではない....
同じ手続き型言語に関数型の特性を追加した言語でも、
調べた範囲だと少なくとも Perl5/Java8/C++11 のクロージャは
・>>4,>>119 のクロージャ定義に沿って設計され、
・クロージャ内で任意の文が書ける
ただしそれら言語がクロージャをサポートした時期は遅かった
真面目に設計したからだろう
対して Python の関数型サポートは素早かったけど、検討が不十分だったと言うほかない
リリース後に改善要望/議論紛糾したあげく、結論を出せず現在に到る(>>197)
2014/12/13(土) 23:27:26.05ID:fdPKe7oz
横だけど、
Rubyのブロックはラムダじゃないしファーストクラスでもないよね
?
メソッドにラムダを渡すこともできるけど、不格好なんだが?
これって、ここのオレオレ定義にてらすとどうなの?
なんだか、ラムダに文を書けない(書かない)ようにしている
Pythonの仕様をあげつらうためだけにオレオレ定義をこねくって
悦に入ってるPythonアンチがいるって感じがするだけなんだが。
Rubyのブロックはラムダじゃないしファーストクラスでもないよね
?
メソッドにラムダを渡すこともできるけど、不格好なんだが?
これって、ここのオレオレ定義にてらすとどうなの?
なんだか、ラムダに文を書けない(書かない)ようにしている
Pythonの仕様をあげつらうためだけにオレオレ定義をこねくって
悦に入ってるPythonアンチがいるって感じがするだけなんだが。
229デフォルトの名無しさん
2014/12/14(日) 00:01:22.20ID:Gw1grNBM Rubyのブロックの中に副作用をジャンジャン書いて
それを繋げるスタイルを関数型と言われても困るわ
文推奨の時点で関数型とは言い難いわけだし
それを繋げるスタイルを関数型と言われても困るわ
文推奨の時点で関数型とは言い難いわけだし
230デフォルトの名無しさん
2014/12/14(日) 00:38:38.65ID:iRnVJ1/v オレオレクロージャ君は言葉が通じないし、
必死でググった的外れで糞長い引用でしか反応しないし、
相手するだけ無駄。
必死でググった的外れで糞長い引用でしか反応しないし、
相手するだけ無駄。
231デフォルトの名無しさん
2014/12/14(日) 02:05:45.83ID:sl2oQCLD うん、ただのPythonアンチでしか無いと思うよ。
Ruby好きでPython嫌いな俺は、Pythonのlambdaが使いにくいのには同意するが
そのためにクロージャの定義のほうを捻じ曲げるのは、ありえないと感じるよ。
そもそも、その定義だとRubyどーなんねん、と思うし。
Rubyには「他言語の関数」に相当するものがなく、
一定の条件を満たし、見かけ上、関数のような呼び出しが可能なメソッドを
便宜的に「関数」と呼んでいるだけだし。
クロージャはブロックという形で存在はしているが、
彼の言う定義に従うならブロックはファーストクラスでなければならない。
でもRubyのブロックはファーストクラスとは言い難い。
lambda関数(実際はもちろんメソッド)が返すのはProcクラスのインスタンスだけれども、
ブロック.is_a? Procインスタンス では無い。そしてメソッドや、ましてや関数でもない。
そもそもブロック単体では値としては取り回せないからProcクラスがあるんだし。
Ruby好きでPython嫌いな俺は、Pythonのlambdaが使いにくいのには同意するが
そのためにクロージャの定義のほうを捻じ曲げるのは、ありえないと感じるよ。
そもそも、その定義だとRubyどーなんねん、と思うし。
Rubyには「他言語の関数」に相当するものがなく、
一定の条件を満たし、見かけ上、関数のような呼び出しが可能なメソッドを
便宜的に「関数」と呼んでいるだけだし。
クロージャはブロックという形で存在はしているが、
彼の言う定義に従うならブロックはファーストクラスでなければならない。
でもRubyのブロックはファーストクラスとは言い難い。
lambda関数(実際はもちろんメソッド)が返すのはProcクラスのインスタンスだけれども、
ブロック.is_a? Procインスタンス では無い。そしてメソッドや、ましてや関数でもない。
そもそもブロック単体では値としては取り回せないからProcクラスがあるんだし。
2014/12/14(日) 10:29:16.99ID:63H3dBz7
オレオレクロージャ君って少し前に某スレでPython disってた人にそっくり
2014/12/14(日) 14:05:17.21ID:2A/iPobJ
lambda
ラ…ランバダ…
ラ…ランバダ…
2014/12/14(日) 14:52:29.83ID:VBy2GaOL
2014/12/14(日) 15:49:06.80ID:hNeAViIY
,-----、
/ ヽ.
| (・) (・) |
/ヽ ̄  ̄ノヽ
/ ヽ_____/ ヽ
| / l | |\
| | 。ノ ヽ。 .|___| \
ヽ___ヽ + ノ,、_、_、_ヽ \
| ヽ| ̄ ̄ ̄ ̄ | ;;;;;;;;;;;;;;;\_ ノ
< ````/\ /\;;;;;;;;;;;;;;;;;/
ヽ;;;;;;| \_/ ヽ;;;;;;;;;;;ノ
 ̄.|___/ \__) ̄ .____
/ | | | \ /
(___| |__)===⊃
勇者の父 ランバダ
/ ヽ.
| (・) (・) |
/ヽ ̄  ̄ノヽ
/ ヽ_____/ ヽ
| / l | |\
| | 。ノ ヽ。 .|___| \
ヽ___ヽ + ノ,、_、_、_ヽ \
| ヽ| ̄ ̄ ̄ ̄ | ;;;;;;;;;;;;;;;\_ ノ
< ````/\ /\;;;;;;;;;;;;;;;;;/
ヽ;;;;;;| \_/ ヽ;;;;;;;;;;;ノ
 ̄.|___/ \__) ̄ .____
/ | | | \ /
(___| |__)===⊃
勇者の父 ランバダ
2014/12/14(日) 15:54:41.51ID:KqwrXZGg
無駄にMP消費していざという時に足りなくなって犬死にする無能
237デフォルトの名無しさん
2014/12/14(日) 20:48:34.17ID:lkA9lgpO >>228
>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(>>199) の関数型言語におけるクロージャ定義に当てはめれば
「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 のクロージャ定義の引用元(ソース)は >>199 で示したが、まともな反論はない
むしろオレオレ定義と騒ぎ立てていた連中がSICP本を読んだ事もないお馬鹿達だったのでは?
あるいはSICP本を読んでいなくても、関数型言語の操作的意味論や処理系実装の知識があれば
>>4 がオレオレ定義でないことは直ぐに理解できていたはず
>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(>>199) の関数型言語におけるクロージャ定義に当てはめれば
「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 のクロージャ定義の引用元(ソース)は >>199 で示したが、まともな反論はない
むしろオレオレ定義と騒ぎ立てていた連中がSICP本を読んだ事もないお馬鹿達だったのでは?
あるいはSICP本を読んでいなくても、関数型言語の操作的意味論や処理系実装の知識があれば
>>4 がオレオレ定義でないことは直ぐに理解できていたはず
238デフォルトの名無しさん
2014/12/14(日) 21:10:51.70ID:Gw1grNBM239デフォルトの名無しさん
2014/12/14(日) 21:42:31.25ID:k3gK/GUJ240デフォルトの名無しさん
2014/12/14(日) 21:59:53.72ID:Y1wljoB2 Rubyistは全員クロージャを間違った解釈してるのか?
それとも、奴だけなのか?
そこが気になるな。
それとも、奴だけなのか?
そこが気になるな。
241デフォルトの名無しさん
2014/12/14(日) 22:03:54.59ID:lkA9lgpO >>229
残念ながら Ruby の関数型プログラミングというスタイルは、
全世界の Ruby コミュニティですでに認知されている
・Functional programming with Ruby
http://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
http://www.atmarkit.co.jp/ait/articles/1404/30/news017_2.html
個人的には、Ruby と多くのOOP言語で採用されているメソッドチェーン・スタイルは:
・データの流れ(いわゆるデータフロー)とメソッドの並びが一致し、
・カッコが入れ子にならない
から、可読性が高いと思う
table.select { |r| .... }.map { |r| .... }.inject(0) { |n, r| .... } # >>189 を参照
それに対して、Python 伝統的な関数適用スタイルでは:
・データの流れ(いわゆるデータフロー)とメソッドの並びが逆転し、
・カッコが入れ子になる
reduce(lambda n, r: ...., 0, map(lambda r: ...., filter(lambda r: ...., table)))
どちらを優れているか?という評価は主観だから、各自で判断してもらいたい
(まだ続くので、ここで切る)
残念ながら Ruby の関数型プログラミングというスタイルは、
全世界の Ruby コミュニティですでに認知されている
・Functional programming with Ruby
http://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
http://www.atmarkit.co.jp/ait/articles/1404/30/news017_2.html
個人的には、Ruby と多くのOOP言語で採用されているメソッドチェーン・スタイルは:
・データの流れ(いわゆるデータフロー)とメソッドの並びが一致し、
・カッコが入れ子にならない
から、可読性が高いと思う
table.select { |r| .... }.map { |r| .... }.inject(0) { |n, r| .... } # >>189 を参照
それに対して、Python 伝統的な関数適用スタイルでは:
・データの流れ(いわゆるデータフロー)とメソッドの並びが逆転し、
・カッコが入れ子になる
reduce(lambda n, r: ...., 0, map(lambda r: ...., filter(lambda r: ...., table)))
どちらを優れているか?という評価は主観だから、各自で判断してもらいたい
(まだ続くので、ここで切る)
242デフォルトの名無しさん
2014/12/14(日) 22:48:49.10ID:lkA9lgpO >>238
次に、関数型プログラミングと(文の評価によって起こる)副作用との関連について
まず関数型プログラミングで副作用は推奨されていない
基本的には map/filter/reduce (Ruby では map/select/inject) といった高階関数を使った
(副作用の無い)参照透明性のあるコードが推奨されている
これは >>241 の文書「Rubyによる関数型プログラミング」で具体的なコード例を使って解説されている
おそらく誤解したのは >>189 の Swift/Ruby/JavaScript コードで while 文と
ローカル変数への破壊的代入を用いていたのを見たからだと思うけど、
これは、「わざわざ」副作用を使った手続き型プログラミングほうが簡潔になる「お題」を選んだからだ
実際、副作用の代わりに再帰を使った Python コード >>205 は「普通のプログラマ」には分かりにくい
(Python だけでなく、この「お題」は Ruby であっても再帰を使えば同じく分かりにくいコードになる)
また(Ruby を含む)大半の手続き型言語処理系だと、TCO(末尾再帰最適化)は実装されていないか不完全である
だから手続き型言語における関数型プログラミングにおいて、
再帰プログラミングには(分かりづらいだけでなく)実用上の制限があるから
ツリーのような再帰的データ構造の探索問題などに限定して利用すべき(上記文書の節「再帰」を参照)
これらの判断について、上記の文書では以下のように記述されている(節「おわりに」から引用):
「Rubyは基本的には命令型言語であるけれど、 関数型プログラミングへの際立った潜在能力があるのだから、
それらをいつどのように使うか(そして、いつ使わないか)を知っておくべきである。 」
次に、関数型プログラミングと(文の評価によって起こる)副作用との関連について
まず関数型プログラミングで副作用は推奨されていない
基本的には map/filter/reduce (Ruby では map/select/inject) といった高階関数を使った
(副作用の無い)参照透明性のあるコードが推奨されている
これは >>241 の文書「Rubyによる関数型プログラミング」で具体的なコード例を使って解説されている
おそらく誤解したのは >>189 の Swift/Ruby/JavaScript コードで while 文と
ローカル変数への破壊的代入を用いていたのを見たからだと思うけど、
これは、「わざわざ」副作用を使った手続き型プログラミングほうが簡潔になる「お題」を選んだからだ
実際、副作用の代わりに再帰を使った Python コード >>205 は「普通のプログラマ」には分かりにくい
(Python だけでなく、この「お題」は Ruby であっても再帰を使えば同じく分かりにくいコードになる)
また(Ruby を含む)大半の手続き型言語処理系だと、TCO(末尾再帰最適化)は実装されていないか不完全である
だから手続き型言語における関数型プログラミングにおいて、
再帰プログラミングには(分かりづらいだけでなく)実用上の制限があるから
ツリーのような再帰的データ構造の探索問題などに限定して利用すべき(上記文書の節「再帰」を参照)
これらの判断について、上記の文書では以下のように記述されている(節「おわりに」から引用):
「Rubyは基本的には命令型言語であるけれど、 関数型プログラミングへの際立った潜在能力があるのだから、
それらをいつどのように使うか(そして、いつ使わないか)を知っておくべきである。 」
243デフォルトの名無しさん
2014/12/14(日) 22:59:19.75ID:iRnVJ1/v もうみんなgaucheに改宗しようぜ
244デフォルトの名無しさん
2014/12/14(日) 23:34:55.92ID:lkA9lgpO >>231
>Rubyには「他言語の関数」に相当するものがなく、......
これは(>>237 に書いたけど)、まったくそのとおり
>でもRubyのブロックはファーストクラスとは言い難い。
ここの「....とは言い難い」という文章表現は曖昧だね
(なぜ「....ではない」と断定的に言い切れなかったのだろうか?)
まず >>237 で書いたように、Ruby の「ブロック付きメソッド呼び出し」は構文糖だ
(対して、簡潔な構文を追求した Smalltalk では、常にブロックはオブジェクトである)
これを構文糖にした理由の一つはメソッド呼び出しコードを簡潔にする目的(>>237)であるが、
ブロックを多用する Ruby のプログラミングスタイルでは、ブロックを評価するたびに
Procオブジェクトを生成していたのでは実行効率の面でオーバヘッドが大きいという理由がある
このためRubyインタプリタの内部だと、
ブロックは(重いオブジェクトを表すC構造体ではなく)専用の軽量なC構造体で表現されている
ただし、(たとえ内部表現が Proc オブジェクトと異なっていても)プログラマから見れば問題にならない
なぜなら、渡されたブロックをいつでも Proc オブジェクトへ変換できる構文糖が最初から用意されているから....
たとえば foo(x, y) { |z| .... } という「ブロック付きメソッド呼び出し」に対して(>>237):
・def foo(x, y); .... ; end
・def foo(x, y, &block); .... ; end
という2つのメソッド定義は「いつでも」交換できる
まとめると:
Ruby のブロックは内部表現だと Proc オブジェクトではないが、
プログラマ目線ではファーストクラスのオブジェクトとして扱うことができる
>Rubyには「他言語の関数」に相当するものがなく、......
これは(>>237 に書いたけど)、まったくそのとおり
>でもRubyのブロックはファーストクラスとは言い難い。
ここの「....とは言い難い」という文章表現は曖昧だね
(なぜ「....ではない」と断定的に言い切れなかったのだろうか?)
まず >>237 で書いたように、Ruby の「ブロック付きメソッド呼び出し」は構文糖だ
(対して、簡潔な構文を追求した Smalltalk では、常にブロックはオブジェクトである)
これを構文糖にした理由の一つはメソッド呼び出しコードを簡潔にする目的(>>237)であるが、
ブロックを多用する Ruby のプログラミングスタイルでは、ブロックを評価するたびに
Procオブジェクトを生成していたのでは実行効率の面でオーバヘッドが大きいという理由がある
このためRubyインタプリタの内部だと、
ブロックは(重いオブジェクトを表すC構造体ではなく)専用の軽量なC構造体で表現されている
ただし、(たとえ内部表現が Proc オブジェクトと異なっていても)プログラマから見れば問題にならない
なぜなら、渡されたブロックをいつでも Proc オブジェクトへ変換できる構文糖が最初から用意されているから....
たとえば foo(x, y) { |z| .... } という「ブロック付きメソッド呼び出し」に対して(>>237):
・def foo(x, y); .... ; end
・def foo(x, y, &block); .... ; end
という2つのメソッド定義は「いつでも」交換できる
まとめると:
Ruby のブロックは内部表現だと Proc オブジェクトではないが、
プログラマ目線ではファーストクラスのオブジェクトとして扱うことができる
245デフォルトの名無しさん
2014/12/14(日) 23:42:14.32ID:NejhiS1a gaucheいいよね
246デフォルトの名無しさん
2014/12/14(日) 23:49:27.85ID:lkA9lgpO247デフォルトの名無しさん
2014/12/14(日) 23:57:54.55ID:pRYhwT4i 最近はほぼgaucheでしかプログラム書いてない。
もう止められない体になってしまった。。。
もう止められない体になってしまった。。。
248デフォルトの名無しさん
2014/12/14(日) 23:58:44.82ID:iRnVJ1/v 俺、numpyとscipyとopencvのサポートがgaucheにくっ付いたら、python捨てるんだ!(遠い目
249デフォルトの名無しさん
2014/12/15(月) 00:02:02.47ID:wtT+wvpm common lisp処理系の方が速いのあるしライブラリも充実してるし良いよ
250デフォルトの名無しさん
2014/12/15(月) 00:07:51.10ID:G9R+2lJx ループしないで全部再帰で書きたい
251デフォルトの名無しさん
2014/12/15(月) 00:08:50.51ID:YlFhPVoF lisp-2なのが何となく嫌
252デフォルトの名無しさん
2014/12/15(月) 00:31:53.12ID:K7E8QpHY >>250 いいよ
253デフォルトの名無しさん
2014/12/15(月) 08:42:12.40ID:J0ddkTzC >>246
だってRubyなんてマイナー言語どうでも良いし?
だってRubyなんてマイナー言語どうでも良いし?
254デフォルトの名無しさん
2014/12/15(月) 11:24:34.16ID:yMEZ5G45 >>240
こいつだけです。と言うかRubyに対しての知見も怪しい
>>244
Rubyのブロック付きメソッド呼び出しのほうを構文糖と。またオレオレ定義?
「ブロック付きメソッド呼び出し」は文法だ、これはlambdaより先に実装されてる
そのブロック部分のみを扱うためにProcクラスもlambdaより先に実装されていて、
そのProcを簡便に扱うためにlambdaと言う構文糖が後から出来た
と言うか「ブロック付きメソッド呼び出し」、昔は「イテレータ呼び出し」だった
イテレータ呼び出しを汎化した結果生まれたのが、ブロック付きメソッド呼び出し
その時代からmapやselectなどの
今で言う関数型的なメソッド群を実装するモジュールEnumerableは
「これをincludeするクラスにはeachメソッドを実装すること」としていた
もしRubyが関数型として設計されていてProcが主なら
call必須なんてことにはしなかっただろうし
関数がメソッドの一種なんてことにはなってない
そしてEnumerableはeachではなく、Array辺りを要求する高階関数群だっただろう
RubyはOOPLとして設計され、それが主で
関数型プログラミングは結果として付いてきた
そこでProcに関数型のラムダ的な挙動を付加し生成するlambdaも出来たんだよ
こいつだけです。と言うかRubyに対しての知見も怪しい
>>244
Rubyのブロック付きメソッド呼び出しのほうを構文糖と。またオレオレ定義?
「ブロック付きメソッド呼び出し」は文法だ、これはlambdaより先に実装されてる
そのブロック部分のみを扱うためにProcクラスもlambdaより先に実装されていて、
そのProcを簡便に扱うためにlambdaと言う構文糖が後から出来た
と言うか「ブロック付きメソッド呼び出し」、昔は「イテレータ呼び出し」だった
イテレータ呼び出しを汎化した結果生まれたのが、ブロック付きメソッド呼び出し
その時代からmapやselectなどの
今で言う関数型的なメソッド群を実装するモジュールEnumerableは
「これをincludeするクラスにはeachメソッドを実装すること」としていた
もしRubyが関数型として設計されていてProcが主なら
call必須なんてことにはしなかっただろうし
関数がメソッドの一種なんてことにはなってない
そしてEnumerableはeachではなく、Array辺りを要求する高階関数群だっただろう
RubyはOOPLとして設計され、それが主で
関数型プログラミングは結果として付いてきた
そこでProcに関数型のラムダ的な挙動を付加し生成するlambdaも出来たんだよ
255デフォルトの名無しさん
2014/12/15(月) 20:13:34.89ID:AoWRRy2d >>241
> また Ruby の「ブロック付きメソッド呼び出し」とそれらを並べる(=チェーンさせる)スタイルは、
> Apple の新言語である Swift にそのまま採用された
Obj-C が inline Smalltalk が書ける C なのに、Swift が Ruby をまねたみたいなデマはやめてくれる?
それと、 Ruby で関数型スタイルのプログラムを書けるということを、Ruby で書いたら関数型プログラムになるかのように書くのもやめてくれる?
> また Ruby の「ブロック付きメソッド呼び出し」とそれらを並べる(=チェーンさせる)スタイルは、
> Apple の新言語である Swift にそのまま採用された
Obj-C が inline Smalltalk が書ける C なのに、Swift が Ruby をまねたみたいなデマはやめてくれる?
それと、 Ruby で関数型スタイルのプログラムを書けるということを、Ruby で書いたら関数型プログラムになるかのように書くのもやめてくれる?
256デフォルトの名無しさん
2014/12/15(月) 21:18:41.61ID:QjagSoag 主観を事実であるかのように語る客観性の無さ
オレオレ定義の根拠を問われて自身の過去の書き込みを引用するコミュニケーション不全
完全に論破されると、自分の間違った主張を相手が言い出したと歴史歪曲しようとする卑怯さ
全てを兼ね備えると>>241みたいな奴になる
オレオレ定義の根拠を問われて自身の過去の書き込みを引用するコミュニケーション不全
完全に論破されると、自分の間違った主張を相手が言い出したと歴史歪曲しようとする卑怯さ
全てを兼ね備えると>>241みたいな奴になる
257デフォルトの名無しさん
2014/12/15(月) 22:27:41.97ID:eMlPsgxM >>254
>そのブロック部分のみを扱うためにProcクラスもlambdaより先に実装されていて、
>そのProcを簡便に扱うためにlambdaと言う構文糖が後から出来た
lambda はメソッドであって、構文糖ではない
>>231 では「もちろん(lamda は)メソッド」と主張しているから、もしも同一人物のカキコなら矛盾している
いったいどちらが正しいの?
>イテレータ呼び出しを汎化した結果生まれたのが、ブロック付きメソッド呼び出し
その「汎化」とは具体的には何を指しているのかな?
もともとイテレータという概念と用語は手続き型言語 CLU で生まれ、Ruby でも採用された
ただし CLU のイテレータは for ... in 構文というループ処理での利用に制限されたのに対して、
(クロージャとしての)ブロックを備えた Ruby ではループ処理以外にも利用できる形で「最初から設計された」
・Rubyist のための他言語探訪 【第 2 回】 CLU
http://magazine.rubyist.net/?0009-Legwork
このためループ処理でもないのにイテレータ(iterator, 反復子)という用語は紛らわしいという声が挙り、
用語「イテレータ呼び出し」は「ブロック付きメソッド呼び出し」へと名称が「後から変更された」
つまり単に用語の命名が「後から」改められだけで、言語仕様の基本は「最初から」何も変わっていないはずです
>RubyはOOPLとして設計され、それが主で関数型プログラミングは結果として付いてきた
スマンが、いいかげん説明は面倒なので以下を読んでください
・Lisp から Ruby への設計ステップ
http://yohshiy.blog.fc2.com/blog-entry-250.html
ただし、もともとメソッド lambda は proc の別名で同じ意味でしたが、
1.8 の時代に lambda の挙動が変更されメソッドとして独立しました
その変更の理由は関数型プログラミングと関連する可能性はありますが、詳しい背景を自分は知りません
言語仕様として「関数型プログラミング向けに後から追加/変更」されたのは、自分の記憶だとコレくらいしかありません
>そのブロック部分のみを扱うためにProcクラスもlambdaより先に実装されていて、
>そのProcを簡便に扱うためにlambdaと言う構文糖が後から出来た
lambda はメソッドであって、構文糖ではない
>>231 では「もちろん(lamda は)メソッド」と主張しているから、もしも同一人物のカキコなら矛盾している
いったいどちらが正しいの?
>イテレータ呼び出しを汎化した結果生まれたのが、ブロック付きメソッド呼び出し
その「汎化」とは具体的には何を指しているのかな?
もともとイテレータという概念と用語は手続き型言語 CLU で生まれ、Ruby でも採用された
ただし CLU のイテレータは for ... in 構文というループ処理での利用に制限されたのに対して、
(クロージャとしての)ブロックを備えた Ruby ではループ処理以外にも利用できる形で「最初から設計された」
・Rubyist のための他言語探訪 【第 2 回】 CLU
http://magazine.rubyist.net/?0009-Legwork
このためループ処理でもないのにイテレータ(iterator, 反復子)という用語は紛らわしいという声が挙り、
用語「イテレータ呼び出し」は「ブロック付きメソッド呼び出し」へと名称が「後から変更された」
つまり単に用語の命名が「後から」改められだけで、言語仕様の基本は「最初から」何も変わっていないはずです
>RubyはOOPLとして設計され、それが主で関数型プログラミングは結果として付いてきた
スマンが、いいかげん説明は面倒なので以下を読んでください
・Lisp から Ruby への設計ステップ
http://yohshiy.blog.fc2.com/blog-entry-250.html
ただし、もともとメソッド lambda は proc の別名で同じ意味でしたが、
1.8 の時代に lambda の挙動が変更されメソッドとして独立しました
その変更の理由は関数型プログラミングと関連する可能性はありますが、詳しい背景を自分は知りません
言語仕様として「関数型プログラミング向けに後から追加/変更」されたのは、自分の記憶だとコレくらいしかありません
258デフォルトの名無しさん
2014/12/15(月) 22:40:54.50ID:G9R+2lJx 俺が平安時代に読んだ本だと、iteratorはアイテレータって書かれてたな。
あとhierarchyはハイアラーキだった。
あとhierarchyはハイアラーキだった。
259デフォルトの名無しさん
2014/12/15(月) 22:46:59.52ID:G9R+2lJx そんなにlispに憧れてるなら、lispを使えばいいのに。
260デフォルトの名無しさん
2014/12/15(月) 22:47:19.92ID:BuhXHDiL > 1.8 の時代に lambda の挙動が変更されメソッドとして独立しました
> その変更の理由は関数型プログラミングと関連する可能性はありますが、詳しい背景を自分は知りません
RubyのProc.newで作られるオブジェクトは
returnの挙動が普通の関数と違ってキモすぎるので
lambdaの方だけでも普通に直したんでしょう
> その変更の理由は関数型プログラミングと関連する可能性はありますが、詳しい背景を自分は知りません
RubyのProc.newで作られるオブジェクトは
returnの挙動が普通の関数と違ってキモすぎるので
lambdaの方だけでも普通に直したんでしょう
261デフォルトの名無しさん
2014/12/15(月) 23:02:52.91ID:BuhXHDiL さらに言えば、Rubyのブロック変数のスコープの扱いが1.9で仕様変更されてるけど、
それについてmatz自身が
> それは、Rubyが最初から関数型言語としてスタートしてないからであって、言語が違うからですよね。
と語っているね
http://www.atmarkit.co.jp/news/200907/24/ruby.html
それについてmatz自身が
> それは、Rubyが最初から関数型言語としてスタートしてないからであって、言語が違うからですよね。
と語っているね
http://www.atmarkit.co.jp/news/200907/24/ruby.html
262デフォルトの名無しさん
2014/12/15(月) 23:10:49.42ID:eMlPsgxM >>255
>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
もし具体的な疑問/質問があれば、個別に返答します
>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
もし具体的な疑問/質問があれば、個別に返答します
263デフォルトの名無しさん
2014/12/15(月) 23:24:28.86ID:eMlPsgxM264デフォルトの名無しさん
2014/12/16(火) 00:31:08.98ID:IiuX/rSM 自己レスになりますが、>>242 では:
> (Python だけでなく、この「お題(>>189)」は Ruby であっても再帰を使えば同じく分かりにくいコードになる)
とカキコしました
で、後から考え直して「手続き型のループ&破壊的代入」ではなく、しかも「関数再帰」も使わずに、
参照透明性がある関数型プログラミングのコードを考えてみました
http://ideone.com/UrfbuL
ポイントは「反復に組み込みメソッド loop」を「ブロック脱出に引数付のbreak文」を使った2点です
なおメソッド loop は一般に loop do .... end という手続き型のスタイルで書かれることが多いために
ループ構文の一種と誤解されがちですが、(lambda を構文糖であると >>254 が 勘違いしたように....)
loop はメソッドですので(コードで示したように) inject へチェーンさせることができます
また「参照透明性はあっても、手続き型の制御構造であるbreak文の利用は反則ではないか?」という
指摘を予測して、
同じスタイルで(break文の代わりに)組み込みメソッド catch と throw を使ったコードも書きました
http://ideone.com/SaCAFi
ただし、この catch/throw は大域脱出のために用意されたメソッドですから、
今回の「お題」のように単一ブロックを脱出するだけならbreak文を使うのが素直だと考えます
ついでに(catch/throw の代わりに)Scheme 由来の継続(continuation)を使ったコードも書きました
http://ideone.com/5t1VEq
> (Python だけでなく、この「お題(>>189)」は Ruby であっても再帰を使えば同じく分かりにくいコードになる)
とカキコしました
で、後から考え直して「手続き型のループ&破壊的代入」ではなく、しかも「関数再帰」も使わずに、
参照透明性がある関数型プログラミングのコードを考えてみました
http://ideone.com/UrfbuL
ポイントは「反復に組み込みメソッド loop」を「ブロック脱出に引数付のbreak文」を使った2点です
なおメソッド loop は一般に loop do .... end という手続き型のスタイルで書かれることが多いために
ループ構文の一種と誤解されがちですが、(lambda を構文糖であると >>254 が 勘違いしたように....)
loop はメソッドですので(コードで示したように) inject へチェーンさせることができます
また「参照透明性はあっても、手続き型の制御構造であるbreak文の利用は反則ではないか?」という
指摘を予測して、
同じスタイルで(break文の代わりに)組み込みメソッド catch と throw を使ったコードも書きました
http://ideone.com/SaCAFi
ただし、この catch/throw は大域脱出のために用意されたメソッドですから、
今回の「お題」のように単一ブロックを脱出するだけならbreak文を使うのが素直だと考えます
ついでに(catch/throw の代わりに)Scheme 由来の継続(continuation)を使ったコードも書きました
http://ideone.com/5t1VEq
265デフォルトの名無しさん
2014/12/16(火) 02:54:32.21ID:178msYck こんな無駄に遠回しなコード沢山書いてどんだけオナニー好きなんだよ。
266デフォルトの名無しさん
2014/12/16(火) 02:58:06.18ID:178msYck >>198の爪の垢でも煎じて飲めよ。
267デフォルトの名無しさん
2014/12/16(火) 07:18:26.71ID:/LiRSDzk >>257
もちろん、本当はただのメソッドであってlambdaは文法要素ではない
あたかも「ブロックはlambdaの構文糖」であるかのような主張をするから、その対比としてそう書いたまでだよ
分かりにくかったね、「構文糖のような存在のメソッド」と修正しておくよ
もちろん、本当はただのメソッドであってlambdaは文法要素ではない
あたかも「ブロックはlambdaの構文糖」であるかのような主張をするから、その対比としてそう書いたまでだよ
分かりにくかったね、「構文糖のような存在のメソッド」と修正しておくよ
268デフォルトの名無しさん
2014/12/16(火) 07:24:54.85ID:/LiRSDzk まあ、「構文糖のような存在のメソッド」って用語がおかしいというなら
「真のクロージャ」って用語もおかしいのだと気付いて欲しいな
「真のクロージャ」って用語もおかしいのだと気付いて欲しいな
2691
2014/12/16(火) 07:48:21.23ID:PApLEh59 なんか知らんけど伸びてて嬉しいです
目標はGCスレ超えです
目標はGCスレ超えです
270デフォルトの名無しさん
2014/12/16(火) 08:02:21.01ID:/LiRSDzk 一応lambdaというメソッドの実装された時期について調べてみたら、結構昔から存在自体はしてたのね
元々procと同じなのに字数多い&Procなのにlambdaって覚えにくいのと1.4当時は関数型とか知らんかったからスルーしてたのかな
そこは俺の記憶違いだったわ
元々procと同じなのに字数多い&Procなのにlambdaって覚えにくいのと1.4当時は関数型とか知らんかったからスルーしてたのかな
そこは俺の記憶違いだったわ
271デフォルトの名無しさん
2014/12/16(火) 08:45:33.81ID:7mh816Ug クロージャがなければ参照カウント型のGCで済むんじゃないか説があるし
ワンチャンあるよ
ワンチャンあるよ
272デフォルトの名無しさん
2014/12/16(火) 08:47:53.04ID:7mh816Ug 構文糖衣とかいいながら
ラムダって名前から甘そうな印象をうけない
名前が悪いよ考え直すべき
ラムダって名前から甘そうな印象をうけない
名前が悪いよ考え直すべき
273デフォルトの名無しさん
2014/12/16(火) 08:56:24.06ID:7mh816Ug クロージャって名前も固いし
意味わかんねえから
貝殻のclamを頑張ってもじって
クリームって名前にするくらいの
努力はあってよかった
意味わかんねえから
貝殻のclamを頑張ってもじって
クリームって名前にするくらいの
努力はあってよかった
274デフォルトの名無しさん
2014/12/16(火) 09:58:24.78ID:/LiRSDzk >>272
そういう意味ではfunctionを名前ありの関数にもラムダにも使ったJavaScriptは上手いと思う
らむだ何ソレ?な人にも「関数名書かないで使うと無名の関数も作れるよ」って説明で事足りるもんね
そういう意味ではfunctionを名前ありの関数にもラムダにも使ったJavaScriptは上手いと思う
らむだ何ソレ?な人にも「関数名書かないで使うと無名の関数も作れるよ」って説明で事足りるもんね
275デフォルトの名無しさん
2014/12/16(火) 10:58:59.39ID:gf3D6lb/ ブロックとProc.newとprocとlambdaと->があるRubyはやり過ぎ
276デフォルトの名無しさん
2014/12/16(火) 11:12:47.94ID:/LiRSDzk >>275
まあ、Rubyは他の組み込みライブラリでも
エイリアスや似たようなメソッド、所属モジュールが違う同様のメソッドとか持つのは普通だからね
俺は昔からproc派、RubyのProcとλ算法は別物だと思うからあの挙動でいいし、早く書けるし
まあ、Rubyは他の組み込みライブラリでも
エイリアスや似たようなメソッド、所属モジュールが違う同様のメソッドとか持つのは普通だからね
俺は昔からproc派、RubyのProcとλ算法は別物だと思うからあの挙動でいいし、早く書けるし
277デフォルトの名無しさん
2014/12/16(火) 22:27:19.26ID:IiuX/rSM >>267
>あたかも「ブロックはlambdaの構文糖」であるかのような主張をするから、
いや「あるかのよう」ではない、>>244 で以下のように、断定的に明記したとおり:
> まず >>237 で書いたように、Ruby の「ブロック付きメソッド呼び出し」は構文糖だ
Ruby インタブリタの内部では「ブロック付きメソッド呼び出し」と
「値渡しされた Proc オブジェクト」とは別の表現(C構造体)が用いられ、それらを相互変換している
ただし Ruby プログラマの視点では、値渡しされたProc オブジェクトで「あるかのように」
(すなわちファーストクラスとして)ブロックを扱う事ができる、だから「ブロックは構文糖」になる
ブロックを評価するのにメソッド Proc#call が必須(>>254)なのは、また別の理由....
それらをごっちゃにすべきではない
>>268
>まあ、「構文糖のような存在のメソッド」って用語がおかしいというなら
いや「構文糖のような」という比喩表現であれば、何の問題も無い
>「真のクロージャ」って用語もおかしいのだと気付いて欲しいな
>>4 でクロージャ定義を示してから >>199 までソースを明かすのを遅らせたのは意図的だったけど、
「真のクロージャ」という曖昧な表現でいらぬ混乱を与えたことは余計だったと反省している
最初からストレートに「関数型言語のクロージャ」とすべきだったね
>あたかも「ブロックはlambdaの構文糖」であるかのような主張をするから、
いや「あるかのよう」ではない、>>244 で以下のように、断定的に明記したとおり:
> まず >>237 で書いたように、Ruby の「ブロック付きメソッド呼び出し」は構文糖だ
Ruby インタブリタの内部では「ブロック付きメソッド呼び出し」と
「値渡しされた Proc オブジェクト」とは別の表現(C構造体)が用いられ、それらを相互変換している
ただし Ruby プログラマの視点では、値渡しされたProc オブジェクトで「あるかのように」
(すなわちファーストクラスとして)ブロックを扱う事ができる、だから「ブロックは構文糖」になる
ブロックを評価するのにメソッド Proc#call が必須(>>254)なのは、また別の理由....
それらをごっちゃにすべきではない
>>268
>まあ、「構文糖のような存在のメソッド」って用語がおかしいというなら
いや「構文糖のような」という比喩表現であれば、何の問題も無い
>「真のクロージャ」って用語もおかしいのだと気付いて欲しいな
>>4 でクロージャ定義を示してから >>199 までソースを明かすのを遅らせたのは意図的だったけど、
「真のクロージャ」という曖昧な表現でいらぬ混乱を与えたことは余計だったと反省している
最初からストレートに「関数型言語のクロージャ」とすべきだったね
278デフォルトの名無しさん
2014/12/16(火) 23:35:24.13ID:178msYck 関数型言語のクロージャと非関数型言語のクロージャはナニが違うですか。
279デフォルトの名無しさん
2014/12/17(水) 00:34:28.88ID:NwnPjzlT 結局、Pythonのクロージャは本物で、Rubyのブロックは偽物って結論になったんか?
280デフォルトの名無しさん
2014/12/17(水) 06:09:12.08ID:4QPsGplH >>279
彼の中だけではそういうことらしい
彼の中だけではそういうことらしい
281デフォルトの名無しさん
2014/12/17(水) 06:10:48.27ID:HxoNcsla 環境もちこしてる関数っぽいやつならクロージャでいいじゃん
282デフォルトの名無しさん
2014/12/17(水) 06:13:43.20ID:4QPsGplH283デフォルトの名無しさん
2014/12/17(水) 06:16:00.02ID:HxoNcsla なんで突っ込まれてるのかさっぱりわからん
284デフォルトの名無しさん
2014/12/17(水) 06:21:06.36ID:4QPsGplH >>283
突っ込んでないよ、超同意してんだよ
突っ込んでないよ、超同意してんだよ
285デフォルトの名無しさん
2014/12/17(水) 07:54:17.64ID:HxoNcsla まじかよ世界は平和だった
286デフォルトの名無しさん
2014/12/17(水) 20:35:47.86ID:JUumI3zm >>278
もともとクロージャの概念/用語は関数型言語で生まれたものだから、
「非関数型言語のクロージャ」とは:
「関数型言語のクロージャ」の定義に対して、どれくらい忠実に実装されているか?
という相対的な評価になるね
もともとクロージャの概念/用語は関数型言語で生まれたものだから、
「非関数型言語のクロージャ」とは:
「関数型言語のクロージャ」の定義に対して、どれくらい忠実に実装されているか?
という相対的な評価になるね
287デフォルトの名無しさん
2014/12/17(水) 21:10:46.15ID:cFsqVLS5 そして、オリジナルのクロージャーが
一番優れているとかいう信者が現れるわけかw
普通はオリジナルを改良した方が
優れているんだがな。
一番優れているとかいう信者が現れるわけかw
普通はオリジナルを改良した方が
優れているんだがな。
288デフォルトの名無しさん
2014/12/17(水) 21:39:32.52ID:JUumI3zm >>279
でれでは、ここまでの結論をまとめてみる
まず最初は。>>286 の評価結果から:
[Python:X]
Python の lambda 構文は式しか書けないという制限があるから、
クロージャ固有の局所環境を持つことができない
したがって、Python の lambda 構文は「関数型言語のクロージャ」ではない
[Ruby:X]
Ruby のブロックはオブジェクトであるから、
その評価にはメソッド Proc#call をコールしなければならない
したがって、Ruby のブロックは「関数型言語のクロージャ」ではない
[JavaScript:O]
JavaScript の関数リテラルは任意の書けるからクロージャ固有の局所環境を持てるし、
なおかつ引数に適用するだけで評価できる
したがって、JavaScript の関数リテラルは「関数型言語のクロージャ」である
結果として、最も忠実に「関数型言語のクロージャ」が実装されている(>>274)、と言える
続けて、この評価結果が現実のプログラミングに与える影響をまとめる
ここでは Apple 公式リファレンスに含まれる Swift クロージャのサンプルコードを「お題」とした(>>189)
・高階関数 map に与えるクロージャをインラインで書ける
[Python:X]
・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>205)
・このため、一般には(インラインで書くのはあきらめて)関数定義を使わざるをえない
[Ruby & JavaScript:O]
・インラインで自然な while ループを使った(ふつうのプログラマにとって)分かりやすいコードが書ける
・参照透明性のある関数型プログラミングで書ける
[Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>205)
[Ruby:O] (関数再帰の代わりに)組み込みの高階関数風メソッドを使うことで、可読性の高いコードが書ける(>>264)
[JavaScript:?] (書けるか否か、現時点では不明)
でれでは、ここまでの結論をまとめてみる
まず最初は。>>286 の評価結果から:
[Python:X]
Python の lambda 構文は式しか書けないという制限があるから、
クロージャ固有の局所環境を持つことができない
したがって、Python の lambda 構文は「関数型言語のクロージャ」ではない
[Ruby:X]
Ruby のブロックはオブジェクトであるから、
その評価にはメソッド Proc#call をコールしなければならない
したがって、Ruby のブロックは「関数型言語のクロージャ」ではない
[JavaScript:O]
JavaScript の関数リテラルは任意の書けるからクロージャ固有の局所環境を持てるし、
なおかつ引数に適用するだけで評価できる
したがって、JavaScript の関数リテラルは「関数型言語のクロージャ」である
結果として、最も忠実に「関数型言語のクロージャ」が実装されている(>>274)、と言える
続けて、この評価結果が現実のプログラミングに与える影響をまとめる
ここでは Apple 公式リファレンスに含まれる Swift クロージャのサンプルコードを「お題」とした(>>189)
・高階関数 map に与えるクロージャをインラインで書ける
[Python:X]
・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>205)
・このため、一般には(インラインで書くのはあきらめて)関数定義を使わざるをえない
[Ruby & JavaScript:O]
・インラインで自然な while ループを使った(ふつうのプログラマにとって)分かりやすいコードが書ける
・参照透明性のある関数型プログラミングで書ける
[Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>205)
[Ruby:O] (関数再帰の代わりに)組み込みの高階関数風メソッドを使うことで、可読性の高いコードが書ける(>>264)
[JavaScript:?] (書けるか否か、現時点では不明)
289デフォルトの名無しさん
2014/12/17(水) 21:47:14.69ID:JUumI3zm290デフォルトの名無しさん
2014/12/17(水) 22:23:00.08ID:NwnPjzlT291デフォルトの名無しさん
2014/12/17(水) 22:32:56.00ID:NwnPjzlT292デフォルトの名無しさん
2014/12/17(水) 22:42:41.33ID:KZ4YaCx1 可読性の良し悪しなんて定量的ではないものを評価対象にするとか
293デフォルトの名無しさん
2014/12/17(水) 22:47:17.42ID:ffqYUKYZ > Python の lambda 構文は式しか書けないという制限があるから、
> クロージャ固有の局所環境を持つことができない
def make_f(n): return lambda x: x + n
f = make_f(1)
n = 1000
f(1) #=> 2
こういう風に、(引数以外の変数を)実行時の環境じゃなくて
自身が定義された環境で解決できればクロージャだよ。
この場合は変数nのことね。
> クロージャ固有の局所環境を持つことができない
def make_f(n): return lambda x: x + n
f = make_f(1)
n = 1000
f(1) #=> 2
こういう風に、(引数以外の変数を)実行時の環境じゃなくて
自身が定義された環境で解決できればクロージャだよ。
この場合は変数nのことね。
294デフォルトの名無しさん
2014/12/17(水) 23:03:51.76ID:dyHF3Jr0295デフォルトの名無しさん
2014/12/17(水) 23:50:33.95ID:JUumI3zm >>291
お題に対して「Python だけがわざわざ関数 applyf をユーザ定義しなければならない」ことを問題視している
>>201 のコードは「お題を(勝手に改変せず)インラインで書ける」という観点だと(評価以前に)失格だ
もしも Python コミュニティにおいて関数 applyf が常識的に認知されていたならば、
(map/filter/reduce 等と同様に) applyf は組み込み関数として実装されていたはず
なお、組込み関数の実装レベルは言語によって差異があるものだから、
公平性を考慮して functools のような標準ライブラリを import するのは認める
また Ruby のメソッド Enumerable#inject に対応する Python の関数は reduce だよ
Python で組込み関数 reduce を使うのは、まったく問題無い
お題に対して「Python だけがわざわざ関数 applyf をユーザ定義しなければならない」ことを問題視している
>>201 のコードは「お題を(勝手に改変せず)インラインで書ける」という観点だと(評価以前に)失格だ
もしも Python コミュニティにおいて関数 applyf が常識的に認知されていたならば、
(map/filter/reduce 等と同様に) applyf は組み込み関数として実装されていたはず
なお、組込み関数の実装レベルは言語によって差異があるものだから、
公平性を考慮して functools のような標準ライブラリを import するのは認める
また Ruby のメソッド Enumerable#inject に対応する Python の関数は reduce だよ
Python で組込み関数 reduce を使うのは、まったく問題無い
296デフォルトの名無しさん
2014/12/17(水) 23:55:13.45ID:dyHF3Jr0 ていうか、さらっと1個の式で書けないような処理はインラインに書こうとするなよ
っていうのがpythonの求めるところなんじゃないの?
っていうのがpythonの求めるところなんじゃないの?
297デフォルトの名無しさん
2014/12/18(木) 00:12:23.41ID:SaitqfQN >>201 はインラインでは書けていないけど、>>205 と比べれば可読性の高いコードであると思うから、
>>291 の主張を受け入れて >>288 を以下のように一部改訂する(* で始まる行を変更している)
改定前:
・高階関数 map に与えるクロージャをインラインで書ける
[Python:X]
・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>205)
* ・このため、一般には(インラインで書くのはあきらめて)関数定義を使わざるをえない
・参照透明性のある関数型プログラミングで書ける
* [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>205)
改訂後:
・高階関数 map に与えるクロージャをインラインで書ける
[Python:X]
・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>205)
* ・このため、一般には(インラインで書くのはあきらめて)関数定義または変数宣言(>>201)を使わざるをえない
・参照透明性のある関数型プログラミングで書ける
* [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>201,205)
>>291 の主張を受け入れて >>288 を以下のように一部改訂する(* で始まる行を変更している)
改定前:
・高階関数 map に与えるクロージャをインラインで書ける
[Python:X]
・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>205)
* ・このため、一般には(インラインで書くのはあきらめて)関数定義を使わざるをえない
・参照透明性のある関数型プログラミングで書ける
* [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>205)
改訂後:
・高階関数 map に与えるクロージャをインラインで書ける
[Python:X]
・インラインでは関数再帰を使った可読性の低いコードになってしまう(>>205)
* ・このため、一般には(インラインで書くのはあきらめて)関数定義または変数宣言(>>201)を使わざるをえない
・参照透明性のある関数型プログラミングで書ける
* [Python:X] 関数再帰で書けるが、可読性の低いコードになってしまう(>>201,205)
298デフォルトの名無しさん
2014/12/18(木) 00:16:28.27ID:5LPNbvYA むしろ標準で用意されてなくてもユーザ定義で拡張できるのは
言語として筋が良いといえる
言語として筋が良いといえる
299デフォルトの名無しさん
2014/12/18(木) 00:18:19.46ID:wQzGbOYd 謎の標準ライブラリ縛りが入りましたw
300デフォルトの名無しさん
2014/12/18(木) 00:22:42.78ID:Xu+bpXu3 1個の式で済む以上の事をやろうとする処理に名前を付ける事が、なぜ可読性の低下につながるの?
301デフォルトの名無しさん
2014/12/18(木) 00:29:24.93ID:wQzGbOYd 再帰は可読性低いって連呼しててワロタ
Rubyユーザって、ブロック使ってるだけで関数型だと思ってるの?
Rubyユーザって、ブロック使ってるだけで関数型だと思ってるの?
302デフォルトの名無しさん
2014/12/18(木) 00:35:38.77ID:Xu+bpXu3 Schemeは普通ならループで済むような事まで再帰で書くぜ
303デフォルトの名無しさん
2014/12/18(木) 00:44:04.09ID:4kRgXtNb 再帰よりnamed let使おう
304デフォルトの名無しさん
2014/12/18(木) 00:52:42.96ID:Xu+bpXu3 named let は再帰でしょ?
305デフォルトの名無しさん
2014/12/18(木) 01:28:37.32ID:4kRgXtNb 書いた後に思った
306デフォルトの名無しさん
2014/12/18(木) 08:20:12.81ID:ETi/Ct7F >>301
彼だけだよ
彼だけだよ
307デフォルトの名無しさん
2014/12/18(木) 08:27:40.63ID:9iQd+rLQ lispおじさんに言わせれば
全部lispのパクりだから
全部クロージャで問題ないよ
全部lispのパクりだから
全部クロージャで問題ないよ
308デフォルトの名無しさん
2014/12/18(木) 09:21:04.09ID:f+DPSsFx なんでクロージャスレでClojureを話題にしないの?
309デフォルトの名無しさん
2014/12/18(木) 09:50:43.10ID:ZOTu6c+H >>308
若いときは買ってでもするものなあ〜んだ?
若いときは買ってでもするものなあ〜んだ?
310デフォルトの名無しさん
2014/12/18(木) 12:49:08.51ID:nVA5J83n >>309
ゲーム
ゲーム
311デフォルトの名無しさん
2014/12/18(木) 19:41:50.11ID:5ReW54RD >>189
流れをナナメ読みかつ関数型言語素人なんだけど、
関数型言語だとそのアップルサイトの例はどういうふうに書くもんなの?
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
流れをナナメ読みかつ関数型言語素人なんだけど、
関数型言語だとそのアップルサイトの例はどういうふうに書くもんなの?
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
312デフォルトの名無しさん
2014/12/18(木) 22:22:25.63ID:2b1ZQukZ >>309
SEX
SEX
313デフォルトの名無しさん
2014/12/18(木) 23:09:02.06ID:SaitqfQN■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 日本行き空路49万件キャンセル 中国自粛呼びかけ 日本行きチケット予約の約32%に相当 ★2 [ぐれ★]
- 【中国局長】両国関係に「深刻な影響」 首相発言の撤回要求 [蚤の市★]
- 【中国外務省】日中関係悪化は高市氏に責任と名指しで非難… ★4 [BFU★]
- 外務省局長は無言で厳しい表情…日中の高官協議終了か 高市首相“台湾”発言で中国が強硬対応 発言撤回求めたか…★3 [BFU★]
- 【卓球】早田ひな、「総額100万スられた」「ずっと憧れていたスペインとイタリア…」ヨーロッパ旅行で悲劇 スリ被害を告白 [muffin★]
- 【インバウンド】中国人観光客の日本での消費額は年間約2兆円超…中国政府は公務員の出張取り消し [1ゲットロボ★]
- 【実況】博衣こよりのえちえち歌枠🧪★2
- 産経新聞「高市早苗の答弁さぁ……思慮が足りてなくね?官僚と詰めずに思いつきで話しているでしょ」 [175344491]
- 【高市速報】日本人の3割「中国への武力行使に踏み切る必要がある」ANN世論調査 [931948549]
- 【雑談】暇人集会所part18
- 【画像】外務省局長「この度はうちの🦎がすみません…」中国「……」 [165981677]
- 外務省局長、よくわからないまま帰国へ [834922174]
