Topics

・関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い

ガラパゴス・ネットスラング=「関数型ポエム」という呪詛、先入観的読書と、フェアなレビューの登場

Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について

JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン

2016年のnode、ES6、React、Babel、Atomエディタ界隈の方向性

Dockerじゃないsystemd-nspawn+machinectlが非常に良い

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その2】関数型プログラミングのイミュータブルな世界観とイミュータブルな実世界を完全に統合

10年先を行く斬新な関数型(FRP)データベースについて説明する 99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その3】

[React (.js Facebook)解説 関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 サポート記事【静的HTML編】React 解説【動的HTML-FRP編】

量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説01量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説02

『関数型プログラミングに目覚めた!』のレビュー(Day-1)について

LISPデータ構造の問題点の指摘と抜本的解法としての新プログラミング言語の策定/純粋関数型言語「SPINOZA」

著書『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』 [Day1]たち読み記事 無料公開中

『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』を大変多くの方々にお買い求めいただき、感謝します。本書の全目次を公開し、質問を受け付けます。

2015年4月30日木曜日

Amazonで、102 人中、93人の方が、「このレビューが参考になった」と投票されている、著書の「クロージャ」の説明が誤っているとの指摘が、誤っていることについて

多くの方に本書をお買い上げいただきましてお礼申し上げます。

著書、関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間
について、
「クロージャ」の説明が誤っています
と、また☆1のレビューが投稿されていますが、誤っていることを説明します。

PS.正直この人が何を言ってるのか、私にはまるっきり理解できないので、こんな曖昧な書き捨てじゃなくて、技術の言葉で翻訳できる人がいたら、コメントかメールください。こんな書き捨てからでも、万が一でもそれなりの議論ができるかも、と淡い期待もしています。(参照等価じゃなくって、参照透過、念の為)

ええともうほんとこういう誤った情報垂れ流されるのどうにかならないんですかねえ。閉じ込めるのは状態じゃなくて環境だよ何なんだこれは。それに状態を閉じ込めたところで参照等価じゃなくなるわけじゃないよホント

問題のレビュー

「お買い上げいただきありがとうございます」

enter image description here

102 人中、93人の方が、「このレビューが参考になった」と投票しています。
5つ星のうち 1.0
「クロージャ」の説明が誤っています, 2015/4/28
投稿者 λ

383~384ページに「関数型プログラミングでオブジェクトを作る仕組み クロージャ」との見出しで
「クロージャって何ですか?」「関数で副作用を起こして、その副作用が起こった環境そのものを閉じ込めておく関数のこと」
「クロージャは、参照透過ではない、命令型のハードウェアモードである、ってことは普通に理解しておきなさい」「はい、普通に理解しています、大丈夫です」
というような説明が具体例を交えて述べられています。しかし、クロージャはレキシカルスコープを実現するための仕組みであって、
副作用(ローカル変数への破壊的代入など)のないクロージャもごく普通に用いられますので、本書の説明は誤っています。
むしろ、クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられています。
「Javascript closure」や「function closure」で検索すれば、MDNや英語版Wikipediaなどですぐにわかるレベルのことです。
クロージャは関数型プログラミングにおける基本的概念の一つですので、重大な誤りだと思います。

えー、

102 人中、93人の方が、「このレビューが参考になった」

らしいです。
もちろんこういうのは不正な投票であることはすでに説明しましたが、
万が一、ほんとうに、

102 人中、93人の方が、「このレビューが参考になった」

のであれば、なんと罪深いデマ拡散行為なのでしょう。

おそらく、これまでこのレビューを眼にしたかなり多くの技術者が
「ああ間違った指摘をしているレビューだ」
と理解していることだと思いますが、

102 人中、93人の方が、「このレビューが参考になった」

というのは、繰り返しになりますが無論、不正な投票なので、
その見識が数値に反映されることは、今後も「絶対に」はないでしょう。
不正でなければ、良識、正しい知見の力学も働きようもありますが、不正投票によるものなので。

もしも、ほんとうに、このレビューをもって、

102 人中、93人の方が、「このレビューが参考になった」

というのが、正確な情勢を反映しているのであれば、
我が国の技術者のレベルは致命的に低い、ということになります。
もちろん、騙された学習者が多いとして、その数を汲んだとしても致命的です。

このレビューも単に、
私が「技術的反論は何一つ見受けられない」と宣言したことを「挑戦」と受け取り、
脊髄反射的に応じた、単なるネガティブキャンペーンが第一目的であり、
広い読者、技術者、学習者にむけて「正しい知識を共有すること」ではないのでしょうから、
罪の意識など感じるわけもなく、
このブログ記事の説明をもっても、今後そのまま誤ったまま放置され、訂正される、という良識は当然まったく期待していません。
訂正されない、という事実をもって、このレビューが技術の修正を装ったネガキャンであることを追認できると思います。

まず、なぜ、私の著書のほうが正しく、この反論者がいい加減な嘘を書いてまでネガキャンをしているのか?結論を直感的に手っ取り早く知りたい読者のために、ざっくりと結論を書きます。

手っ取り早く、ざっくりと

Wikipedia日本語版では、かなり簡潔にその答えがあります。

http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3

クロージャ(クロージャー、英: closure)、関数閉包はプログラミング言語における関数オブジェクトの一種。

はい、この一文は私の責任において断言しますが。正確です。
Wikipedia日本語版の記事はプログラミングの分野でも、首をかしげるものが多いことは、以前なんかの記事で私も書きましたが、これに限ってはかなり正確です。

クロージャ、関数閉包、という字面でも自明ですが、これは、
「関数」が一義的に関与する存在であり、
「関数」が
「なにか」を
「閉じ込める」
仕組みのことです。

その「なにか」っていうのは何か?
もちろん「状態」です。

「状態」を「閉じこめたら」「参照透過ではなくなる」のは、著書で解説していることですね。
「状態」を「閉じ込める」ものにアクセスできる「関数」の「オブジェクト」って何か?
当然、オブジェクト指向の「オブジェクト」とまったく同じものです。

さて、この反論者は、

しかし、クロージャはレキシカルスコープを実現するための仕組みであって、

とか、書いているわけですが、同じWikiepdia項目の続き、

いくつかの言語ではラムダ式や無名関数で実現している。引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決することを特徴とする。関数とそれを評価する環境のペアであるともいえる。この概念は少なくとも1960年代のSECDマシンまで遡ることができる。

http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3

自身が定義された環境(静的スコープ)において解決することを特徴とする

上記つなぎ合わせると、
クロージャとは、

レキシカル(静的)スコープにおいて解決することを特徴とする、(by Wikipedia日本語版)
レキシカル(静的)スコープを実現するための仕組み (by 反論者)

となりますね。はい、さっそく論理破綻しました。

もちろん、論理破綻したのは、

レキシカル(静的)スコープにおいて解決することを特徴とする、(by Wikipedia日本語版)

が正しくて、

レキシカル(静的)スコープを実現するための仕組み(by 反論者)

が間違っていて、無理やり文章をつなげたからです。

クロージャとは、

レキシカル(静的)スコープを実現するための仕組み

では、ありません。

クロージャとは、レキシカル(静的)スコープがすでに実装されている環境の土台の上にある仕組みです。

以上がかなり、ざっくりとした説明ですが、より詳細に、精査してみましょう。

より詳細に精査してみる

反論者の論点が複数あり列挙します。

クロージャはレキシカルスコープを実現するための仕組み

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。

「Javascript closure」や「function closure」で検索すれば、MDNや英語版Wikipediaなどですぐにわかるレベルのこと

クロージャは関数型プログラミングにおける基本的概念の一つ

すべて間違いです。

順序は前後しますが、

英語版Wikipediaなどですぐにわかるレベルのこと

をまず精査してみます。
http://en.wikipedia.org/wiki/Closure_(computer_programming)

In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions.

この表現は、わかりにくい、というか、この反論者のように誤読して勘違いする人が多いだろうからどうか?と思うわけですが、その下の、

History and etymologyを見ればより意味が明らかになります。

The concept of closures was developed in the 1960s for the mechanical evaluation of expressions in the λ-calculus and was first[citation needed] fully implemented in 1970 as a language feature in the PAL programming language to support lexically scoped first-class functions.

lexically scoped first-class functions
レキシカルスコープのファーストクラスの関数
をサポートするために実装された、ということです。

上記双方の文章で共通しているのは、
レキシカルスコープ + ファーストクラスの関数
と2つの要素がある、ということです。

MDN

で調べてみると、

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

The solution to this puzzle is that myFunc has become a closure. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.

この謎の秘密とは、myFuncがクロージャになった、ということです。
あるクロージャとは、
1.関数
2.関数が生成された環境
の2つを結びつける特別な種類のオブジェクトです。
その環境は、クロージャが生成された時間のスコープにある、あらゆるローカル変数を保持しています。

(これはレキシカルスコープのこと。)

英語版Wikipediaから読み解ける
レキシカルスコープ + ファーストクラスの関数
であることと上記MDNの記述を合わせて整合的に確認できる事実とは、
まず、最初にレキシカルスコープという枠組みがあって、
その上に、クロージャという状態保持能力がある関数(ファーストクラスオブジェクト)の存在があるということ。

故に、

クロージャはレキシカルスコープを実現するための仕組み

というのは、完全な誤りです。

さて、次の要素、

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。

「ほぼすべて」とか書いてたら、「胡散臭いな」と疑いましょう。
正確性が担保できないから、あとあとの「逃げ道」を用意している欺瞞が多いです。
実際これは欺瞞で、著書の解説の誤りの指摘という文脈で考えるのならば、間違いです。

クロージャとは、上記で再確認したとおり、また著書に正確に書いている通り、
レキシカルスコープのローカル変数が閉じ込められた環境の「状態」を保持する関数オブジェクトですが、この人物の書きっぷりから読者が受ける印象とは、
 クロージャは関数型言語の実現に用いられる「必須の技術」なんだ!
 Haskellもそうなんだから、間違いない!
ってことでしょう。
「ほぼすべて」という逃げ口上は、もちろん著書の解説の反論文脈にあるので、あまり気にされません。

クロージャは関数型プログラミングにおける基本的概念の一つ

とダメ押しもされています。

レキシカル(静的)スコープでないほうのスコープ、動的スコープ
のWikipedia記事を参照すると、

動的スコープを採用している代表的な言語としては古典LISPやEmacs Lisp、LOGO、Perl4などがある。

とあります。これも私の責任で保証しますが、正しいです。

もちろん、

古典LISP
Emacs Lisp

は関数型言語ですよね。著書でもLispが関数型言語の古典であることは説明しました。

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。
クロージャは関数型プログラミングにおける基本的概念の一つ

であるのならば、なんで

クロージャはレキシカルスコープを実現するための仕組み

をもってレキシカルスコープになっておらない、動的スコープである、

古典LISP
Emacs Lisp

が関数型言語でありえるのでしょうか?たしか、

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。

「はず」だったのに・・・

結論

もう宜しいでしょうか?
当たり前なのです。
なぜならば、クロージャとは「状態を保持するオブジェクト」なのだから。

「状態を保持するオブジェクト」が
状態を保持しないことが基本中の基本の、
「関数型プログラミングの基本的概念」であるはずがありません。

もちろん、クロージャという「状態を保持するオブジェクト」が、
「関数型言語の実現のために用いられている」必須技術であるわけもありません。

なぜなら、クロージャとは、オブジェクト指向のオブジェクトと等価な存在なのだから。

本書では、それ故に、

383~384ページに「関数型プログラミングでオブジェクトを作る仕組み クロージャ」との見出し

として、最後の最後のDay5に、Day1-4の関数型プログラミングの本論と、しっかり分離して解説しています。別、というか、
関数型と対立するパラダイムに属する技術として、クロージャの解説は完全にわけました。

他の多くの関数型プログラミングの解説か書籍では、まさに、
クロージャが、まるで
「関数型プログラミングの基本的概念」
「関数型言語の実現のために用いられている」必須技術
であるかのごとく、ごちゃまぜにして、
読者がとんでもない勘違いをして当然の解説がされている、のでしょうか?

少なくとも、

「Javascript closure」や「function closure」で検索すれば、MDNや英語版Wikipediaなどですぐにわかるレベルのこと

とか、現状、「技術的反論など何一つ見受けられない」という当ブログ記事に反応して、
何がなんでも貶めてやろうと先走るから、意図的か、勘違いか早とちりか、わかりませんが、
挑戦する、そして、このエントリも読んでいることだと思いますが、
誤りを認識しながら、訂正もしないで、そのまま不当な指摘のレビューを残しているわけです。

Amazonレビューで嘘を書かないこと、それが技術的議論のための最低限の要件である

繰り返します。現状、「技術的反論など何一つ見受けられない」。
嘘まみれなので、「不正なノイズ」と分類されます。

0 コメント:

コメントを投稿

Popular Posts