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月19日木曜日

OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて

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

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

『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと

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

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

本来のFRPを理解せず中傷を重ねる連中への再度宿題

「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの

この辺の続きとなります。
この際、成り行き上かなり「気が向いた」ことと、延々と悪質な連中の(真性の天然の可能性もあるにはあるが、相手は複数であるし、総体としては多分わかって誤魔化している)誤魔化しがまかり通っていることを再確認したし、いろいろ中傷(嘘,誤魔化しをしている自覚があれば批判でなく中傷だ)してる君らに、改めて課題を出しておこうと思います。いろいろはっきりすることでしょう。

第三者による書き込み

http://anond.hatelabo.jp/20160518171946

まあお絵かきは綺麗に書けるってことでいいんじゃないの?
そんで岡部氏のFRPでは綺麗に書けて、状態渡し派の関数型には書けない次なるお題でとどめを刺せばいいんでは?

を目撃して、「なるほどそのとおりだ」と思ったこともあります。また、「お絵かきアプリ」にしても、直近の自作FRPライブラリ=TimeEngine公開後も、こちらから提示するまでもない、と思っていた、というか連中の妄想、思い込み度合いを見くびっていたことがあり、この際きちんと白黒つけるべきだと思いました。

無理なら別にやらなくていい。多分無理だろうし。君らが言い連ねているのは、机上の空論だから。
机上の空論じゃない、と証明できる場合のみ、今回の課題をクリアしてみせてくれれば良い。

その前に、この「机上の空論」の議論について、今回の課題にむけて、これまでの経緯の復習も兼ねて、重複、再掲する部分多々ある形式で、前提をまとめてみます。

まず最初に、そもそもの大前提だけれど、私にいろいろ文句垂れてくるOCamlのプログラマー複数人を中心とする連中にむけて、私は、

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

と題するエントリにおいて、こう書いた。

再掲


素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??

机上 = Desktop デスクトップのアプリをOCamlで書いて見せてくださいよ。議論はしなくて良いから。

「疑似科学者」なんて罵倒するなら、自分で証明しろ、って思いますね。
さあどうぞ。

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

まあ、技術者ならば、科学的精神をリスペクトするならば、
らくだの卯之助‏@camloebaさん、あなたが自身の関数型プログラミングのスキルが「机上の空論」でないことを示してください。


再掲おわり
以上を受けて、

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

においても、

追記(2015/05/30):デスクトップアプリケーション??

(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。

と、@nonstarter なる正体不明の自称教育関係者が書いており、

「OCamlで「お絵かきロジック」を実装してみせよと要求する」ときちんと要件は理解しているようでした。

しかし、

もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。

と言いながら、なぜか急にHaskellのコードが貼り付けらら得ており、Haskellのお絵かきアプリのコードしか書いていない。また、なにかと、elmのコードを持ち出してくる。
あのね、OCamlの関数型のコーダに向かって、OCamlで実用的なアプリを書けるのか?と確認しているのに。

TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)にもすでに書いたけれど、

(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)

とまた「原理的に不可能でない」などという「机上の空論」を自覚ない天然なのか、わざとやってるのかわらからないけれど、繰り返している。
さらに畳み掛けるように、

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

というように、とにもかくにも、(状態渡し)に固執しながら、でもいちおう(状態渡し)の限界を別のひとから指摘されたから、それは一応発現する、でもなお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不要論の大風呂敷を広げる、適当な屁理屈をとってつけて読者を惑わせて恥ずかしくないの?と思う。自称大学の教職にある捨てアカウントらしいが、知的誠実さが少しでも残っているのならば、ただちに修正することをおすすめする。言っても無駄でしょうが。どうせ捨てアカウントだし、こちらを中傷し放題で、自分は間違ったデマを垂れ流しても、恥はかき捨てで大変結構ですね。割を食うのは学習者です。まあやっぱり恥を知ってほしいです。

私が一貫して酷評している、
「関数型言語」に関するFAQ形式の一般的説明
においても、

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

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

と、(状態渡し)の関数型プログラミングで、なんでもできるように書いているが、どこまで本当なんでしょうか?複雑なのがあたりまえの実用的なアプリには通用しない、ってちゃんと初学者に教えていますか?教えていないでしょ?

したがって、改めて、東北大学の住井 英二郎@esumii、らくだの卯之助@camloeba あるいは、
@nonstarterらへのOCamlのデスクトップ(Web)アプリの宿題を出したいと思う。

繰り返し念の為ですが、もちろん別に義務なんてないし、多分出来ないとおもうから、無理してやる必要もない。やらない、ということが一つの答えとなるから。

課題

ToDoListという単純なGUIアプリを書け。

ちょっといろいろ考えましたが、状態の更新があるGUIアプリとして
適度に複雑で、適度に単純な課題を選択しました。

適度に複雑、というのは、前々回の「カウンターアプリ」にしろ、
前回の「お絵かきアプリ」については、課題が単純すぎて、
連中が誤魔化せたので、今回はそれ以上に、誤魔化しにくい程度に複雑である、ということです。

第三者による書き込み

http://anond.hatelabo.jp/20160518171946

まあお絵かきは綺麗に書けるってことでいいんじゃないの?
そんで岡部氏のFRPでは綺麗に書けて、状態渡し派の関数型には書けない次なるお題でとどめを刺せばいいんでは?

で提起されるような要件のとおり、ある程度の複雑さのハードルを満たしながら、当方のFRPのアプローチでは極めてシンプルに記述できることを示せる程度に単純な課題です。

念の為に付随要件、OCamlの状態渡しによる関数型で実装せよ

  • OCaml で君らがお題目唱えているとおり、(状態渡し)の関数型のコードで書くこと。これまで君らが誤魔化してきたように、HaskellやElmなど他の言語を「都合よくつまみ食い」してはならない。

  • FRPのメリットなんてない、とかぶちあげているみたいなので、たとえFRPのメリットをようやく今更途中で気づいたとしても、間違ってもOCamlのFRPライブラリなんかを検索して探し出して、そのFRPライブラリを利用して書いてはならない。あくまでも(状態渡し)の関数型コードで書くこと。

これは、君らが延々とこちらの主張を押さえ込むように強弁してきた要件なので、当たり前。出来なきゃ、その時点で君らの嘘が確定する。以上の条件に反しなければ別にどんなライブラリを使おうが自由。

当方は、JavaScript+TimeEngine+Reactをもって、FRPで実装します

JavaScript(いろいろ君らが関数型プログラミングの文脈で否定してきた言語)
+FRPライブラリTimeEngine
(いろいろ君らが真のFRPでなく破壊的代入だの命令型だの適当に中傷している当方によるライブラリ)
+React(FRPの末端(View)を担う、君らが否定的なJavaScriptでは今時デファクトのFBによるフロントエンドライブラリ)

をもって実装。

すでに実装しているので、アプリの詳細要件の提示を兼ねて

TimeEngine公式サイト
http://timeengine.github.io/

のDemo10

以下は動作中のスクリーンショット画像

enter image description here

極めて簡易なToDoリストの基本的動作で

1.ユーザからのToDo項目のテクスト入力を受付け
2. ボタンを押すことによって、内容が確定し上記リストに順次追加される
3. 入力欄は自動的にクリアされ、ボタン上には次のカウントが(#2,#3など)にアップデート表示される
4. アプリタイトル直下に適当なフォーマットで現在時刻を表示させる
5. アプリのスタートや入力確定項目のデバッグログをコンソールに表示させる

index.jsx

(() => {
  'use strict';
  const TodoElement = () => {
    const ClockElement = __Element(__
      .intervalSeq(Immutable.Range(), 100)
      .__(() => (<div>{moment().format('MMMM Do YYYY, h:mm:ss a')}</div>)));
    const __items = __(true);
    const ListElement = __Element(__([__items])
      .__(() => ((__items).map((item) => (<li>{item}</li>)))));
    const InputElement = () => {
      const __value = __();
      const onChange = (e) => (__value.t = e.target.value);
      const onClick = () => (__.log.t = __items.t = __value.t);
      const __seqEl = __([__value])
        .__((value) => (<div>
        <input type="text" value={value} onChange={onChange}/>
        <button onClick = {onClick}>{'NewToDo#' + (__items.length + 1)}</button></div>));
      const dummy = __.log.__(() => (__value.t = ""));
      __.log.t = "started!";
      return __Element(__seqEl);
    };
    return (<div><h2>ToDo</h2>
      {ClockElement}<p/>
      {ListElement}
      {InputElement()}</div>);
  };
  const mount = ReactDOM.render(TodoElement(), document.getElementById('todo'));
})();

基本、すべてconstのみのFRPコードです。
念の為ですが、

http://anond.hatelabo.jp/20160514005947

kenokabe氏のコードは破壊的代入バリバリの命令型プログラムそのもの

http://anond.hatelabo.jp/20160515231526

またすさまじいスパゲッティコード
kenokabeさんのコードはライブラリの内部実装だけでなく、ライブラリのユーザに見えるレベルでも
もろに命令型の破壊的代入ですね。

http://anond.hatelabo.jp/20160516112619

kenokabeさんの心の中ではそうなのかもしれませんが、ライブラリのユーザから客観的に見れば(分析哲学ではなく関数型言語の意味で)参照不透明なので、関数型プログラミングのメリットは享受できない、命令型の破壊的代入と等価ですね。

http://anond.hatelabo.jp/20160517094425

kenokabe氏のコードでもマウスが動くたびに同じ__drawFrom.tへの破壊的代入が行われるんですがそれは

http://anond.hatelabo.jp/20160516192742

これは岡部健氏が著書で「論理破綻」と批判していた、命令型言語の破壊的代入そのものです。

命令型の破壊的代入と等価と思うのは、あなたの本来の意味におけるFRPにたいする哲学的理解あるいは概念の理解が足りないからです。
関数型プログラミング、そしてFRPのメリットを享受しています。
「論理破綻」などどこにもありません。ただのFRPです。

http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b

JavaScriptか、少なくともその処理系が、関数型プログラミングに不適切です。@nonstarter

なお上の事は kenokabe の関数型言語に対する歪んだ理解の原因の一つは、末尾最適化のない JavaScript 実装を使う事に固執したためであるという事も意味します。 @yataketa9056

岡部氏の著書やコードは拝見しましたが、実用的なGUIアプリはありません。また、ReactやFRP以前に岡部氏のJavaScriptコードは無意味に複雑・冗長で、失礼ながらまさに「スパゲッティ」と言わざるを得ません。 @Lambada

kenokabeさんに代わって(もちろん変数の破壊的更新を伴わない純粋にFRPなJavaScriptコードで)実装されると一連のご主張に説得力が多少は増すかと思いますのでとてもお勧めです。 @nonstarter

JavaScriptでのFRPなんか仰々しく広める暇があったら、 @nonstarter

すでに述べたとおり2です。私がElmコードを示した理由は、単にJavaScriptよりもFRPに適しているからです @Lambada

素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。@nonstarter

まあ、その他枚挙に暇がなくキリがないので、この程度にしておきますが、
好き勝手な言い分のJavaScriptをもって、好き勝手な言い分のFRPで関数型プログラミングしたことと、FRPと極めて親和性の高いJavaScriptのフロントエンドとしてのReactのおかげで、かなり楽にコーディングできました。

ではOCamlでFRPを使わない関数型プログラミングでの実装のコードを見れる日は来るんでしょうか?
できたら知らせてください。お互いのコードを比較して精査してみましょう。どんなコードが出てくるんでしょうか?

精査して、簡潔さにおいて比較しうるに足る代物が出せたのなら、次のレベルに進めましょう。これでもまだ「状態渡し」で誤魔化しきれるかもしれないから。その懸念だけがある。

あああと、駱駝に言っておきますが、自分が不慣れな理解できないコードを眺めて「スパゲッティ・コード」と侮辱するのは悪い癖です。止めなさい。そして、「無意味に複雑・冗長」だと思うなら、ハッタリでないのなら、切り詰めて簡約したコードをさっと出しましょう。今回も「無意味に複雑・冗長」な「スパゲッティ・コード」と思うのならば、どの部分がそうなのか?明示した上で書き直したものを見せてください。

0 コメント:

コメントを投稿

Popular Posts