関数型言語に必ずくっついてるこれ
いらんでしょ?匿名クラスで充分でしょ
探検
クロージャって何がいいの? [転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
1デフォルトの名無しさん
2014/11/08(土) 13:11:47.84ID:6V2MLUHb2014/11/08(土) 13:17:58.06ID:rszc5DFq
マジレスすると、クロージャーよりも
関数内関数の方がいい。
クロージャーは変数スコープが不必要に広い。
多くの場合、クロージャーの外は見える必要がない。
逆に見えてしまうと不用意に変数を書き換えてしまう。
関数内関数がない言語が多いから
仕方なくクロージャーを使うしかないが、
Java8のラムダの方がまだ安全なコードを書くことが出来る。
(ラムダも外のスコープが参照できる場合があるので完璧ではない)
つまり俺がいいたいのは、クロージャーを使うと苦労するのジャー。
関数内関数の方がいい。
クロージャーは変数スコープが不必要に広い。
多くの場合、クロージャーの外は見える必要がない。
逆に見えてしまうと不用意に変数を書き換えてしまう。
関数内関数がない言語が多いから
仕方なくクロージャーを使うしかないが、
Java8のラムダの方がまだ安全なコードを書くことが出来る。
(ラムダも外のスコープが参照できる場合があるので完璧ではない)
つまり俺がいいたいのは、クロージャーを使うと苦労するのジャー。
2014/11/08(土) 13:42:47.14ID:alIlcZLx
ディスクロージャ
2014/11/08(土) 14:33:50.79ID:Wb7Sa5AG
>>1
関数型言語の操作的意味論において、クロージャとは:
「ラムダ式と局所環境とを組合せた概念」
を指す
このクロージャを具象構文で表したものが一般的な「ラムダ式」であり、
クロージャを識別子に束縛したものが一般的な「関数宣言」である
Standard ML という関数型言語だと、
たとえばラムダ式は fn x => x + 1 であり、関数宣言は val succ = fn x => x + 1 である
ここで、関数宣言には fun succ x = x + 1 と簡潔に書ける構文糖を用いるのが一般的
だから、あらゆる関数型言語ないし関数型プログラミングが可能なあらゆる言語であれば、
クロージャ(という概念)は必要不可欠に存在である、と言える
また Java の「匿名クラス」もクロージャ(という概念)を応用した具象構文の一種である
で、Java 8 で導入された「ラムダ式」もクロージャの具象構文だけど、
匿名クラスよりも簡潔に書ける利点があるから、多くのケースで広く利用されるようになるだろう
両者の間には、局所環境と組み合わせる対象が「匿名クラス」ではクラスという単位であるのに対して、
「ラムダ式」では式という(クラスよりも粒の小さな)単位であるという違いがある
目的に応じて適切に両者を使い分けることが望ましい
関数型言語の操作的意味論において、クロージャとは:
「ラムダ式と局所環境とを組合せた概念」
を指す
このクロージャを具象構文で表したものが一般的な「ラムダ式」であり、
クロージャを識別子に束縛したものが一般的な「関数宣言」である
Standard ML という関数型言語だと、
たとえばラムダ式は fn x => x + 1 であり、関数宣言は val succ = fn x => x + 1 である
ここで、関数宣言には fun succ x = x + 1 と簡潔に書ける構文糖を用いるのが一般的
だから、あらゆる関数型言語ないし関数型プログラミングが可能なあらゆる言語であれば、
クロージャ(という概念)は必要不可欠に存在である、と言える
また Java の「匿名クラス」もクロージャ(という概念)を応用した具象構文の一種である
で、Java 8 で導入された「ラムダ式」もクロージャの具象構文だけど、
匿名クラスよりも簡潔に書ける利点があるから、多くのケースで広く利用されるようになるだろう
両者の間には、局所環境と組み合わせる対象が「匿名クラス」ではクラスという単位であるのに対して、
「ラムダ式」では式という(クラスよりも粒の小さな)単位であるという違いがある
目的に応じて適切に両者を使い分けることが望ましい
2014/11/08(土) 16:17:08.12ID:gNjtEENQ
/ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄\
∠ ノ
丶 |
ノ |
| / ̄ ̄ ̄ ̄\ |
| / ヽ |
| | | |
| | | |
| | | |
/ | | /
ヽ \_/| |\_/ ヽヘ
| / \ /
 ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄
パンとか止めるやつ
∠ ノ
丶 |
ノ |
| / ̄ ̄ ̄ ̄\ |
| / ヽ |
| | | |
| | | |
| | | |
/ | | /
ヽ \_/| |\_/ ヽヘ
| / \ /
 ̄ ̄ ̄ ̄ ̄ ̄  ̄ ̄ ̄ ̄ ̄ ̄
パンとか止めるやつ
6デフォルトの名無しさん
2014/11/08(土) 16:19:08.12ID:gwropNof >>5
それ、パンとか止めるやつだろ!
それ、パンとか止めるやつだろ!
2014/11/08(土) 16:28:06.78ID:Z0nNiFel
/ ̄ ̄\
/ _ノ ヽ、_ \
. | ( ●)(● ) |
,-,-,-,__ | (__人__) │rヽヽヽヽ__ 「クイックロック バッグ クロージャー!!」
r.l .' ' .'.r_l | `⌒ ´ . | ´l .|/
.ヽ| | | | | /_
._,,-ーヽ /-‐ ヽ /‐''",' /. `ヽ
/ /`''‐-',. ヽ ./ rj,.-‐''´`l ./
\ | 二ヽ ヽ三 |ー‐'´
`''‐ヽ ―`ヘ j `―r'´
`T ´ j. ./ j
ヽ .ヽ、 ___ / ,'
| ./(>)^ ヽ\ i
| ./ (_ (<) \ .i
/ .! ./ /rェヾ__)⌒::: ヾ.\
/ ∧i. `⌒´-'´ u; ノ ヽ
| .\ヽ 、 , / |
.ヽ ',. ー 一 ./ /
', .', ./ /
.', ', / /
/ヽ、 \ / /
/ | ヽ―‐/ ./ \
./ .l 丿 ゝ ( ヽ
/ / / \ ', ',
/ /-‐''´ `''‐| ',
./ __| . / .',
| `ヽ、 ./ ̄ .|
| ヽ / /
`"''-,,__ ,,,,丿 ゝ、__,,-''
/ _ノ ヽ、_ \
. | ( ●)(● ) |
,-,-,-,__ | (__人__) │rヽヽヽヽ__ 「クイックロック バッグ クロージャー!!」
r.l .' ' .'.r_l | `⌒ ´ . | ´l .|/
.ヽ| | | | | /_
._,,-ーヽ /-‐ ヽ /‐''",' /. `ヽ
/ /`''‐-',. ヽ ./ rj,.-‐''´`l ./
\ | 二ヽ ヽ三 |ー‐'´
`''‐ヽ ―`ヘ j `―r'´
`T ´ j. ./ j
ヽ .ヽ、 ___ / ,'
| ./(>)^ ヽ\ i
| ./ (_ (<) \ .i
/ .! ./ /rェヾ__)⌒::: ヾ.\
/ ∧i. `⌒´-'´ u; ノ ヽ
| .\ヽ 、 , / |
.ヽ ',. ー 一 ./ /
', .', ./ /
.', ', / /
/ヽ、 \ / /
/ | ヽ―‐/ ./ \
./ .l 丿 ゝ ( ヽ
/ / / \ ', ',
/ /-‐''´ `''‐| ',
./ __| . / .',
| `ヽ、 ./ ̄ .|
| ヽ / /
`"''-,,__ ,,,,丿 ゝ、__,,-''
8デフォルトの名無しさん
2014/11/08(土) 18:29:54.75ID:+pW0VlFs2014/11/08(土) 18:31:45.04ID:Z0nNiFel
>>8
最後の行に同意してくれてありがとう
最後の行に同意してくれてありがとう
2014/11/08(土) 21:41:30.87ID:1bx+kI6Q
おもてたんとちゃうこのスレ
2014/11/08(土) 22:16:16.20ID:BzSpEdoH
クロージャーってただのメソッド一つのクラスだろ
2014/11/09(日) 01:25:23.88ID:5LKfT6rZ
まじすか
2014/11/09(日) 02:04:06.76ID:8LiWtrih
という見方、扱い方もできるねって話だろ
2014/11/09(日) 05:57:17.96ID:n2NDOrh4
ActionListenerなんて、実装当時にクロージャがあったら存在してたかどうか怪しいクラスだよね
15デフォルトの名無しさん
2014/11/09(日) 07:54:16.27ID:6VpE/OBT lispの方言かとおもった
2014/11/09(日) 09:19:55.73ID:nlmXbEn2
2014/11/09(日) 10:23:47.55ID:gYZvrVR/
>>11
複数にできるよ
複数にできるよ
2014/11/09(日) 16:16:30.86ID:K4BO8Ja1
関数内で関数が定義できる事とクロージャと何の関係があるんだ?
比較できるものじゃないでしょ
比較できるものじゃないでしょ
2014/11/09(日) 16:48:40.28ID:EbU/SVlS
まあ、クロージャは関数内関数の用途をも内包することは多いんじゃね?
2014/11/09(日) 17:24:14.45ID:xhtawW2X
>>16
それはあまり使われていない関数型言語限定の話ですね。
それはあまり使われていない関数型言語限定の話ですね。
2014/11/09(日) 17:32:09.95ID:PiaxZAwM
2014/11/09(日) 17:38:41.70ID:50xVLBic
オレオレ言語仕様を考えてるんだけどさ今どの言語を見てもlambdaだらけじゃない
RAII出来る言語だとクロージャに環境掴まれるだけでリソースリークしそうなわけよ
ならイランでしょ?というわけでたてた
RAII出来る言語だとクロージャに環境掴まれるだけでリソースリークしそうなわけよ
ならイランでしょ?というわけでたてた
2014/11/09(日) 18:18:41.40ID:K4BO8Ja1
クロージャだからって外の環境全部掴む必要無いんじゃね
クロージャが使用してない変数については各スコープのタイミングで解放すれば十分じゃないの
クロージャが使用してない変数については各スコープのタイミングで解放すれば十分じゃないの
2014/11/09(日) 18:20:47.86ID:xhtawW2X
evalが使える言語では、使用していないかどうか
実行するまでわからないのでそれは無理。
実行するまでわからないのでそれは無理。
2014/11/09(日) 18:24:28.78ID:KOr7L+hP
>>20,21
関数型言語ではなく関数型プログラミングの話だと考えれば、
すでに多くの言語でクロージャという概念は幅広く普及していると言えるのではないかと
たとえば C#、Java8、C++11、JavaScript、Ruby 等々
もちろん Python のように、クロージャが存在しない手続き型言語も広く使われているけどね
また、C++ や Java でも古い規格だとクロージャは存在していなかった
関数型言語ではなく関数型プログラミングの話だと考えれば、
すでに多くの言語でクロージャという概念は幅広く普及していると言えるのではないかと
たとえば C#、Java8、C++11、JavaScript、Ruby 等々
もちろん Python のように、クロージャが存在しない手続き型言語も広く使われているけどね
また、C++ や Java でも古い規格だとクロージャは存在していなかった
2014/11/09(日) 18:40:07.36ID:lx9et4kr
Pythonの関数は外の環境掴んでるからクロージャ
嘘は良くない
嘘は良くない
2014/11/09(日) 18:40:57.06ID:nlmXbEn2
>>24
クロージャじゃなくてevalを禁止すれば良いんじゃね?
クロージャじゃなくてevalを禁止すれば良いんじゃね?
2014/11/09(日) 18:55:58.44ID:KOr7L+hP
2014/11/09(日) 18:59:22.34ID:KOr7L+hP
>>28 を訂正、ラムダ式(匿名関数)の話であるのを書き忘れていた
X:>25 で挙げたクロージャを備えた言語は、どれも外の環境を掴んで
O:>25 で挙げたクロージャを備えた言語は、どれもラムダ式の中で外の環境を掴んで
X:>25 で挙げたクロージャを備えた言語は、どれも外の環境を掴んで
O:>25 で挙げたクロージャを備えた言語は、どれもラムダ式の中で外の環境を掴んで
2014/11/09(日) 19:03:23.62ID:lx9et4kr
2014/11/09(日) 19:08:15.30ID:nlmXbEn2
不毛だからケンカする前に用語を定義しろよ
オレオレ定義じゃないんだったら引用も必要
http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3
> クロージャ(クロージャー、英: closure)、関数閉包はプログラミング言語における関数オブジェクトの一種。
> いくつかの言語ではラムダ式や無名関数で実現している。引数以外の変数を実行時の環境ではなく、
> 自身が定義された環境(静的スコープ)において解決することを特徴とする。
オレオレ定義じゃないんだったら引用も必要
http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3
> クロージャ(クロージャー、英: closure)、関数閉包はプログラミング言語における関数オブジェクトの一種。
> いくつかの言語ではラムダ式や無名関数で実現している。引数以外の変数を実行時の環境ではなく、
> 自身が定義された環境(静的スコープ)において解決することを特徴とする。
2014/11/09(日) 19:13:25.68ID:nlmXbEn2
> (ラムダ式ではなく)関数で外の環境を掴めるのは当たり前の話であり、嘘は良くない
とりあえずelispにケンカ売ってるのだけは分かった
とりあえずelispにケンカ売ってるのだけは分かった
2014/11/09(日) 19:19:20.49ID:5LKfT6rZ
pythonのlambdaって外の環境見えないの?
2014/11/09(日) 19:22:02.17ID:lx9et4kr
見えるよ
2014/11/09(日) 19:25:16.21ID:5LKfT6rZ
そうだよね...
2014/11/09(日) 19:39:55.45ID:KOr7L+hP
>>30
C#、Java8、C++11、JavaScript、Ruby 等々の関数型プログラミングが可能な言語では、
どれも「ラムダ式の中であっても外の環境を参照し、それを局所環境に保存」できる
それに対して、Python だと「ラムダ式の中では外の環境を参照する」ことしかできない
つまり、手続き型言語の Python は関数型プログラミングには不向きである、と言える
>>31
>> 引数以外の変数を実行時の環境ではなく、
>> 自身が定義された環境(静的スコープ)において解決することを特徴とする。
クロージャを備えた言語ではクロージャ自身が局所環境を持つということだね(>>4 も参照)
だから、関数内でもラムダ式内であっても局所環境で変数を解決できる
それに対して(クロージャを備えず、代わりに)関数という実行環境しか持たない Python では、
関数内では変数を解決できてもラムダ式内で変数を解決できない
つまり、Python はクロージャを持たない手続き型言語
C#、Java8、C++11、JavaScript、Ruby 等々の関数型プログラミングが可能な言語では、
どれも「ラムダ式の中であっても外の環境を参照し、それを局所環境に保存」できる
それに対して、Python だと「ラムダ式の中では外の環境を参照する」ことしかできない
つまり、手続き型言語の Python は関数型プログラミングには不向きである、と言える
>>31
>> 引数以外の変数を実行時の環境ではなく、
>> 自身が定義された環境(静的スコープ)において解決することを特徴とする。
クロージャを備えた言語ではクロージャ自身が局所環境を持つということだね(>>4 も参照)
だから、関数内でもラムダ式内であっても局所環境で変数を解決できる
それに対して(クロージャを備えず、代わりに)関数という実行環境しか持たない Python では、
関数内では変数を解決できてもラムダ式内で変数を解決できない
つまり、Python はクロージャを持たない手続き型言語
2014/11/09(日) 19:44:13.19ID:5LKfT6rZ
pythonのlambdaって単に単純な関数定義のシンタックスシュガーなんじゃないの?
lambdaなんて名前が付いてるからアレだけど。
lambdaなんて名前が付いてるからアレだけど。
2014/11/09(日) 19:44:17.88ID:KOr7L+hP
2014/11/09(日) 19:47:57.23ID:nlmXbEn2
2014/11/09(日) 19:48:24.99ID:5LKfT6rZ
>>38
ラムダ式を評価した結果も関数定義を評価した結果も同じfunctionだよ。
ラムダ式を評価した結果も関数定義を評価した結果も同じfunctionだよ。
2014/11/09(日) 20:00:59.51ID:lx9et4kr
>>40 たしかに
import inspect
def func(x):
return lambda n: x * n
func(5)(4) #=> 20 (Clojure)
inspect.isfunction(func) #=> True
inspect.isfunction(func(1)) #=> True
import inspect
def func(x):
return lambda n: x * n
func(5)(4) #=> 20 (Clojure)
inspect.isfunction(func) #=> True
inspect.isfunction(func(1)) #=> True
2014/11/09(日) 20:10:51.52ID:KOr7L+hP
>>39
>・「変数を解決する」という用語が未定義
失礼、言語処理系や言語意味論を知らない人には難しい表現だった
「変数を解決する」とは、変数に束縛された値を求めることを意味する
単純な実装では、変数と値の対(ペア)の集合である環境から、変数をキーに値を探索することで実現できる
>・「ラムダ式のみクロージャと認める」というのは>>31とは異なる定義だが、そのような定義をしている文献が引用されてない
「ラムダ式のみクロージャと認める」とは言っていないよ
C#、Java8、C++11、JavaScript、Ruby 等々の一般的な言語では関数でもラムダ式でも局所環境を持てる
これは「クロージャ自身が局所環境を持つ(>>4)」というクロージャ定義からすれば、自然な結果である
それに対して、ラムダ式では局所環境を持てない Python にはクロージャの概念が欠落しているんじゃないのか?
と指摘しているだけ
あるいは処理系への実装を失敗した?、あるいは言語設計上の欠陥を見落とした?という指摘と言い換えてもいい
Python の言語設計者達はクロージャの概念を知っているつもりだったのかもしれないけどね......
>・「変数を解決する」という用語が未定義
失礼、言語処理系や言語意味論を知らない人には難しい表現だった
「変数を解決する」とは、変数に束縛された値を求めることを意味する
単純な実装では、変数と値の対(ペア)の集合である環境から、変数をキーに値を探索することで実現できる
>・「ラムダ式のみクロージャと認める」というのは>>31とは異なる定義だが、そのような定義をしている文献が引用されてない
「ラムダ式のみクロージャと認める」とは言っていないよ
C#、Java8、C++11、JavaScript、Ruby 等々の一般的な言語では関数でもラムダ式でも局所環境を持てる
これは「クロージャ自身が局所環境を持つ(>>4)」というクロージャ定義からすれば、自然な結果である
それに対して、ラムダ式では局所環境を持てない Python にはクロージャの概念が欠落しているんじゃないのか?
と指摘しているだけ
あるいは処理系への実装を失敗した?、あるいは言語設計上の欠陥を見落とした?という指摘と言い換えてもいい
Python の言語設計者達はクロージャの概念を知っているつもりだったのかもしれないけどね......
2014/11/09(日) 20:14:38.63ID:nlmXbEn2
2014/11/09(日) 20:19:48.73ID:5LKfT6rZ
pythonでは関数=クロージャなんじゃないの?
ラムダ式は関数定義の略記方だよ。
ラムダ式は関数定義の略記方だよ。
2014/11/09(日) 20:27:21.21ID:5LKfT6rZ
変数に束縛された値を求めることは評価するっていうんだと思う。
再束縛は別の値を束縛すること。
再束縛は別の値を束縛すること。
2014/11/09(日) 20:32:25.05ID:lx9et4kr
Lispっぽくクロージャ書けるよ
f = (lambda x:
(lambda y=2*x:
(lambda z=x*y:
(lambda w: w * (y + z))))()())
g = f(2)
g(3) #=> 36
f = (lambda x:
(lambda y=2*x:
(lambda z=x*y:
(lambda w: w * (y + z))))()())
g = f(2)
g(3) #=> 36
2014/11/09(日) 20:34:00.52ID:KOr7L+hP
>>43
言葉を「変数の再束縛」へ言い換えただけでは、結論は同じだよ
C#、Java8、C++11、JavaScript、Ruby 等々の一般的な言語では関数やラムダ式はクロージャを元に
設計されているから、外の環境を参照した値を「局所変数に再束縛」できる
それが当たり前で、自然な関数型プログラミングができる
それに対して(クロージャを元にしていない)手続き型言語の Python では、
ラムダ式の中だと「局所変数に再束縛」できない
従って、手続き型言語の Python は関数型プログラミングには不向きである
言葉を「変数の再束縛」へ言い換えただけでは、結論は同じだよ
C#、Java8、C++11、JavaScript、Ruby 等々の一般的な言語では関数やラムダ式はクロージャを元に
設計されているから、外の環境を参照した値を「局所変数に再束縛」できる
それが当たり前で、自然な関数型プログラミングができる
それに対して(クロージャを元にしていない)手続き型言語の Python では、
ラムダ式の中だと「局所変数に再束縛」できない
従って、手続き型言語の Python は関数型プログラミングには不向きである
2014/11/09(日) 20:34:54.87ID:nlmXbEn2
>>45
評価はPythonのラムダの中でも出来るよな?
評価はPythonのラムダの中でも出来るよな?
2014/11/09(日) 20:37:14.94ID:nlmXbEn2
2014/11/09(日) 20:40:33.21ID:lx9et4kr
2014/11/09(日) 20:49:43.56ID:lx9et4kr
>>44
そうだよ
そうだよ
2014/11/09(日) 21:05:06.25ID:KOr7L+hP
>>47
クロージャを備えた言語であれば、ラムダ式を入れ子にした複雑なコードを書かなくても、
単純明瞭で可読性の高いコードが書ける
f = function(x) {
y = 2 * x;
z = x * y;
return function(w) { return w * (y + z) }
}
g = f(2);
print(g(3));
これがクロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々の普通の言語と
関数型プログラミングに不向きな手続き型言語 Python との違い
クロージャを備えた言語であれば、ラムダ式を入れ子にした複雑なコードを書かなくても、
単純明瞭で可読性の高いコードが書ける
f = function(x) {
y = 2 * x;
z = x * y;
return function(w) { return w * (y + z) }
}
g = f(2);
print(g(3));
これがクロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々の普通の言語と
関数型プログラミングに不向きな手続き型言語 Python との違い
2014/11/09(日) 21:08:04.55ID:lx9et4kr
ラムダ式の入れ子は分かりにくいから
関数型プログラミングに向いてない
関数型とは一体…
関数型プログラミングに向いてない
関数型とは一体…
2014/11/09(日) 21:09:53.89ID:5LKfT6rZ
そもそも関数型プログラミングって堂々と代入してるようじゃダメなのでは
2014/11/09(日) 21:12:20.49ID:lx9et4kr
どれだけ間違いを指摘しても
Pythonにクロージャが無いって意見を上書きできない
これが参照透過性です
Pythonにクロージャが無いって意見を上書きできない
これが参照透過性です
2014/11/09(日) 21:14:02.40ID:KOr7L+hP
2014/11/09(日) 21:18:46.76ID:KOr7L+hP
>>53
>ラムダ式の入れ子は分かりにくいから
>関数型プログラミングに向いてない
添削しよう:
ラムダ式の入れ子は分かりにくいから、
ラムダ式の入れ子や関数内関数を多用しなければならない手続き型言語の Python は
関数型プログラミングに向いてない
それに対して、クロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々の普通の言語では、
クロージャ自身が持つ局所環境内の変数に代入(=束縛)できるから、
関数型プログラミングに向いている
>ラムダ式の入れ子は分かりにくいから
>関数型プログラミングに向いてない
添削しよう:
ラムダ式の入れ子は分かりにくいから、
ラムダ式の入れ子や関数内関数を多用しなければならない手続き型言語の Python は
関数型プログラミングに向いてない
それに対して、クロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々の普通の言語では、
クロージャ自身が持つ局所環境内の変数に代入(=束縛)できるから、
関数型プログラミングに向いている
2014/11/09(日) 21:25:01.25ID:KOr7L+hP
2014/11/09(日) 21:31:21.14ID:lx9et4kr
変数に再束縛できないから、変数に代入できないに意見が変わったね
やっと>>30に追いついたね
やっと>>30に追いついたね
2014/11/09(日) 21:36:16.07ID:lx9et4kr
>>46の変数は外から見えないという意味で
紛れもなく局所変数
紛れもなく局所変数
2014/11/09(日) 21:41:46.54ID:LUEi6lWE
Java 8にクロージャなんかあったっけ?
ただのラムダだったような
ただのラムダだったような
2014/11/09(日) 21:44:14.34ID:KOr7L+hP
2014/11/09(日) 21:45:18.38ID:lx9et4kr
普通は関数定義するよ
当たり前じゃん
当たり前じゃん
2014/11/09(日) 21:49:19.33ID:lx9et4kr
ところで関数はクロージャじゃないって
どこの文化なの?
聞いたことない
どこの文化なの?
聞いたことない
2014/11/09(日) 21:50:58.85ID:KOr7L+hP
2014/11/09(日) 21:55:24.38ID:lx9et4kr
言語的にはJavaのラムダは
ただのメソッド一つのクラスだよ
ただのメソッド一つのクラスだよ
2014/11/09(日) 21:58:19.30ID:KOr7L+hP
2014/11/09(日) 22:04:34.10ID:lx9et4kr
2014/11/09(日) 22:05:03.57ID:TZMLlS/6
Java 8のクロージャは「effectively finalに限りキャプチャ可能」
というなんちゃってな局所環境だけどな
effectively finalの導入でかろうじて使い物になるかも知れないレベル
というなんちゃってな局所環境だけどな
effectively finalの導入でかろうじて使い物になるかも知れないレベル
2014/11/09(日) 22:10:31.90ID:KOr7L+hP
2014/11/09(日) 22:13:13.99ID:n2NDOrh4
>>38
…Haskellにはクロージャが無いと?
…Haskellにはクロージャが無いと?
2014/11/09(日) 22:21:17.10ID:KOr7L+hP
2014/11/09(日) 22:21:52.15ID:lx9et4kr
>>70
だから普通はこう書くよ
あれ?一番簡潔になった?
def f(x):
y = 2 * x
z = x * y
return lambda w: w * (y + z)
g = f(2)
g(3)
だから普通はこう書くよ
あれ?一番簡潔になった?
def f(x):
y = 2 * x
z = x * y
return lambda w: w * (y + z)
g = f(2)
g(3)
2014/11/09(日) 22:25:17.72ID:lx9et4kr
2014/11/09(日) 22:28:55.78ID:GwhuA7Og
>クロージャを識別子に束縛したものが関数だから
C#やECMAScriptの匿名関数は関数ではないと。
珍妙な新説ですなふむふむ
C#やECMAScriptの匿名関数は関数ではないと。
珍妙な新説ですなふむふむ
2014/11/09(日) 22:31:31.78ID:KOr7L+hP
2014/11/09(日) 22:45:45.31ID:KOr7L+hP
>>73
たとえば JavaScript なら、ラムダ式だけ(>>52)と関数定義との併用、
それらのどちらでも簡潔なコードが書けるよ
function f(x) {
y = 2 * x
z = x * y
return function(w) { return w * (y + z) }
}
g = f(2)
g(3)
結局、Python では「ラムダ式を放棄して」関数定義しなければ簡潔なコードを書けない、
ということが実証されてしまったようだね
つまり、真のクロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々のふつうの言語では、
ラムダ式だけでも関数定義との併用でも、ケースバイケースで選択して簡潔で可読性のあるコードを「書ける」けど、
手続き型言語の Python だとラムダ式だけでは「入れ子になったカッコだらけ」の汚いコード(>>47)しか書けないから、
常に関数定義で「書かなければならない」という違いがある
たとえば JavaScript なら、ラムダ式だけ(>>52)と関数定義との併用、
それらのどちらでも簡潔なコードが書けるよ
function f(x) {
y = 2 * x
z = x * y
return function(w) { return w * (y + z) }
}
g = f(2)
g(3)
結局、Python では「ラムダ式を放棄して」関数定義しなければ簡潔なコードを書けない、
ということが実証されてしまったようだね
つまり、真のクロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々のふつうの言語では、
ラムダ式だけでも関数定義との併用でも、ケースバイケースで選択して簡潔で可読性のあるコードを「書ける」けど、
手続き型言語の Python だとラムダ式だけでは「入れ子になったカッコだらけ」の汚いコード(>>47)しか書けないから、
常に関数定義で「書かなければならない」という違いがある
2014/11/09(日) 22:46:49.16ID:nlmXbEn2
2014/11/09(日) 22:49:23.73ID:5LKfT6rZ
2014/11/09(日) 22:51:44.34ID:lx9et4kr
2014/11/09(日) 22:54:09.40ID:nlmXbEn2
2014/11/09(日) 22:56:01.93ID:5LKfT6rZ
でもまあ、pythonの文法が変態なのは間違いない。
2014/11/09(日) 22:56:21.23ID:KOr7L+hP
2014/11/09(日) 22:59:47.88ID:QKkGL4h0
2014/11/09(日) 23:01:05.93ID:lx9et4kr
2014/11/09(日) 23:08:28.24ID:KOr7L+hP
>>80
>で、なぜ関数定義でクロージャが作れる
>Pythonにクロージャがない事になるの?
>>72 で書いたように、真のクロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々の
ふつうの言語では(関数定義だけではなく)ラムダ式でもクロージャが作られるという違いがあるからだ
対して、Python のラムダ式ではクロージャが作られない(だから、局所変数へ値を代入できない)
もし「Pythonにクロージャがない」という主張が不適切であるのならば、
>>42 の最後で書いたように、
「Python の言語設計者達は、処理系への実装を失敗した、あるいは言語設計上の欠陥を見落とした」
と言い換えてもいいよ
こんな使い物にならないラムダ式で満足しなければならないとは、最大の被害者は Python プログラマだよね
だって、他のふつうの言語であれば「ふつうに書ける」ことが、Python じゃ「書けない」のだから....(>>83)
>で、なぜ関数定義でクロージャが作れる
>Pythonにクロージャがない事になるの?
>>72 で書いたように、真のクロージャを備えた C#、Java8、C++11、JavaScript、Ruby 等々の
ふつうの言語では(関数定義だけではなく)ラムダ式でもクロージャが作られるという違いがあるからだ
対して、Python のラムダ式ではクロージャが作られない(だから、局所変数へ値を代入できない)
もし「Pythonにクロージャがない」という主張が不適切であるのならば、
>>42 の最後で書いたように、
「Python の言語設計者達は、処理系への実装を失敗した、あるいは言語設計上の欠陥を見落とした」
と言い換えてもいいよ
こんな使い物にならないラムダ式で満足しなければならないとは、最大の被害者は Python プログラマだよね
だって、他のふつうの言語であれば「ふつうに書ける」ことが、Python じゃ「書けない」のだから....(>>83)
2014/11/09(日) 23:13:26.40ID:5LKfT6rZ
ラムダ式の構文が残念だと言いたいなら、最初からそう言えばいいじゃん。
2014/11/09(日) 23:16:00.89ID:KOr7L+hP
>>84
ラムダ式が引数に値を束縛できるのは、関数型言語を知っていれば常識だよ
そんなことも知らないの?
で、引数以外の局所変数に値を束縛するには、純粋なラムダ式に加えてクロージャが必要になるって話だよ
ラムダ式が引数に値を束縛できるのは、関数型言語を知っていれば常識だよ
そんなことも知らないの?
で、引数以外の局所変数に値を束縛するには、純粋なラムダ式に加えてクロージャが必要になるって話だよ
2014/11/09(日) 23:18:21.66ID:G8K4RNhm
>ラムダ式が引数に値を束縛できるのは
それ束縛じゃねーだろ
キミはアホなのか?
それ束縛じゃねーだろ
キミはアホなのか?
2014/11/09(日) 23:18:59.88ID:nlmXbEn2
2014/11/09(日) 23:23:03.86ID:lx9et4kr
2014/11/09(日) 23:26:01.65ID:lx9et4kr
2014/11/09(日) 23:27:54.79ID:KOr7L+hP
2014/11/09(日) 23:30:45.91ID:nlmXbEn2
2014/11/09(日) 23:33:02.09ID:KOr7L+hP
2014/11/09(日) 23:33:22.37ID:5KptUVSU
使い勝手で一番使い物にならないのはJavaだろ?
void m() {
int y = f();
y = y + 1;
new Thread(
() -> {ここでyを使えないKUSO言語}
);
}
void m() {
int y = f();
y = y + 1;
new Thread(
() -> {ここでyを使えないKUSO言語}
);
}
2014/11/09(日) 23:33:25.09ID:5LKfT6rZ
ID:KOr7L+hP が言ってるのは、
関数の引数にもう少し複雑な処理をインラインで書きたいのに、
defは値返さねえし、lambdaは1行しか書けねえし、
まったく融通がきかねえな!
みたいな字面上の不満であって、関数型プログラミングだのクロージャだの全然関係ない。
関数の引数にもう少し複雑な処理をインラインで書きたいのに、
defは値返さねえし、lambdaは1行しか書けねえし、
まったく融通がきかねえな!
みたいな字面上の不満であって、関数型プログラミングだのクロージャだの全然関係ない。
2014/11/09(日) 23:36:58.94ID:lx9et4kr
2014/11/09(日) 23:39:26.26ID:nlmXbEn2
真のクロージャとかいうオレオレ用語
もちろん引用もなければ定義もない
もちろん引用もなければ定義もない
100デフォルトの名無しさん
2014/11/09(日) 23:40:53.08ID:KOr7L+hP >>94
クロージャという概念を正しく理解していないと、
Python みたいなラムダ式に欠陥のある言語が設計されてしまうというお話だよ
言い換えると、クロージャという概念を用いると、
なぜ Python のラムダ式が欠陥品なのかを明解に説明できる
このクロージャの利点は、このスレの主旨からは逸脱していないと思うよ
クロージャという概念を正しく理解していないと、
Python みたいなラムダ式に欠陥のある言語が設計されてしまうというお話だよ
言い換えると、クロージャという概念を用いると、
なぜ Python のラムダ式が欠陥品なのかを明解に説明できる
このクロージャの利点は、このスレの主旨からは逸脱していないと思うよ
101デフォルトの名無しさん
2014/11/09(日) 23:42:02.22ID:nlmXbEn2102デフォルトの名無しさん
2014/11/09(日) 23:57:43.62ID:KOr7L+hP >>98
No だね
あえていえば「クロージャもどき」とか「なんちゃってクロージャ」だね
真のクロージャであれば無名関数でも間数定義でも作られ、
無名関数であってもクロージャを構成する局所環境を持つことができる
これが、 C#、Java8、C++11、JavaScript、Ruby 等々の
「ふつうの言語」における「ふつうのクロージャ」だ
おそらくクロージャを正しく理解していなかったんだろね、Python 言語設計者達は....
No だね
あえていえば「クロージャもどき」とか「なんちゃってクロージャ」だね
真のクロージャであれば無名関数でも間数定義でも作られ、
無名関数であってもクロージャを構成する局所環境を持つことができる
これが、 C#、Java8、C++11、JavaScript、Ruby 等々の
「ふつうの言語」における「ふつうのクロージャ」だ
おそらくクロージャを正しく理解していなかったんだろね、Python 言語設計者達は....
103デフォルトの名無しさん
2014/11/09(日) 23:59:39.38ID:yjLcynWs 話をまとめよう
世間一般のクロージャの要件:
局所環境を持つ(変数を束縛できる)
関数をインラインで書ける
キチガイのクロージャの要件:
クソージャの中にクソージャが書ける
若しくは
言語設計上の欠陥を見落としたことを認める(>>86の発言)
のいずれか
世間一般のクロージャの要件:
局所環境を持つ(変数を束縛できる)
関数をインラインで書ける
キチガイのクロージャの要件:
クソージャの中にクソージャが書ける
若しくは
言語設計上の欠陥を見落としたことを認める(>>86の発言)
のいずれか
104デフォルトの名無しさん
2014/11/10(月) 00:08:24.74ID:LMH7nFF4105デフォルトの名無しさん
2014/11/10(月) 00:14:31.96ID:cCGgoLPL まあここはscheme最強っていう事にしておきますか。
106デフォルトの名無しさん
2014/11/10(月) 00:28:52.73ID:LMH7nFF4 >>101
> 構文の字面しか見てないし
だとすれば、Martin Fowler氏も「構文の字面しか見てない」ってもとになるんだろな
・Martin Fowler's Bliki in Japanese - クロージャ
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?Closure
Lsip/Smalltalk/Ruby/JavaScript といったプログラミング言語では、
クロージャやブロックを多用したスタイルが好まれる
だから、Python みたいな無名関数で局所環境を持てない言語で同じようにクロージャを
多用するスタイルを試みると、「ラムダ式が入れ子でカッコだらけ(>>46)」な汚いコードや、
いちいち「関数定義しなければならない(>>73)」ケースと頻繁に出会うから、ストレスが溜まる
まあ「Python は手続き型言語」だから仕方ないんだよと自分に言い聞かせて我慢してるけど、
プログラミング言語を自由に選べるなら、真っ先に Python は除外するね、自分なら
もし、これが「構文の字面しか見てない」と思えるのなら、それはそれでもいいんじゃないのかもね.....
> 構文の字面しか見てないし
だとすれば、Martin Fowler氏も「構文の字面しか見てない」ってもとになるんだろな
・Martin Fowler's Bliki in Japanese - クロージャ
http://capsctrl.que.jp/kdmsnr/wiki/bliki/?Closure
Lsip/Smalltalk/Ruby/JavaScript といったプログラミング言語では、
クロージャやブロックを多用したスタイルが好まれる
だから、Python みたいな無名関数で局所環境を持てない言語で同じようにクロージャを
多用するスタイルを試みると、「ラムダ式が入れ子でカッコだらけ(>>46)」な汚いコードや、
いちいち「関数定義しなければならない(>>73)」ケースと頻繁に出会うから、ストレスが溜まる
まあ「Python は手続き型言語」だから仕方ないんだよと自分に言い聞かせて我慢してるけど、
プログラミング言語を自由に選べるなら、真っ先に Python は除外するね、自分なら
もし、これが「構文の字面しか見てない」と思えるのなら、それはそれでもいいんじゃないのかもね.....
107デフォルトの名無しさん
2014/11/10(月) 00:37:52.21ID:cCGgoLPL Pythonはlambdaの不便さも含めて構文がアレなので大嫌いだけど、
ライブラリが色々そろってて便利だから結局よく使っているのであった。
ライブラリが色々そろってて便利だから結局よく使っているのであった。
108デフォルトの名無しさん
2014/11/10(月) 00:42:53.31ID:zIX5GD/A pythonのlambdaってmapやfilterを追加したときに申し訳程度に付けたって感じ
109デフォルトの名無しさん
2014/11/10(月) 02:52:22.03ID:qQmxJFhq >>106
その文章を書いた人の考えと、君の解釈には随分とズレがあるようだ
その文章を書いた人の考えと、君の解釈には随分とズレがあるようだ
110デフォルトの名無しさん
2014/11/10(月) 06:04:53.17ID:i3Y7RgoA 馬鹿には無理
111デフォルトの名無しさん
2014/11/10(月) 07:14:42.95ID:0mRy26rG Pythonの不自由さ(関数型のクロージャに近いの)はGuidoの方針じゃないの?
嫌なら、おとなしくジェネレータ使えばいいじゃん。
嫌なら、おとなしくジェネレータ使えばいいじゃん。
112デフォルトの名無しさん
2014/11/10(月) 08:48:39.72ID:PWSP4TjP クロージャは何がいいんだよ!
https://i.imgur.com/fTQTEYN.gif
https://i.imgur.com/fTQTEYN.gif
113デフォルトの名無しさん
2014/11/10(月) 09:04:03.39ID:HTkQymog 引数に別名付けたくなる程に中身が長いなら
関数にも名前付けろってのがGuidoの方針なんだろ
文法的に拡張可能なのに、あえてリジェクトしてるくらいだし
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
関数にも名前付けろってのがGuidoの方針なんだろ
文法的に拡張可能なのに、あえてリジェクトしてるくらいだし
http://www.artima.com/weblogs/viewpost.jsp?thread=147358
114デフォルトの名無しさん
2014/11/10(月) 10:20:30.55ID:CeTPRNSr1151
2014/11/10(月) 11:39:28.98ID:rdbd3Lyi 何がクロージャかよりどこが好きかでクロージャを語れよ!!(ドンッ
116デフォルトの名無しさん
2014/11/10(月) 20:33:09.35ID:AR7BQCkT クロージャとメソッドで f[x] と f(x) を使い分けなきゃダメなRubyが
一番ウンコだと思う
一番ウンコだと思う
117デフォルトの名無しさん
2014/11/10(月) 20:39:42.07ID:5eyjbk6/118デフォルトの名無しさん
2014/11/10(月) 21:34:09.37ID:Xzn5T3EF119デフォルトの名無しさん
2014/11/10(月) 22:47:25.14ID:oQ75X8QG 文系出身プログラマ「クロージャ?なにそれ?服入れるとこ??」
ってやつに対してドヤ顔ができる
ってやつに対してドヤ顔ができる
120デフォルトの名無しさん
2014/11/11(火) 06:32:45.68ID:G8l0apNf クロー系の最強魔法です 消費MP60
121118
2014/11/11(火) 21:00:28.44ID:UknPa1bY レスお願いします
122デフォルトの名無しさん
2014/11/11(火) 22:06:02.40ID:3gT2I0NB 若い時に買ってでもすることは?
苦労じゃ!くろうじゃ!クロージャ!
苦労じゃ!くろうじゃ!クロージャ!
123デフォルトの名無しさん
2014/11/12(水) 01:25:01.41ID:G1/eYMX4 クロージャの良さを、クロージャを使うことで劇的に
簡潔になる例を使って説明してください
簡潔になる例を使って説明してください
124デフォルトの名無しさん
2014/11/12(水) 07:27:28.43ID:ptlTHlgg コールバック関数を別途書かなくて良くなります。
もしコールバック関数の為だけにインスタンス変数を定義していたなら、
それも必要が無くなります。
消費MP 5
もしコールバック関数の為だけにインスタンス変数を定義していたなら、
それも必要が無くなります。
消費MP 5
125デフォルトの名無しさん
2014/11/12(水) 08:10:30.04ID:G1/eYMX4 コールバック関数地獄のJSのコードは
可読性が悪い上に簡潔でも無いので、失格です
可読性が悪い上に簡潔でも無いので、失格です
126デフォルトの名無しさん
2014/11/12(水) 08:13:15.39ID:/hly7+iy オールバックって額からハゲるだろ?
127デフォルトの名無しさん
2014/11/12(水) 08:27:11.27ID:cKuXIrT/128デフォルトの名無しさん
2014/11/12(水) 20:27:05.24ID:3VJGATlA129デフォルトの名無しさん
2014/11/12(水) 20:37:53.49ID:L8labB6g 見慣れてるかどうかだと思うけどな
130デフォルトの名無しさん
2014/11/12(水) 20:38:24.71ID:5GyhUZuz >>128
代案も出さずに批判だけするなら、幼稚園児にだってできるよ
代案も出さずに批判だけするなら、幼稚園児にだってできるよ
131デフォルトの名無しさん
2014/11/12(水) 20:52:00.80ID:UPi6O5bX リスナーI/Fをインプリメントしたオブジェクト渡せばいいのでは
132デフォルトの名無しさん
2014/11/12(水) 21:14:25.68ID:ptlTHlgg それではそのオブジェクトを定義しなくてはならなくなります。
クロージャはそのようなデリゲートオブジェクトやコールバックパターンからの解放なのです。
消費MP 12
クロージャはそのようなデリゲートオブジェクトやコールバックパターンからの解放なのです。
消費MP 12
133デフォルトの名無しさん
2014/11/12(水) 21:16:45.87ID:eep146vT JavaScript(だけに限らないが)
クロージャーが見難いんじゃなくて
非同期の入れ子が見にくいんだろ。
で、それを解決するライブラリが存在する。
結局のところ、そのライブラリ
Promiseとかを使えば解決する問題。
クロージャーが見難いんじゃなくて
非同期の入れ子が見にくいんだろ。
で、それを解決するライブラリが存在する。
結局のところ、そのライブラリ
Promiseとかを使えば解決する問題。
134デフォルトの名無しさん
2014/11/12(水) 21:23:36.45ID:G1/eYMX4 結局のところ、コールバックはクロージャのメリットじゃないんですね?
もっと良い方法があるのですから
もっと良い方法があるのですから
135デフォルトの名無しさん
2014/11/12(水) 21:36:55.56ID:ptlTHlgg いや、クロージャ使ってそのスコープで解決しちゃえばコールバック関数要らないって話なんだが。
136デフォルトの名無しさん
2014/11/12(水) 21:59:20.14ID:G1/eYMX4 Haskellのdo記法みたいなのがあれば
クロージャをチェインしていっても読み難くならないという話ですか?
クロージャをチェインしていっても読み難くならないという話ですか?
137デフォルトの名無しさん
2014/11/12(水) 22:58:17.02ID:L8labB6g 小規模なコールバックだったらインラインで書いた方が見通しが良いだろうし、
複雑なのだったら分けて書いた方が理解しやすいだろうし、
あれが最強他はゴミとか言ってるのが一番ダメなんじゃね?
複雑なのだったら分けて書いた方が理解しやすいだろうし、
あれが最強他はゴミとか言ってるのが一番ダメなんじゃね?
138デフォルトの名無しさん
2014/11/15(土) 12:17:49.98ID:uUcubJGq 結局クロージャの利点てコールバックが楽にかけるってだけ?
ならクロージャや匿名オブジェクトじゃなくて匿名メソッドが書ければ充分だな
ならクロージャや匿名オブジェクトじゃなくて匿名メソッドが書ければ充分だな
139デフォルトの名無しさん
2014/11/15(土) 12:25:31.04ID:u4ZMuG60 楽に書けるって事じゃなくて、そのスコープで完結できるって事じゃね?
140デフォルトの名無しさん
2014/11/15(土) 12:56:58.32ID:XlhMXrhL とりあえずコードで語れば?
大規模開発でメリットが出てくるとかの話じゃないんだし
大規模開発でメリットが出てくるとかの話じゃないんだし
141デフォルトの名無しさん
2014/11/15(土) 14:40:16.71ID:EFct/v5k 見た目的にも変数の値の可視性的にもそこのスコープってとこが楽だよね
142デフォルトの名無しさん
2014/11/15(土) 14:43:26.00ID:XlhMXrhL つまりインラインでクラス定義できるのでも良いわけだよね
143デフォルトの名無しさん
2014/11/15(土) 15:14:55.72ID:EFct/v5k >>142
本来そうだけど 、
シンタックスはインラインだけど実際はただの内部クラスで、
生成時の環境を一切利用できない言語もあるから何とも言えない。
クロージャの代わりにクラスを用いると何となくそういう実装になる。
ローカル環境の代わりにインスタンス変数を用いる方向にいくから。
FILE *fp = fopen(..);
doHoge( ^(const char*msg){ fputs(msg,fp); });
fclose(fp);
みたいに簡便にクロージャ生成時の外部の変数(の値のコピー)を
保持し使用できるクロージャとは方向性が違う。
ローカルメソッドに至っては環境が一昨渡せない
シングルスレッド前提ならグローバル変数を使えばいいわけだけど
本来そうだけど 、
シンタックスはインラインだけど実際はただの内部クラスで、
生成時の環境を一切利用できない言語もあるから何とも言えない。
クロージャの代わりにクラスを用いると何となくそういう実装になる。
ローカル環境の代わりにインスタンス変数を用いる方向にいくから。
FILE *fp = fopen(..);
doHoge( ^(const char*msg){ fputs(msg,fp); });
fclose(fp);
みたいに簡便にクロージャ生成時の外部の変数(の値のコピー)を
保持し使用できるクロージャとは方向性が違う。
ローカルメソッドに至っては環境が一昨渡せない
シングルスレッド前提ならグローバル変数を使えばいいわけだけど
144デフォルトの名無しさん
2014/11/15(土) 15:54:48.49ID:uUcubJGq (擬似言語)
fw = new FileWriter();
doHoge( fw.witer );
fw.close();
こんなのをワンラインで書ければ満足なんだろ?匿名メソッドで十分じゃない
fw = new FileWriter();
doHoge( fw.witer );
fw.close();
こんなのをワンラインで書ければ満足なんだろ?匿名メソッドで十分じゃない
145デフォルトの名無しさん
2014/11/15(土) 15:58:46.71ID:EFct/v5k >>144
じゃ匿名メソッドで書いてごらんよ
じゃ匿名メソッドで書いてごらんよ
146デフォルトの名無しさん
2014/11/15(土) 23:46:47.75ID:JsFAZjCZ with (fw, new FileWriter()) {
doHoge(fw.witer);
}
こうやって書けるほうがいい
doHoge(fw.witer);
}
こうやって書けるほうがいい
147デフォルトの名無しさん
2014/11/16(日) 10:37:06.14ID:ZMiOBdAw じゃあこれは?
FILE *fp = fopen(..);
doHoge( ^(const char*msg){ fprintf(fp, "Hoge: %s\n", msg); });
fclose(fp);
FILE *fp = fopen(..);
doHoge( ^(const char*msg){ fprintf(fp, "Hoge: %s\n", msg); });
fclose(fp);
148デフォルトの名無しさん
2014/11/16(日) 11:54:54.13ID:fx2XWh+X >>146
もはや匿名メソッドすら要らない派が出てくるしww
もはや匿名メソッドすら要らない派が出てくるしww
149デフォルトの名無しさん
2014/11/18(火) 16:33:41.48ID:cuxiU0eb Java8すら使わせてもらえない人が必死なスレにしか見えなくなってきた
150デフォルトの名無しさん
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 に分類されている
それだと 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 に分類されている
151デフォルトの名無しさん
2014/11/19(水) 23:00:05.80ID:074lLX1H クロージャばりばり使うlisp方言でもwith構文は使うよ
152デフォルトの名無しさん
2014/11/19(水) 23:12:18.42ID:3WdraWBV クロージャとクリーンアップ処理とは別の話じゃないの?
153デフォルトの名無しさん
2014/11/19(水) 23:33:41.68ID:PA9iCB5s Pythonが憎すぎて既知外になった人の相手をしちゃいけません
154デフォルトの名無しさん
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になってるわけじゃない
お前、ほんと、馬鹿だよね?
> なお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になってるわけじゃない
お前、ほんと、馬鹿だよね?
155デフォルトの名無しさん
2014/11/19(水) 23:57:41.67ID:eeZRz+g3 クロージャと with 構文のどちらも持っている言語であれば、
ケースバイケースで可読性や好みで使い分ければいいのではないかと
問題はクロージャを持たない、あるいは
「世間一般のクロージャの要件(>>104)」を満たせない言語では、
with 構文という(クロージャと比べて)不自由な代用品を使わざるをえない
という話
ケースバイケースで可読性や好みで使い分ければいいのではないかと
問題はクロージャを持たない、あるいは
「世間一般のクロージャの要件(>>104)」を満たせない言語では、
with 構文という(クロージャと比べて)不自由な代用品を使わざるをえない
という話
156デフォルトの名無しさん
2014/11/20(木) 00:02:30.91ID:fhZ8V3Hu157デフォルトの名無しさん
2014/11/20(木) 00:19:03.39ID:wJ3BgpRF >>154
>ここで言ってるwithは例外が起きた時にリソースを解放する機能を持ったもの。
わざわざ with という構文を追加して言語の意味論を複雑にしなくても、
もし汎用的な概念であるクロージャがあれば、同じ事を実現できるってことだよ
もし Python にもクロージャがあるなら、他の言語達と同様に
with 構文を使わなくてもリソースの自動解放を簡潔に表現できるハズだけど、
手続き型言語の Python では無理だろうね
それとも、書けるかな?
>ここで言ってるwithは例外が起きた時にリソースを解放する機能を持ったもの。
わざわざ with という構文を追加して言語の意味論を複雑にしなくても、
もし汎用的な概念であるクロージャがあれば、同じ事を実現できるってことだよ
もし Python にもクロージャがあるなら、他の言語達と同様に
with 構文を使わなくてもリソースの自動解放を簡潔に表現できるハズだけど、
手続き型言語の Python では無理だろうね
それとも、書けるかな?
158デフォルトの名無しさん
2014/11/20(木) 00:20:15.54ID:7GcQ+ika pythonでも引数にクロージャ受け取ってwithの中でそれを実行する関数つくれば、rubyのそれと等価じゃね?
pythonはlambdaが制限きついから複雑な処理はインラインには書けないけど。
pythonはlambdaが制限きついから複雑な処理はインラインには書けないけど。
159デフォルトの名無しさん
2014/11/20(木) 00:29:37.23ID:wJ3BgpRF160デフォルトの名無しさん
2014/11/20(木) 00:36:40.77ID:ri7Qzvfi 「世間一般のクロージャの要件」が
全然世間一般の定義じゃない件
全然世間一般の定義じゃない件
161デフォルトの名無しさん
2014/11/20(木) 00:37:00.07ID:7GcQ+ika >>159
def make_f(x):
def f(y):
return x * y
return f
例えばこんなのがあったとして、このmake_f()が返すものは何?
def make_f(x):
def f(y):
return x * y
return f
例えばこんなのがあったとして、このmake_f()が返すものは何?
162デフォルトの名無しさん
2014/11/20(木) 00:42:39.12ID:wJ3BgpRF163デフォルトの名無しさん
2014/11/20(木) 00:44:55.24ID:7GcQ+ika >>162
「クロージャみたいなモノ」もしくは「クロージャもどき」と、クロージャの違いは何?
「クロージャみたいなモノ」もしくは「クロージャもどき」と、クロージャの違いは何?
164デフォルトの名無しさん
2014/11/20(木) 00:45:40.70ID:ri7Qzvfi165デフォルトの名無しさん
2014/11/20(木) 00:47:27.27ID:wJ3BgpRF166デフォルトの名無しさん
2014/11/20(木) 00:52:13.60ID:7GcQ+ika167デフォルトの名無しさん
2014/11/20(木) 00:58:03.79ID:wJ3BgpRF168デフォルトの名無しさん
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
ちょっと前まで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
169デフォルトの名無しさん
2014/11/20(木) 01:03:38.95ID:ri7Qzvfi170デフォルトの名無しさん
2014/11/20(木) 01:04:53.19ID:wJ3BgpRF171デフォルトの名無しさん
2014/11/20(木) 01:06:05.89ID:7GcQ+ika >>170
じゃあさ、これが返すものは何?
(define (make_f x)
(define (f y)
(* x y))
f)
じゃあさ、これが返すものは何?
(define (make_f x)
(define (f y)
(* x y))
f)
172デフォルトの名無しさん
2014/11/20(木) 01:07:50.18ID:fhZ8V3Hu173デフォルトの名無しさん
2014/11/20(木) 01:10:58.55ID:wJ3BgpRF174デフォルトの名無しさん
2014/11/20(木) 01:11:10.32ID:7GcQ+ika >>171
ごめん。それで (make_f 10) とか実行した時に返ってくるもの、の間違い。
ごめん。それで (make_f 10) とか実行した時に返ってくるもの、の間違い。
175デフォルトの名無しさん
2014/11/20(木) 01:15:12.19ID:wJ3BgpRF176デフォルトの名無しさん
2014/11/20(木) 01:18:52.68ID:7GcQ+ika177デフォルトの名無しさん
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などがある。
> さすがに Wikipedia のページ著者が
Wikipediaの編集者を持ち上げるのは良いけど、
お前の主張とは違う事が書いてあるぜ
読めるか?Pythonって書いてある
> クロージャを持つ言語に、C# 3.0、C++11、ECMAScript(JavaScriptを含む)、Groovy、Java 8(予定)、
> Perl、Python、Ruby、PHP(5.3以降)、Lua、Squirrelなどがある。
178デフォルトの名無しさん
2014/11/20(木) 01:28:21.39ID:wJ3BgpRF179デフォルトの名無しさん
2014/11/20(木) 01:32:42.88ID:fhZ8V3Hu180デフォルトの名無しさん
2014/11/20(木) 09:44:37.50ID:BfhGUngW with構文はスコープから抜ける時にclose的な関数を必ず呼び出してくれる保証があるけど、
Rubyのブロックにはそんな保証は無い
だからRubyではウッカリcloseを忘れても分かりにくい
そういうのは良くない
Rubyのブロックにはそんな保証は無い
だからRubyではウッカリcloseを忘れても分かりにくい
そういうのは良くない
181デフォルトの名無しさん
2014/11/20(木) 11:08:08.37ID:nwROesTX >>178
> Wikipedia の記事が常に 100% 正しいと思っているのかな?
思ってないけど、あんたが言っていることよりかは
正しいと思うね。
だって、あんたの言うことのほうが正しいなら
wikipediaを修正すればいいわけだから。
> Wikipedia の記事が常に 100% 正しいと思っているのかな?
思ってないけど、あんたが言っていることよりかは
正しいと思うね。
だって、あんたの言うことのほうが正しいなら
wikipediaを修正すればいいわけだから。
182デフォルトの名無しさん
2014/11/20(木) 12:57:07.44ID:5gFBGGbj なんだ、この偏執狂たちの罵り合いはw
そんなことより、問題。
若い内に買ってでもしろ、と言われるものはなぁんだ?
そんなことより、問題。
若い内に買ってでもしろ、と言われるものはなぁんだ?
183デフォルトの名無しさん
2014/11/20(木) 15:15:51.24ID:W3M4RtQD ああ、let-inが無いからpythonのはクロージャじゃないって主張か。
斜め上だな。
斜め上だな。
184デフォルトの名無しさん
2014/11/20(木) 16:40:50.21ID:2szoNUEC 環境と変数を手軽に包めるのは有難いけどなあ
XMLベースのジョブ管理言語とか
ちょっとしたVM作るときに
継続の表現にクロージャなしだとだるいよ
さらに無名クラスも無い言語だと
本物のVM作らなきゃいけなくなる
XMLベースのジョブ管理言語とか
ちょっとしたVM作るときに
継続の表現にクロージャなしだとだるいよ
さらに無名クラスも無い言語だと
本物のVM作らなきゃいけなくなる
185デフォルトの名無しさん
2014/11/20(木) 20:12:20.93ID:IqIimPum186デフォルトの名無しさん
2014/11/21(金) 13:07:27.23ID:obtZMam2187デフォルトの名無しさん
2014/11/21(金) 13:13:28.47ID:zygDXSz1 >>186
ご愁傷さまです。
ご愁傷さまです。
188デフォルトの名無しさん
2014/11/29(土) 13:01:53.24ID:OX49RFg5 >>188
?
?
189デフォルトの名無しさん
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 が劣る典型的な一例になる
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 が劣る典型的な一例になる
190デフォルトの名無しさん
2014/12/10(水) 20:24:01.24ID:Q728OFWk と言うかどう見てもこないだまでこのスレに居た俺俺定義の人ですな
191デフォルトの名無しさん
2014/12/10(水) 20:43:29.64ID:Q728OFWk よく見たら、そのスレで誘導かけてるの、話振ったお前本人じゃねーかw
俺俺定義が認められなかったから逃げて来たのか?
俺俺定義が認められなかったから逃げて来たのか?
192デフォルトの名無しさん
2014/12/10(水) 21:30:40.85ID:AwBDqpLr クロージャの定義は>>4って書かれてたがStandard MLにラムダ式はない
けど当然SMLにはクロージャがあるわけで
ソースはThe Definition of Standard ML, revised edition
けど当然SMLにはクロージャがあるわけで
ソースはThe Definition of Standard ML, revised edition
193デフォルトの名無しさん
2014/12/10(水) 21:46:37.74ID:ZY5znPCs 関数型プログラミングってどういうのを指して言ってるんだろ
194デフォルトの名無しさん
2014/12/10(水) 21:50:32.14ID:gkNqf6iG195デフォルトの名無しさん
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
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
196デフォルトの名無しさん
2014/12/11(木) 21:48:16.84ID:AENhOzwc197デフォルトの名無しさん
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
過去に何度もネット上で話題になっていたようだね:
・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
198デフォルトの名無しさん
2014/12/11(木) 22:55:21.60ID:aWaBOmKM199デフォルトの名無しさん
2014/12/11(木) 23:02:23.22ID:GpAyUabF >>196
ではクロージャ定義の引用元ソースを示そうね
答えは書籍「計算機プログラムの構造と解釈」、いわゆるSICP本だ
その中の節「3.2.1 評価の規則」に手続きオブジェクトが、いわゆるクロージャに対応する
http://sicp.iijlab.net/fulltext/x321.html
そしてクロージャを視覚化したのが、
このページの図3.2にあるオタマジャクシの卵が2つ並んだ図形になる
単純な話だと思うけど、難しいかな?
ではクロージャ定義の引用元ソースを示そうね
答えは書籍「計算機プログラムの構造と解釈」、いわゆるSICP本だ
その中の節「3.2.1 評価の規則」に手続きオブジェクトが、いわゆるクロージャに対応する
http://sicp.iijlab.net/fulltext/x321.html
そしてクロージャを視覚化したのが、
このページの図3.2にあるオタマジャクシの卵が2つ並んだ図形になる
単純な話だと思うけど、難しいかな?
200デフォルトの名無しさん
2014/12/11(木) 23:27:50.83ID:GpAyUabF >>198
関数を宣言せずに書くという制約の元ですから、とてもPythonらしいコードだと思います
しかもループの代わりに関数再帰を使っているのですから、より関数型プログラミングらしいとも言えます
ただし、元々 Swift で書かれていたサンプルコードを各 LL へと書き直しているのですから、
もし以下の点を改善できれば(Pythonらしさという意味では)完璧でしょう:
・中間変数 f を宣言せず、リスト内包式の中にラムダ式をインラインで書く
・Swift のコードは辞書を使っているのですから、それを(勝手に)配列 digits へ改変せず、
Python でも(Ruby や JavaScript と同様に)辞書を使って書く
関数を宣言せずに書くという制約の元ですから、とてもPythonらしいコードだと思います
しかもループの代わりに関数再帰を使っているのですから、より関数型プログラミングらしいとも言えます
ただし、元々 Swift で書かれていたサンプルコードを各 LL へと書き直しているのですから、
もし以下の点を改善できれば(Pythonらしさという意味では)完璧でしょう:
・中間変数 f を宣言せず、リスト内包式の中にラムダ式をインラインで書く
・Swift のコードは辞書を使っているのですから、それを(勝手に)配列 digits へ改変せず、
Python でも(Ruby や JavaScript と同様に)辞書を使って書く
201デフォルトの名無しさん
2014/12/12(金) 00:10:51.51ID:kNbqUbaQ202デフォルトの名無しさん
2014/12/12(金) 09:01:50.64ID:hLblKLHb >>199
で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?
「Schemeという特定の言語」で「クロージャはlambda式で作られる」と書いてあるだけだが?
いい加減、誤摩化して逃げ回るのは止めたら?
で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?
「Schemeという特定の言語」で「クロージャはlambda式で作られる」と書いてあるだけだが?
いい加減、誤摩化して逃げ回るのは止めたら?
203デフォルトの名無しさん
2014/12/12(金) 19:05:12.73ID:1wfis/cT 別にPythonのラムダに式が書けないから問題だと言うだけなら荒れねーよ
そこで「だからPythonにはクロージャが無い」って言う
決して成り立たない等式を持ち込むから「いやそのりくつはおかしい」って言われてんのに
そしたら既存のクロージャという用語の定義のほうを弄ろうとするから叩かれてんだろうが
プログラミングに例えるなら、お前は自分の書いた関数で
組み込み整数型の値にそのままリスト処理を適用しようとして例外吐かれたから、と
整数クラスのほうがリストとして振る舞うようにメソッドを書き換えようとしてる
そこで「だからPythonにはクロージャが無い」って言う
決して成り立たない等式を持ち込むから「いやそのりくつはおかしい」って言われてんのに
そしたら既存のクロージャという用語の定義のほうを弄ろうとするから叩かれてんだろうが
プログラミングに例えるなら、お前は自分の書いた関数で
組み込み整数型の値にそのままリスト処理を適用しようとして例外吐かれたから、と
整数クラスのほうがリストとして振る舞うようにメソッドを書き換えようとしてる
204デフォルトの名無しさん
2014/12/12(金) 22:20:24.14ID:ZYnyJXBo205デフォルトの名無しさん
2014/12/12(金) 22:38:08.46ID:hhr7pvhS206デフォルトの名無しさん
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.
とりあえずクロージャの定義を貼っておきますね
反論よろしく
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.
207デフォルトの名無しさん
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という特定の言語」と書いてあるの?
いい加減、誤摩化して言い逃れをするのは止めたら?
> で、どこに「クロージャは無名関数でなければダメ」と書いてあるの?
もちろん「クロージャは無名関数でなければダメ」とは書かれていない
同時に「ラムダ式に文が書かなくともクロージャである」とも書かれていない
SICP本を理解するには、記述されている定義から類推によって解釈できる知性が必要だね
>「Schemeという特定の言語」で「クロージャはlambda式で作られる」と書いてあるだけだが?
この節で記述されているのはクロージャの一般的な概念であり、特定の言語や実装には限定されない
ここで記述されている概念に沿って設計された言語であれば、たとえば:
・Scheme なら (lambda (x) .... ) で、
・Standard ML なら fn x => .... で、
・JavaScript なら function(x) { ..... } で、
・Ruby なら proc { |x| .... } で作られる
ここで.... の部分には、破壊的代入や入出力等の副作用を伴う任意のコードが書ける
唯一、書けないのは Python だけ
で、どこに「Schemeという特定の言語」と書いてあるの?
いい加減、誤摩化して言い逃れをするのは止めたら?
208デフォルトの名無しさん
2014/12/12(金) 23:54:36.75ID:ZYnyJXBo209デフォルトの名無しさん
2014/12/13(土) 00:01:46.30ID:HrrHquek 一時変数を消すためにそんなパズルみたいな事やって読みやすいわけないだろw
210デフォルトの名無しさん
2014/12/13(土) 00:13:09.40ID:HrrHquek >>207
schemeではlambdaが本質的なもので(define (f x) 〜)はシンタックスシュガーだけど、
pythonではdefが本質的なものでlambdaの方がシンタックスシュガーなのでは。
schemeではlambdaが本質的なもので(define (f x) 〜)はシンタックスシュガーだけど、
pythonではdefが本質的なものでlambdaの方がシンタックスシュガーなのでは。
211デフォルトの名無しさん
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 で書いたように)単なる式だけではなく
破壊的代入や入出力等の副作用を伴う任意のコードも書けると解釈するのが自然だと考える
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 で書いたように)単なる式だけではなく
破壊的代入や入出力等の副作用を伴う任意のコードも書けると解釈するのが自然だと考える
212デフォルトの名無しさん
2014/12/13(土) 02:01:28.39ID:6/3yjF6w213デフォルトの名無しさん
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:SaitqfQN314デフォルトの名無しさん
2014/12/19(金) 00:07:27.38ID:lMWP4GlC >>313
おおっ!わざわざどうも!
SMLとOCamlの関係だからこういう似たような感じになるのかな?
それともループを再帰に置き換えたらどうせどの言語でもこんな感じかな?
それにしても関数型言語なるものを知るにつれて思うのは、
再帰についてはすがすがしいが、
それ以外についてはタイプ量が増えがちってこと。
ハッシュテーブルひとつ準備するのにもウダウダ。
関数型どうのというより、個別の言語によるのかもしれないけど…。
おおっ!わざわざどうも!
SMLとOCamlの関係だからこういう似たような感じになるのかな?
それともループを再帰に置き換えたらどうせどの言語でもこんな感じかな?
それにしても関数型言語なるものを知るにつれて思うのは、
再帰についてはすがすがしいが、
それ以外についてはタイプ量が増えがちってこと。
ハッシュテーブルひとつ準備するのにもウダウダ。
関数型どうのというより、個別の言語によるのかもしれないけど…。
315デフォルトの名無しさん
2014/12/20(土) 00:24:39.20ID:0cpPf2uS >>314
>SMLとOCamlの関係だからこういう似たような感じになるのかな?
SML も OCaml も同じML族の一員ですから、そんな感じになるのも不思議じゃないと思いますね
>それともループを再帰に置き換えたらどうせどの言語でもこんな感じかな?
SML 以外の関数型言語は触った程度のレベルなので、以下はあくまで私見です:
・Lisp でも似た感じの再帰になる
ただし Lisp は TCO が保証されていないから、一般的な反復処理であれば
loop や while マクロ(または、その相当品)で手続き的なループで書く
・Scheme は TCO が言語仕様で保証されているので、普通は再帰で書く(>>302)
また継続(call/cc)があるので、loop や while の相当品を関数として自前で定義することも可能
・Haskell の場合、初めのうちは(ML や Scheme と同様に)再帰で書く
ただし Haskell だと文字列は文字型のリストであり、標準ライブラリの unfoldl を使う事を学ぶようになる
・関数プログラミングの楽しみ
http://www.amazon.co.jp//dp/4274068056
第3章「おりがみプログラミング」で詳しく解説されています
ということで Haskell の定義を参考にして、SML でも関数 unfoldl で再帰を抽象化したコードを書きました:
http://ideone.com/o5JM86
ここで unfold とは、よく知られている fold の双対な概念です
(fold は、Ruby だと inject、Lisp や JavaScript では reduce と呼ばれています)
fold xs が「あるリスト xs を畳んだ値 y」を返すのに対し、
unfold y は「ある値 y を広げたリスト xs」を返します
なお、「畳む/広げる」という言葉よりも「分解する(destruct)/組立てる(construct)」のほうが直感的かもしれません
(* 長いので、続く *)
>SMLとOCamlの関係だからこういう似たような感じになるのかな?
SML も OCaml も同じML族の一員ですから、そんな感じになるのも不思議じゃないと思いますね
>それともループを再帰に置き換えたらどうせどの言語でもこんな感じかな?
SML 以外の関数型言語は触った程度のレベルなので、以下はあくまで私見です:
・Lisp でも似た感じの再帰になる
ただし Lisp は TCO が保証されていないから、一般的な反復処理であれば
loop や while マクロ(または、その相当品)で手続き的なループで書く
・Scheme は TCO が言語仕様で保証されているので、普通は再帰で書く(>>302)
また継続(call/cc)があるので、loop や while の相当品を関数として自前で定義することも可能
・Haskell の場合、初めのうちは(ML や Scheme と同様に)再帰で書く
ただし Haskell だと文字列は文字型のリストであり、標準ライブラリの unfoldl を使う事を学ぶようになる
・関数プログラミングの楽しみ
http://www.amazon.co.jp//dp/4274068056
第3章「おりがみプログラミング」で詳しく解説されています
ということで Haskell の定義を参考にして、SML でも関数 unfoldl で再帰を抽象化したコードを書きました:
http://ideone.com/o5JM86
ここで unfold とは、よく知られている fold の双対な概念です
(fold は、Ruby だと inject、Lisp や JavaScript では reduce と呼ばれています)
fold xs が「あるリスト xs を畳んだ値 y」を返すのに対し、
unfold y は「ある値 y を広げたリスト xs」を返します
なお、「畳む/広げる」という言葉よりも「分解する(destruct)/組立てる(construct)」のほうが直感的かもしれません
(* 長いので、続く *)
316デフォルトの名無しさん
2014/12/20(土) 00:32:09.09ID:0cpPf2uS (* >>315 の続き *)
なお、map や filter といった高階関数を一般化したものが fold であることは
よく知られていますが、ここでリストを代数(群)に見立てた圏論の視点で再構成すると:
・fold を(更に)一般化したものがカタモルフィズム(catamorphism)である
・unfold を(更に)一般化したものがアナモルフィズム(anamorphism)である
という、本質的な形でリスト処理を定義できるようになります
(モナドとは関連しない)圏論を応用したプログラミングについては、以下のプレゼンがお薦めです
・Introduction to Categorical Programming (Revised)
http://www.slideshare.net/sakai/introduction-to-categorical-programming-revised
p.18 の図式を使った「圏論でのリスト型の定義」が直感的です
詳細については、以下の記事で紹介されている論文(英語)が分かりやすかったです
・Haskellと圏論を学んできて、そのまとめとしてちょうどよい論文を見つけたのでメモ。
https://plus.google.com/+OsamuNagano/posts/7cPfAQ145Yi
>それにしても関数型言語なるものを知るにつれて思うのは、....
ML や Haskell は静的型付けによる安全性と高速化を主眼に設計された言語ですから、
Ruby や Python といったスクリプト言語の置き換えには成り得ないと考えます
これに関しては、以前に別スレ「LLにおける関数型プログラミング」で説明しています
http://peace.2ch.net/test/read.cgi/tech/1345123070/28
また ML や Haskell の強力な型推論は、データ型に関する矛盾(=バグ)が存在しないことを(実行の前に)証明しますが、
動かしては書き直す(いわゆるトライ&エラー)が一般的なスクリプトプログラミングには不向きだと考えます
(* これで終わり *)
なお、map や filter といった高階関数を一般化したものが fold であることは
よく知られていますが、ここでリストを代数(群)に見立てた圏論の視点で再構成すると:
・fold を(更に)一般化したものがカタモルフィズム(catamorphism)である
・unfold を(更に)一般化したものがアナモルフィズム(anamorphism)である
という、本質的な形でリスト処理を定義できるようになります
(モナドとは関連しない)圏論を応用したプログラミングについては、以下のプレゼンがお薦めです
・Introduction to Categorical Programming (Revised)
http://www.slideshare.net/sakai/introduction-to-categorical-programming-revised
p.18 の図式を使った「圏論でのリスト型の定義」が直感的です
詳細については、以下の記事で紹介されている論文(英語)が分かりやすかったです
・Haskellと圏論を学んできて、そのまとめとしてちょうどよい論文を見つけたのでメモ。
https://plus.google.com/+OsamuNagano/posts/7cPfAQ145Yi
>それにしても関数型言語なるものを知るにつれて思うのは、....
ML や Haskell は静的型付けによる安全性と高速化を主眼に設計された言語ですから、
Ruby や Python といったスクリプト言語の置き換えには成り得ないと考えます
これに関しては、以前に別スレ「LLにおける関数型プログラミング」で説明しています
http://peace.2ch.net/test/read.cgi/tech/1345123070/28
また ML や Haskell の強力な型推論は、データ型に関する矛盾(=バグ)が存在しないことを(実行の前に)証明しますが、
動かしては書き直す(いわゆるトライ&エラー)が一般的なスクリプトプログラミングには不向きだと考えます
(* これで終わり *)
317デフォルトの名無しさん
2014/12/20(土) 07:17:42.63ID:tzPxF8Oh 長い
3行でまとめろ
3行でまとめろ
318デフォルトの名無しさん
2014/12/20(土) 12:12:13.43ID:PEBuGla8 珍しく普通に相手にしてもらって
うれしくてたまらない
オレオレクロージャくんであった
うれしくてたまらない
オレオレクロージャくんであった
319デフォルトの名無しさん
2014/12/20(土) 16:08:48.96ID:5dXZUu33 >>315-316
> Lisp は TCO が保証されていないから
TCOが保証されての末尾再帰。何がすがすがしいって、これですよね。
これがあるから書いていける。
保証なしで気軽に再帰なんかしてもスタックオーバーフローでげんなりだし。
> Haskell だと文字列は文字型のリストであり、標準ライブラリの unfoldl を
おったまげですね。初めてunfoldなるもんを知りました。
Rubyでinject、OCamlでfold_left/fold_rightは馴染みがあったんですが。
何かHaskellって…グイグイ来てますよね!(小学生並みの感想)。
> cata, ana, 圏論, 圏論でのリスト型の定義
リンク先拝見しましたが現時点でどうも1ミリも理解できていません。半笑いです。
> http://ideone.com/o5JM86
ありがとうございます。よく考えると37行目の「 ^ output」が不要にも見えますね。
> Lisp は TCO が保証されていないから
TCOが保証されての末尾再帰。何がすがすがしいって、これですよね。
これがあるから書いていける。
保証なしで気軽に再帰なんかしてもスタックオーバーフローでげんなりだし。
> Haskell だと文字列は文字型のリストであり、標準ライブラリの unfoldl を
おったまげですね。初めてunfoldなるもんを知りました。
Rubyでinject、OCamlでfold_left/fold_rightは馴染みがあったんですが。
何かHaskellって…グイグイ来てますよね!(小学生並みの感想)。
> cata, ana, 圏論, 圏論でのリスト型の定義
リンク先拝見しましたが現時点でどうも1ミリも理解できていません。半笑いです。
> http://ideone.com/o5JM86
ありがとうございます。よく考えると37行目の「 ^ output」が不要にも見えますね。
320デフォルトの名無しさん
2014/12/20(土) 16:23:01.32ID:a9XjC0LN 源クロウジャ義経
321デフォルトの名無しさん
2014/12/20(土) 19:01:20.98ID:tzPxF8Oh >>318
分かりやすいですー
分かりやすいですー
322デフォルトの名無しさん
2014/12/21(日) 00:04:04.16ID:YWufr8fT >>319
>よく考えると37行目の「 ^ output」が不要にも見えますね。
バグ指摘ありがとうございます、変数 output そのものが不要でした
対策を以下へ反映し、ついでに Ruby と Python でも unfold を使って書いてみました
・Standard ML
http://ideone.com/3L6yJ0
・Ruby
http://ideone.com/4OzC0s
・Python
http://ideone.com/8TouzI
>おったまげですね。初めてunfoldなるもんを知りました。
「unfold は fold の双対な概念」であることを知れば、応用範囲は広がります
今回は文字列の unfold でしたが、リスト/配列/辞書/集合/スタック/キューといった
「コレクション・オブジェクトにおける fold/unfold」を考えることから始めませう
>よく考えると37行目の「 ^ output」が不要にも見えますね。
バグ指摘ありがとうございます、変数 output そのものが不要でした
対策を以下へ反映し、ついでに Ruby と Python でも unfold を使って書いてみました
・Standard ML
http://ideone.com/3L6yJ0
・Ruby
http://ideone.com/4OzC0s
・Python
http://ideone.com/8TouzI
>おったまげですね。初めてunfoldなるもんを知りました。
「unfold は fold の双対な概念」であることを知れば、応用範囲は広がります
今回は文字列の unfold でしたが、リスト/配列/辞書/集合/スタック/キューといった
「コレクション・オブジェクトにおける fold/unfold」を考えることから始めませう
323デフォルトの名無しさん
2014/12/21(日) 09:15:25.48ID:KrmABo99324デフォルトの名無しさん
2014/12/21(日) 16:48:41.14ID:MvQSKDIW この話題クロージャとか特に関係なく、Pythonの無名関数には文を書けず式しか書けないという単純な事実の指摘でOK?
関数型プログラミングのラムダとしては困らないが、手続き型言語における無名関数としては不便だろうな
自分はPythonを使わないので、Pythonでの「普通の」プログラミングスタイルがどっちなのかは知らん
関数型プログラミングのラムダとしては困らないが、手続き型言語における無名関数としては不便だろうな
自分はPythonを使わないので、Pythonでの「普通の」プログラミングスタイルがどっちなのかは知らん
325デフォルトの名無しさん
2014/12/21(日) 17:05:17.75ID:MvQSKDIW Hackで適当に書いてみたら本体は一行だった。PHPの緩さにラムダ加わるの最強
$strings = array_map($n ==> array_reduce(str_split($n), ($s, $d) ==> $s . $digitNames[$d]), $numbers);
$strings = array_map($n ==> array_reduce(str_split($n), ($s, $d) ==> $s . $digitNames[$d]), $numbers);
326デフォルトの名無しさん
2014/12/21(日) 17:15:45.30ID:KrmABo99 そんなので良ければPythonでも一行
strings = [''.join(digitNames[x] for x in str(n)) for n in numbers]
strings = [''.join(digitNames[x] for x in str(n)) for n in numbers]
327デフォルトの名無しさん
2014/12/21(日) 17:21:26.20ID:MvQSKDIW あれ、それdigitNames[x]のxに文字列で渡ると思うけど、Pythonも勝手に数値に変換してくれるんだっけ?
整数に変換してやらないと駄目な記憶があっていちいち面倒くさいと思ってた
整数に変換してやらないと駄目な記憶があっていちいち面倒くさいと思ってた
328デフォルトの名無しさん
2014/12/21(日) 18:11:16.63ID:axFrURca digitnames = { "0": "Zero" ... } なら>>327
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はアロー演算子が欲しいところだ。
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はアロー演算子が欲しいところだ。
329デフォルトの名無しさん
2014/12/21(日) 18:21:39.18ID:MvQSKDIW 最強言ったから気に食わなかったならスマンカッタ
PHPの緩さは、こういうのが動くところ。>>325でそのまま動く
$digitNames = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','.'=>'Point','-'=>'Minus'];
$numbers = [1.234, -5.4321];
PHPの緩さは、こういうのが動くところ。>>325でそのまま動く
$digitNames = ['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine','.'=>'Point','-'=>'Minus'];
$numbers = [1.234, -5.4321];
330デフォルトの名無しさん
2014/12/21(日) 23:04:35.55ID:YWufr8fT >>323
>>322 と比較すると:
・わざわざジェネレータで「組立てた」シーケンスを
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 実装を以下に書いた:
http://ideone.com/vpTBlR
・__unfoldl_string_rec__:一般再帰による実装(>>322 と同じ)
・__unfoldl_string_while__:while 文と破壊的代入を使った手続き型実装
あわせて Ruby の実装コードも更新した:
http://ideone.com/9x6s0h
コードの要点を示す:
・Python のジェネレータを Ruby では外部イテレータ Enumerator と呼ぶが、
(Ruby 1.9 以降のメソッド定義マナーに従い)ブロックが渡されていない場合には
(組込みメソッド Object#to_enum を使って)外部イテレータを返すようにした
・3種類のメソッド定義を示した
・String#__unfoldl_rec__:一般再帰による実装(>>322 と同じ)
・String#__unfoldl_until__:until 文と破壊的代入を使った手続き型実装
・String#__unfoldl_loop__:メソッド loop を使った参照透明性のある関数型実装(>>264)
最後に、Ruby と同様な「Haskell の unfold 定義」に従った
Python のジェネレータ実装については、>>323 への宿題としておく
(ML や Haskell といった静的型付け関数型言語に慣れていないと、難しいかもしれないが....)
>>322 と比較すると:
・わざわざジェネレータで「組立てた」シーケンスを
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 実装を以下に書いた:
http://ideone.com/vpTBlR
・__unfoldl_string_rec__:一般再帰による実装(>>322 と同じ)
・__unfoldl_string_while__:while 文と破壊的代入を使った手続き型実装
あわせて Ruby の実装コードも更新した:
http://ideone.com/9x6s0h
コードの要点を示す:
・Python のジェネレータを Ruby では外部イテレータ Enumerator と呼ぶが、
(Ruby 1.9 以降のメソッド定義マナーに従い)ブロックが渡されていない場合には
(組込みメソッド Object#to_enum を使って)外部イテレータを返すようにした
・3種類のメソッド定義を示した
・String#__unfoldl_rec__:一般再帰による実装(>>322 と同じ)
・String#__unfoldl_until__:until 文と破壊的代入を使った手続き型実装
・String#__unfoldl_loop__:メソッド loop を使った参照透明性のある関数型実装(>>264)
最後に、Ruby と同様な「Haskell の unfold 定義」に従った
Python のジェネレータ実装については、>>323 への宿題としておく
(ML や Haskell といった静的型付け関数型言語に慣れていないと、難しいかもしれないが....)
331デフォルトの名無しさん
2014/12/22(月) 08:52:28.54ID:6avCYBJ9 Pythonの場合リストを返したかったら list(unfold(f, x)) で良くね?
毎回 s += a 等やって組み立てるよりも速いぞ
毎回 s += a 等やって組み立てるよりも速いぞ
332デフォルトの名無しさん
2014/12/22(月) 09:03:18.85ID:6avCYBJ9 あ、もしかしてunfoldlじゃないからダメって言ってんの?
unfoldには unfoldr と unfoldl の二種類あって、HaskellではPreludeにあるのはunfoldrだけだぞ
unfoldには unfoldr と unfoldl の二種類あって、HaskellではPreludeにあるのはunfoldrだけだぞ
333デフォルトの名無しさん
2014/12/22(月) 09:04:46.38ID:6avCYBJ9 ちなみに>>330が自信満々に貼ってる方のHaskellのunfoldの定義はunfoldrの方なw
334デフォルトの名無しさん
2014/12/22(月) 09:07:58.19ID:ZCDWZl5G unfold :: (B -> Maybe (A, B)) -> B -> [A]
じゃないから駄目とか言っといて、なんで出してる実装はことごとく
unfold :: (B -> Maybe (A, B)) -> B -> A
なの? バカなの?
じゃないから駄目とか言っといて、なんで出してる実装はことごとく
unfold :: (B -> Maybe (A, B)) -> B -> A
なの? バカなの?
335デフォルトの名無しさん
2014/12/22(月) 14:26:58.64ID:51sTiTTJ またオレオレ定義君がやらかしちゃったかー
336デフォルトの名無しさん
2014/12/22(月) 21:08:27.40ID:8h2AGQmm cにクロージャくれよっておもってたけど
今ならgoがあるんだよな
今ならgoがあるんだよな
337デフォルトの名無しさん
2014/12/22(月) 21:10:47.28ID:VRBNRD9f C++使ったら?スコープ抜けた際どうなるか、必要ならコピーを持たせよう、とかスマポにするかーとか、考える必要はあるけど
338デフォルトの名無しさん
2014/12/22(月) 21:16:46.96ID:6skO2mFq >>336
clangならblocksが使えるんじゃないかしら
clangならblocksが使えるんじゃないかしら
339デフォルトの名無しさん
2014/12/23(火) 06:28:08.32ID:pszL50YR ほー objc じゃなくても使えるのか。
まあ objc に c のソースだけ食わせて使ってもいいんだけど。
まあ objc に c のソースだけ食わせて使ってもいいんだけど。
340デフォルトの名無しさん
2014/12/23(火) 11:28:17.27ID:St4HMSPr boost lambdaで怖い思いしたから
c++はng
コンパイルエラーから黒魔術なコード出されてもこまる
c++はng
コンパイルエラーから黒魔術なコード出されてもこまる
341デフォルトの名無しさん
2014/12/23(火) 11:30:55.43ID:0dLhalMI そういうのはreplで対話的に書けたほうがいいな
342デフォルトの名無しさん
2014/12/23(火) 14:09:04.60ID:Og1JN7U7 このスレのおかげでクロージャの良さと
Ruby信者のキモさが分かりました
ありがとうございました
Ruby信者のキモさが分かりました
ありがとうございました
343デフォルトの名無しさん
2014/12/27(土) 00:25:14.89ID:randw1SU クロージャなんて最近の言語は大抵あるからね
次に関数型言語からパクって欲しいのはパターンマッチ
次に関数型言語からパクって欲しいのはパターンマッチ
344デフォルトの名無しさん
2014/12/29(月) 07:25:36.12ID:Br8mMuyh disると公開される
345デフォルトの名無しさん
2014/12/29(月) 16:50:56.24ID:9aAL2Pj2 まぁ別にいらないっちゃいらないな。
最近の言語はいろいろ付けすぎだわ。
もっと仕様単純でいいよ。
最近の言語はいろいろ付けすぎだわ。
もっと仕様単純でいいよ。
346デフォルトの名無しさん
2014/12/29(月) 17:19:30.86ID:LxjJzYoX パターンマッチの無い言語にパターンマッチを付けられるような言語がいい
347デフォルトの名無しさん
2014/12/29(月) 19:45:55.93ID:NKff8BVB348デフォルトの名無しさん
2014/12/30(火) 17:09:02.43ID:AU/nggqJ その万能プリプロセッサがあればいいんだけど
349デフォルトの名無しさん
2014/12/30(火) 18:06:56.67ID:mxKZGqd3 m4通すとか?
350デフォルトの名無しさん
2014/12/30(火) 18:40:21.70ID:AU/nggqJ その言語処理系を書かた言語のコードを直接書き変えるような書き方じゃなくて
その言語自体で新しい表現(パターンマッチとか)を定義出来るようにするってこと
その言語自体で新しい表現(パターンマッチとか)を定義出来るようにするってこと
351デフォルトの名無しさん
2014/12/30(火) 19:32:00.99ID:tU/2zS2Z >>346
lispおじさんだ!
lispおじさんだ!
352デフォルトの名無しさん
2014/12/30(火) 20:40:47.63ID:LKC757rT lispでマクロ使えばおk
353デフォルトの名無しさん
2014/12/31(水) 23:19:03.80ID:tqgvohnx >>350
たぶんschemeにドハマリするタイプ
たぶんschemeにドハマリするタイプ
354デフォルトの名無しさん
2015/01/01(木) 00:15:11.77ID:6s4ScpeL on lispとかlet over lambdaがあるcommon lispの方がいいんじゃね
355デフォルトの名無しさん
2015/01/01(木) 08:49:44.48ID:Vz2QaCIS あなほりマクロ怖い
356デフォルトの名無しさん
2015/01/01(木) 19:26:59.51ID:LWrX8qsS やっぱりpythonとかhaskellのコードと比べると
専用の構文があった方がスッキリ書ける
でもそうすると自由度が無くなってマクロがうまく使えないジレンマ
専用の構文があった方がスッキリ書ける
でもそうすると自由度が無くなってマクロがうまく使えないジレンマ
357デフォルトの名無しさん
2015/01/01(木) 19:31:53.89ID:LWrX8qsS 一応リーダマクロを使えば解決するんだけど結局使わなくなる
358デフォルトの名無しさん
2015/01/02(金) 09:58:20.63ID:ie8IusfS lispおじさんのせいで
すっかりマクロ談義スレになったな
すっかりマクロ談義スレになったな
359デフォルトの名無しさん
2015/01/02(金) 10:14:10.05ID:PL75YfkA 真のクロージャとマクロ、どっちがマシか難しいところだな
360デフォルトの名無しさん
2015/01/02(金) 11:28:56.61ID:Ur5QsT6D 二つのいいところを組み合わせたものが最強ではないだろうか?
つまりマクロージャー
つまりマクロージャー
361デフォルトの名無しさん
2015/01/02(金) 12:10:26.52ID:ie8IusfS マクロにコンテクストが付いて回るclの事だよねそれ
362デフォルトの名無しさん
2015/01/02(金) 15:30:32.04ID:/upm+g4t マクロとクロージャを組み合わせればOOPも継続も後から付けられる
363デフォルトの名無しさん
2015/01/02(金) 15:37:48.79ID:Ur5QsT6D いろんなことができる。そうマクロージャならね!
364デフォルトの名無しさん
2015/01/02(金) 20:00:41.84ID:ZuY3pBgY365デフォルトの名無しさん
2015/01/02(金) 20:28:34.80ID:UWr+Udi0 onlispでは継続を表わすクロージャを引数で渡してそれをマクロで包んでる
これだと使う側が末尾呼出的に書かないといけない縛りがある
cl-contは式をwithマクロで包んでその式をcodewalkしてcps変換してる
これだと使う側が末尾呼出的に書かないといけない縛りがある
cl-contは式をwithマクロで包んでその式をcodewalkしてcps変換してる
366デフォルトの名無しさん
2015/01/02(金) 21:04:50.09ID:ZuY3pBgY ありがとうございます。On Lisp 読んでみます。
3671
2015/01/09(金) 13:33:15.35ID:3m5OEfmN そもそも関数が一級オブジェクトである必要があるのかどうか疑問が出てきました
ifelse( aaa, xxx,
ifelse( bbb, yyy,
ifelse( ccc, zzz,
iii )))
↑死ね
IDE使えってことなんでしょうけど認知に負荷をかける言語仕様は間違ってると思うんですよね
これよりはメソッドチェーンの方がかなりスマートだと思う
foo(aaa){xxx}.bar(bbb){yyyy}.baz(ccc){zzz}
ifelse( aaa, xxx,
ifelse( bbb, yyy,
ifelse( ccc, zzz,
iii )))
↑死ね
IDE使えってことなんでしょうけど認知に負荷をかける言語仕様は間違ってると思うんですよね
これよりはメソッドチェーンの方がかなりスマートだと思う
foo(aaa){xxx}.bar(bbb){yyyy}.baz(ccc){zzz}
368デフォルトの名無しさん
2015/01/11(日) 21:16:33.98ID:8HLn7hr5 それだと全てのメソッドで条件分岐を想定した実装にしなくちゃいけなくなるのでは
369デフォルトの名無しさん
2015/01/16(金) 01:40:03.14ID:U7RTYgR7 Pythonはパターンマッチ以前にSwichtすらない
370デフォルトの名無しさん
2015/01/16(金) 08:39:36.86ID:oLGQ6wLb >>369
そんなもんがある言語を見たことないが
そんなもんがある言語を見たことないが
371デフォルトの名無しさん
2015/01/16(金) 23:23:44.50ID:obgM8cFp なんかドイツ語?みたいな切り方だな
372デフォルトの名無しさん
2015/01/21(水) 16:33:15.48ID:Out9u5nx ゲルマンおじさんこわい!
373デフォルトの名無しさん
2015/01/22(木) 01:37:45.45ID:8pwMw7VT スウィヒトとか読むの?ドイツ語ってよくわからんタイミングで濁るイメージあ?からジットとかかな
374デフォルトの名無しさん
2015/01/22(木) 08:08:05.98ID:VatMjg6z スヴィヒトだな、あえてカタカナを当てれば
375デフォルトの名無しさん
2015/01/24(土) 00:56:47.04ID:hSO7J5Oj 中二病みたい
376デフォルトの名無しさん
2015/01/27(火) 21:37:55.87ID:x1TLH4fz ここまでnonlocalなし
377デフォルトの名無しさん
2016/01/10(日) 19:01:54.47ID:sdj7zt3O Objective-Cのblocksが便利だというからいろいろ読んでみたが
使い道がよーわからん。他言語のクロージャやラムダだということで
他言語のクロージャやラムダについて読んでたらもっと混迷が深まった。
使い道がよーわからん。他言語のクロージャやラムダだということで
他言語のクロージャやラムダについて読んでたらもっと混迷が深まった。
378デフォルトの名無しさん
2016/03/29(火) 09:21:36.23ID:/c8bAcK4 サッカーブッシュ日本代表日程ぷあたん(しゅっちょうまいくろ教育長交代)春文執行40代売上差額シュガーチョコ
https://www.youtube.com/watch?v=NDq1QoJY0nY宇ドナルドアナリストパワーストーンコーチングとしまえん
サッカーブッシュ日本代表日程古本屋よしたけしゅっちょうちょこしゅがー
ディーラー税務署天才開発者死亡詰みヨミドクターマイクロサービス不足
サッカーブッシュ日本代表日程ぷあたんシフト光金さかい強制バイト人権侵害問題
春分資源執行ニューヨーク低原価ぼったステーキソルトレイク福岡横浜新橋奴隷課金パチシフト強制バイト問題新潟米センター生残
コスメ24チャリティー隠れ40代生活保護プレイボーイバイトレードいたりあん接待問題
マスコミKARDローンケーオーサービス不足婚活パーティー寄付金執行原発ビジネス
FBIチャイニーズタイホテル売上事務所ガチャ決算ガチャキャンペーン(販売報道陣過激派組織向携帯最新情報提供終了
校長発言細心注意ノートン産廃エラー(著作権クレーム中国反応融資高額教育費)(中国捕鯨団体40代社員サッカーコメント
高額入学金ヤフウ新橋大学ヤフウ新橋理事長FX経費 おじや50代資産ガリバズフィード40代エリート
https://www.youtube.com/watch?v=NDq1QoJY0nY宇ドナルドアナリストパワーストーンコーチングとしまえん
サッカーブッシュ日本代表日程古本屋よしたけしゅっちょうちょこしゅがー
ディーラー税務署天才開発者死亡詰みヨミドクターマイクロサービス不足
サッカーブッシュ日本代表日程ぷあたんシフト光金さかい強制バイト人権侵害問題
春分資源執行ニューヨーク低原価ぼったステーキソルトレイク福岡横浜新橋奴隷課金パチシフト強制バイト問題新潟米センター生残
コスメ24チャリティー隠れ40代生活保護プレイボーイバイトレードいたりあん接待問題
マスコミKARDローンケーオーサービス不足婚活パーティー寄付金執行原発ビジネス
FBIチャイニーズタイホテル売上事務所ガチャ決算ガチャキャンペーン(販売報道陣過激派組織向携帯最新情報提供終了
校長発言細心注意ノートン産廃エラー(著作権クレーム中国反応融資高額教育費)(中国捕鯨団体40代社員サッカーコメント
高額入学金ヤフウ新橋大学ヤフウ新橋理事長FX経費 おじや50代資産ガリバズフィード40代エリート
379デフォルトの名無しさん
2016/05/01(日) 14:33:24.76ID:tKi6j9CT 匿名通信(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的に分散され、特定のサーバーに依存しません
い
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的に分散され、特定のサーバーに依存しません
い
380デフォルトの名無しさん
2018/06/30(土) 19:46:44.69ID:AmpLvy/F 保守
381デフォルトの名無しさん
2018/07/05(木) 02:00:11.95ID:RfoszcD2 S8R
382デフォルトの名無しさん
2018/07/19(木) 09:21:29.22ID:DyCUHSWz 関数型で参照透過性とか言ってるのに
クロージャにしたら意味ないじゃん。
やっぱりオブジェクト指向のほうが優れてるの?
クロージャにしたら意味ないじゃん。
やっぱりオブジェクト指向のほうが優れてるの?
383デフォルトの名無しさん
2018/07/19(木) 15:23:16.35ID:n84GXL2z ラムダ式はともかくクロージャなんて純粋な関数型では使わないだろう
384デフォルトの名無しさん
2018/08/03(金) 08:55:18.28ID:4j7d3TQF 関数型ではクロージャーは当たり前
というより関数とクロージャーに意味論的な違いはない
特定のパターンの書き方の関数をそう呼んでるだけ
というより関数とクロージャーに意味論的な違いはない
特定のパターンの書き方の関数をそう呼んでるだけ
385デフォルトの名無しさん
2018/08/03(金) 14:55:46.25ID:fAsZ4eFv >>384
ラムダ式と混同してる?
ラムダ式と混同してる?
386デフォルトの名無しさん
2018/08/03(金) 20:20:49.90ID:uYN9BNxM387デフォルトの名無しさん
2018/08/04(土) 19:50:14.71ID:47wZhJf+ クロージャとラムダを混同してないかって事じゃね?
388デフォルトの名無しさん
2018/08/04(土) 20:43:06.82ID:GiulTy4Z なんでじゃねじゃね言い合うのか
なぜ本人同士が出てきてやりあわないのか
なぜ本人同士が出てきてやりあわないのか
389デフォルトの名無しさん
2018/08/05(日) 00:06:57.49ID:79cO6f6/390デフォルトの名無しさん
2018/08/05(日) 00:35:34.24ID:GRCljFf8 お前はさながらコミュ症と称されるくちだなw
391デフォルトの名無しさん
2018/08/05(日) 19:05:22.36ID:2n69scci これはひどい
392デフォルトの名無しさん
2018/08/23(木) 08:46:43.71ID:NPcuqlt3 苦労じゃー
ら無駄
ら無駄
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- NY円、一時1ユーロ=180円台まで下落…1999年のユーロ導入以来初 [蚤の市★]
- 【外交】日中関係悪化、長期化の様相 2012年には自動車輸出80%減も ロイター★3 [1ゲットロボ★]
- 国内ホテル、既にキャンセルも 訪日客関連業界、事態見守る ★3 [蚤の市★]
- 「どうしようもない」 ため息つくアジアの玄関口 中国の訪日自粛で−福岡市 [蚤の市★]
- 橋下徹氏 外務省幹部の訪中受け「口だけ番長」へ痛烈指摘 「喧嘩は日本の完敗…なんとかっこ悪い日本か」★2 [冬月記者★]
- 「稼ぐのよ!」高市総理が電話ガチャ切りで伝えたこと 鈴木憲和農林水産大臣が国政報告会に出席 自身が目指す農政の方針語る [煮卵★]
- 『しんちゃんと岸田さん』 [175344491]
- 日本株、大暴落!!! [252835186]
- 港区女子「50kg越えちゃった、港区だとデブ界隈だよ(>.<)」🤳パシャッ👉10万いいね [329329848]
- 識者「『フリーパレスチナ』とかイキってる連中が台湾の話になると『中国を怒らせるな!』ってなる。ほんと左翼の正義って薄っぺらい」 [279254606]
- 【超悲報】中国への武力行使、世論調査で「賛成」「どちらかといえば賛成」48.8% 「反対」「どちらかといえば反対」の44.2%を上回る [314039747]
- んなっても良いお🏡
