「お絵かきアプリ」と「クリックカウンター」を簡単に実装できると見せかける誤魔化しと嘘 原理的に可能かどうか?と実用的であるかどうか?は違うが、それを「銀の弾」ではない、という言葉をもって自らの嘘、誤魔化しの言い訳として悪用するな
「レビュー」と称する欺瞞に満ちた、批判のための批判記事
『関数型プログラミングに目覚めた!』のレビュー(Day-1)には、こんな追記がありました。
追記(2015/05/30):デスクトップアプリケーション??
著者はブログで@camloebaさんや@esumiiさんにデスクトップアプリケーションをOCamlで作成するように求めているようです。著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。
が、さらに「追記」の「追記」がなされたようです。
(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)
この
コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にするとOCamlでは困難であろうという指摘を頂いています。
とは、
というものです。(太字は岡部によるもの)
この @nonstarterらの強弁に欺瞞を感じる良識のある指摘です。
まず、@nonstarterによる「言い分」
著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません
ですが、私の趣旨は明らかで、実用的なアプリを書けるのか?ということに尽きます。
前回、
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
において、趣旨を大前提として再確認しました。
著者が挙げている「クリックカウンター」や「お絵かき」の類
とは、FacebookのGUIコンポーネント指向、FRPライブラリである、Reactを活用した簡単なサンプルであり、同様yに、著書のDay5に示した、マウスドラッグのサンプルWebアプリです。
これらは、あくまで「実用性意味」を大前提とした投げかけでした。
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??
ということです。
「実用に耐えうる」こういう極めてシンプルなテーゼに徹頭徹尾誤魔化しを続けているのが、『関数型プログラミングに目覚めた!』のレビュー(Day-1)
であり、それは、最終的に、プラグマティックで真摯な読者への裏切りとして決着します。
@nonstarterらが「回答」した、「副作用を使用せずに書くのもなんら困難ではありません」とする、「クリックカウンター」や「お絵かき」は「スケールしません。」 「机上の空論」である
OCamlでは「破壊的代入の類の副作用」を使用せずに一般の GUI アプリケーションを書くのはほとんど無理でしょう。なぜなら OCaml の全ての GUI ライブラリは状態は副作用を使うことを前提にメインループが設計されているからです。これを乗り越えるとすると @Lambada さんのようにメインループ自体を自分で書く事になり、一般的にはスケールしません。
と良心的な指摘、欺瞞の看破のコメントもあるように、連中が、岡部の言うようなFRPを使わなくても、「なんら困難ではありません。」かんたんに書けるという趣旨で放言しているコードは、「スケールしません。」
つまり、問題を極めて単純化して簡単な解放で事足りるものに限定したら、それは「なんら困難ではありません。」「かんたんに書ける」わけですが、ちょっと複雑になってきたら、もう破綻する、複雑な、つまり実用的なアプリなんて書けっこない、ということです。
「机上の空論」です。
実用に耐えない「机上の空論」のコードを自ら実装した当然の結果への言い訳、「銀の弾ではない」???
「机上の空論」を自分が勝手に放言するのは、良識ある人間に看破されるだけだが、それを勝手に一般化して、言い訳するマジックワードが、「銀の弾ではない」です。
追記(2015/05/30):デスクトップアプリケーション??
の最後には、こういうデタラメが書かれています。
いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。
間違い、デタラメです。
まず、私は、
素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??
「実用に耐えうる」複雑なケースを想定したコードを示せ、と要求した。
私が示したコードは、GUIの関数合成を具現化したコンポーネント指向のReactをベースとし、同時にイベントを合成可能なFRPのコードです。
コンポーネント指向は、関数合成であり、
綺麗な関数合成では上手くいかないようなものになることが多い
というものを最初から、根本的に解決するアプローチであり、私はそのサンプルコードを首尾一貫して、著書でも、先の「問いかけ」のブログ記事でも示しているわけです。
当然、いくらでもスケール可能なことは、FacebookやInstagramのサイトで実証されている現在進行形でアクティブに開発され多くの技術者が参入している次世代Webのデファクトである技術です。
スケールしない、複雑になったら破綻する、「クリックカウンター」や「お絵かき」のコードではありません。
一方で、@nonstarterらは、「副作用を使用せずに書くのもなんら困難ではありません」などと、読者を勘違いさせて当たり前の、極めて単純な実装でしか使えないコードしか示せませんでした。
「机上の空論」です。
極めて限定された、単純な問題でしか使えない、「机上の空論」の実用に耐えないコードを、「副作用を使用せずに書くのもなんら困難ではありません」と、あたかも簡単に書ける、その先に実用性があると読者を勘違いさせて、思い込ませて、騙してまるで平気な感じです。こういう看過できない欺瞞を暴くために、私は、
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??
と、先にコンポーネント指向、FRPでサンプルコード示して問いかけたわけですが、もうその「回答」のダメさっぷりは明らかでしょう。
この自らの「回答」のダメさぷりを、まるで一般的な関数型プログラミングの限界のように、また読者を欺いて、正当化するのが、この連中の常套手段です。
どういうことか?
銀の弾丸にはならないと言わなければなりません ???
こういう言い草です。
@nonstarterが強弁するとおり、
状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません
のであれば、
そもそも、私がサンプルとして示した、コンポーネント指向のReactで、UIを関数合成して見せているコードでは、「綺麗な関数合成で上手くいっている」(それがReactの関数ライブラリとしての真価)わけなので、「本質的に銀の弾丸」である、ということになります。
それを自分たちが、コンポーネント、FRPでなくても「なんら困難ではありません」などと、極めて限定的な単純化された例題にしか適用できないスケールしない実用に耐えないコードを勝手に示しておいて、だから、関数合成では上手く行かない、銀の弾ではない、などと説明されても、こちらとしては、ほらね?だからあんたらダメなんだよ、わかったかい?と再確認する意味しかありません。
関数型プログラミング、コンポーネント指向、FRPは、机上の空論でない、真に実用に耐えるアプケーションを構築するために必須な「銀の弾丸」である、この見解を改めて確認し、異論があるのであれば、こちらは、すでにスケールするコンポーネント指向のFRPのReactで構築したアプリを提示しているのだから、再度、
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??
と広い読者にむけて、自らの主張を立証していただきたいと考えています。絶対無理でしょうが。
なんども繰り返し確認しますが、関数型プログラミングのGUI実用化、世界的潮流としては、
で示したような状況があり、これは「銀の弾」として重宝されながら圧倒的な普及を見せているわけです。
あさっての方向をみて、あたかも実用的だと見せかけながら「机上の空論」に執着しながら、「机上の空論」で実用に耐えないから「銀の弾ではない」というような自己の規定した論理の中で無限ループするトートロジーのようなことを言ってる連中には、絶対無理でしょう。
コンポーネント指向、FRPでなければ、実用的なプログラミングはできないとする私の主張をわざわざ否定したいえばかりに、わざわざまた「机上の空論」を開陳して、結果「銀の弾ではない」、と結論づけて、あんたら何がしたいのか?読者の足を引っ張って楽しいのか?
自ら、実用的局面でなんら価値を生み出すことはなく、ありもしない限界的を設定して、こちらの言うことが間違いだと見せかけるために、批判のための批判がしたいだけだろう?ということです。
末尾再帰ループの最適化
気づきにくいといけませんので、上にあるLambadaさんのコメントの追記部分を転記させていただきます:
追記:岡部氏が最近のブログエントリで、上述のプログラムは再帰を使っているので「即効で」スタックオーバーフローすると主張していますが、関数型プログラミングの基本の一つである末尾再帰なので、スタックオーバーフローしません。もし仮に末尾再帰がスタックオーバーフローするJavaScript処理系があったとしたら、JavaScriptか、少なくともその処理系が、関数型プログラミングに不適切です。
岡部氏は上述のプログラムを無限ループに書き換えて「Chromeタグ(原文ママ)の反応がなくな」ったと主張していますが、無限ループにしたら反応がなくなって当然です。なお、少なくとも私の手元のChromeやFirefoxでは、無限ループする末尾再帰ですら(当然ながらブラウザの反応は重くなりますが)スタックオーバーフローは再現しません(メモリ消費量も特に増えません)。岡部氏がスタックオーバーフローと主張している画面には「Either Chrome ran out of memory or the process for the webpage was terminated for some other reason」(Chromeのメモリがなくなったか、もしくは何らかの他の理由でWebページのプロセスが終了されました)とあるので、スタックオーバーフローではなく、無限ループしているプロセスを強制終了した等かもしれません。
なお、他の方々から、Graphics.loop_at_exitではなく、ネイティブなOCaml処理系であればGraphics.wait_next_eventを、js_of_ocamlであればGraphics_js.loopを用いるべきとのご指摘をいただきました。そのとおりなのですが、元の文で述べたとおり、最も手っ取り早く試していただけるTry OCamlで動くよう、Graphics.loop_at_exitを用いました。また、そもそもTry OCamlのGraphics.loop_at_exitやjs_of_ocamlのGraphics_js.loopはループでも再帰でもなく、イベントハンドラの登録を行なって戻ってくるだけなのでスタックオーバーフローなど起こるわけがない、とのご指摘もいただきました。ありがとうございます。なお、私も単なる素人ですし不適切なことを書いているだろうとは思いますが、今回のkenokabeさんの一連の主張を見ると流石に私ですら真面目に取り合う必要を感じません。しかしkenokabeさんがどのような理解の水準で関数プログラミングに関する書籍を執筆し(てしまっ)たのかが著者ご本人のお蔭で完全に明らかになったように思います。
まず、この人をはじめ、私が「末尾再帰最適化を理解していない、知らなかった」ということにしたいようです。
岡部はXXを知らない、理解していない、という勝手な決めつけ、中傷をもって、本のレビューとするという悪質な手口はこの@nonstarterによる常套手段ですが、もちろん知っています。
まず、念の為に、解説すると、
再帰ループの末尾最適化とは、
【学習者要注意!】『関数型プログラミングに目覚めた!』のレビュー(Day-1)の「状態遷移関数」を使った非FRPのGUIコードがメモリリークする実用に耐えない不良品でしかなかったことについて 読者騙せて楽しいですか?
で、発生するような問題をコンパイラレベルで回避するための言語の仕組みです。
とあるように、単に、スタックオーバーフローする再帰関数の無限ループを、内部で関数呼び出しでない無限ループのコードに書き換えることで実装されています。
上記のように、同じJavaScriptであってもバージョンによって、末尾再帰最適化の実装があったりなかったり、Javaも同様です。C#では、末尾再帰最適化はありませんが、F#ではあったりします。
趨勢として、JavaScript,C#,Javaなどのメインストリーム言語では、末尾再帰最適化はない、と考えていた方が良いでしょう。
OCamlは、末尾再帰最適化はあるのでしょう、よく知りませんが、しかしいずれにせよ、コンパイラがメモリリークしないように書き換えてくれる言語であったとしても、イベントハンドリングするために、コード上で無限ループを回して、1ループごとに、イベントハンドラー追加するような設計はアホな設計です。こんなことをすべきではありません。
こういうアホな設計を正当化したいのが、
なにがなんでもFRPを使わなくても書けるという机上の空論のやり方であり、延々と説明してきたとおり、スケールしません。イベント、UIを関数合成するような私が提示しているやり方ではないので、実用に耐えるコードではありません。
実用に耐えない、ということを自己正当化するために、彼らがなんて言うのか?というと、
本質的には銀の弾丸にはならないと言わなければなりません
とか、
素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。
とかです。
そもそも、関数型プログラミングのメリットとは、簡潔な構造であり、生産性であり、実用的であるからです。
純粋関数型プログラミングだ!と、結果、無残な無限ループごとにイベントハンドリング追加するような無理な設計であったり、末尾再帰最適化してくれるからOCamlだ、JavaScriptは使えない、という話では、ありません。
関数型プログラミングとは汎用的な概念であり、特定の関数型プログラミング言語に縛られたり依存するものではない
JavaScriptが関数型プログラミング言語としてもっとも実用的である
Reactをはじめとする、コンポーネント指向、FRPは強固な汎用性と実用性が実証されている
ということです。
とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)
繰り返しますが、私がデスクトップアプリだのFRPだのコンポーネント指向だの書いているのは実用に耐えうるアプリについてであり、
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??
実用に耐えない、関数合成もできない、極めて限定的で単純な「机上の空論」の誤魔化しコードを提示しろ、と言ったのではありません。
すでにReactを中心に実用化がバリバリとなされ活発に開発が進んでいる現状の2015年において、
とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。
みたいな、「原理的に不可能でない」と強弁するので、その原理的に不可能でない「FRPがなんら必要でない、という趣旨には充分」なやり方を採用したら、複雑なアプリは書けない、と来る。
だったら、「机上の空論」として、原理的に不可能でなくても、「机上の空論」ではない現実的なプログラミングにおいては、実用に耐えない、「充分」でないですよね?
挙句の果てに、そのダメさを自己正当化するために、「銀の弾丸ではない」とわけのわからない一般化をして、可能性の限定を正当化する、とめちゃくちゃな言い分をして、読者を愚弄しているのがこういう連中である、ということです。
0 コメント:
コメントを投稿