Topics
・関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い
・ガラパゴス・ネットスラング=「関数型ポエム」という呪詛、先入観的読書と、フェアなレビューの登場
・JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン
・2016年のnode、ES6、React、Babel、Atomエディタ界隈の方向性
・Dockerじゃないsystemd-nspawn+machinectlが非常に良い
・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日間』を大変多くの方々にお買い求めいただき、感謝します。本書の全目次を公開し、質問を受け付けます。
2018年12月9日日曜日
2016年5月24日火曜日
続スケールするFRPアプリ課題:TimeEngine+React(JS)とOCamlの比較
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い
TimeEngineの __x.t = __x.t + 1; について
この辺の続きとなります。
特に前回、
スケールするFRPアプリ課題:わかりやすい嘘誤魔化しをしないように
この課題についてです。
FRP必要ない、とかぶちあげてた@nonstarterを「擁護」あるいは結託してたんだから、FRP使うとかもちろんなしで。
純粋関数型の「状態渡し」で実用的なアプリを「なんら困難もなく」書けるんでしょ?
FRPと複雑性は変わらんのでしたよね?じゃあ、当方のFRPのコードと同等以下の複雑性で、
関数型「状態渡し」をもって書けるはずです。
もっとも適当な嘘ハッタリじゃあなければね。さあやって見せてください。どうぞ。
と煽ったら、まんまと書いてくれました。ご苦労様。
これまで連中がやらかしてた嘘誤魔化しを徹底的にこちらが糾弾する形で、追い込んだので、
(そういう作業も手間がかかるんですよね、最初から誤魔化ししなければいい)
ここに来てようやくそれなりに嘘ごまかしが排除された実用的GUIアプリの比較対象となりうるコードが登場してきました。
まあ、さぞかし「大変」だったことでしょう(笑)
連中が総体として、傍観者、客観的読者へ向けて印象づける
「いともかんたんに、なんでも関数型の状態渡しでできる、OCamlでも何でも一緒」
「FRPも状態渡しも一緒、FRPはなんら必要なし、メリットなし@nonstarter」
という趣旨の大嘘@はとりあえず確定したようなので、確認していきましょう。
OCamlソースコード
module H = Dom_html
let g x = Js.Opt.get x (fun () -> assert false)
let o x = Js.Opt.return x
let s = Js.string
let i = string_of_int
type ('a, 'b) state =
(* just to omit explicit annotation of complex types by (ab)using "polymorphism" *)
{ itemss : 'a list list; cur : int; selects : 'b }
let _ = H.window##onload <- H.handler (fun _ ->
Firebug.console##debug(s "DoNe2 starting");
let d = H.document in
let tm = g (d##getElementById (s "todo2_time")) in
ignore
(H.window##setInterval
(Js.wrap_callback (fun _ ->
tm##textContent <- o (jsnew Js.date_now ()##toString ())),
100.));
let nu = g (H.CoerceTo.input (g (d##getElementById (s "todo2_new")))) in
let selects = g (d##getElementById (s "todo2_selects")) in
let select1 = g (H.CoerceTo.input (g (d##getElementById (s "todo2_select1")))) in
let selected = g (d##getElementById (s "todo2_selected")) in
let input = g (H.CoerceTo.input (g (d##getElementById (s "todo2_input")))) in
let go = g (H.CoerceTo.input (g (d##getElementById (s "todo2_go")))) in
let ul = g (H.CoerceTo.ul (g (d##getElementById (s "todo2_ul")))) in
(* ここまでDOMの準備。ここから本体 *)
let rec generate_handlers st =
let rec handle_sub _ =
let v = input##value in
let rec add_v pos = function (* 補助関数 *)
| [] -> assert false
| items :: itemss when pos = 1 -> (items @ [v]) :: itemss
| items :: itemss -> items :: add_v (pos - 1) itemss in
let new_itemss = add_v st.cur st.itemss in
Firebug.console##debug(s ("DoNe2 adding to List#" ^ i st.cur ^ ": " ^ Js.to_string v));
input##value <- s "";
configure_ui { st with itemss = new_itemss };
Js._false
and handle_nu _ =
let new_list = H.createInput ~_type:(s "submit") d in
let new_selects = st.selects @ [new_list] in
let new_itemss = st.itemss @ [[]] in
let new_cur = List.length new_selects in
new_list##value <- s ("List#" ^ i new_cur);
Dom.appendChild selects new_list;
configure_ui { (* st with *) itemss = new_itemss; cur = new_cur; selects = new_selects };
Js._false
and handle_select new_cur _ =
configure_ui { st with cur = new_cur };
Js._false
in
(handle_sub, handle_nu, handle_select)
and configure_ui st =
selected##textContent <- o (s ("List#" ^ i st.cur));
go##value <- s ("NewDoNe#" ^ i (1 + List.length (List.nth st.itemss (st.cur - 1))));
let rec rm_all_child p = (* 補助関数 *)
Js.Opt.case (p##firstChild) (fun () -> ())
(fun c ->
ignore (p##removeChild(c));
rm_all_child p) in
rm_all_child ul;
List.iter
(fun item ->
let li = H.createLi d in
li##textContent <- o item;
Dom.appendChild ul li)
(List.nth st.itemss (st.cur - 1));
let (handle_sub, handle_nu, handle_select) = generate_handlers st in
go##onclick <- H.handler handle_sub;
nu##onclick <- H.handler handle_nu;
List.iteri
(fun n selected ->
selected##onclick <- H.handler (handle_select (1 + n)))
st.selects
in
configure_ui { itemss = [[]]; cur = 1; selects = [select1] };
Js._false)
まず、「非常に長い」です。
これまで、あたかも簡単に短く書けるようなフリしたコードを出していたけど、ほんの少し複雑にスケールしたアプリが課題になると、途端に急にコードが倍増した。なんで?
これまで課題が簡単である、というある種の特性を利用し、それが複雑になるとすぐに破綻するコードである、という、学習者にとってもっとも重要な情報をひた隠しにし、あたかも汎用的に通用するスケールする設計とコードである、というフリをしてきたのが、実際に破綻してしまったからです。
つまり、これまで誤魔化していた、課題の単純性という特性の利用、誤魔化しが通用しなくなり、破綻して、一気に膿が出てきた分量が、この目に見えるコード量の急増分です。
言い換えると、すでにこうやって急増したコードをベースに、いろいろ削る形で修正すれば、一個前のより単純な、ToDoリストアプリが簡単に書けます。そして、より単純な、ToDoリストアプリからまた順当に機能追加すれば、このコードになるでしょう。こういうのがスケールする設計で、コードであると言います。
前回からまるで様子の異なった、コードがなんか倍増しているということは、前回の設計が、問題がスケールしたら、まったく通用せず破綻した、ということを意味します。
この人物のコメントです。
動いてると思うけど書き殴りだから細かいことは気にしないでね
単に機能が増えて面倒になっただけで、状態渡しのしかたは前回と同じ。ちなみに今回も頑張れば状態渡しすら使わずに書けそうだけど、これは使ったほうが楽かな。
メインループではなくハンドラでOCaml部分の状態渡しをしてるので、「メインループを書き直してるからスケールしない」というのとは少し違う。
(状態渡しや関数型云々とは無関係に)やっぱりDOMかつ静的型だとちょっと長くなるね(定数倍ファクターなのでスケール云々とも無関係)。前回のから改造しててOCaml部分の不整合はデバッグしなくてもコンパイラが見つけてくれるので開発は明らかに楽だったけど。
まあ
それなりの試行錯誤の末に「苦労したんだな」
というのが行間から溢れ出ています。お疲れ様。
実際に、前回この人物は、「状態渡し」で書きたくない理由についての言い訳として、
以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。
と発言しており、
「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常
つまり、今回慣れない、かなりイレギュラーな実装を試みた、というのがわかります。
「非常に長いコードである」という点については、
静的型だとちょっと長くなる
らしいです。つまり、
実用的なGUIアプリをOCamlで静的(イミュータブル)な関数型のスタイルをもって実装しようとすると、簡潔になるどころか、コードがかなり煩雑になり長くなる
ということが、反発していた、誤魔化し続けていた当のOCamlプログラマー自身の手により実証されました。
すなわち、これが、この人物を含め、胡散臭い連中がずっと誤魔化してきてけして表明しなかった動かしがたい事実であり、私が、当初、あんたら関数型について偉そうな事言ってるけど、スケールする実用的なGUIアプリとか、そのやリ方ですんなり書けるわけ?と批判した核心的な要素となります。
@nonstarterはじめ、連中がさんざん中傷してきた、JavaScriptの関数型において、
いまやGUIフロントエンドのデファクトとなってしまっている、FacebookReact、
それに、私のTimeEngineというFRPライブラリを適用してFRP、関数型で書いた、同じGUIアプリのソースコードは以下でした。比較検討のために再掲します。
スケールするFRPアプリ課題:わかりやすい嘘誤魔化しをしないように
TimeEngine公式サイト
http://timeengine.github.io/
のDemo11
ソースコード(index.jsx)
const TodoElement = () => {
const ClockElement = __Element(__.intervalSeq(Immutable.Range(), 100)
.__(() => (<div>{moment().format('MMMM Do YYYY, h:mm:ss a')}</div>)));
const __fdList = __().__((val) => (__.log.t = val));
const __lists = __(true).__((__list) => (__fdList.t = __lists.length));
const ListofListElement = __Element(__([__lists])
.__(() => ((__lists).map((list, i) => (
<button onClick = {() => (__.log.t = __fdList.t = i)}>{'List#' + (i + 1)}</button>)))));
const InputElement = () => {
const __value = __();
const onChange = (e) => (__value.t = e.target.value);
const onClick = () => (__.log.t = __lists[__fdList.t].t = __value.t);
const onClickNL = () => (__.log.t = __lists.t = __(true));
const __seqEl = __([__value]).__((value) => (<div>
<h4>{'List#' + (__fdList.t + 1)}
<button onClick = {onClickNL}>{'NewList'}</button></h4>
{__lists[__fdList.t].map((item) => (<li>{item}</li>))}
<input type="text" value={value} onChange={onChange}/>
<button onClick = {onClick}>{'NewToDo#' + (__lists[__fdList.t].length + 1)}</button></div>));
__.log.__(() => (__value.t = ""));
return __Element(__seqEl);
};
__lists.t = __(true); //new items-list
const __delay = __.intervalSeq(Immutable.Seq.of("started!"), 1000)
.__(() => (__.log.t = "showInput"));
return (<div><h2>ToDo</h2>{ClockElement}<p/>
{ListofListElement}<p/>{InputElement()}</div>);
};
const mount = ReactDOM.render(TodoElement(), document.getElementById('todo'));
公平性のため、空行、コメントを除外して、コードの行数の単純比較
をしてみると、
OCamlの関数型状態渡し : 74行
JavaScript+React+TimeEngineのFRP : 29行
です。もちろん、あちらも当方も、いくらでも改行は整理することは可能ですが、
可読性とバランスを双方とっているようにみえる現行のコードでの単純比較となります。
同じGUIアプリを関数型で実装するのに、JS+TimeEngine(React)のFRPでは、OCamlの状態渡し関数型より、行数にして半分以下
で書けている、ということが証明されました。
まあ、視認しても、ぱっと見でも、どちらが簡潔に短く表現できているのか?
一目瞭然だと思います。
そして念の為ですが、ちょっと例題を複雑にしたらこうなった、ということであり、
より複雑性が増したら、さらにこの差は顕在化し、デバッグその他の差異は深刻になる、
というのは明らかです。
たとえば、私が書いた上記のFRPのコードですが、
const
で定義している定数をそのまま抜き出して列挙してみると、
これらはそのまま関数型コードの構造になっています。
const TodoElement
const ClockElement
const __fdList
const __lists
const ListofListElement
const InputElement
const __value
const onChange
const onClick
const onClickNL
const __seqEl
const mount
こうなります。GUI部品のReactのElementは、
ToDoElementが、最後にmountされる一番外側のコンポーネントであり、
それらの内訳は以下の3つ。
- ClockElement
- LIstOfListElement
- InputElement
さらに、3つのユーザ入力イベント宣言
- onChange
- onClick
- onClickNL
に加え、FRP値
- __fdList (現在フォーカスされているリスト)
- __lists (リスト群)
- __value (ユーザ入力テクスト)
- (__seqEl)
以上の各const
の宣言を列挙することは、そのままアプリの設計の概略となっています。
関数型、宣言型コード全体として極めて見通しのよいコードになっています。
当然、アプリケーションがいくら複雑になろうとも、このシンプルな構造の延長でいくらでもスケール可能です。
さて、このような明瞭簡潔な構造が、この人物が苦労して書いた「スパゲッティ・コード」
OCamlの状態渡し関数型コードにあるでしょうか?
動いてると思うけど書き殴りだから細かいことは気にしないでね
単に機能が増えて面倒になっただけで、状態渡しのしかたは前回と同じ。ちなみに今回も頑張れば状態渡しすら使わずに書けそうだけど、これは使ったほうが楽かな。
やっぱりDOMかつ静的型だとちょっと長くなるね
前回のから改造しててOCaml部分の不整合はデバッグしなくてもコンパイラが見つけてくれる
こういう発言からも明らかでしょう。
つまりこのコードは、コンパイラが不整合を見つけてくれないと、コーダーには手に負えないほど複雑であり、「面倒」であり、「動いてると思うけど、細かいことは気にしないでね」と言い訳せざるをえないほどに、設計についてはあやふやで、関数型でイミュータブルに書くには「異常」な努力が必要で、当然、長いコードである、
ということになります。
不整合をコンパイラが見つけてくれる?
私がJavaScriptのFRPのコード書くときは、そんなもんは必要ないですが?
この人物の最後の言い訳です。
俺もOCamlの勉強になったけど、「できない」と断言されたことをすぐにやって見せたんだから(それも3回。しかも他人に「課題」とか言った本人は1年がかり、かつ関数型ではなく全くの命令型。決して認めないようだが。)、もうつきあう義理はないよね。
まあ、こうやってちょっと本気出されて、徹底的に嘘ごまかしが通用しないレベルまで引き上げられて、こっちがあっさり書けるコードを、コンパイラに不整合チェックしてもらわないと自分のコードの妥当性すら確信できないような複雑なコードを書かざるを得ない、関数型で破壊的代入のないイミュータブルなコードを書くってだけで、むしろOCamlによるGUIでは通常らしい破壊的代入、命令型より「長くなる」、ということを痛感して、自分らが主張していたことが「机上の空論」であった、とようやく理解できたんじゃないかな?
「できない」と断言されたことをすぐにやって見せた(それも3回)
正確に書き直してあげると、こっちの議論、批判の趣旨くらいは理解していたはずだ。
それを踏まえて、例題が、カウンターやお絵かきと単純すぎたことを良いことに、
「あたかもスッキリ簡単に書ける」ように嘘誤魔化しをし、
上記馬脚が顕れたような要素、つまりこちらが当初から指摘し批判していたことについてまるで認めなかった誤魔化しが2回あり、
最後の1回(今回)で、それが、
「やっぱりできなかった」ということをパフォーマンスして見せた、つまり、
FRPと複雑性は変わらんのでしたよね?じゃあ、当方のFRPのコードと同等以下の複雑性で、 関数型「状態渡し」をもって書けるはずです。
という課題について、
コンパイラの整合性チェック頼みの、君自身が実装に自信がないような言い訳するしか無い「 補助関数 」なるものがある複雑怪奇かつ倍の行数以上の長く煩雑なコードしか提示できなかった、
のだから、
「絶対出来ない」という当方の予想通りであり、課題は不合格
ということになります。残念でした・・・
これまで君が書いたコードはすべて、その延長線上ですぐに破綻する、スケールしない設計であった、ということが今回証明されたのだから、
「できもしないことを簡単にできるように見せかけてきた」ことが白日の下にさらされた、
にすぎない。
かつ関数型ではなく全くの命令型。決して認めないようだが。)
何度も繰り返すけど、TimeEngineの __x.t = __x.t + 1; についてで、説明してあげたことについて、
まだ駄々をこねたいのならば、あいもかわらず馬鹿だね、とあきれるしかないし、
何を中傷しようとも、
const TodoElement
const ClockElement
const __fdList
const __lists
const ListofListElement
const InputElement
const __value
const onChange
const onClick
const onClickNL
const __seqEl
const mount
というように、こちらの書く、FRPのコードは、すべてconstantに静的にコードがすっきりと設計されており、
一方で、そちらのコードは、そんなすっきりとした設計などどこにも存在しておらず、
まさに誰かさんがみたら「スパゲッティ・コード」と評するしかない代物であり、
現実に、
動いてると思うけど書き殴りだから細かいことは気にしないでね
などと書いた本人が、動作の妥当性についてすら、自信をもって提示できないという言い訳をいきなりかましたり、
前回のから改造しててOCaml部分の不整合はデバッグしなくてもコンパイラが見つけてくれる
などと、不整合について、設計段階では確信すらもてずコンパイラ頼み、
という惨憺たる状況を自分自身で白状してしまっている。
イミュータブルなコードを書く関数型プログラミングのGUIのアプリの適用について、
この惨状が一般的な真実であることは、
以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。
と、今回のような、極めて初歩的なGUIアプリの実装の局面でさえ、
今回自分で書いた関数型のアプローチが、
異常、不適切
であることをすでに認めてしまっていることからも、語るに落ちている状態。
以上のような、自信の悲惨なパフォーマンス、こちらがきちんと詰めたら、しっかりと嘘誤魔化しが暴かれた、証明された、という自覚くらいはもってるだろうから、
もうつきあう義理はないよね。
と逃げたくなる気持ちはよくわかる。
そうだね、今回もうはっきりとした結果は出た。万人が追認してくれるだろう、非常にわかりやすい結果だ。
これ以上やっても、結果は同じなので、これ以上、こちらがハードルを上げる意味もないだろう。
いや、あるかな?こういうGUIアプリなんて、こっちは、いくらでも複雑に書けるんだよ、何の苦労もなくね。
でも、これ以上複雑にしたら、もうそちらは、関数型で書くのは非常に苦しくなるんだろう?
そういうのを確認してやるのも面白いと思うけど、あらかじめ逃げの先手うってるところをみると、
もう限界っぽいし、繰り返しになるが、必死にコード書けたとしても、結果は同じだよね?
「中国製不正アクセス機器を使って誹謗中傷してる犯罪者集団」みたいな妄想はマジ勘弁。それを釣りで煽ってる奴ら(単独?)もな。
うん、最後になるが、これ書いてるの多分、
http://okaml.blogspot.jp/2016/05/done.html
で、
たとえ「過去の値」が不要になっても
と、追記して強調する癖とか、例のQiita記事の@lambada と全く同一の挙動であり、いわゆる駱駝、
で書いたように、こいつは、
らくだの卯之助@camloeba だと自分は思ってる。
らくだの卯之助@camloebaが、私を中傷する2chスレッドで、犯罪者集団と合流して、
Newbie伊藤 ◆p02ZTYXhPKG5
というコテハンで、
497:Newbie伊藤 ◆p02ZTYXhPKG5 :2015/12/26(土) 12:23:39.50 ID:vcolQJWW.net
956 仕様書無しさん 2015/12/26(土) 12:05:32.47
田中がaskの仕様変更からものの数日で実用的なGUIアプリをHaskellで作成して公開していて草
http://tanakh.jp/posts/2015-12-20-tomori-nao.html
499:Newbie伊藤 ◆p02ZTYXhPKG5 :2015/12/26(土) 12:26:12.92 ID:vcolQJWW.net
くらえ、素人!
と、下劣なAAを貼り付けて喜んでいるのは、上記リンクで説明したとおりだし、
【弱者を放置して】赤木智弘30【アイマスラブ】
http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19
という、仲間割れメンバーのスレで、
19 名無しさん@社会人 2015/11/03(火) 21:00:52.89
369 :M7.74(catv?):2015/11/03(火) 12:06:52.44 ID:gYJokkH60
投稿者: 俺 (ID:0001) 投稿日時:15年 10月 11日 14:09
なので、当面は以下の通りで行きます。
いかんせん、Qiita以降の奴しか知らないので、不慣れなところはレギュラーが極力、バックアップ願います。
8賢枠 (暫定) 2015/10/02
・スキルハンターの鷹
・知の答弁人田中
・思考のゼロ除算ボレロ
・辣腕ギークのキャメル
・知のオーバーフロー加藤
・AIG(A-Jiro is Guru)
・菅本・ザ・ストリートプログラマー
・(空席)
以上。
暴露されたとおり、
・辣腕ギークのキャメル
という、バレバレの「ミッションネーム」を、@tikuwa_zeroという主犯によって与えられて、さすがにそれは、ということで、
Newbie伊藤 ◆p02ZTYXhPKG5にしたことも知ってる。
また
AIG(A-Jiro is Guru)
というのは、2chのそのスレで、「さすがAIGさん」とか「先生」とか言われてる人物なんだけれども、
これはもちろん、
東北大学の住井 英二郎@esumiiのことだろう。
今、舛添都知事の税金の問題が糾弾されているけれども、
君は、国民の税金をもらって仕事させてもらっている立場だよね?住井さん。
明らかに平日の勤務時間中に、2ちゃんねるで当方を誹謗中傷するスレッドにお友達の駱駝と一緒に書き込んで、「先生」だの、「8賢者」「ウィザード組」だの持ち上げられて、犯罪集団と合流して何やってるんだい?
またもちろん、今回のOCamlを書いた人間は、OCamlを勉強している人、などではなく、
ご指名ではないけど久々に書いてみました。
というのは、こちらが駱駝サンと「指名」しているから、本人が呼応した、
という当然の憶測を警戒するから、わざわざ書いているのであり、
俺もOCamlの勉強になったけど
などとその他、複数回、OCamlを勉強中の人間をアピールしているのは、「カモフラージュ」であると見ている。別に褒め称えるつもりじゃないけど、まあOCamlで飯を食ってる人間だけのことはあるね、君は断じて「OCamlを勉強している人」などではない。これは嘘だ。
短時間で「書き殴り」で書ける、それなり以上に手慣れた人間が書く実装とコード。
もちろん、FRPとか使ってないので状態渡しでかなり無理して書いているけど、無理したら書ける程度のスキルがちゃんとある。
じゃあなんで、
「OCamlを勉強している人」
という嘘ついて、カモフラージュしてるのか?プロだと特定されたら都合が悪いからだよね?
ご指名ではないけど久々に書いてみました。
とわざわざ自分ではない、とアピールしないと都合が悪い。
まああいかわらずだね。駱駝。名指しされて、黙っていられなくなって、
でも、オモテで自分だとやれば、リスクがあるもんだから、匿名ブログこさえて、
他の人間が書くの待つのもどかしいし、OCamlのプロの自分がやったほうが、
手っ取り早く思い通りのコード書けるってわかってるから、自分でやったんだろ?
いったい誰がその君のポッと出の、こさえた本人しか知らない匿名ブログをUPされるとほぼ同時に、
前々から、こっちを誹謗中傷する犯罪者集団の2chのスレに逐一貼り付けてるんだ?
おまえだろ?
とりあえず、
「OCamlの関数型できないことを、さもすんなりできるように喧伝していたいた」
君らの嘘誤魔化しが、
OCamlのイミュータブルな関数型プログラミングでGUIアプリ書くことなんて「机上の空論」である、
ということが、
自分自身の発言と、自分が書いたコードによって、
証明されてよかったじゃない。
2016年5月23日月曜日
スケールするFRPアプリ課題:わかりやすい嘘誤魔化しをしないように
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い
TimeEngineの __x.t = __x.t + 1; について
この辺の続きとなります。
特に
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
この課題についてです。
http://anond.hatelabo.jp/20160521172426
http://megalodon.jp/2016-0521-1450-10/okaml.blogspot.jp/
また瞬殺
なる投稿を見ました。
なんで、Web魚拓のリンクなのか知りませんが、元URLは、
です。
K
だの
okaml
だの
お絵かきロジック(笑)というかマウスのドラッグ(ボタンの状態)
クリックカウンター(笑)
だの、まあ当方を愚弄しているつもりなんでしょう。しょうもないですね。こういうところからも、
Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について
という集団の存在の蓋然性が確認できると思います。
「瞬殺」らしいですが、「そういうこと」にしたいらしいですが、まったく「瞬殺」されていないどころか、
まあいつもの、
できないことをさもできるように見せかける嘘誤魔化し
満載なので、以下ざっと説明してみます。
http://okaml.blogspot.jp/2016/05/done.html
から全文引用してみます。
2016年5月21日土曜日
Done
ご指名ではないけど久々に書いてみました。OCamlもJSも詳しくないので細かいことは知らない。(追記:入力消すの忘れてたので修正。)
module H = Dom_html
let g x = Js.Opt.get x (fun () -> assert false)
let o = Js.Opt.return
let s = Js.string
let _ = H.window##onload <- H.handler (fun _ ->
Firebug.console##debug (s "DoNe starting");
let d = H.document in
let tm = g (d##getElementById (s "todo_time")) in
ignore
(H.window##setInterval
(Js.wrap_callback (fun _ ->
tm##textContent <- o (jsnew Js.date_now ()##toString ())),
100.));
let txt = g (H.CoerceTo.input (g (d##getElementById (s "todo_text")))) in
let btn = g (H.CoerceTo.input (g (d##getElementById (s "todo_button")))) in
let ul = g (d##getElementById (s "todo_ul")) in
btn##onclick <- H.handler (fun _ ->
let v = txt##value in
Firebug.console##debug (s ("DoNe adding: " ^ Js.to_string v));
let li = H.createLi d in
li##textContent <- o v;
Dom.appendChild ul li;
btn##value <- s ("NewDoNe#" ^ string_of_int (1 + ul##childNodes##length));
txt##value <- s "";
Js._false);
Js._false)
- 今回は「状態渡し」すら要らないので「お絵かき」より簡単。何をさせたかったのかまったくわからない。
- すでに別の人も指摘しているとおり、以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。
- 自分から要求した「お絵かき」の「トイプログラム」すら1年もかかって自称FRP(実際にはFunctionalですらない命令型プログラム。哲学とか時刻とか理屈をこねたり過去の値を保存したところで、ユーザから見て命令型の非単一代入であることに何ら変わりはない。ちなみにその保存のしかただとJS処理系がガベコレできないのでメモリリークします。)でしか書けないのに、また他人に実装を要求する正当性は1ミリもない。
(引用終わり)
なんで、この連中、先の「ライブラリ内のソースコード」や「命令型」「破壊的代入」のこともそうなんですが、おんなじこと何度も言わないと理解できないのかな?と常にイラっとさせられるんですが、当方がOCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけてで示した条件は、以下でした。
念の為に付随要件、OCamlの状態渡しによる関数型で実装せよ
OCaml で君らがお題目唱えているとおり、(状態渡し)の関数型のコードで書くこと。これまで君らが誤魔化してきたように、HaskellやElmなど他の言語を「都合よくつまみ食い」してはならない。
FRPのメリットなんてない、とかぶちあげているみたいなので、たとえFRPのメリットをようやく今更途中で気づいたとしても、間違ってもOCamlのFRPライブラリなんかを検索して探し出して、そのFRPライブラリを利用して書いてはならない。あくまでも(状態渡し)の関数型コードで書くこと。
これは、君らが延々とこちらの主張を押さえ込むように強弁してきた要件なので、当たり前。出来なきゃ、その時点で君らの嘘が確定する。以上の条件に反しなければ別にどんなライブラリを使おうが自由。
これだけ。たったこれだけなんですよ。
OCamlの状態渡しによる関数型で実装せよ
上記引用したコードは、
OCaml ◯
関数型 ◯
状態渡し X
です。よって不合格。
もちろん、これワザとやらかしてる、つまり、
関数型で実用的アプリが書けるか?
関数型プログラミング(OCaml)の「状態渡し」は実用的アプリの実装に耐えうるか?
というテーマで連中が嘘誤魔化しばっかりやらかしてるから、耐久テストしてあげてるんですね。
状態渡し X
なんで、アウトです。でも、こういう連中は悪質ですから、Xなのにまるで◯のように偽装します。誤魔化します。今回さらにそこを詰めるために「かんたんな」実証実験するために新しい課題を出しますが、その前に
状態渡し X
の言い訳がこれです。
- 今回は「状態渡し」すら要らないので「お絵かき」より簡単。何をさせたかったのかまったくわからない。
いやいや、「すら要らない」って、こっちは、「状態渡し」で書けと縛りをかけたんだ。
何をさせたかったのかまったくわからない。って、
関数型プログラミング(OCaml)の「状態渡し」は実用的アプリの実装に耐えうるか?
ということ。わかってるよね?
さらに言い訳が続きます。
すでに別の人も指摘しているとおり、以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。
あのさ、例の@nonstarterは、こう書いてるんだ。
『関数型プログラミングに目覚めた!』のレビュー(Day-1)
追記(2015/05/30):デスクトップアプリケーション??
(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。
(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)
いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。
もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。
純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。
いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)…..結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)……
らしい。とにもかくにも、状態のあるアプリは、
関数型(状態渡し)で書けるらしい。FRPが関数型プログラミングで、
なんら必要でないという「趣旨」を示すために、
(状態渡し)
に固執しているが、でもいちおう(状態渡し)の限界を別のひとから指摘されたから、それは一応発言する、でもなおFRPはあくまで否定。
まったくもってわけのわからない理由で。
えーっとさ、
http://okaml.blogspot.jp/ のやつ。
君、前からいたよな?そのブログに、この@nonstarterの主張に呼応して、
状態渡しでのOCamlのお絵かきアプリ書いて「ほらみろ」とばかりにやらかしてるよな?
@nonstarterの上記の発言に明らかに同調し、それをもって、こちらの主張を否定しているのは明白だよな?
ところが!ここにきて、
以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。
と来た。こういうのが、
嘘ごまかし
だというんだ。
?OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。
へえ、つまり、実用的なアプリを書くには、OCamlでは関数型言語としては役不足であり適切ではない、不適切であることをここに来て認めるんだ?
これ、こちらが最初からずーーっと主張していたことだけど?
@nonstarter は
追記(2015/05/30):デスクトップアプリケーション??
みたいな、「状態渡し」で書ける、FRPがなんら必要でない、という趣旨には充分だ、と宣い、
あたかもこちらが間違った主張をしているように「見せかけた」。
君はその頃から、
?OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。
という知見をもち、発言の訂正を促したのかい?
君がそのブログで書いたのは、@nonstarterの主張を擁護すべくOCamlによる関数型「状態渡し」のお絵かきアプリだ。
以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。
おいおい、冗談だろ?(苦笑
じゃあいったい何が、OCamlをもって、関数型で実用に足るGUIアプリの実装として適切で正常なんだ??
はい、その言い訳が続く
書けないとか言うから反例として書いただけ。
「反例」ってあのな。@nonstarterの「趣旨」は、
もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。
純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。
だろ?これ誰が読んでも、「ああそうか、OCamlで状態渡しでなんでも書けるんだ」って思うだろう。このとき誰が
以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。
なんてことを思うんだい?「書けないとか言うから反例として書いただけ」?嘘こけ。総体として、とにかく、@nonstarterの援護射撃をして、岡部が間違っているという「印象」を拡散できればそれでよかったんだろ?そういうのが、悪質で、嘘ごまかしだっていうんだ。
OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。
うん、つまりOCamlで、関数型のGUIプログラミングをするには、不適切であると。だからさっさと認めろよな?
「関数型言語」に関するFAQ形式の一般的説明 - Qiita
住井@東北大の例のFAQにもこう書いてある。
それだと入出力や状態(state)すら表せないのでは?
いいえ、純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。非常に簡単に言うと、例えばhello(x) = “Hello, ” + x + “!”みたいな関数で(これも文法は適当です)、文字列hogehogeを入力するとHello, hogehoge!と出力する、みたいなプログラムを書くことができます。
同様に、状態(の変化)についても、古い状態を引数として受け取り、新しい状態を戻り値として返す関数により表すことができます。
この人物はOCamlのプログラマーであるが、関数型のおすすめの本としての各種教科書には、そのまさに、「普通は副作用(破壊的代入を含む)を使う」デスクトップアプリの例ばかり書かれていた。だから、おかしいだろう?といえば、この@nonstarterの状態渡しバンザイ、FRP必要なしネガキャンが不当に巻き起こされた。
「岡部のいうことがまちがっていた」という印象のみを拡散することにやっきになり、集団的に「お絵かきアプリが関数型で書けない」「破壊的代入だ」だのそういうことばかり喧伝していた。君らは嘘つきなんだよ。
誰が割りを食う?読者だろう?真面目に勉強したい初学者たちだろう?恥をしれよ。デマ集団。
だから、そういう嘘誤魔化しをやめろ、と。わからないですかね?自覚あるでしょ?
ここでの命題は、極めてシンプルで明瞭で、それはただひとつ。
関数型プログラミング(OCaml)の「状態渡し」は実用的アプリのコードに耐えうるか?
それだけ。そして前回のお題で、
状態渡し X
であるということは、
さっそくもう、この程度の複雑さのGUIアプリについて、
「状態渡し」では書けなかった
ということでよろしいですね?
逆に言うと、こちらががわざわざ手間をかけて、こういう連中の嘘、ごまかしについて
指摘してやらないと、そのまま「逃げ切る」つもりでいるわけです。
つまり、大局的な構図としては、
1 私、岡部が、この一連の国内の自称関数型コミュニティの連中による嘘、ごまかしを指摘する。
2 それが、事実だと、薄々感づいてるjが、嘘、ごまかしの上塗りをして、あたかも岡部が間違っているような印象操作をする
3 私がアホらしくなって、放棄するのを待つ
こんなところでしょう。
実際に
3の私がアホらしくなって、放棄すれば、連中の逃げ切り勝ちです。つまり嘘、ごまかしを拡散したまま、読者に嘘ごまかしを信用させ、正しい批判を加えた岡部が間違っていると思わせ、自分たちの嘘、ごまかしが正しいと信じさせる。
自分から要求した「お絵かき」の「トイプログラム」すら1年もかかって自称FRP(実際にはFunctionalですらない命令型プログラム。
「自分から要求した」とか、1年もかかって、とかいう要素は、上記の、この悪質な人物が、単に嘘誤魔化しを延々と続けてきたという上記の話なのでおわり。
次に、
自称FRP(実際にはFunctionalですらない命令型プログラム。哲学とか時刻とか理屈をこねたり過去の値を保存したところで、ユーザから見て命令型の非単一代入であることに何ら変わりはない。
これだけど、もう馬鹿に何度同じ話をしても同じだと痛感。
こちらとしては、もう、これ
TimeEngineの __x.t = __x.t + 1; について
以上、噛み砕いて説明するのは、多分不可能だし、
「あーあー都合の悪いこと聞こえない」
と理屈もへったくれもなく、よりによってFRPについて「時刻とか理屈をこねたり」などと平気でいうオバカさん相手にはどうしようもないです。
ちなみにその保存のしかただとJS処理系がガベコレできないのでメモリリークします。)でしか書けないのに、また他人に実装を要求する正当性は1ミリもない。
こういう悪質な相手の「ちなみに」は、自分が上記のような理屈もへったくれもない、デタラメをまきちらして、説得力のない文章を書いてる直後に出るのが常套手段(この人物に限らないパターン)なので、最大限の注意が必要。まず、本論と関係ない、次に、主張の信ぴょう性がない。
「メモリリークします」ってあほかと。FRPは、たとえば、こういうTODOリストなど、全部のデータが必要な場合、そんな、FRP値が処理系によって知らない間にガベコレされたら、それは単にデータの損失なの。わかるかな?わからないかな?
最後に、
また他人に実装を要求する正当性は1ミリもない。
別に君に実装を要求した覚えはない。自分で、
ご指名ではないけど久々に書いてみました。OCamlもJSも詳しくないので細かいことは知らない。(追記:入力消すの忘れてたので修正。)
ひまだから、やってやったみたいなポーズでしゃしゃりでてきたんだろう?
しかも、すべて、例題が単純であることをよいことに、
できないことをあたかも簡単にできるように見せかける誤魔化しという連中の一貫した悪質な手口。
「状態渡し」では書けなかった
今回は、きっちり宣言したとおり、「状態渡し」で書いたら複雑になるように、問題設定していたが、「状態渡し」でも書けるという問題の単純さを悪用し、「状態渡し」で書いたら複雑になる、と痛感したがゆえに、ルール違反の「状態渡し」なしので書いて、しかも、それが例外的、異常な実装だと言い訳し、前回まで状態渡しで、nonstarterを擁護していたのは、「反例」だから、とまた言い訳する。
また他人に実装を要求する正当性は1ミリもない。
というのは、上記のような自己都合で「状態渡し」なしのルール違反をした
「状態渡し」のコードが書けなかったことを後ろめたいと自覚しているから、最後っ屁で、
ルール設定にいちゃもんつけてるんだね。
いやあのね、こっちが、嘘つけよ!と批判していて、
「OCaml」で、関数型で、実用的なアプリを、状態渡しで、FRPなしで、書ける!とさんざん反論していたのは、こちらでなく君らだから。
今回のTODOリスト、こんな、内部的にリストの状態を保持しない、画面に書きっぱなしの代物なんぞ、
内容をろくに管理も保存もなにもできないのは自明で、実用的ではない。
こんなことは、大前提として、つまり、アプリが状態を扱うという意味を大前提として「状態渡し」で書け、と条件付けたのに、
「状態」を扱えば煩雑になるとわかりきっているからそこから逃げて、誤魔化してこう書いたわけです。
今回は「状態渡し」すら要らないので「お絵かき」より簡単。何をさせたかったのかまったくわからない。
盗っ人猛々しいですね(苦笑
関数型プログラミング(OCaml)の「状態渡し」は実用的アプリの実装に耐えうるか?
「状態渡し」で書けんのか? と問いただしている。
君らの誤魔化しを一個一個潰すことをしたい。
わかってるくせに、「状態渡し」で書けない卑怯な言い訳をして、あたかもこちらのせいにしているようなので、より「状態渡し」で書けるのか?というのを明確にするように、この延長で、
もう一段、例題のハードルをあげてやることにしましょう。
再度確認ですか、今回、上記のような大前提をもって、
「状態渡し」をもって書けという条件でしたので、
この人物は、この条件を満たせなかった、つまり課題をクリアできなかった、ということを確認しておきます。
そしてそれを踏まえながら、新たにこういう誤魔化しさえ通用しない、
つまり、アプリが単純であることをいいことに、
必要な要件を潰して、表面上だけは動作しているように見せかける、
という誤魔化しができないように、ハードル一段引き上げ、
状態を扱うしかないように、アプリを少し複雑にしてみます。
状態渡しでは煩雑にしかかけないようにハードルを設定する。
あたかもスケールするように喧伝している誤魔化しがある。では問題を複雑にしていって
その誤魔化しの延長線上で、そのアプローチが破綻しないか?
スケールするのか?
そういうことを確認しているにすぎない。
ちょっと複雑になったら通用しない、破綻する、ならそんなもんは「机上の空論だ」
そういうことを言っているにすぎない。
私が気に入らないのは、
この一連の国内の自称関数型コミュニティの連中による、悪質な手口
つまり、
本質とずらす、議論のすり替え、ひとりが誤魔化す、
あとの連中はその嘘、誤魔化しに気づいているが沈黙、そういう手口。
その嘘、誤魔化しによって、あたかも、まるで、私、岡部のほうがいい加減なことを主張している、
と初学者をはじめとする真摯にプログラミングを学びたいと考えている衆目、読者にむけて印象づけようとする。
こちらが黙っていると、「真理」について割を食ってる広い読者の犠牲のもとに、自分たちがただしいと嘘をついたまま、有耶無耶にしようとする。
しかし、こうやっていろいろ突っついてやると、そのうち必ずこの誤魔化している連中の馬脚が現れます。
ハードル上げによって、今回君、君らがごまかしたように、
「状態渡しで書け」ときちんと明示してるのに
「状態渡しなしでも書けるから、状態渡しで書く必要がない」という論理をすり替えを無効化する。
そんな誤魔化しは許容されるはずもない。あたりまえだろう?
「状態渡しでは書けない」あるいは「状態渡しで書くことは困難で煩雑である」
という論点に、改めて引き戻すことになる。
なんで、こっちがこんな明確化をわざわざせんといかんのか?
それは君、君らが、誤魔化しをしているからだろう?ということです。
すぐバレるような嘘、誤魔化しをすんな、ってことです。
それをわざわざこっちが訂正しないと、その嘘、ごまかししたまま逃げ切るつもりだろう?
その嘘、誤魔化しで割を食うのは誰だい?君らの嘘、ごまかしを真に受けて信じてしまった学習者だろう?
ってことです。
ああもちろん
「指名されてないですが」などと、出てきた分際で、
もうどうしようもない、とおもったら、投げ出して逃げて結構ですよ?
そのための「匿名ブログ」でしょうからね?恥のかき捨て結構じゃないですか。
嘘誤魔化し全開の自覚アリアリで中傷する相手は実名
自分は責任負わずにすむ匿名。いつもの悪質な手口です。
一体、誰が 、その学習者を欺く、嘘誤魔化しまみれで、人を中傷することだけが唯一の存在価値の
悪質な捨てブログ書いてるんでしょうね?
毎度悪質ですね。
課題
前回書いたアプリ:ToDoリストをそのまま拡張し、複数のリストを扱えるようにせよ
以下、こちらですでにJavaScript+TimeEngine+Reactをもって実装したライブデモ
TimeEngine公式サイト
http://timeengine.github.io/
のDemo11
を提示しながら説明。
以下は動作中のスクリーンショット画像
① 起動させた直後、前回の仕様とほぼ同じであるが、これはデフォルトで、[List#1]になっている。
② [NewList]ボタンをクリックすることで、次の[List#2]を新規に作成できる。このように新規に作成されたリストは、別のリストとは独立しながら同様の動作をする。たとえば、[NewToDo#N]ボタンに表示されているNはそれぞれのリスト固有のカウント値である。
③ すでに作成しているToDoリストについては上部の[List#1]や[List#2]ボタンをクリックすることで切り替え表示ができる。
ソースコード(index.jsx)
const TodoElement = () => {
const ClockElement = __Element(__.intervalSeq(Immutable.Range(), 100)
.__(() => (<div>{moment().format('MMMM Do YYYY, h:mm:ss a')}</div>)));
const __fdList = __().__((val) => (__.log.t = val));
const __lists = __(true).__((__list) => (__fdList.t = __lists.length));
const ListofListElement = __Element(__([__lists])
.__(() => ((__lists).map((list, i) => (
<button onClick = {() => (__.log.t = __fdList.t = i)}>{'List#' + (i + 1)}</button>)))));
const InputElement = () => {
const __value = __();
const onChange = (e) => (__value.t = e.target.value);
const onClick = () => (__.log.t = __lists[__fdList.t].t = __value.t);
const onClickNL = () => (__.log.t = __lists.t = __(true));
const __seqEl = __([__value]).__((value) => (<div>
<h4>{'List#' + (__fdList.t + 1)}
<button onClick = {onClickNL}>{'NewList'}</button></h4>
{__lists[__fdList.t].map((item) => (<li>{item}</li>))}
<input type="text" value={value} onChange={onChange}/>
<button onClick = {onClick}>{'NewToDo#' + (__lists[__fdList.t].length + 1)}</button></div>));
__.log.__(() => (__value.t = ""));
return __Element(__seqEl);
};
__lists.t = __(true); //new items-list
const __delay = __.intervalSeq(Immutable.Seq.of("started!"), 1000)
.__(() => (__.log.t = "showInput"));
return (<div><h2>ToDo</h2>{ClockElement}<p/>
{ListofListElement}<p/>{InputElement()}</div>);
};
const mount = ReactDOM.render(TodoElement(), document.getElementById('todo'));
このコードは、前回示したコードに、要件が複雑になった差分だけ順当に、コードを積みましたにすぎません。GUIはFRPとReactで接続して書かれており、単に宣言型のコードが増えただけです。
命令型って言いたいだけの頭のおかしい指摘はあてはまりません。
こういうのをスケールする設計であると言います。
さて、例の人、人たちは、「あたかもなんでもできるような」今回の
「状態渡しすら必要ない」とか言ってたコードの延長でどんなコードを書いてくれるんでしょうか?
そろそろコードが、これまであなたがたが広い真摯な読者を欺くような形でやってきた、
あらゆる悪質な嘘誤魔化しが効かないレベルに突入してきました。
OCamlで、スケールする「関数型」の「状態渡し」のGUIアプリのコードを書いてください。
FRP必要ない、とかぶちあげてた@nonstarterを「擁護」あるいは結託してたんだから、FRP使うとかもちろんなしで。
純粋関数型の「状態渡し」で実用的なアプリを「なんら困難もなく」書けるんでしょ?
FRPと複雑性は変わらんのでしたよね?じゃあ、当方のFRPのコードと同等以下の複雑性で、
関数型「状態渡し」をもって書けるはずです。
もっともらい適当な嘘ハッタリじゃあなければね。
さあやって見せてください。どうぞ。
なお、念の為ですが、「状態渡し」での素の実装が見たいわけなので、なんかGUIフレームワークの「タブ」切り替えライブラリみたいなもんを使って、また誤魔化さないでください。そういう議論ではない、くらいもうわかっているでしょう。
2016年5月20日金曜日
TimeEngineの __x.t = __x.t + 1; について
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い
この辺の続きとなります。
特に、前回のエントリ
の続きです。
前回、
const items = (true);
という、時間軸上の世界線の「定数」 const
であるのならば、
「破壊的代入」なんておこりうるはずもない。
ということです。
「破壊的代入」がなされている、と批判した時点で、
その人物は、
FRPのValue ”OverTime” がイミュータブルな定数である
という意味なんて、本当はこれっぽちも理解していない、ということが白日の下にさらされます。
つまり、中傷してる連中は、FRPの哲学的理解が足りないからそういうことが言えるのだ、ということですね。
と説明しました。
それでもなお「どうしても理解できない人」はいます。まあ仕方ないです。
仕方ないですが、それはその人物の知的素養の問題であって、私の問題でもTimeEngineというFRPライブラリの問題でもありません。
執拗に繰り返されるのが、
本来のFRPを理解せず中傷を重ねる連中への再度宿題
で、すでに説明したこれです。
(再掲)
http://anond.hatelabo.jp/20160516192742
実際、timeengine.js を読み込んだ状態で、以下のようになります。
> const __x = __();
undefined
> __x.t = 1;
1
> __x.t = __x.t + 1;
2
> __x.t;
2
なお私を他の誰かと決めつけるのは、その方たちにご迷惑ですのでおやめください。
……と言っても聞き入れていただけるとは思えないので、私ももうこれ以上の書き込みはやめます。
できるだけ丁寧に技術的な誤りだけを指摘したつもりですが、やはり誹謗中傷しか返ってこないようで残念です。
http://anond.hatelabo.jp/20160517094425
kenokabe氏のコードでもマウスが動くたびに同じ__drawFrom.tへの破壊的代入が行われるんですがそれは
などと書いているのですが、いま説明しているように、
Date.now = Date.now + 1
というステートメントが、概念的な意味を成さないように、
=の両辺が等しいという、関数型プログラミングのパラダイムにおいては、
__x.t = __x.t + 1;
というFRPライブラリの使用は概念的な意味を成しません。
なんでこういうことをするのか?というと、なんか悪意があるか、
それとも、FRPが「時間軸上の値を表現したデータタイプ」についてのパラダイムである、
ということを全く理解していないから、こういう文句のつけかた、それこそ誹謗中傷をして平気なのでしょう。
あえてこの住井らしき人物がわざとやらかした「破壊的代入」という命令型パラダイムにおいて、考えてみると、この人物の意図によると、
「右辺の現在値」を「左辺の現在値」に代入するという命令型の時系列的意図しかありえないでしょうから、
右辺の現在値に1を加えて、改めて、左辺の現在地とする
ということです、つまり、左辺、右辺の現在時間が異なる、FRPライブラリにおいては、
.t
によって表現される時刻による「時間軸上の値」は異なって当然であるということになります。
よって、
__x.t = __x.t + 1;
というのは、
右辺を評価した現在時間における
__x上のある値に1を加えたものを
次の瞬間以降の
__x上の値として更新する、という意味合いになります。
もちろん、これは、=の左右で値が異なるという命令型ステップの解釈であり、
そういう命令形パラダイムを大前提とした記法においては、TimeEngineの振る舞いはこう解釈される、
ということにすぎませんし、そのような記法を禁じるようなSanityCheckを実装しているわけではありません、
ご自由にどうぞ、といったところでしょうか。
(再掲ここまで)
なんかよくわかりませんが、そんなに難しいこと言っていますかね?
同じことを言うと思いますが、また同じことを言いたいと思います。
まず、第一に、
__x
というのが、時間軸の世界線の無限リストで、
イミュータブルな定数である、
__x.t
というのが、now
などで表される、それ以外では表しようがない「現在時刻」における、
__x
上の分布値である、
という意味を理解しておれば、これらはすべてイミュータブルな定数なので、
「破壊的代入」など原理的に起こりえない、と自然に理解できる、ということです。
理解できないのならば、それはその人の哲学的側面における知性の問題であり、
そもそも時間にまつわる、関数型プログラミング、FRPのことなどははなっから諦めたほうが良い、ということです。まず、身の程をわきまえて、こちらを中傷することなどもっての他です。
次に、
関数型プログラミングとは、宣言型プログラミングなので、
根本的に、式を用意したならば、その両辺が等しい、という数学的宣言をすることと同じです。
__x.t = __x.t + 1;
という、方程式の左右で値が異なる「論理破綻」した記述をするのは、
そういう宣言を記述した、コーダーその人の責任です。
TimeEngineでは、そんなところまでSanityCheckするつもりもないですから、どうぞご勝手に、ということですが、こう書けるから、TimeEngineは命令形で、破壊的代入だ!
つまり、
これは岡部健氏が著書で「論理破綻」と批判していた、命令型言語の破壊的代入そのものです。
できるだけ丁寧に技術的な誤りだけを指摘したつもりですが、やはり誹謗中傷しか返ってこないようで残念です。
とか、表明するに至っては「頭がおかしい」としか思えません。
関数型、宣言型のパラダイムにおいて、= の両辺がことなる宣言をわざわざして、
破壊的代入を試みたたのは、この人であるし、FRPライブラリの領分でもなんでもないわけです。
「思い込みの激しい」人間に説明をするには、困難を極めるのですが、できるだけこの人物の意図を想像しながら、こちらもやってあげましょう。
まず、この人物の意図としては、
命令型プログラミングをやりたい!
というのがあるのでしょう。
繰り返しますが、
__x.t = __x.t + 1;
ってのは、両辺の値が明らかに異なっているので、論理破綻しており、
=の両辺の値が等しいと宣言することで、コーディングする関数型、宣言型のパラダイムからは逸脱しています。
次に、
破壊的代入をしたい!
という強い意図が感じられます。
もちろん、=の両辺の値が等しいというパラダイムにおいては、そういう行為は意味を成さないし、そういうスタイルで書いてはいけないのですが、JavaScriptのネイティブな仕様としては、破壊的代入も自由にできるので、やろうと思えば可能です。もちろん、関数型プログラミングを志向するならやるべきではないのは自明です。でもこの人物は、破壊的代入をしたい!と駄々をこねているわけです。自由にさせておきましょう。
でもそうしたいというのは、FRPライブラリの責任でも設計者の私の責任でもなく、彼自身の強い希望なのです。私のせいだ、みたいなことは言わないでください。というか言われてますが、あほらしいですが。
JavaScriptのネイティブな仕様として、
__x.t = __x.t + 1;
と書いた場合、
右辺 __x.t + 1
が先に評価され、
左辺 __x.t
に代入されます。
この人物の強い意図として、
- 命令型プログラミングをして
- 破壊的代入をして
と、__x の挙動に興味がある、ということみたいなので、
const __x = __(true);
__x.t = 99;
__x.t = __x.t + 1;
こんなコードを書いてみましょう。
FRP値のフラグをtrue
とするのは、
この人物が、「破壊的代入」に興味があるからです。
つまり、
命令型のフローのあるコードを書いて、
破壊的代入前
破壊的代入後
という、
コードの上下
コードの左右 (方程式の左右)
の時間経過みたいなことを前提にしてコードを書きたがっているからです。
関数型、宣言型のスタイルにおいては、このような、
コードの上下、左右で、時間が経過するような概念は用いませんが、
彼がそうしたいと熱望しているわけです。好きにさせてあげましょう。
結果はどうなるか?というと、すでに書いています。
const x = (true);
という、時間軸上の世界線の「定数」 const
であるのならば、
「破壊的代入」なんておこりうるはずもない。
ということです。
const __x = __(true);
__x.t = 99;
__x.t = __x.t + 1;
__.log.t = __x[0]; //99
__.log.t = __x[1]; //100
となります。
イミュータブルな時間軸上の世界線の「定数」
__x には、
その命令型のコードフロー時間における、
それぞれの分布値
__x.t
が分布しています。
もうちょっと正確にいうと、
別の、__x.t に切り替わるまで、
直近の__x.t が継続して分布しています。
式の右辺を先に評価して、というこのコーダーの意図で、
その時点の、__x.t が読み出される。
一個上の行で評価された時間での、 __x.t = 99;というのがありますから、
それが得られています。それに1を加算して、
今度は、左辺の時間の、__x.t に値を代入します。
「破壊的代入」というのは、そういう行為です。
前あった、右辺の値を、
新たに、左辺の値を上書き破壊するように代入する。
だったら、「時間」が違うわけです。BeforeAfter 破壊前、破壊後。
当然、TimeEngineはその意図のとおり振る舞いますから、
結果、格納された集合値の__xの全体としては、
破壊前、破壊後と、この人物が、意図したであろう、2つの異なる時間の値が存在するはずです。
__.log.t = __x[0]; //99
__.log.t = __x[1]; //100
意図したとおりになってるじゃないですか?なんか問題あります?
どこにも論理の破綻はない。
まあ、命令型であったとしても、かように、
= っていうのが、関数型、宣言型とは意味合いが異なる、
コードの上下、
式の両辺で時間が異なる、という自覚があればこのように整合的にコーディングすることは可能です。
まあしつこい中傷行為は、いい加減にしてほしいです。
おわり。
TImeEngineは命令型でも破壊的代入でもない
住井 英二郎@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値で、オプションつけて、データ保持させると、
ドローしたすべてのストロークがデータとして蓄積されるし、
リプレイみたいなことも簡単にできます。
C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
この辺の続きとなります。
まず「課題」についてですが、いまのところ、私が知る限り、まだどこにもされていません。
念の為ですが、Twitterやら幼稚な念仏唱えているだけと一部馬鹿にされている病人が誹謗中傷連ねたいだけの2chスレの書き込みなんかいちいちチェックしてるわけもないので、万一そんなとこに書きなぐっても見てるわけもありません。
本来のFRPを理解せず中傷を重ねる連中への再度宿題
の「本来のFRP」による「お絵かきアプリ」っていったいどこにあるの?という課題については、
「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの
と説明したとおりです。単なるごまかしです。
直近の、
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
ToDoの関数型GUIアプリについてもいまのところ無回答です。
2,3それらしい言い訳が
http://anond.hatelabo.jp/20160519142942
じゃあOCamlで純粋関数型や(本当の)FRPで複雑なGUIアプリが書けるかと言うと、
理論的には不可能ではないかもしれんが、もともと非純粋なので
誰もそういうライブラリを整備してないから、ライブラリから作るのは
まあ面倒だろうし、わざわざ非純粋関数型言語で純粋関数型のGUIを作る動機も
現時点ではまずないだろう。これもすでに指摘されているとおり。
http://anond.hatelabo.jp/20160520051838
「状態渡し派」なんてレッテル張りも典型的な詭弁(藁人形論法)。
誰も状態渡しで何でも簡単に書けるなんて言ってないし、状態渡しで書くべきとも言ってない。
「お絵かきアプリ」には自称FRPが絶対に必要、という明らかに誤った主張に対する反例として
nonstarter他が「状態渡し」を挙げただけ。
それなのにHaskellだから認めないとか、OCamlでも簡単だったから認めないとか……
自分で「FRPが必要」と断言して挙げた例題なのに。
「やらない」「できない」言い訳を始めているようで非常にほほえましいですね。
ちなみにこの胡散臭い人物がいう「純粋関数型」については後述します。
「お絵かきアプリ」には自称FRPが絶対に必要、という明らかに誤った主張
「実用的アプリ」を書ける、という観点において、
この程度の簡単なアプリなら書ける、書けたという誤魔化しがなされたにすぎません。
「お絵かきアプリ」というのは、あくまで複雑なものが普通である「実用的アプリ」の具体例のひとつとして登場しただけで、
その課題が「実用的なアプリ」というトピックにおいてどうも単純すぎたようだ、だからもうちょっと複雑な具体例で検討してみようか?
、というのが現在進行している議論です。
「実用的アプリ」の具体例として単純すぎた実装が、連中のいう「純粋関数型」で書けたからといって、
「原理的」に複雑な「実用的アプリ」が書ける、わけもないですが、それが
「実用的」な観点で、君ら誤魔化してるだろ?と言ってるわけです。
@nonstarterは、FRPでも結局は「状態渡し」と一緒で、実用的なアプリを関数型を書くのには問題があるのは一緒だ、とさらに、FRPにまで話を進めてもそれは一緒だ、とさらに大嘘を書いているので、
以上の2点の嘘ごまかしを証明しようというのが今のステップです。
「実用的」複雑なGUIアプリが書けるのか?というトピックにおいて、
こちらが単純すぎる課題を出してしまったことに便乗し、
「ほら書けただろ!」と、それ以上複雑になってくると通用しないことを自覚しながら、
「原理的」に問題ないというポーズだけ示し、
さらに、FRPでも一緒だ!と「誤魔化している」ことを批判されているのに、意味が伝わりませんかね?
「机上の空論」であると。
「机上の空論」じゃ埒が明かないので、こちらは、
さらに複雑な課題において、証明してみせよ、と具体的なコードを示せと言ってる。
君らのなかの「純粋関数型」君らののなかの「FRP」がどうであれ、
こちらはすでに、コードを示した。
君らは頑なに強弁してた、
Ocaml+状態渡し(FRPのメリットなんてないらしい)関数型でコードは示せない。
それがすべてを物語っているだろう?君らの一連の関数型のGUI実用アプリのの言説なぞ机上の空論であると。
ちなみに、
『話題の岡部健(kenokabe)が自分のブログで凄いこと言ってる』
http://anond.hatelabo.jp/20160519214037
で、
ttp://kenokabe-techwriting.blogspot.jp/
このブログエントリの昨日と本日日付の分を見ると、たくさんの増田の投稿がリンク付きで引用されている。
しかもよく見ると、個々の増田の投稿を、実在の学者やツイッターユーザーが行ったと決めつけてるフシがあるんだよね。
自説を否定する増田に対して憤慨してる様子なんだけど、文脈からするとどうも「駱駝」っていう人物が投稿していると言いたげなんだよね。「あなた」とか「君ら」という言葉からすると。
というか、完全にそれを前提にブログを書いているんだどう見ても。
増田の投稿に対して憶測で特定の人物だと決めつけてこういうエントリ書くような奴は初めて見た。
あと学者の「住井」って人物にも噛みついている様子なんだけど、過去のエントリを見るとこの岡部、駱駝・住井両名に対してよくわからない挑戦状みたいなエントリを何の前触れもなくアップロードしてるんだよ。
内容からすると、やはり誰が書いたのか正体が見えない投稿を、その両名が行ったと決めつけてるようなんだよね。
このタイトルも凄い、
Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について
どこの厨房だよと思ったらどうも真剣に書いてるみたいなんだよね。
第三者による書き込み
http://anond.hatelabo.jp/20160518171946
って言ってるけど、これ岡部氏本人による自己弁護だよねぇ・・・・。一体何をしたらここまで常軌を逸した発言に及ぶんだ。
という
ttp://kenokabe-techwriting.blogspot.jp/
という2ch記法ではじまる、たいへんわかりやすい印象操作工作活動をあいかわらずやらかしています。
さっそく、突っ込みも入っているようですが、
「実在の学者」
とか、普通こんな不自然な言い草します?(笑)
これは、「実在のベンゴシ」と、ほうぼうでお経のように唱えていると小馬鹿にされている、まさに、
この構成員の口癖そのものです。いろいろワキが甘いですね。書き込みの癖って隠せないですよね?
誹謗中傷集団の構成員が、
事情通をアピールしながら、
文脈からするとどうも「駱駝」っていう人物が投稿していると言いたげなんだよね。「あなた」とか「君ら」という言葉からすると。
憶測で特定の人物だと決めつけてこういうエントリ書くような奴は初めて見た。
あと学者の「住井」って人物にも噛みついている様子なんだけど、過去のエントリを見るとこの岡部、駱駝・住井両名に対してよくわからない挑戦状みたいなエントリを何の前触れもなくアップロードしてるんだよ。
とか、「今初めて知りました感」を演出している。
「背景に詳しい事情通」なのに「今初めて知りました感」を演出。
こういうのを「自作自演」っていうんでしょ?いつも工作活動ごくろうさまです。
さて、最後に
第三者による書き込み
http://anond.hatelabo.jp/20160518171946って言ってるけど、これ岡部氏本人による自己弁護だよねぇ・・・・。一体何をしたらここまで常軌を逸した発言に及ぶんだ。
違いますよ。第三者です。自分が自作自演の常習だから、といって、
「自分たちに都合の悪い岡部への弁護」は「岡部の自作自演」みたいな都合の良い決め付けはやめなさい。
全部のやりとりを引用すると
http://anond.hatelabo.jp/20160518164005
状態を変数に持つ必要はない、というところは伝わってるのかな
状態を引数で与えて新たな状態を得る、という形で書ける、と
そのほうが関数型的、というと反発するんだろうけど
岡部氏もやろうと思えばそういう風に書けるんじゃないの?
http://anond.hatelabo.jp/20160518170332
そんな「状態渡し」の話はもう周回遅れでとっくに終わってる。
複雑なGUIアプリを関数型で「状態渡し」で書いたら、そのうちスケールしなくなる、ってのは例の当事者が認めてて、
FRPに話がようやく移ったのが今。
http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-frp.html
http://anond.hatelabo.jp/20160518171946
まあお絵かきは綺麗に書けるってことでいいんじゃないの?
そんで岡部氏のFRPでは綺麗に書けて、状態渡し派の関数型には書けない次なるお題でとどめを刺せばいいんでは?
と言う感じです。
岡部は孤立している、要するにそういう図式を堅持したい、という魂胆はいつもミエミエでわかりやすいですが、自分の信じたい世界を作り上げる、自分の都合の悪い真実については、岡部の妄想というのもわかりやすいです。
「実在の学者」とか、毎日「実在のベンゴシ」がどうたら異常なお経唱えてるから、不自然だと気づかないんですよ?病気?
純粋関数型
他にもこんな書き込みがあります。
http://anond.hatelabo.jp/20160519175956
岡部さん曰わくは、「ぼくの主張に同調的な国内の学者たちは、
自称関数型コミュニティの圧力を恐れて、表立って肯定できない」とのことです。
また、
「nonstarter氏や住井教授のようなエントリの内容は、日本国内でのみ少数の合意が得られてるに過ぎず、海外では主流ではない。
僕の理解こそが世界的合意を得られており、stakuoverflowでmapとreduceの理解が出来ていないような質問をしたのは、海外のレベルを探るためである」
という趣旨の主張もあるようです
それに対してさっそくついたトラックバックを引用すると
http://anond.hatelabo.jp/20160520072553
観測できる事実として、岡部さんと住井さん、nonstarteさんの振る舞いが目立ってきた頃から、
国内ネットでは、地雷、滅多なことを言わないほうがいいという風潮がありました。
しかも、「純粋関数型」が何か?というさえ、海外では関数型プログラミング界隈の著名人、
たとえば岡部さんが引き合いに出す論文のエリオットはじめ、合意が取れていません。
http://conal.net/blog/posts/the-c-language-is-purely-functiona
「nonstarter氏や住井教授のようなエントリの内容は、日本国内でのみ少数の合意が得られてるに過ぎず、海外では主流ではない。」
よって、これは岡部さんのほうが公平な現実について発言しており、が正しいと判断します。
住井さんをはじめ、岡部さんが批判する相手は、議論となっている関数型プログラミングの定義などが、まるで世界的に合意がされており岡部さんのみが異端だという主張ばかりしており、あまり信用できません。
そのとおりです。
私が 住井 @東北大をはじめとする自称関数型コミュニティによる言説が非常に胡散臭いとおもうのは、
例の関数型PGの一般的説明、なるものもそうですし、まるで学術的にコンセンサスがとれており、
自分の言っていることが正しい、と断定的に論じているところです。
http://conal.net/blog/posts/the-c-language-is-purely-functiona
というのは、知らなかったですが、
The C language is purely functional
「純粋関数型」についての議論です。2009年5月時点の投稿
Conal Elliottについては、私もその発言について信頼しており引用してみます。
There has been a scurry of reaction on twitter and reddit to Robert Fischer’s post saying that Scala is Not a Functional Programming Language. James Iry responded by saying that analogous reasoning leads to the conclusion that Erlang is Not Functional
My first inclination was to suggest that Haskell, as commonly practiced (with monadic IO), is not a functional language either. Instead, I’m going to explain how it is that the C language is purely functional.
要約すると、
Robert Fischer’のポスト ー Scalaは関数型プログラミング言語ではない、についてTwitterやReddit(海外の活発な掲示板)で、ちょっとしたリアクションがあった
James Iryは、同じ理由でErlangは関数型ではない、という結論も出せる、答えた。自分の最初の考えとしては、Haskell、(IOモナド) も関数型言語ではないとサジェストしたいというものだった。しかしかわりに、C言語も純粋関数型であるということをここで説明しようと思う。
(中略)リンク先読んでください
What about Haskell?(最後部分)じゃあHaskellはどうなの?(純粋関数型か?)
Which leads to the question: is Haskell+IO a purely functional programming language?
Sure it is, even as much as its predecessor C (more precisely, cpp+C).
Some who ought to know better would claim that Haskell+IO is only technically pure. (See claims and follow-up discussion, in response to a remark from James Iry.)I must then respond that, in that case, even C programming is only technically pure.
Which is absurd.これはある質問にたどりつく:じゃあHaskell+IOというのは、純粋関数型言語なのか?
もちろんそうだ。そしてその先行者であるC(正確に言うとC++)も同じ程度にそうなのだが。
訳知り者はこう文句言うことだろう:Haskell+IOのみが唯一「テクニカル」に純粋である、と。
なら私はこう返すしか無い、ではその場合、Cプログラムのみが唯一唯一「テクニカル」に純粋である、と。
馬鹿げている。
コメント欄もふくめて、要するに明確な合意に至っていない、ということは普通にわかります。
住井その他の日本国内の自称関数型コミュニティの胡散臭い言動の根本的な問題は、素人全般、学習者にむけて、まるで学会で明確な合意がなされており確固たる「一般的説明」があり、私のような「別の意見」を表明すると、「勉強しろ」だの「独自見解」で「合意と違う」という嘘を平気で押し付けてくることです。
実際に「参照透明性」についても、
http://stackoverflow.com/questions/210835/what-is-referential-transparency
で示されているように、関数型プログラマーと、意味論とは食い違うことが明確化されていたり、
Purity vs Referential transparency
http://stackoverflow.com/questions/4865616/purity-vs-referential-transparency?rq=1
The terms do appear to be defined differently, but I’ve always thought of one implying the other; I can’t think of any case when an expression is referentially transparent but not pure, or vice-versa.
純粋性 vs 参照透明性
これらの用語は、別のものと定義されているようだ、しかし、自分はいつもお互いがお互いを暗喩的に意味しているように考えている。つまり、「ある表現が参照透明であって、純粋でない」というケースがおもいつかないし、逆方向についてもそうだ。
あと、Wikipedia(英語版)のデタラメな説明への疑念、が質問者によって表明されており、
Is there a simpler way to understand the differences between a pure expression and a referentially transparent one, if any? If there is a difference, an example expression that clearly demonstrates it would be appreciated.
なんか、その純粋性と参照透明性についての違いみたいなものを理解できる、もっと単純な方法はないのか?「違い」みたいなものがあれば、明確に表現している例を教えてくれるとありがたい。
もっとも支持を集めた答え
If I gather in one place any three theorists of my acquaintance, at least two of them disagree on the meaning of the term “referential transparency.” And when I was a young student, a mentor of mine gave me a paper explaining that even if you consider only the professional literature, the phrase “referentially transparent” is used to mean at least three different things. (Unfortunately that paper is somewhere in a box of reprints that have yet to be scanned. I searched Google Scholar for it but I had no success.)
もし、自分の知り合いの3人の理論家を集めたら、少なくとも、2人は、「参照透明性」という用語について合意しない。そして、自分が若い学生だった頃、自分の担当教師は、「参照透明性」というものが、少なくとも、3つの異なる意味で使われていることを説明する論文を渡してくれた・・・
I cannot inform you, but I can advise you to give up: Because even the tiny cadre of pointy-headed language theorists can’t agree on what it means, the term “referentially transparent” is not useful. So don’t use it.
わからない、でも、アドバイスできることとして、「あきらめなさい」、なぜならば、インテリ言語学者の少数集団でさえ、それが何を意味するのか合意できていない。
「参照透明性」っていう用語は役立たずだ。だから使うな。
・・・・という感じです。
実際そこらじゅうで見るのが、
「純粋関数型」っていう概念を「参照透明性」という用語、概念をもって説明しようとするものであり、わかったようなわかってないような人らを量産しています。
その上、たとえば、
http://anond.hatelabo.jp/20160516112619
kenokabeさんの心の中ではそうなのかもしれませんが、ライブラリのユーザから客観的に見れば(分析哲学ではなく関数型言語の意味で)参照不透明なので、関数型プログラミングのメリットは享受できない、命令型の破壊的代入と等価ですね。
はい、この「訳知り顔」の誰かさんも、また偉そうに、
参照不透明だから→関数型プログラミングではない、論法を取っています。
えーっとそれっていったいどういう意味?
あなたの言うこと、世界的に合意されているの?
「あなたの心の中」以外でまともな説明はされているの?
(分析哲学ではなく関数型言語の意味で)参照不透明、と()つけたのは、多分、Qiitaでも話題になっていた、
http://stackoverflow.com/questions/210835/what-is-referential-transparency
これを警戒しているのでしょうが、実際
「関数型言語での参照透明性」っていうのと
「分析哲学での参照透明性」の違い、なんて、まともに合意なんてされていません。
この人物も適当に
「(分析哲学ではなく関数型言語の意味で)参照不透明」とか、「この人物の心の中」での「参照透明性」を語っているにすぎません。
わからないことを、あたかもわかっているように断じる、これがこの連中の悪い癖です。
ああ、ちなみに、この
私のFRPライブラリは参照不透明?で、命令型の破壊的代入っていう中傷について、またしばらく後にエントリします。あたらしい課題つきで。
というか、さっさと、
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
これやってくださいね?OCamlで状態渡しで、あ、やっぱり、できない、でよろしいんですね?
2016年5月19日木曜日
OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?
住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き
『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと
TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/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
以下は動作中のスクリーンショット画像
極めて簡易な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を使わない関数型プログラミングでの実装のコードを見れる日は来るんでしょうか?
できたら知らせてください。お互いのコードを比較して精査してみましょう。どんなコードが出てくるんでしょうか?
精査して、簡潔さにおいて比較しうるに足る代物が出せたのなら、次のレベルに進めましょう。これでもまだ「状態渡し」で誤魔化しきれるかもしれないから。その懸念だけがある。
あああと、駱駝に言っておきますが、自分が不慣れな理解できないコードを眺めて「スパゲッティ・コード」と侮辱するのは悪い癖です。止めなさい。そして、「無意味に複雑・冗長」だと思うなら、ハッタリでないのなら、切り詰めて簡約したコードをさっと出しましょう。今回も「無意味に複雑・冗長」な「スパゲッティ・コード」と思うのならば、どの部分がそうなのか?明示した上で書き直したものを見せてください。
Popular Posts
-
これは連載記事です。 これは連載記事で、順次更新されます。 量子コンピュータとは?ひとことで この宇宙があらかじめ持っている計算能力に量子のレベルでアクセスして計算するマシン。 ちなみに、よくある、 量子ビット ,キュービット、キュビット、クビット(英: qubit)...
-
(追記)2015/4 関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 を無事出版しました。 (関連記事) 関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い 自分の考...
-
登場人物 セキヤ 高1男子。都内の進学校に通っている。 プログラミングが趣味でコンピュータ部に入部した。 サクラ 高2女子。IQ145の知能を持つ美少女。 セキヤの学校のコンピュータ部の先輩で、セキヤを厳しく指導する。 コンピュータ部では、いち早く頭角...
-
続編というか補足解説: 99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう 『数学ガ...
-
私の著書である、 関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間 のAmazonレビュー欄にて、以前からネットストーキングして執拗に誹謗中傷を繰り返す集団を中心に露骨なネガティブキャンペーンが展開されています。 もちろん、著書を出版し...
-
関数型プログラミングそのものが「何」であるか?そんなことはとりあえず<まったく>重要ではない。 関数型プログラミングが「銀の弾」であるのは「何故」なのか?関数型プログラミングは、あなたのコーディングで「何を可能」とするのか?その根本的な「理由」を知ることがもっとも重要であ...
-
HelloWorld
-
国内の不健全な言論環境 本エントリは、後世の記録のために残します。当方の主張の是非については、大げさではなく、長い時系列をもってフェアに判定されることを望みます。 このエントリは、2015年現在の国内における、関数型プログラミングをめぐる言論状況について分析し、広い読者に各...
-
関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 で、内容の流れ、紙面、諸々の都合で書ききれなかった、React (.js Facebook)の補足解説で、本書の読者のためのサポート記事です。 著書では、前章からの流れを受けて、関数型プログラ...
-
神に酔える無神論者「神とはすなわち自然であり、万物に存在する」って言ってたらユダヤ社会から追放されたスピノザ 「 存在するものの秩序ある調和の中に自らを現す スピノザの神 なら信じるが、人間の運命や行動に関わる人格のある神は信じない。 」 アルバート・アインシュタイン ...