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日間』を大変多くの方々にお買い求めいただき、感謝します。本書の全目次を公開し、質問を受け付けます。

2016年5月6日金曜日

TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)

TimeEngine
https://www.npmjs.com/package/timeengine
https://github.com/TimeEngine/timeengine
プロジェクトgithub.io ページ
http://timeengine.github.io/
の「素朴実在論」の画像リンクなどが切れていたので、メンテナンスついでに
お絵かきアプリのLIVE-DEMOを追加しました。

Demo #9

Simple Draw

のところに

DRAW HERE ↓

として実装したCanvasを埋め込んでいます。

念の為にソースコードを再掲:

    const canvas = document.getElementById('canvas1');
    const ctx = canvas.getContext('2d');
    const __mouseDown = __();
    const __drawFrom = __();
    const __drawTo = __()
      .__(
        (val) => {
          ctx.beginPath();
          ctx.moveTo(__drawFrom.t.x, __drawFrom.t.y);
          ctx.lineTo(val.x, val.y);
          ctx.closePath();
          ctx.stroke();
          __drawFrom.t = val;
          return val;
        }
    );
    canvas.onmousedown = (e) => {
      __mouseDown.t = 1;
      __drawFrom.t = {
        x: e.clientX,
        y: e.clientY
      };
    };
    canvas.onmouseup = (e) => {
      __mouseDown.t = 0;
    };
    canvas.onmousemove = (e) => {
      if (__mouseDown.t === 1) {
        __drawTo.t = {
          x: e.clientX,
          y: e.clientY
        };
      }
    };

なぜ今、「お絵かきアプリ」なのかというと、まあ以前から何かとあちらこちらであることないこと吹聴して当方を中傷誹謗してきた住井 英二郎@esumii、らくだの卯之助@camloebaなどが存在していて(こちらは文句言われてることに気がつくまでこの関数型プログラミング界隈のろくでもない連中のことなど知らんかった)、彼らがOCamlに傾倒しているのは勝手だし、結構なことだが、まあお世辞にも一般的に実用的なアプリの範疇で普及しているとは言い難いOCamlのようなプログラミング言語をもって、広く一般的なプログラマあるいはこれから実用的なアプリを書こうとしようと勉強している初学者に向けて、まるでその延長線上で実用的なアプリが書けるかのようなトーンでいろいろ言っていることに苦言を呈したことがありました。つまり、入門者が一生懸命やったって「出口」が見えにくい、ということです。

住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?

個人的に、OCamlを振り回して、国内で関数型プログラミングで、なんかこういう、私の主張にたいしても上から目線で偉そうにごちゃごちゃ文句いってくる連中が、GUIアプリ書いてる事象を目撃したことがこれまで一度もない。
なんで?

そういうことです。

そうすると、まあ嘘くさい喧伝への批判、つまり実用的なスキームにおけるポテンシャルの限界という、彼らが初学者にはけして(正直に)語らない要素はの指摘は彼らにとっては触れられたくない、気に入らない要素であるわけで、
http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b
例の当方への批判記事に即座に
追記(2015/05/30):デスクトップアプリケーション??

という追記が@nonstarterなる捨てアカウントの人物よりなされました。(基本、著作について著者の実名をもって批判する際にこのように匿名の捨てアカウントで批判するのは、卑怯だと思いますし、住井 英二郎@esumii、らくだの卯之助@camloebaについても、
Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件についてというように、極めて卑劣な手段をもって、当方に「対抗」しようとしているとか、もうこの関数型プログラミングにまつわる連中の姿勢、行動の一切合切が胡散臭く、単なる「関数型プログラミングコミュニティ」とかいうろくでもない縄張り意識を守りたいがためになんか攻撃してくる、程度のことでしょう。)

著者はブログで@camloebaさんや@esumiiさんにデスクトップアプリケーションをOCamlで作成するように求めているようです。著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。
(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)

まず、「単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません」ということですが、彼自身自覚したコメントで突っ込みがあるように、「OCaml の全ての GUI ライブラリは状態は副作用を使うことを前提にメインループが設計されている」わけで、そんなことは、巷のOCamlの関数型の本のくせに実用むけ章になった途端に破壊的代入しまくりで「なんじゃこれ、関数型じゃないし」と私が書いて、連中がなんか怒っちゃたくだりでもう終わってる話です。

追記の後半部分の(追記)は重要で、まさに語るに落ちるという感じで興味深いです。

原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。

とか、こちらはそもそも実用的な観点から、そんなもんは無理筋だ、という論旨の展開をしておるのに、「原理的に不可能でないなら」「という趣旨には十分です。」と、また机上の空論ぶりを全開に吐露したり、「またこの主張自体はHaskellでのコードによっても充分に示されています。」とか、なんでOCamlの実用的な限界を論じているのにHaskellのコードによってでしか「充分に示されない」のか?とかツッコミどころが満載で、非常におもしろいです。

もう一度確認すると、私の基本的な観察としては、

個人的に、OCamlを振り回して、国内で関数型プログラミングで、なんかこういう、私の主張にたいしても上から目線で偉そうにごちゃごちゃ文句いってくる連中が、GUIアプリ書いてる事象を目撃したことがこれまで一度もない。
なんで?

というのがあるのですが、この第三者が指摘したとおり、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろう、ことは状況をざっと見れば誰でもすぐにわかります。

そりゃチューリング完全なプログラミング言語であれば「原理的」に実現不可能なプログラミング課題というのは存在しないのですが、「原理的」とか机上の空論のおはなしではなくて、実際上の観点から言うと、OCamlというのは、そもそもそういう入出力が発生する時間遷移することが主題の実用的なデスクトップアプリケーションの実現にまったく熱心ではない言語環境である、程度の共通理解は得られるでしょう。

OCamlは関数型プログラミング言語を標榜している一方で、GUI関連になると明らかに非関数型でしか書けない解説で満ち溢れていて、複雑なGUI、入出力の段になると関数型で書くことが困難な自覚はあるっぽい。「既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難」。しかし何故か、FAQ.入出力は「純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。」などと、ぶちあげるだけはぶちあげて、将来的にその言葉を信じてついていった学習者が壁にぶち当たることはけして解説されていない、という胡散臭い状況があるわけです。

こういった問題の象徴として出てきたのがこの「お絵かきロジック」あるいは「お絵かきアプリ」です。
関数型プログラミングの文脈からいくと、あくまで原理的でも机上の空論でもない関数型プログラミングとしての軸をとると、関数型リアクティブプログラミング(FRP)が必要になります。

今回私が自作のFRPライブラリのDEMOコードとして追加した、当記事の冒頭のお絵かきアプリのコードは極めて簡潔ですが、簡潔に書けるのはあくまでもFRPで設計してるからです。念の為ですが、すべての値は、constとなっています。

さて、@nonstarterなる捨てアカウントの人物の言い分によると、

いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。

だそうです。
まったくわけのわからない言い分ですね。

大事なポイントは、「(状態渡し)」で時間遷移していく、複雑なことが普通である実用的アプリケーションを書こうとすると、

  • 状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる

  • そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い

ということです。まあこの捨てアカウントの人物はその程度の理解と自覚はしっかりあるようですし、ここまでは言ってる意味はわかるし、普通に正しい(それ以降は全部間違っていますが)。

彼が言ってる正しい部分をまさに私は指摘している。それは根本的に、時間遷移の概念を関数型のパラダイムに抽象化したFRPを適用していないのが問題なのであって、あんたらはそんなことは一切触れずに、まるで、「(状態渡し)」で最終的になんでもできるかのように、初学者に向けても説明してるじゃないか、というか、実際、OCamlで実用的なデスクトップアプリを書いてるのみたことないけど、できるの?そんなに言うなら書いて見せてよ?、、、というところまでが、私の「問題提起」なのでした。

ここまでは当然この胡散臭い捨てアカウントも理解しているようですが、続いて、

結局のところ少なくとも現状のFRPも本質的には銀の弾丸にはならないと言わなければなりません

(多分何がなんでも自分の理解を超える要素は否定したいと大風呂敷を広げる)
一応とってつけた理由:

(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)

???????意味不明。
まあ、この人物がFRPが何たるか理解していないのは、ほぼ確実でしょう。
FRPの本質は「時間軸」のプログラミング言語上での抽象化であり、なんかわけわかりませんが、この一連の議論で、FRPという言葉さえでてくるも、「時間」とか言っているのが私ただひとりだけ、という非常にわけのわからない、もとい、ある意味、連中がどういう知見レベルをもって当方を批判、あるいは中傷しているのかが非常にわかりやすい状況です。

念の為ですが、TimeEngineのプロジェクトgithub.io ページ
http://timeengine.github.io/
にも書いていますが、1997年の論文で、http://dl.acm.org/citation.cfm?id=258973

Fran (Functional Reactive Animation) is a collection of data types and functions for composing richly interactive, multimedia animations. The key ideas in Fran are its notions of behaviors and events. Behaviors are time-varying, reactive values, while events are sets of arbitrarily complex conditions,

Fran (Functional Reactive Animation) として、初めてFRPを明示的にプログラミングパラダイムとして導入したことで知られているConal Elliottは、 
http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming
において、こう宣言しています。

I do resonate with Laurence G’s simple description that FRP is about - “datatypes that represent a value ‘over time’ ” -. Conventional imperative programming captures these dynamic values only indirectly, through state and mutations. The complete history (past, present, future) has no first class representation. Moreover, only discretely evolving values can be (indirectly) captured, since the imperative paradigm is temporally discrete. In contrast, FRP captures these evolving values directly and has no difficulty with continuously evolving values.
Dynamic/evolving values (i.e., values “over time”) are first class values in themselves. You can define them and combine them, pass them into & out of functions. I called these things “behaviors”.

面倒なんで全部訳しませんが、ポイントは、

  • FRP is about - “datatypes that represent a value ‘over time’ “
  • Dynamic/evolving values (i.e., values “over time”) are first class values in themselves.

FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、
ということです。

したがって、
「いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのこと」とか、そういうおはなしとは全く別の話題ですし、
FRPでは「(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくる)」なる言及は、FRPのパラダイムを論じる上で意味を成しません。

(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。

これもどういう意味なのか全く意味がわかりません。
とにかく、力づくで理屈を捻じ曲げても、とにかくFRPという彼にとっては新しい未知の概念の導入なんて無意味だ、ということを力説したいという熱意だけは伝わってきます。

ちなみに、大した意味はありませんが、敢えてFRPライブラリ(Reactive-Banana)を使うとこうなります:

大した意味がないどころか、FRPライブラリを導入するということは、時間軸上の展開している値をファーストクラスにして、時間発展する系を関数型プログラミングの枠組みで統一的に取り扱えるようにする、という甚大なパラダイムの変化であり、大きな意味があります。
 

FRPライブラリを使ってもコードが先のものと殆ど変わらないことに注意してください。要するにこれらのコードの本質は状態遷移を純粋な関数(ここではeTrans)で表現するところにあり、イベントストリームやシグナル・ビヘイビアといったFRP特有の要素を用いるか否かにはないということが示されています。

そりゃさ、この程度ならば「殆ど変わらない」のだが、とりもなおさず君自身が言ってたとおり、

  • 状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる

  • そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い

という状況が顕在化するばするほど、「殆ど変わらない」どころか、本質的な違いが顕在化する。

まず批判ありきで私個人を中傷するにとどまらず、何も知らんくせに、FRPの意味もわかってないくせに、批判ありきのFRP不要論の大風呂敷を広げる、適当な屁理屈をとってつけて読者を惑わせて恥ずかしくないの?と思う。自称大学の教職にある捨てアカウントらしいが、知的誠実さが少しでも残っているのならば、ただちに修正することをおすすめする。言っても無駄でしょうが。どうせ捨てアカウントだし、こちらを中傷し放題で、自分は間違ったデマを垂れ流しても、恥はかき捨てで大変結構ですね。割を食うのは学習者です。まあやっぱり恥を知ってほしいです。

FRPは、時間発展する系の時間軸上の値をファーストクラスにして扱うというパラダイムであり、TimeEngineは、時間軸上の値をJavaScriptのファーストクラスとして提供する、FRPライブラリとして開発しました。

お絵かきアプリのLIVE-DEMOですが、明確な設計思想、つまり
時間軸上の値をJavaScriptのファーストクラスとして提供する
という設計思想をもって自分で開発したFRPライブラリを使って、

  1. mouseイベントからFRPの値に表現
  2. FRPの値の構成をcanvasと接続する

というだけですから、簡潔かつ、設計もコーディングも単純、つまり簡単です。
実質コーディング時間は10分程度だったんじゃないでしょうか?
実際に、プロジェクトgithub.io ページ
http://timeengine.github.io/
に列挙している他の、たとえばカウントアプリのほうがよほど複雑なわけで、これは一番簡単な部類に入ります。

ぶっちゃけ、TImeEngineの各DEMOのプレゼンテーションだけでも、お絵かきアプリは一番カンタンな部類だということはわかりそうなものですが、
こういう胡散臭い連中は、「言い聞かせてもわからない」「自分に都合の良い、相手に都合が悪くなりそうな設定を信じたいように信じる」病人なので、

ところで岡部はいつになったら彼の言う「お絵かきロジック」を破壊的代入を用いない関数型のJavaScriptで書いてみせるんだろうか。
そんなトイプログラムのコードも示せないとなると岡部のCS理解とコーディング能力は推して知るべしということになるわけだが。

だとか、

目が潰れそうなスパゲティコードだが、これでは「お絵かきロジック」のようなトイコードすら関数型で書けはしないということは岡部健自身が一番よくわかっているだろう。お前さんがDate.now()で岡部がかいた恥をほじくり返して晒すのは死者に鞭打つようなものだ。もし反論したければ、お前さんがこのオモシロ timeengine で「お絵かきロジック」を関数型で書いてみせてくれればいいのだよ。簡単だろう(笑う)。まあ、できやしないのはわかりきっているのだが(とはいえそれができないのは岡部のせいなので気に病む必要はない)。

だとか、

こうして絶対にコードを書かずにいつまでも逃げまわるのであったwww

だとか、言ってるようで、頭痛が痛くなってきます。
まあ、TimeEngine自体を開発するのは、かなり大変でしたが、冒頭のコードみたいなお絵かきアプリを書くのは、かなり簡単です。

これが簡単な作業だとわからない連中に向かって、簡単なコードをついでにUPしなかったのは、「ほんとうにしょうもない」と心底思っていたからです。

いやこの10分でかけるコードを書くのに、1年くらいかかった!とか、またしょうもない中傷、妄想を続けるのは自由です。
実際「2ヶ月たってもお絵かきアプリを書けない」「3ヶ月たってもお絵かきアプリを書けない」とか、延々と中傷していましたね?中傷というか、ナイーブに本気でそう思ってったぽいのは、知見レベルが低いのか、思いこみの強い病的な性向によるものなのか、いずれにせよかなり気持ち悪いです。

実際、簡単なコードだ、とUPして見せて理解できるのかさえもよくわかりませんが、少なくともこんなもんが難しい課題だと少しでも思ってるのは本当にJavaScriptでFRPを書くのが困難だ、と本気で思ってればそういう気持ちになりえるのかな?とは想像可能です。が、正直頭のおかしい連中のことはよくわかりません。
今後もこれまでと変わらず、自分が信じたいことだけ信じて、初学者を惑わすデマを拡散していってください。

住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?

OCamlで書かれた「お絵かきデスクトップアプリ」に関しては、らくだの卯之助@camloebaあたりがUPした、ガッタガタのそれこそトイアプリを見ましたが、私がまともなもんを見る日は来るのでしょうか?

らくだの卯之助‏@camloebaさん、あなたが自身の関数型プログラミングのスキルが「机上の空論」でないことを示せ。

という投げかけには、示されていない、無回答であるということになります。非常にしょうもないことですが、改めて連中のノリを観察すると、本気で、こちらが「お絵かきアプリ」を書かない、というか、あほらしいので書くまでもなく放置していることを心の拠り所にしていたっぽいので、今回改めて、明示的にもう一度、ボールを投げ返しておきます。

そういえば、「関数型言語」に関するFAQ形式の一般的説明
にも、

それだと入出力や状態(state)すら表せないのでは?

いいえ、純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。

と、すでに引用した@nonstarterなる捨てアカウントの人物の言い分

いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)’

と全く同じことが書かれており、住井@esumii が語る、関数型プログラミングの、時間遷移する複雑なアプリの実用性は、すべて(状態渡し)一点で処理しようとしているように見えます。少なくとも私は、
@nonstarterはもとより、らくだの卯之助‏@camloeba、住井@esumii その他とりまきの自称関数型コミュニティの連中が「動的に時間発展する値を、時間軸上の静的な値として俯瞰し、ファーストクラスとして扱う」というコンテクストにおける正しいFRPの文脈で話しているのは一度たりとも見たことがありません。

まあデタラメな知識でFRPがなんたるか理解せず、意味不明な言説をもってFRPの導入の妥当性を全力で否定した上で、(状態渡し)一点ばりの問題点

  • 状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる

  • そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い

と宣言しているということは、連中のOCamlでのコーディングの実用性は、上記が上限だということになります。そういうことですよね?(笑)

0 コメント:

コメントを投稿

Popular Posts