[表示 : 全て 最新50 1-99 101- 201- 301- 2ch.scのread.cgiへ]
Update time : 06/18 19:36 / Filesize : 147 KB / Number-of Response : 385
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

クロージャって何がいいの?



1 名前:デフォルトの名無しさん [2014/11/08(土) 13:11:47.84 ID:6V2MLUHb.net]
関数型言語に必ずくっついてるこれ
いらんでしょ?匿名クラスで充分でしょ

175 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:10:58.55 ID:wJ3BgpRF.net]
>>171
>>32 にある「いくつかの言語では」という前置きは、
後から出てくる Smalltalk や Ruby のブロック構文を指すと
考えるのが自然じゃないかな?

さすがに Wikipedia のページ著者が
「ラムダ式や無名関数」と「関数定義」との違いも
分からないほどのお馬鹿さんだとは思えないしね

176 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:11:10.32 ID:7GcQ+ika.net]
>>173
ごめん。それで (make_f 10) とか実行した時に返ってくるもの、の間違い。

177 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:15:12.19 ID:wJ3BgpRF.net]
>>173
クロージャだね

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

が返すのもクロージャだね

178 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:18:52.68 ID:7GcQ+ika.net]
>>177
>>163のpythonのコードと完全に同じなんだけどw

179 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:18:56.43 ID:fhZ8V3Hu.net]
>>175
> さすがに Wikipedia のページ著者が

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

> クロージャを持つ言語に、C# 3.0、C++11、ECMAScript(JavaScriptを含む)、Groovy、Java 8(予定)、
> Perl、Python、Ruby、PHP(5.3以降)、Lua、Squirrelなどがある。

180 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:28:21.39 ID:wJ3BgpRF.net]
>>179
Wikipedia の記事が常に 100% 正しいと思っているのかな?

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

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

さて、>>179 は書き直せるかな?

181 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 01:32:42.88 ID:fhZ8V3Hu.net]
>>180
>>171が正解と考えれば全く矛盾してないので、お前が間違ってるんだよ

182 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 09:44:37.50 ID:BfhGUngW.net]
with構文はスコープから抜ける時にclose的な関数を必ず呼び出してくれる保証があるけど、
Rubyのブロックにはそんな保証は無い
だからRubyではウッカリcloseを忘れても分かりにくい
そういうのは良くない

183 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 11:08:08.37 ID:nwROesTX.net]
>>180
> Wikipedia の記事が常に 100% 正しいと思っているのかな?

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

だって、あんたの言うことのほうが正しいなら
wikipediaを修正すればいいわけだから。



184 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 12:57:07.44 ID:5gFBGGbj.net]
なんだ、この偏執狂たちの罵り合いはw

そんなことより、問題。
若い内に買ってでもしろ、と言われるものはなぁんだ?

185 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 15:15:51.24 ID:W3M4RtQD.net]
ああ、let-inが無いからpythonのはクロージャじゃないって主張か。
斜め上だな。

186 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 16:40:50.21 ID:2szoNUEC.net]
環境と変数を手軽に包めるのは有難いけどなあ
XMLベースのジョブ管理言語とか
ちょっとしたVM作るときに
継続の表現にクロージャなしだとだるいよ
さらに無名クラスも無い言語だと
本物のVM作らなきゃいけなくなる

187 名前:デフォルトの名無しさん mailto:sage [2014/11/20(木) 20:12:20.93 ID:IqIimPum.net]
https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Closures

188 名前:デフォルトの名無しさん mailto:sage [2014/11/21(金) 13:07:27.23 ID:obtZMam2.net]
>>184
セックス…かな
年とると立たなくなるから

189 名前:デフォルトの名無しさん mailto:sage [2014/11/21(金) 13:13:28.47 ID:zygDXSz1.net]
>>188
ご愁傷さまです。

190 名前:デフォルトの名無しさん mailto:sage [2014/11/29(土) 13:01:53.24 ID:OX49RFg5.net]
>>190


191 名前:デフォルトの名無しさん mailto:sage [2014/12/10(水) 19:56:15.27 ID:veDvxwge.net]
Swift スレでクロージャの話題で荒れそうだったので、こちらへ移動しとく
 peace.2ch.net/test/read.cgi/tech/1415860741/153

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

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

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

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

これが Swift や Ruby 等と比較すると、関数型プログラミングで Python が劣る典型的な一例になる

192 名前:デフォルトの名無しさん mailto:sage [2014/12/10(水) 20:24:01.24 ID:Q728OFWk.net]
と言うかどう見てもこないだまでこのスレに居た俺俺定義の人ですな

193 名前:デフォルトの名無しさん mailto:sage [2014/12/10(水) 20:43:29.64 ID:Q728OFWk.net]
よく見たら、そのスレで誘導かけてるの、話振ったお前本人じゃねーかw
俺俺定義が認められなかったから逃げて来たのか?



194 名前:デフォルトの名無しさん mailto:sage [2014/12/10(水) 21:30:40.85 ID:AwBDqpLr.net]
クロージャの定義は>>4って書かれてたがStandard MLにラムダ式はない
けど当然SMLにはクロージャがあるわけで
ソースはThe Definition of Standard ML, revised edition

195 名前:デフォルトの名無しさん mailto:sage [2014/12/10(水) 21:46:37.74 ID:ZY5znPCs.net]
関数型プログラミングってどういうのを指して言ってるんだろ

196 名前:デフォルトの名無しさん mailto:sage [2014/12/10(水) 21:50:32.14 ID:gkNqf6iG.net]
>>191のサンプルが手続き型全開の書き方で笑った


>>195
関数(に名前付けたくない)型プログラミング

197 名前:デフォルトの名無しさん mailto:sage [2014/12/11(木) 21:30:20.83 ID:GpAyUabF.net]
>>193
Swift スレの質問「Python が Swift や Ruby より劣ってるのは何か」に答えただけ
で、具体的に反論できないから罵倒を始めて Swift スレが荒れそうだったから、
こちらへ移動してきた


>>194
>>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
    www2u.biglobe.ne.jp/~oz-07ams/prog/ecma262r3/13_Function_Definition.html
・Python では、その言語リファレンスで「ラムダ式」と呼ばれている:
  ・6. 式 (expression) ― Python 3.4.2 ドキュメント
   docs.python.jp/3.4/reference/expressions.html#lambda

198 名前:デフォルトの名無しさん mailto:sage [2014/12/11(木) 21:48:16.84 ID:AENhOzwc.net]
>>197
肝心のクロージャの定義の引用はまだですか?
俺俺定義はお腹いっぱいなんですよ

199 名前:デフォルトの名無しさん mailto:sage [2014/12/11(木) 22:44:15.05 ID:GpAyUabF.net]
調べてみると、Python のラムダ式で任意の文が書けないという問題(>>191)は、
過去に何度もネット上で話題になっていたようだね:
・Is it possible to have multiple statements in a python lambda expression? - Stack Overflow (May 14 '09)
 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)
 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)
 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
 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
 www.artima.com/weblogs/viewpost.jsp?thread=147358

まさに「みんなを納得させるほどの「結論」じゃない」というのは、こういう状況を指しているんだろね....
 peace.2ch.net/test/read.cgi/tech/1417333026/9

200 名前:デフォルトの名無しさん mailto:sage [2014/12/11(木) 22:55:21.60 ID:aWaBOmKM.net]
>>191
普段Python書かないからPythonicではないかもしれないが、だいたいこんな感じだろう。
ideone.com/0vAET2

それで、何が問題なんだ?

201 名前:デフォルトの名無しさん mailto:sage [2014/12/11(木) 23:02:23.22 ID:GpAyUabF.net]
>>198
ではクロージャ定義の引用元ソースを示そうね

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

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

単純な話だと思うけど、難しいかな?

202 名前:デフォルトの名無しさん mailto:sage [2014/12/11(木) 23:27:50.83 ID:GpAyUabF.net]
>>200
関数を宣言せずに書くという制約の元ですから、とてもPythonらしいコードだと思います
しかもループの代わりに関数再帰を使っているのですから、より関数型プログラミングらしいとも言えます

ただし、元々 Swift で書かれていたサンプルコードを各 LL へと書き直しているのですから、
もし以下の点を改善できれば(Pythonらしさという意味では)完璧でしょう:
・中間変数 f を宣言せず、リスト内包式の中にラムダ式をインラインで書く
・Swift のコードは辞書を使っているのですから、それを(勝手に)配列 digits へ改変せず、
 Python でも(Ruby や JavaScript と同様に)辞書を使って書く

203 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 00:10:51.51 ID:kNbqUbaQ.net]
>>202
注文が多いな。
ideone.com/KWnSgA



204 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 09:01:50.64 ID:hLblKLHb.net]
>>201
で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?
「Schemeという特定の言語」で「クロージャはlambda式で作られる」と書いてあるだけだが?

いい加減、誤摩化して逃げ回るのは止めたら?

205 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 18:43:57.39 ID:JZfpq2Ndq]
以前も書いたけどPythonistaは走り書き以外でlambdaなんて使わないから。

206 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 19:05:12.73 ID:1wfis/cT.net]
別にPythonのラムダに式が書けないから問題だと言うだけなら荒れねーよ
そこで「だからPythonにはクロージャが無い」って言う
決して成り立たない等式を持ち込むから「いやそのりくつはおかしい」って言われてんのに
そしたら既存のクロージャという用語の定義のほうを弄ろうとするから叩かれてんだろうが

プログラミングに例えるなら、お前は自分の書いた関数で
組み込み整数型の値にそのままリスト処理を適用しようとして例外吐かれたから、と
整数クラスのほうがリストとして振る舞うようにメソッドを書き換えようとしてる

207 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 22:20:24.14 ID:ZYnyJXBo.net]
>>203
お疲れさまです
中間変数 f は消えましたが、今度は中間変数 applyf が現れてしまいましたね....

208 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 22:38:08.46 ID:hhr7pvhS.net]
>>207
ideone.com/zAN4uA

209 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 22:42:02.66 ID:hLblKLHb.net]
>>207
とりあえずクロージャの定義を貼っておきますね
反論よろしく

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.

210 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 23:33:45.85 ID:ZYnyJXBo.net]
>>204
> で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?

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


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

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

で、どこに「Schemeという特定の言語」と書いてあるの?
いい加減、誤摩化して言い逃れをするのは止めたら?

211 名前:デフォルトの名無しさん mailto:sage [2014/12/12(金) 23:54:36.75 ID:ZYnyJXBo.net]
>>208
ありがとうございます、これで完璧ですね

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

で、これらは主観による評価ですから、
いくら議論しても誰もが納得できる結論へとは収束しないでしょう
すべての Pythonista にとって >>208 が読みやすく書きやすいと感じるのなら、
それはそれでいいんじゃないでしょうか

212 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 00:01:46.30 ID:HrrHquek.net]
一時変数を消すためにそんなパズルみたいな事やって読みやすいわけないだろw

213 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 00:13:09.40 ID:HrrHquek.net]
>>210
schemeではlambdaが本質的なもので(define (f x) 〜)はシンタックスシュガーだけど、
pythonではdefが本質的なものでlambdaの方がシンタックスシュガーなのでは。



214 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 00:39:02.24 ID:gzcIElev.net]
>>209
Wikipedia 英語版の解説と同じに見えるけど、何を言いたいのかな?
・Closure (computer programming) - Wikipedia, the free encyclopedia
 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本(>>121) および >>4 のそれと矛盾していない
そして Haskell のような純粋関数型言語に限定した文脈ではないのだから、
文中の "function code" は(>>210 で書いたように)単なる式だけではなく
破壊的代入や入出力等の副作用を伴う任意のコードも書けると解釈するのが自然だと考える

215 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 02:01:28.39 ID:6/3yjF6w.net]
>>4
>クロージャを識別子に束縛したものが一般的な「関数宣言」である

よかった、pythonにもちゃんとクロージャあった

216 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 02:13:23.84 ID:6/3yjF6w.net]
foo = lambda bar: bar
これはクロージャである

っていうのが偽であることを定義から証明すればいいんじゃないかな
反例あげればいいだけだよね?

217 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 02:17:02.89 ID:6/3yjF6w.net]
あ、まちがえたそれはクロージャじゃない
def foo():
bar = 1

これに訂正

218 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 07:14:46.97 ID:toJAZvUP.net]
>>211
それはPythonの書き方じゃないんだよ。
お前が>>202で指定したから、結果的にそうなっただけで。

それで、結局「クロージャを書けない」から「読みにくい」に問題をすり替えて終わりか?

219 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 08:00:50.00 ID:1EyzOdES.net]
ideone.com/C5hOIB

220 名前:デフォルトの名無しさん mailto:sage [2014/12/13(土) 10:42:15.83 ID:ygYpq94K.net]
イデオンこわい

221 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 12:26:47.45 ID:sGDpUYPr.net]
>>210
> もちろん「クロージャは無名関数でなければダメ」とは書かれていない

なんだ、Pythonのdefで良かったんだ

知らないみたいだから教えてあげるけど、Pythonではdefで関数定義すると
環境を持ったクロージャになってるんだよ、勉強になったね

222 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 12:40:53.92 ID:sGDpUYPr.net]
>>211
>>203のapplyfは、特定のロジックに依存しない汎用的な関数だけど、
こういうものの定義や使用も認めないってことは
ライブラリによる拡張も否定するってことでOK?

ライブラリを使わないと外部イテレータが使えないRubyをdisってるの?

223 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 14:05:13.26 ID:ZLG0O37u.net]
>>210
書かれてない要素を勝手に追加するから
オレオレ定義って言われるんだよ

クロージャの定義には無名関数であることも、文が書けるor書けないことも、
含まれてないんたから、勝手に条件に追加すんな



224 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 14:39:36.41 ID:1EyzOdES.net]
>>220
>>219 はPythonのlambdaからでも副作用を伴うメソッド呼べますよってコードだな

225 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 20:13:18.59 ID:gzcIElev.net]
>>213
本質という言葉の定義が曖昧ですが、自分なりにコメントします

まず >>209(= Wikipedia, >>214)の章「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 は手続き型言語だから」ということですね

226 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 20:39:14.11 ID:HrrHquek.net]
>>225
本質的ってのは、よりプリミティブなものっていう意味で書いたんだよ。

first-class valueってのは、変数に代入したり、関数の引数に渡したり、
関数の値として返したりできるオブジェクトの事だよ。
def だの lambda だのっていうのはそういうオブジェクトであるクロージャを作り出すための構文だよ。

pythonは手続き型言語だっていうけど、そんなの当たり前だろw
rubyだのjavascriptだのだって手続型言語だよ。

227 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 21:42:39.17 ID:gzcIElev.net]
>>226
> 本質的ってのは、よりプリミティブなものっていう意味で書いたんだよ。

その意味であれば、関数型言語と Ruby/JavaScript だと
関数定義よりもクロージャのほうがが本質的だね
プリミティブな名前とクロージャから関数(or メソッド)が作られるという
因果関係があるのだから

ただし、Python だけは違うみたいだね


> rubyだのjavascriptだのだって手続型言語だよ。

外見は手続き型言語だけど、どちらの言語もLISPをベースに設計されている
だから最初から関数型言語と同等なクロージャを備えて誕生した
それが知られるようになったのは最近だから、知らない人は多いけどね.....
手続き型言語として生まれ、後付けで関数型を増築した Python とは違うのだよ
 peace.2ch.net/test/read.cgi/tech/1409526637/857

--
> パクリどころか Ruby と JavaScript は、これらの作者自身が
> Lisp を基礎として言語を設計したと語っている
>
> ・Lisp から Ruby への設計ステップ
>  yohshiy.blog.fc2.com/blog-entry-250.html
> ・JavaScript: The World's Most Misunderstood Programming Language
>  www.crockford.com/javascript/javascript.html
> (邦訳版「JavaScriptの勉強:世界で最も誤解されたプログラミング言語」へのリンクは閉鎖)
>
> だから関数型プログラミングという土俵の上で Ruby や JavaScript に
> 手続き型言語の Python がいくら挑戦しても勝てずに負け続けているのは、
> しごく当然な結果なわけ

228 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 22:07:55.30 ID:HrrHquek.net]
>外見は手続き型言語だけど、どちらの言語もLISPをベースに設計されている

S式で表現されてなきゃlispじゃねえよ。

229 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 22:14:57.19 ID:HrrHquek.net]
だいたいlispが関数型言語だって言うことにも抵抗がある。

230 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 23:06:18.71 ID:gzcIElev.net]
>>227
>手続き型言語として生まれ、後付けで関数型を増築した Python とは違うのだよ

自己レスで補足する(すべての手続き型言語が Python と同じではない....

同じ手続き型言語に関数型の特性を追加した言語でも、
調べた範囲だと少なくとも Perl5/Java8/C++11 のクロージャは
>>4,>>121 のクロージャ定義に沿って設計され、
・クロージャ内で任意の文が書ける
ただしそれら言語がクロージャをサポートした時期は遅かった
真面目に設計したからだろう

対して Python の関数型サポートは素早かったけど、検討が不十分だったと言うほかない
リリース後に改善要望/議論紛糾したあげく、結論を出せず現在に到る(>>199)

231 名前:名無しさん@そうだ選挙に行こう mailto:sage [2014/12/13(土) 23:27:26.05 ID:fdPKe7oz.net]
横だけど、
Rubyのブロックはラムダじゃないしファーストクラスでもないよね

メソッドにラムダを渡すこともできるけど、不格好なんだが?
これって、ここのオレオレ定義にてらすとどうなの?

なんだか、ラムダに文を書けない(書かない)ようにしている
Pythonの仕様をあげつらうためだけにオレオレ定義をこねくって
悦に入ってるPythonアンチがいるって感じがするだけなんだが。

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的に分散され、特定のサーバーに依存しません







[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<147KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef