住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い
この辺の続きとなります。
まず「課題」についてですが、いまのところ、私が知る限り、まだどこにもされていません。
念の為ですが、Twitterやら幼稚な念仏唱えているだけと一部馬鹿にされている病人が誹謗中傷連ねたいだけの2chスレの書き込みなんかいちいちチェックしてるわけもないので、万一そんなとこに書きなぐっても見てるわけもありません。
本来のFRPを理解せず中傷を重ねる連中への再度宿題
の「本来のFRP」による「お絵かきアプリ」っていったいどこにあるの?という課題については、
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
と説明したとおりです。単なるごまかしです。
http://anond.hatelabo.jp/20160520054338
http://anond.hatelabo.jp/20160517023637
>ライブラリユーザは現在時刻から状態への写像fを
>参照透明な関数なりストリームなりで記述して、
>それを処理系が実際のシステム時刻t=0,1,2,…に適用して
>状態f(0),f(1),f(2),…を得る
はっきりと「処理系が」って書いてあるのに、K氏は本気で
ユーザプログラムにf(0),f(1),f(2),…みたいなコードがないのが
「反論」になると思ったのだろうか……
まさか本当に「処理系」という言葉がわからなかった??
もちろん、わかっていますよ?それ込みです。
だから、その処理系のライブラリのソースコードのいったいどこに、
「実際のシステム時刻t=0,1,2,…」ってのをとって、
状態f(t)にしているところがあるんですか?
「これ以上は説明も回答もしない。」とか書いたのは、そこを有耶無耶にして誤魔化したいからでしょ?
タイマーイベント、あるいはあらゆるイベントの時点での、
ある値とるなら、それは単に普通のイベント駆動であって、
こちらが論じていた「現在時刻」はそれ以外のシンボルでは表現できない、という議論とも関係ないし、
FRPとも関係ないですよね?
ただ、「実際のシステム時刻t=0,1,2,…」という、それっぽい口ぶりで真似したかっただけですか?
「実際のシステム時刻t=0,1,2,…」という、時間軸のストリームの値は、
ライブラリ処理系ではなく、プログラマーレベルの目線で、
「時間を抽象化したファーストクラスな値」とするのがFRPで意味がでてくるのであって、
裏でイベントドリブンで、処理系「実際のシステム時刻t=0,1,2,…」とか、あんた何が言いたいの?
誤魔化したいだけだよね?っていうことです。
そういう誤魔化しばかり書きなぐるのはもういい加減にしろ、っていうことです。
次に、
直近の、
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
ToDoの関数型GUIアプリについてもいまのところ無回答です。
前回、
私のFRPライブラリは参照不透明?で、命令型の破壊的代入っていう中傷について、またしばらく後にエントリします。あたらしい課題つきで。
とあたらしい課題を示唆したのですが、連中が出来もしないことを机上の空論を並べ立てていた、
という分水嶺となる良い課題だ、という意見をもらったこととや、
あたらしい課題を与えて、ペンディングされてる課題が未解決なのに、
つけ入るスキを与えるべきではない、議論が発散してしまい、
また誤魔化される余地が生まれる危険性がある、
という意見も頂いたので、当面上記の、ToDoリストアプリにもとづいて話を進めていきます。
さて、「命令型の破壊的代入っていう中傷」についてですが、前回いろいろいろ引用したのに加えて、
直近の中傷はこういう感じです。
http://anond.hatelabo.jp/20160519135844
http://kenokabe-techwriting.blogspot.com/2016/05/ocamlgui-esumii-camloebanonstarter.html
の自称関数型コードに出てくる
__value.t = e.target.value
__items.t = __value.t
等々も、kenokabe氏の心の中では「時間軸でインデックスされた何か」なのかもしれないが、
客観的にはマウスクリック等のたびに同じメンバ変数__value.tや__items.tへの
破壊的代入が何度も実行される命令型プログラムそのもの。
__valueや__itemsにconstがついていても、__value.tや__item.tはconstではない。
ここでもういちど、
http://kenokabe-techwriting.blogspot.com/2016/05/ocamlgui-esumii-camloebanonstarter.html
の自称関数型コード
と中傷されている、
課題の私が書いたToDoリストアプリのコードを再掲しておきましょう。
(() => {
'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で抽象化してファーストクラスにした値。
これも何度も説明しました。
const __items = __(true);
っていうのは、
ミュータブルに見える「リストアイテム」を、
本来イミュータブルな時間軸において、
FRPで抽象化してファーストクラスにした値、のことです。
10分前に追加したある「リストアイテム」は、
イミュータブルな時間軸の世界線上で、その10分前のポイントに分布、
2分前に追加したある「リストアイテム」は、
イミュータブルな時間軸の世界線上で、その2分前のポイントに分布。
未来に追加されるであろう「リストアイテム」でさえ、
イミュータブルな時間軸の世界線上で、その未来方向のあるポイントに分布。
時間軸は無限リストであり、関数型プログラミングでは、無限があつかえるのと同じ原理で、
未来方向に広がっている無限リストでもこうやって抽象化できる、ということです。
中傷してる連中は、まずこの
FirstClass Value “Over TIme” という概念をまず理解してんの?
っていう疑念がある。多分できていない。
いずれにせよ、
const __items = __(true);
とイミュータブルな定数として宣言してしまいます。
ほんでですね、
__valueや__itemsにconstがついていても、__value.tや__item.tはconstではない。
という主張についてなんですが、
以上のはなしを理解しておれば、
そのそれぞれ、つまり
10分前に追加したある「リストアイテム」は、
イミュータブルな時間軸の世界線上で、その10分前のポイントに分布、
2分前に追加したある「リストアイテム」は、
イミュータブルな時間軸の世界線上で、その2分前のポイントに分布。
未来に追加されるであろう「リストアイテム」でさえ、
イミュータブルな時間軸の世界線上で、その未来方向のあるポイントに分布。
という話を理解しておれば、それは原理的に同様に、イミュータブルである、
const
である、ということが自然と理解できるはずです。
自然と理解できてない、ってことは、すなわち、上で言ってるような「意味」
がわかっていないということです。
時間軸がイミュータブルな無限ストリームで、
現在値というのはt
であるとか、now
であるとか、
そういうあるシンボルでしか表現できないものであって、こうするしかない、という意味が理解できないひとたちです。
たしかに、「ライブラリの実装下レベル」では、FRPにせよ、その他関数型にしても、
破壊的代入しまくるし、このt
だって、オブジェクトのプロパティとして破壊的代入はされるわけです。
でも、いい加減しつこいんですよねー。
「ライブラリの実装下レベル」で、破壊的だの命令型だのいう、中傷。
だから、OCamlとかHaskellとか、あんたらの満足する純粋関数型ってのは、
言語実装レベル下で、純粋関数型でソースコード書かれてるの?C++とかで破壊的代入されてるだろう?
という話です。もうしつこいし、いい加減にしてくれ、っていうのがまたあります。
あくまで、ライブラリユーザレベルにおいて、
const __items = __(true);
(ちなみにこの__(true)については、後で話します。
trueがあろうがなかろうが、本題とは関係ないので、当面気にせずに)
というように、定数です。t
が破壊的代入されている!
とおもっているのは、上記のとおりそれは使い手の理解の問題であり、
ライブラリ下の実装と結びつけて、批判するのは、間違いです。
さて、実装の本題に戻ります。
イベント駆動において、
イミュータブルな定数
__items
の時間軸上のそのイベントが発生した、ある時間Tにおける値(現在値)は、
__items.t
で表現され、
それは、 別の
イミュータブルな定数
__value.t
の時間軸上のそのイベントが発生した、ある時間Tにおける値(現在値)は、
__value.t
で表現される値と等しくなる、と宣言します。
これは断じて命令型ではないし、なんの「破壊的代入」も発生していない宣言である、
ということが理解できるでしょうか?
理解してる人は良い。
延々と中傷している一連の連中はなんも理解していないということになります。
要するに、イミュータブルな時間軸の世界線において、
イベントが発生したそれぞれのポイントで、それぞれの値を順次格納していく、ということになります。
念の為ですが、便宜上「それぞれの値を順次格納していく」と書きましたが、
数学的には、決定論的に最初から決定されている、とみなす宣言文です。
時間軸を無限リストとして扱う、ということは、すなわち、
無限の未来方向までひっくるめて全部数学的な値として抽象化するということなので、
便宜上言ったような、
時間の流れに従って「それぞれの値を順次格納していく」変数
ではなくて、
未来方向においても「それぞれの値を順次格納している」定数
として扱っているということです。
変化しません。イミュータブルな定数です。
これが
FRPのValue ”OverTime” がイミュータブルな定数である本当の意味です。よろしいでしょうか?
だから
const __items = __(true);
という、時間軸上の世界線の「定数」 const
であるのならば、
「破壊的代入」なんておこりうるはずもない。
ということです。
「破壊的代入」がなされている、と批判した時点で、
その人物は、
FRPのValue ”OverTime” がイミュータブルな定数である
という意味なんて、本当はこれっぽちも理解していない、ということが白日の下にさらされます。
つまり、中傷してる連中は、FRPの哲学的理解が足りないからそういうことが言えるのだ、ということですね。
かように、
__items
には、すべてのリストアイテムが、コードが宣言された瞬間に
const __items = __(true);
とされた時点でもう「すでに」全部入っています。
FRP的には、そう見做されている、数学の定数です。
格納されているそれぞれの地点と1:1に対応しているのが、
const onClick = () => (__.log.t = __items.t = __value.t);
という、クリックイベントの宣言文です。
えーっとクリックイベントの宣言文って、命令型ですか?違うでしょ?
単に、これも
イミュータブルな時間軸の世界線におけるマウスクリックの挙動の分布
と、
イミュータブルな時間軸の世界線におけるリストアイテムの分布
が一致している、という数学的な宣言にすぎません。
命令型というのは、
Step1
Step2
というように、コードの上下方向を利用して、評価させていくものであり、
上記の時間軸上の世界線の分布について、ある要素とある要素でマッピングして呼応させる、というのとまったく関係ありません。
このコードも、
const __items = __(true);
このコードも、
const onClick = () => (__.log.t = __items.t = __value.t);
単に、
イミュータブルな時間軸の世界線における値の分布の宣言文であり、
コードの宣言においては何も評価されません。
断じて命令型の要素などない、ということです。よろしいですか?
さて、
__items
というFRP定数には、
すべてのリストアイテムの値が時間軸上に分布して格納されています。
そのままでは、数学的な抽象的存在であり、
ユーザの目にもふれず「実用的なアプリ」として、役に立たないわけですから、
Reactを利用して、フロントエンドのDOM要素としてマッピングしてやります。
const ListElement = __Element(__([__items])
.__(() => ((__items).map((item) => (<li>{item}</li>)))));
これもただ数学的な関係を宣言しているだけです。命令型の要素はどこにもありません。
おっと!
__items
のt
が「破壊的代入」されて破壊されてしまったのなら、
いったいなぜ、このようなマッピングが可能になって、実際に、
TimeEngine公式サイト
http://timeengine.github.io/
のDemo10
というように、動作してしまうのでしょうか!?
論より証拠。私が実装したFRPは、そのFRPの設計哲学どおりに挙動しているわけです。
命令型の要素なんて微塵もないし、破壊的代入をもって破壊されたのならば、
リストなんて列挙表示されてるはずがないだろう?
でも実際には、破壊されずに全部きちんと表示されていますよね?
ってことです。
もういいでしょうか?意味もわかってないのに、己の無知無理解を棚に上げて
中傷するのはもういい加減にしてください。
というか、どなたがやってるんですかね?匿名で恥はかきすてで毎度結構なことですよね?
岡部が、kenokabeが、と書き込むが、自分の名前はださずに、なんか複数でやってる。オモテにでてこいよ?
と思う。
あと、なんでもいいから、さっさとこの課題のコード書いてみせてください。
「机上の空論」でないのならば。
さて、最後に、本論と関係ないことですが、テクニカルなことです。’
const __items = __(true);
というようにtrue
オプションがかかっていますが、
他のコードなどでは、
const __a = __();
というようになっています。
例えば「お絵かきアプリ」では、
イミュータブルな時間軸の世界線に分布する、
実行時点までの過去すべてのデータを保持すると、
現在時間が未来方向に進むにつれて、計算機上のメモリにデータが蓄積されていきますから、
メモリリークのような現象が起こります。
ほとんどの場合、「状態遷移」だけ扱いたいので、過去のデータは全部捨てていきます。
というか、ライブラリ実装上は、単に保持はしない。
const __items = __(true);
とかオプションつけた場合、ちゃんと保持するし、別の宣言文をもってデータ全体にアクセスできますよ、ということです。
もちろん、「お絵かきアプリ」のFRP値で、オプションつけて、データ保持させると、
ドローしたすべてのストロークがデータとして蓄積されるし、
リプレイみたいなことも簡単にできます。
0 コメント:
コメントを投稿