tag:blogger.com,1999:blog-13478567297699346022024-03-21T04:31:55.053+09:00岡部 健の技術記事 Ken Okabe's tech writing
<br><br>
Contact : kenokabe@gmail.com
Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.comBlogger53125tag:blogger.com,1999:blog-1347856729769934602.post-71061726195889929042018-12-09T23:46:00.000+09:002018-12-09T23:46:12.576+09:00最新記事・ブログ移転していました
<a href="http://kentechdoc.blogspot.com/2018/12/30javascript_4.html">30分でわかるJavaScriptプログラマのためのモナド入門
</a>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-84247389028690596442016-05-24T08:20:00.001+09:002016-05-24T17:51:45.233+09:00続スケールするFRPアプリ課題:TimeEngine+React(JS)とOCamlの比較<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/c.html">C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine.html">TImeEngineは命令型でも破壊的代入でもない</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-xt-xt-1.html">TimeEngineの __x.t = __x.t + 1; について</a></p>
<p>この辺の続きとなります。</p>
<p>特に前回、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/frp_23.html">スケールするFRPアプリ課題:わかりやすい嘘誤魔化しをしないように</a></p>
<p>この課題についてです。</p>
<blockquote>
<p>FRP必要ない、とかぶちあげてた@nonstarterを「擁護」あるいは結託してたんだから、FRP使うとかもちろんなしで。 <br>
純粋関数型の「状態渡し」で実用的なアプリを「なんら困難もなく」書けるんでしょ? <br>
FRPと複雑性は変わらんのでしたよね?じゃあ、当方のFRPのコードと同等以下の複雑性で、 <br>
関数型「状態渡し」をもって書けるはずです。 <br>
もっとも適当な嘘ハッタリじゃあなければね。さあやって見せてください。どうぞ。</p>
</blockquote>
<p>と煽ったら、まんまと書いてくれました。ご苦労様。</p>
<p>これまで連中がやらかしてた嘘誤魔化しを徹底的にこちらが糾弾する形で、追い込んだので、 <br>
(そういう作業も手間がかかるんですよね、最初から誤魔化ししなければいい) <br>
<strong>ここに来てようやくそれなりに嘘ごまかしが排除された実用的GUIアプリの比較対象となりうるコードが登場</strong>してきました。</p>
<p>まあ、さぞかし「大変」だったことでしょう(笑) <br>
連中が総体として、傍観者、客観的読者へ向けて印象づける <br>
「いともかんたんに、なんでも関数型の状態渡しでできる、OCamlでも何でも一緒」 <br>
「FRPも状態渡しも一緒、FRPはなんら必要なし、メリットなし@nonstarter」 <br>
という趣旨の大嘘@はとりあえず確定したようなので、確認していきましょう。</p>
<p><a href="http://okaml.blogspot.jp/">http://okaml.blogspot.jp/</a></p>
<h2 id="ocamlソースコード">OCamlソースコード</h2>
<pre class="prettyprint"><code class=" hljs coffeescript"><span class="hljs-built_in">module</span> H = Dom_html
<span class="hljs-reserved">let</span> g x = Js.Opt.get x <span class="hljs-function"><span class="hljs-params">(fun () -> assert <span class="hljs-literal">false</span>)</span>
<span class="hljs-title">let</span> <span class="hljs-title">o</span> <span class="hljs-title">x</span> = <span class="hljs-title">Js</span>.<span class="hljs-title">Opt</span>.<span class="hljs-title">return</span> <span class="hljs-title">x</span>
<span class="hljs-title">let</span> <span class="hljs-title">s</span> = <span class="hljs-title">Js</span>.<span class="hljs-title">string</span>
<span class="hljs-title">let</span> <span class="hljs-title">i</span> = <span class="hljs-title">string_of_int</span>
<span class="hljs-title">type</span> <span class="hljs-params">(<span class="hljs-string">'a, '</span>b)</span> <span class="hljs-title">state</span> =
<span class="hljs-params">(* just to omit explicit annotation <span class="hljs-keyword">of</span> complex types <span class="hljs-keyword">by</span> (ab)using <span class="hljs-string">"polymorphism"</span> *)</span>
{ <span class="hljs-title">itemss</span> : '<span class="hljs-title">a</span> <span class="hljs-title">list</span> <span class="hljs-title">list</span>; <span class="hljs-title">cur</span> : <span class="hljs-title">int</span>; <span class="hljs-title">selects</span> : '<span class="hljs-title">b</span> }
<span class="hljs-title">let</span> <span class="hljs-title">_</span> = <span class="hljs-title">H</span>.<span class="hljs-title">window</span>##<span class="hljs-title">onload</span> <- <span class="hljs-title">H</span>.<span class="hljs-title">handler</span> <span class="hljs-params">(fun _ ->
Firebug.<span class="hljs-built_in">console</span>##debug(s <span class="hljs-string">"DoNe2 starting"</span>);
<span class="hljs-reserved">let</span> d = H.<span class="hljs-built_in">document</span> <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> tm = g (d##getElementById (s <span class="hljs-string">"todo2_time"</span>)) <span class="hljs-keyword">in</span>
ignore
(H.<span class="hljs-built_in">window</span>##setInterval
(Js.wrap_callback (fun _ ->
tm##textContent <- o (jsnew Js.date_now ()##toString ())),
<span class="hljs-number">100.</span>));
<span class="hljs-reserved">let</span> nu = g (H.CoerceTo.input (g (d##getElementById (s <span class="hljs-string">"todo2_new"</span>)))) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> selects = g (d##getElementById (s <span class="hljs-string">"todo2_selects"</span>)) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> select1 = g (H.CoerceTo.input (g (d##getElementById (s <span class="hljs-string">"todo2_select1"</span>)))) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> selected = g (d##getElementById (s <span class="hljs-string">"todo2_selected"</span>)) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> input = g (H.CoerceTo.input (g (d##getElementById (s <span class="hljs-string">"todo2_input"</span>)))) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> go = g (H.CoerceTo.input (g (d##getElementById (s <span class="hljs-string">"todo2_go"</span>)))) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> ul = g (H.CoerceTo.ul (g (d##getElementById (s <span class="hljs-string">"todo2_ul"</span>)))) <span class="hljs-keyword">in</span>
(* ここまでDOMの準備。ここから本体 *)
<span class="hljs-reserved">let</span> rec generate_handlers st =
<span class="hljs-reserved">let</span> rec handle_sub _ =
<span class="hljs-reserved">let</span> v = input##value <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> rec add_v pos = <span class="hljs-reserved">function</span> (* 補助関数 *)
| [] -> assert <span class="hljs-literal">false</span>
| items :: itemss <span class="hljs-keyword">when</span> pos = <span class="hljs-number">1</span> -> (items @ [v]) :: itemss
| items :: itemss -> items :: add_v (pos - <span class="hljs-number">1</span>) itemss <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> new_itemss = add_v st.cur st.itemss <span class="hljs-keyword">in</span>
Firebug.<span class="hljs-built_in">console</span>##debug(s (<span class="hljs-string">"DoNe2 adding to List#"</span> ^ i st.cur ^ <span class="hljs-string">": "</span> ^ Js.to_string v));
input##value <- s <span class="hljs-string">""</span>;
configure_ui { st <span class="hljs-reserved">with</span> itemss = new_itemss };
Js._false
<span class="hljs-keyword">and</span> handle_nu _ =
<span class="hljs-reserved">let</span> new_list = H.createInput ~_type:(s <span class="hljs-string">"submit"</span>) d <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> new_selects = st.selects @ [new_list] <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> new_itemss = st.itemss @ [[]] <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> new_cur = List.length new_selects <span class="hljs-keyword">in</span>
new_list##value <- s (<span class="hljs-string">"List#"</span> ^ i new_cur);
Dom.appendChild selects new_list;
configure_ui { (* st <span class="hljs-reserved">with</span> *) itemss = new_itemss; cur = new_cur; selects = new_selects };
Js._false
<span class="hljs-keyword">and</span> handle_select new_cur _ =
configure_ui { st <span class="hljs-reserved">with</span> cur = new_cur };
Js._false
<span class="hljs-keyword">in</span>
(handle_sub, handle_nu, handle_select)
<span class="hljs-keyword">and</span> configure_ui st =
selected##textContent <- o (s (<span class="hljs-string">"List#"</span> ^ i st.cur));
go##value <- s (<span class="hljs-string">"NewDoNe#"</span> ^ i (<span class="hljs-number">1</span> + List.length (List.nth st.itemss (st.cur - <span class="hljs-number">1</span>))));
<span class="hljs-reserved">let</span> rec rm_all_child p = (* 補助関数 *)
Js.Opt.<span class="hljs-reserved">case</span> (p##firstChild) (fun () -> ())
(fun c ->
ignore (p##removeChild(c));
rm_all_child p) <span class="hljs-keyword">in</span>
rm_all_child ul;
List.iter
(fun item ->
<span class="hljs-reserved">let</span> li = H.createLi d <span class="hljs-keyword">in</span>
li##textContent <- o item;
Dom.appendChild ul li)
(List.nth st.itemss (st.cur - <span class="hljs-number">1</span>));
<span class="hljs-reserved">let</span> (handle_sub, handle_nu, handle_select) = generate_handlers st <span class="hljs-keyword">in</span>
go##onclick <- H.handler handle_sub;
nu##onclick <- H.handler handle_nu;
List.iteri
(fun n selected ->
selected##onclick <- H.handler (handle_select (<span class="hljs-number">1</span> + n)))
st.selects
<span class="hljs-keyword">in</span>
configure_ui { itemss = [[]]; cur = <span class="hljs-number">1</span>; selects = [select1] };
Js._false)</span></span></code></pre>
<h2 id="まず非常に長いです">まず、「非常に長い」です。</h2>
<p>これまで、あたかも簡単に短く書けるようなフリしたコードを出していたけど、ほんの少し複雑にスケールしたアプリが課題になると、途端に急にコードが倍増した。なんで?</p>
<p>これまで課題が簡単である、というある種の特性を利用し、それが複雑になるとすぐに破綻するコードである、という、学習者にとってもっとも重要な情報をひた隠しにし、あたかも汎用的に通用するスケールする設計とコードである、というフリをしてきたのが、実際に破綻してしまったからです。 <br>
つまり、<strong>これまで誤魔化していた、課題の単純性という特性の利用、誤魔化しが通用しなくなり、破綻して、一気に膿が出てきた分量が、この目に見えるコード量の急増分</strong>です。</p>
<p>言い換えると、すでにこうやって急増したコードをベースに、いろいろ削る形で修正すれば、一個前のより単純な、ToDoリストアプリが簡単に書けます。そして、より単純な、ToDoリストアプリからまた順当に機能追加すれば、このコードになるでしょう。こういうのがスケールする設計で、コードであると言います。 <br>
前回からまるで様子の異なった、コードがなんか倍増しているということは、前回の設計が、問題がスケールしたら、まったく通用せず破綻した、ということを意味します。</p>
<p>この人物のコメントです。</p>
<blockquote>
<p>動いてると思うけど書き殴りだから細かいことは気にしないでね <br>
単に機能が増えて面倒になっただけで、状態渡しのしかたは前回と同じ。ちなみに今回も頑張れば状態渡しすら使わずに書けそうだけど、これは使ったほうが楽かな。 <br>
メインループではなくハンドラでOCaml部分の状態渡しをしてるので、「メインループを書き直してるからスケールしない」というのとは少し違う。 <br>
(状態渡しや関数型云々とは無関係に)やっぱりDOMかつ静的型だとちょっと長くなるね(定数倍ファクターなのでスケール云々とも無関係)。前回のから改造しててOCaml部分の不整合はデバッグしなくてもコンパイラが見つけてくれるので開発は明らかに楽だったけど。</p>
</blockquote>
<p>まあ</p>
<h2 id="それなりの試行錯誤の末に苦労したんだな">それなりの試行錯誤の末に「苦労したんだな」</h2>
<p>というのが行間から溢れ出ています。お疲れ様。 <br>
実際に、前回この人物は、<strong>「状態渡し」で書きたくない理由についての言い訳</strong>として、</p>
<blockquote>
<p>以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。</p>
</blockquote>
<p>と発言しており、</p>
<blockquote>
<p>「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常</p>
</blockquote>
<p>つまり、今回慣れない、かなりイレギュラーな実装を試みた、というのがわかります。</p>
<p>「非常に長いコードである」という点については、</p>
<blockquote>
<p>静的型だとちょっと長くなる</p>
</blockquote>
<p>らしいです。つまり、</p>
<h2 id="実用的なguiアプリをocamlで静的イミュータブルな関数型のスタイルをもって実装しようとすると簡潔になるどころかコードがかなり煩雑になり長くなる">実用的なGUIアプリをOCamlで静的(イミュータブル)な関数型のスタイルをもって実装しようとすると、簡潔になるどころか、コードがかなり煩雑になり長くなる</h2>
<p>ということが、反発していた、誤魔化し続けていた当のOCamlプログラマー自身の手により実証されました。</p>
<p>すなわち、これが、この人物を含め、胡散臭い連中がずっと誤魔化してきてけして表明しなかった動かしがたい事実であり、私が、当初、あんたら関数型について偉そうな事言ってるけど、スケールする実用的なGUIアプリとか、そのやリ方ですんなり書けるわけ?と批判した核心的な要素となります。</p>
<p>@nonstarterはじめ、連中がさんざん中傷してきた、JavaScriptの関数型において、 <br>
いまやGUIフロントエンドのデファクトとなってしまっている、FacebookReact、 <br>
それに、私のTimeEngineというFRPライブラリを適用してFRP、関数型で書いた、同じGUIアプリのソースコードは以下でした。比較検討のために再掲します。</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/frp_23.html">スケールするFRPアプリ課題:わかりやすい嘘誤魔化しをしないように</a></p>
<p>TimeEngine公式サイト <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
のDemo11 </p>
<h2 id="ソースコードindexjsx">ソースコード(index.jsx)</h2>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">const</span> TodoElement = () => {
<span class="hljs-keyword">const</span> ClockElement = __Element(__.intervalSeq(Immutable.Range(), <span class="hljs-number">100</span>)
.__(() => (<span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span>{moment().format('MMMM Do YYYY, h:mm:ss a')}<span class="hljs-tag"></<span class="hljs-title">div</span>></span>)));
const __fdList = __().__((val) => (__.log.t = val));
const __lists = __(true).__((__list) => (__fdList.t = __lists.length));
const ListofListElement = __Element(__([__lists])
.__(() => ((__lists).map((list, i) => (
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {() =></span> (__.log.t = __fdList.t = i)}>{'List#' + (i + 1)}<span class="hljs-tag"></<span class="hljs-title">button</span>></span>)))));
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) => (<span class="hljs-tag"><<span class="hljs-title">div</span>></span>
<span class="hljs-tag"><<span class="hljs-title">h4</span>></span>{'List#' + (__fdList.t + 1)}
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {<span class="hljs-attribute">onClickNL</span>}></span>{'NewList'}<span class="hljs-tag"></<span class="hljs-title">button</span>></span><span class="hljs-tag"></<span class="hljs-title">h4</span>></span>
{__lists[__fdList.t].map((item) => (<span class="hljs-tag"><<span class="hljs-title">li</span>></span>{item}<span class="hljs-tag"></<span class="hljs-title">li</span>></span>))}
<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">{value}</span> <span class="hljs-attribute">onChange</span>=<span class="hljs-value">{onChange}</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {<span class="hljs-attribute">onClick</span>}></span>{'NewToDo#' + (__lists[__fdList.t].length + 1)}<span class="hljs-tag"></<span class="hljs-title">button</span>></span><span class="hljs-tag"></<span class="hljs-title">div</span>></span>));
__.log.__(() => (__value.t = ""));
return __Element(__seqEl);
};
__lists.t = __(true); //new items-list
const __delay = __.intervalSeq(Immutable.Seq.of("started!"), 1000)
.__(() => (__.log.t = "showInput"));
return (<span class="hljs-tag"><<span class="hljs-title">div</span>></span><span class="hljs-tag"><<span class="hljs-title">h2</span>></span>ToDo<span class="hljs-tag"></<span class="hljs-title">h2</span>></span>{ClockElement}<span class="hljs-tag"><<span class="hljs-title">p</span>/></span>
{ListofListElement}<span class="hljs-tag"><<span class="hljs-title">p</span>/></span>{InputElement()}<span class="hljs-tag"></<span class="hljs-title">div</span>></span>);
};
const mount = ReactDOM.render(TodoElement(), document.getElementById('todo'));</span></code></pre>
<h2 id="公平性のため空行コメントを除外してコードの行数の単純比較">公平性のため、空行、コメントを除外して、コードの行数の単純比較</h2>
<p>をしてみると、</p>
<p>OCamlの関数型状態渡し : <strong>74行</strong> <br>
JavaScript+React+TimeEngineのFRP : <strong>29行</strong></p>
<p>です。もちろん、あちらも当方も、いくらでも改行は整理することは可能ですが、 <br>
可読性とバランスを双方とっているようにみえる現行のコードでの単純比較となります。</p>
<h2 id="同じguiアプリを関数型で実装するのにjstimeenginereactのfrpではocamlの状態渡し関数型より行数にして半分以下">同じGUIアプリを関数型で実装するのに、JS+TimeEngine(React)のFRPでは、OCamlの状態渡し関数型より、行数にして半分以下</h2>
<p>で書けている、ということが証明されました。</p>
<p>まあ、視認しても、ぱっと見でも、どちらが簡潔に短く表現できているのか? <br>
一目瞭然だと思います。</p>
<p>そして念の為ですが、ちょっと例題を複雑にしたらこうなった、ということであり、 <br>
より複雑性が増したら、さらにこの差は顕在化し、デバッグその他の差異は深刻になる、 <br>
というのは明らかです。</p>
<p>たとえば、私が書いた上記のFRPのコードですが、 <br>
<code>const</code> で定義している定数をそのまま抜き出して列挙してみると、 <br>
これらはそのまま関数型コードの構造になっています。 </p>
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword">const</span> TodoElement
<span class="hljs-keyword">const</span> ClockElement
<span class="hljs-keyword">const</span> __fdList
<span class="hljs-keyword">const</span> __lists
<span class="hljs-keyword">const</span> ListofListElement
<span class="hljs-keyword">const</span> InputElement
<span class="hljs-keyword">const</span> __value
<span class="hljs-keyword">const</span> onChange
<span class="hljs-keyword">const</span> onClick
<span class="hljs-keyword">const</span> onClickNL
<span class="hljs-keyword">const</span> __seqEl
<span class="hljs-keyword">const</span> mount </code></pre>
<p>こうなります。GUI部品のReactのElementは、 <br>
ToDoElementが、最後にmountされる一番外側のコンポーネントであり、 <br>
それらの内訳は以下の3つ。</p>
<ul>
<li>ClockElement</li>
<li>LIstOfListElement</li>
<li>InputElement</li>
</ul>
<p>さらに、3つのユーザ入力イベント宣言</p>
<ul>
<li>onChange </li>
<li>onClick </li>
<li>onClickNL </li>
</ul>
<p>に加え、FRP値</p>
<ul>
<li>__fdList (現在フォーカスされているリスト)</li>
<li>__lists (リスト群)</li>
<li>__value (ユーザ入力テクスト)</li>
<li>(__seqEl)</li>
</ul>
<p>以上の各<code>const</code>の宣言を列挙することは、そのままアプリの設計の概略となっています。 <br>
関数型、宣言型コード全体として極めて見通しのよいコードになっています。 <br>
当然、アプリケーションがいくら複雑になろうとも、このシンプルな構造の延長でいくらでもスケール可能です。</p>
<p>さて、このような明瞭簡潔な構造が、この人物が苦労して書いた「スパゲッティ・コード」 <br>
OCamlの状態渡し関数型コードにあるでしょうか?</p>
<blockquote>
<p>動いてると思うけど書き殴りだから細かいことは気にしないでね</p>
<p>単に機能が増えて面倒になっただけで、状態渡しのしかたは前回と同じ。ちなみに今回も頑張れば状態渡しすら使わずに書けそうだけど、これは使ったほうが楽かな。</p>
<p>やっぱりDOMかつ静的型だとちょっと長くなるね</p>
<p>前回のから改造しててOCaml部分の不整合はデバッグしなくてもコンパイラが見つけてくれる</p>
</blockquote>
<p>こういう発言からも明らかでしょう。 <br>
つまりこのコードは、コンパイラが不整合を見つけてくれないと、コーダーには手に負えないほど複雑であり、「面倒」であり、「動いてると思うけど、細かいことは気にしないでね」と言い訳せざるをえないほどに、設計についてはあやふやで、関数型でイミュータブルに書くには「異常」な努力が必要で、当然、長いコードである、</p>
<p>ということになります。</p>
<p>不整合をコンパイラが見つけてくれる? <br>
私がJavaScriptのFRPのコード書くときは、そんなもんは必要ないですが?</p>
<p>この人物の最後の言い訳です。</p>
<blockquote>
<p>俺もOCamlの勉強になったけど、「できない」と断言されたことをすぐにやって見せたんだから(それも3回。しかも他人に「課題」とか言った本人は1年がかり、かつ関数型ではなく全くの命令型。決して認めないようだが。)、もうつきあう義理はないよね。</p>
</blockquote>
<p>まあ、こうやってちょっと本気出されて、徹底的に嘘ごまかしが通用しないレベルまで引き上げられて、こっちがあっさり書けるコードを、コンパイラに不整合チェックしてもらわないと自分のコードの妥当性すら確信できないような複雑なコードを書かざるを得ない、関数型で破壊的代入のないイミュータブルなコードを書くってだけで、むしろOCamlによるGUIでは通常らしい破壊的代入、命令型より「長くなる」、ということを痛感して、自分らが主張していたことが「机上の空論」であった、とようやく理解できたんじゃないかな?</p>
<blockquote>
<p>「できない」と断言されたことをすぐにやって見せた(それも3回)</p>
</blockquote>
<p>正確に書き直してあげると、こっちの議論、批判の趣旨くらいは理解していたはずだ。 <br>
それを踏まえて、例題が、カウンターやお絵かきと単純すぎたことを良いことに、 <br>
「あたかもスッキリ簡単に書ける」ように嘘誤魔化しをし、 <br>
上記馬脚が顕れたような要素、つまりこちらが当初から指摘し批判していたことについてまるで認めなかった誤魔化しが2回あり、 <br>
最後の1回(今回)で、それが、</p>
<h3 id="やっぱりできなかったということをパフォーマンスして見せたつまり">「やっぱりできなかった」ということをパフォーマンスして見せた、つまり、</h3>
<h2 id="frpと複雑性は変わらんのでしたよねじゃあ当方のfrpのコードと同等以下の複雑性で-関数型状態渡しをもって書けるはずです">FRPと複雑性は変わらんのでしたよね?じゃあ、当方のFRPのコードと同等以下の複雑性で、 関数型「状態渡し」をもって書けるはずです。 </h2>
<p>という課題について、</p>
<h2 id="コンパイラの整合性チェック頼みの君自身が実装に自信がないような言い訳するしか無い-補助関数-なるものがある複雑怪奇かつ倍の行数以上の長く煩雑なコードしか提示できなかった">コンパイラの整合性チェック頼みの、君自身が実装に自信がないような言い訳するしか無い「 補助関数 」なるものがある複雑怪奇かつ倍の行数以上の長く煩雑なコードしか提示できなかった、</h2>
<p>のだから、</p>
<h3 id="絶対出来ないという当方の予想通りであり課題は不合格">「絶対出来ない」という当方の予想通りであり、課題は不合格</h3>
<p>ということになります。残念でした・・・</p>
<p>これまで君が書いたコードはすべて、その延長線上ですぐに破綻する、スケールしない設計であった、ということが今回証明されたのだから、 <br>
「できもしないことを簡単にできるように見せかけてきた」ことが白日の下にさらされた、 <br>
にすぎない。</p>
<blockquote>
<p>かつ関数型ではなく全くの命令型。決して認めないようだが。)</p>
</blockquote>
<p>何度も繰り返すけど、<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-xt-xt-1.html">TimeEngineの __x.t = __x.t + 1; について</a>で、説明してあげたことについて、 <br>
まだ駄々をこねたいのならば、あいもかわらず馬鹿だね、とあきれるしかないし、 <br>
何を中傷しようとも、</p>
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword">const</span> TodoElement
<span class="hljs-keyword">const</span> ClockElement
<span class="hljs-keyword">const</span> __fdList
<span class="hljs-keyword">const</span> __lists
<span class="hljs-keyword">const</span> ListofListElement
<span class="hljs-keyword">const</span> InputElement
<span class="hljs-keyword">const</span> __value
<span class="hljs-keyword">const</span> onChange
<span class="hljs-keyword">const</span> onClick
<span class="hljs-keyword">const</span> onClickNL
<span class="hljs-keyword">const</span> __seqEl
<span class="hljs-keyword">const</span> mount </code></pre>
<p>というように、こちらの書く、FRPのコードは、すべてconstantに静的にコードがすっきりと設計されており、 <br>
一方で、そちらのコードは、そんなすっきりとした設計などどこにも存在しておらず、 <br>
まさに誰かさんがみたら「スパゲッティ・コード」と評するしかない代物であり、 <br>
現実に、</p>
<blockquote>
<p>動いてると思うけど書き殴りだから細かいことは気にしないでね</p>
</blockquote>
<p>などと書いた本人が、動作の妥当性についてすら、自信をもって提示できないという言い訳をいきなりかましたり、</p>
<blockquote>
<p>前回のから改造しててOCaml部分の不整合はデバッグしなくてもコンパイラが見つけてくれる</p>
</blockquote>
<p>などと、不整合について、設計段階では確信すらもてずコンパイラ頼み、 <br>
という惨憺たる状況を自分自身で白状してしまっている。</p>
<p>イミュータブルなコードを書く関数型プログラミングのGUIのアプリの適用について、 <br>
この惨状が一般的な真実であることは、</p>
<blockquote>
<blockquote>
<p>以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。</p>
</blockquote>
</blockquote>
<p>と、今回のような、極めて初歩的なGUIアプリの実装の局面でさえ、 <br>
今回自分で書いた関数型のアプローチが、</p>
<h3 id="異常不適切"> 異常、不適切</h3>
<p>であることをすでに認めてしまっていることからも、語るに落ちている状態。</p>
<p>以上のような、自信の悲惨なパフォーマンス、こちらがきちんと詰めたら、しっかりと嘘誤魔化しが暴かれた、証明された、という自覚くらいはもってるだろうから、</p>
<blockquote>
<p>もうつきあう義理はないよね。</p>
</blockquote>
<p>と逃げたくなる気持ちはよくわかる。 <br>
そうだね、<strong>今回もうはっきりとした結果は出た。万人が追認してくれるだろう、非常にわかりやすい結果だ。</strong> <br>
これ以上やっても、結果は同じなので、これ以上、こちらがハードルを上げる意味もないだろう。 <br>
いや、あるかな?こういうGUIアプリなんて、こっちは、いくらでも複雑に書けるんだよ、何の苦労もなくね。 <br>
でも、これ以上複雑にしたら、もうそちらは、関数型で書くのは非常に苦しくなるんだろう? <br>
そういうのを確認してやるのも面白いと思うけど、あらかじめ逃げの先手うってるところをみると、 <br>
もう限界っぽいし、繰り返しになるが、必死にコード書けたとしても、結果は同じだよね?</p>
<blockquote>
<p>「中国製不正アクセス機器を使って誹謗中傷してる犯罪者集団」みたいな妄想はマジ勘弁。それを釣りで煽ってる奴ら(単独?)もな。</p>
</blockquote>
<p>うん、最後になるが、これ書いてるの多分、</p>
<p><a href="http://okaml.blogspot.jp/2016/05/done.html">http://okaml.blogspot.jp/2016/05/done.html</a></p>
<p>で、</p>
<p><strong>たとえ「過去の値」が不要になっても</strong></p>
<p>と、追記して強調する癖とか、例のQiita記事の@lambada と全く同一の挙動であり、いわゆる駱駝、</p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p>で書いたように、こいつは、 <br>
らくだの卯之助@camloeba だと自分は思ってる。</p>
<p>らくだの卯之助@camloebaが、私を中傷する2chスレッドで、犯罪者集団と合流して、 <br>
Newbie伊藤 ◆p02ZTYXhPKG5 <br>
というコテハンで、</p>
<pre class="prettyprint"><code class=" hljs avrasm"><span class="hljs-number">497</span>:Newbie伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span>:<span class="hljs-number">23</span>:<span class="hljs-number">39.50</span> ID:vcolQJWW<span class="hljs-preprocessor">.net</span>
<span class="hljs-number">956</span> 仕様書無しさん <span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span>:<span class="hljs-number">05</span>:<span class="hljs-number">32.47</span>
田中がaskの仕様変更からものの数日で実用的なGUIアプリをHaskellで作成して公開していて草
<span class="hljs-label">http:</span>//tanakh<span class="hljs-preprocessor">.jp</span>/posts/<span class="hljs-number">2015</span>-<span class="hljs-number">12</span>-<span class="hljs-number">20</span>-tomori-nao<span class="hljs-preprocessor">.html</span>
<span class="hljs-number">499</span>:Newbie伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span>:<span class="hljs-number">26</span>:<span class="hljs-number">12.92</span> ID:vcolQJWW<span class="hljs-preprocessor">.net</span>
くらえ、素人! </code></pre>
<p>と、下劣なAAを貼り付けて喜んでいるのは、上記リンクで説明したとおりだし、</p>
<p>【弱者を放置して】赤木智弘30【アイマスラブ】 <br>
<a href="http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19">http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19</a></p>
<p>という、仲間割れメンバーのスレで、</p>
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-number">19</span> 名無しさん@社会人 <span class="hljs-number">2015</span>/<span class="hljs-number">11</span>/<span class="hljs-number">03</span>(火) <span class="hljs-number">21</span>:<span class="hljs-number">00</span>:<span class="hljs-number">52.89</span>
<span class="hljs-number">369</span> :M7<span class="hljs-number">.74</span>(catv?):<span class="hljs-number">2015</span>/<span class="hljs-number">11</span>/<span class="hljs-number">03</span>(火) <span class="hljs-number">12</span>:<span class="hljs-number">06</span>:<span class="hljs-number">52.44</span> ID:gYJokkH60
投稿者: 俺 (ID:<span class="hljs-number">0001</span>) 投稿日時:<span class="hljs-number">15</span>年 <span class="hljs-number">10</span>月 <span class="hljs-number">11</span>日 <span class="hljs-number">14</span>:<span class="hljs-number">09</span>
なので、当面は以下の通りで行きます。
いかんせん、Qiita以降の奴しか知らないので、不慣れなところはレギュラーが極力、バックアップ願います。
<span class="hljs-number">8</span>賢枠 (暫定) <span class="hljs-number">2015</span>/<span class="hljs-number">10</span>/<span class="hljs-number">02</span>
・スキルハンターの鷹
・知の答弁人田中
・思考のゼロ除算ボレロ
・辣腕ギークのキャメル
・知のオーバーフロー加藤
・AIG(A-Jiro <span class="hljs-keyword">is</span> Guru)
・菅本・ザ・ストリートプログラマー
・(空席)
以上。 </code></pre>
<p>暴露されたとおり、 <br>
・辣腕ギークのキャメル <br>
という、バレバレの「ミッションネーム」を、@tikuwa_zeroという主犯によって与えられて、さすがにそれは、ということで、 <br>
Newbie伊藤 ◆p02ZTYXhPKG5にしたことも知ってる。 <br>
また <br>
AIG(A-Jiro is Guru) <br>
というのは、2chのそのスレで、「さすがAIGさん」とか「先生」とか言われてる人物なんだけれども、 <br>
これはもちろん、 <br>
東北大学の住井 英二郎@esumiiのことだろう。 <br>
今、舛添都知事の税金の問題が糾弾されているけれども、 <br>
君は、国民の税金をもらって仕事させてもらっている立場だよね?住井さん。 <br>
明らかに平日の勤務時間中に、2ちゃんねるで当方を誹謗中傷するスレッドにお友達の駱駝と一緒に書き込んで、「先生」だの、「8賢者」「ウィザード組」だの持ち上げられて、犯罪集団と合流して何やってるんだい?</p>
<p>またもちろん、今回のOCamlを書いた人間は、OCamlを勉強している人、などではなく、</p>
<blockquote>
<p>ご指名ではないけど久々に書いてみました。</p>
</blockquote>
<p>というのは、こちらが駱駝サンと「指名」しているから、本人が呼応した、 <br>
という当然の憶測を警戒するから、わざわざ書いているのであり、</p>
<blockquote>
<p>俺もOCamlの勉強になったけど</p>
</blockquote>
<p>などとその他、複数回、OCamlを勉強中の人間をアピールしているのは、「カモフラージュ」であると見ている。別に褒め称えるつもりじゃないけど、まあOCamlで飯を食ってる人間だけのことはあるね、君は断じて「OCamlを勉強している人」などではない。これは嘘だ。</p>
<p>短時間で「<strong>書き殴り</strong>」で書ける、それなり以上に手慣れた人間が書く実装とコード。</p>
<p>もちろん、FRPとか使ってないので状態渡しでかなり無理して書いているけど、無理したら書ける程度のスキルがちゃんとある。 <br>
じゃあなんで、 <br>
「OCamlを勉強している人」 <br>
という嘘ついて、カモフラージュしてるのか?プロだと特定されたら都合が悪いからだよね?</p>
<blockquote>
<p>ご指名ではないけど久々に書いてみました。</p>
</blockquote>
<p>とわざわざ自分ではない、とアピールしないと都合が悪い。</p>
<p>まああいかわらずだね。駱駝。名指しされて、黙っていられなくなって、 <br>
でも、オモテで自分だとやれば、リスクがあるもんだから、匿名ブログこさえて、 <br>
他の人間が書くの待つのもどかしいし、OCamlのプロの自分がやったほうが、 <br>
手っ取り早く思い通りのコード書けるってわかってるから、自分でやったんだろ? <br>
いったい誰がその君のポッと出の、こさえた本人しか知らない匿名ブログをUPされるとほぼ同時に、 <br>
前々から、こっちを誹謗中傷する犯罪者集団の2chのスレに逐一貼り付けてるんだ? <br>
おまえだろ?</p>
<p>とりあえず、</p>
<p>「OCamlの関数型できないことを、さもすんなりできるように喧伝していたいた」 <br>
君らの嘘誤魔化しが、 <br>
<strong>OCamlのイミュータブルな関数型プログラミングでGUIアプリ書くことなんて「机上の空論」である</strong>、 <br>
ということが、 <br>
自分自身の発言と、自分が書いたコードによって、 <br>
証明されてよかったじゃない。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-89474041598294026842016-05-23T00:06:00.001+09:002016-05-24T17:52:12.547+09:00スケールするFRPアプリ課題:わかりやすい嘘誤魔化しをしないように<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/c.html">C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine.html">TImeEngineは命令型でも破壊的代入でもない</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-xt-xt-1.html">TimeEngineの __x.t = __x.t + 1; について</a></p>
<p>この辺の続きとなります。</p>
<p>特に <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p>この課題についてです。</p>
<p><a href="http://anond.hatelabo.jp/20160521172426">http://anond.hatelabo.jp/20160521172426</a></p>
<blockquote>
<p><a href="http://megalodon.jp/2016-0521-1450-10/okaml.blogspot.jp/">http://megalodon.jp/2016-0521-1450-10/okaml.blogspot.jp/</a> <br>
また瞬殺</p>
</blockquote>
<p>なる投稿を見ました。 <br>
なんで、Web魚拓のリンクなのか知りませんが、元URLは、</p>
<p><a href="http://okaml.blogspot.jp/">http://okaml.blogspot.jp/</a></p>
<p>です。</p>
<h4 id="k">K</h4>
<p>だの</p>
<h4 id="okaml">okaml</h4>
<p>だの</p>
<blockquote>
<p>お絵かきロジック(笑)というかマウスのドラッグ(ボタンの状態) <br>
クリックカウンター(笑)</p>
</blockquote>
<p>だの、まあ当方を愚弄しているつもりなんでしょう。しょうもないですね。こういうところからも、 <br>
<a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a> <br>
という集団の存在の蓋然性が確認できると思います。</p>
<p>「瞬殺」らしいですが、「そういうこと」にしたいらしいですが、まったく「瞬殺」されていないどころか、 <br>
まあいつもの、</p>
<h3 id="できないことをさもできるように見せかける嘘誤魔化し">できないことをさもできるように見せかける嘘誤魔化し</h3>
<p>満載なので、以下ざっと説明してみます。</p>
<p><a href="http://okaml.blogspot.jp/2016/05/done.html">http://okaml.blogspot.jp/2016/05/done.html</a></p>
<p>から全文引用してみます。</p>
<h3 id="2016年5月21日土曜日">2016年5月21日土曜日</h3>
<h3 id="done">Done</h3>
<blockquote>
<p>ご指名ではないけど久々に書いてみました。OCamlもJSも詳しくないので細かいことは知らない。(追記:入力消すの忘れてたので修正。)</p>
</blockquote>
<pre class="prettyprint"><code class=" hljs coffeescript"><span class="hljs-built_in">module</span> H = Dom_html
<span class="hljs-reserved">let</span> g x = Js.Opt.get x <span class="hljs-function"><span class="hljs-params">(fun () -> assert <span class="hljs-literal">false</span>)</span>
<span class="hljs-title">let</span> <span class="hljs-title">o</span> = <span class="hljs-title">Js</span>.<span class="hljs-title">Opt</span>.<span class="hljs-title">return</span>
<span class="hljs-title">let</span> <span class="hljs-title">s</span> = <span class="hljs-title">Js</span>.<span class="hljs-title">string</span>
<span class="hljs-title">let</span> <span class="hljs-title">_</span> = <span class="hljs-title">H</span>.<span class="hljs-title">window</span>##<span class="hljs-title">onload</span> <- <span class="hljs-title">H</span>.<span class="hljs-title">handler</span> <span class="hljs-params">(fun _ ->
Firebug.<span class="hljs-built_in">console</span>##debug (s <span class="hljs-string">"DoNe starting"</span>);
<span class="hljs-reserved">let</span> d = H.<span class="hljs-built_in">document</span> <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> tm = g (d##getElementById (s <span class="hljs-string">"todo_time"</span>)) <span class="hljs-keyword">in</span>
ignore
(H.<span class="hljs-built_in">window</span>##setInterval
(Js.wrap_callback (fun _ ->
tm##textContent <- o (jsnew Js.date_now ()##toString ())),
<span class="hljs-number">100.</span>));
<span class="hljs-reserved">let</span> txt = g (H.CoerceTo.input (g (d##getElementById (s <span class="hljs-string">"todo_text"</span>)))) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> btn = g (H.CoerceTo.input (g (d##getElementById (s <span class="hljs-string">"todo_button"</span>)))) <span class="hljs-keyword">in</span>
<span class="hljs-reserved">let</span> ul = g (d##getElementById (s <span class="hljs-string">"todo_ul"</span>)) <span class="hljs-keyword">in</span>
btn##onclick <- H.handler (fun _ ->
<span class="hljs-reserved">let</span> v = txt##value <span class="hljs-keyword">in</span>
Firebug.<span class="hljs-built_in">console</span>##debug (s (<span class="hljs-string">"DoNe adding: "</span> ^ Js.to_string v));
<span class="hljs-reserved">let</span> li = H.createLi d <span class="hljs-keyword">in</span>
li##textContent <- o v;
Dom.appendChild ul li;
btn##value <- s (<span class="hljs-string">"NewDoNe#"</span> ^ string_of_int (<span class="hljs-number">1</span> + ul##childNodes##length));
txt##value <- s <span class="hljs-string">""</span>;
Js._false);
Js._false)</span></span></code></pre>
<blockquote>
<ul>
<li>今回は「状態渡し」すら要らないので「お絵かき」より簡単。何をさせたかったのかまったくわからない。</li>
<li>すでに別の人も指摘しているとおり、以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。</li>
<li>自分から要求した「お絵かき」の「トイプログラム」すら1年もかかって自称FRP(実際にはFunctionalですらない命令型プログラム。哲学とか時刻とか理屈をこねたり過去の値を保存したところで、ユーザから見て命令型の非単一代入であることに何ら変わりはない。ちなみにその保存のしかただとJS処理系がガベコレできないのでメモリリークします。)でしか書けないのに、また他人に実装を要求する正当性は1ミリもない。</li>
</ul>
</blockquote>
<p>(引用終わり)</p>
<p>なんで、この連中、先の「ライブラリ内のソースコード」や「命令型」「破壊的代入」のこともそうなんですが、おんなじこと何度も言わないと理解できないのかな?と常にイラっとさせられるんですが、当方が<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a>で示した条件は、以下でした。</p>
<h2 id="念の為に付随要件ocamlの状態渡しによる関数型で実装せよ">念の為に付随要件、OCamlの状態渡しによる関数型で実装せよ</h2>
<ul>
<li><p>OCaml で君らがお題目唱えているとおり、(状態渡し)の関数型のコードで書くこと。これまで君らが誤魔化してきたように、HaskellやElmなど他の言語を「都合よくつまみ食い」してはならない。</p></li>
<li><p>FRPのメリットなんてない、とかぶちあげているみたいなので、たとえFRPのメリットをようやく今更途中で気づいたとしても、間違ってもOCamlのFRPライブラリなんかを検索して探し出して、そのFRPライブラリを利用して書いてはならない。あくまでも(状態渡し)の関数型コードで書くこと。</p></li>
</ul>
<p>これは、君らが延々とこちらの主張を押さえ込むように強弁してきた要件なので、当たり前。出来なきゃ、その時点で君らの嘘が確定する。以上の条件に反しなければ別にどんなライブラリを使おうが自由。</p>
<p>これだけ。たったこれだけなんですよ。</p>
<h1 id="ocamlの状態渡しによる関数型で実装せよ">OCamlの状態渡しによる関数型で実装せよ</h1>
<p>上記引用したコードは、 <br>
OCaml ◯ <br>
関数型 ◯ <br>
状態渡し X</p>
<p>です。よって不合格。</p>
<p>もちろん、これワザとやらかしてる、つまり、 <br>
関数型で実用的アプリが書けるか?</p>
<h2 id="関数型プログラミングocamlの状態渡しは実用的アプリの実装に耐えうるか">関数型プログラミング(OCaml)の「状態渡し」は実用的アプリの実装に耐えうるか?</h2>
<p>というテーマで連中が嘘誤魔化しばっかりやらかしてるから、耐久テストしてあげてるんですね。</p>
<p>状態渡し X <br>
なんで、アウトです。でも、こういう連中は悪質ですから、Xなのにまるで◯のように偽装します。誤魔化します。今回さらにそこを詰めるために「かんたんな」実証実験するために新しい課題を出しますが、その前に <br>
状態渡し X <br>
の言い訳がこれです。</p>
<blockquote>
<ul>
<li>今回は「状態渡し」すら要らないので「お絵かき」より簡単。何をさせたかったのかまったくわからない。</li>
</ul>
</blockquote>
<p>いやいや、「すら要らない」って、こっちは、「状態渡し」で書けと縛りをかけたんだ。 <br>
何をさせたかったのかまったくわからない。って、</p>
<h2 id="関数型プログラミングocamlの状態渡しは実用的アプリの実装に耐えうるか-1">関数型プログラミング(OCaml)の「状態渡し」は実用的アプリの実装に耐えうるか?</h2>
<p>ということ。わかってるよね?</p>
<p>さらに言い訳が続きます。</p>
<blockquote>
<p>すでに別の人も指摘しているとおり、以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。書けないとか言うから反例として書いただけ。</p>
</blockquote>
<p>あのさ、例の@nonstarterは、こう書いてるんだ。</p>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a></p>
<h2 id="追記20150530デスクトップアプリケーション">追記(2015/05/30):デスクトップアプリケーション??</h2>
<blockquote>
<p>(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。</p>
<p>(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)</p>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<h3 id="もちろんocamlであれhaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません">もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。</h3>
<h3 id="純粋な関数プログラミングでguiアプリケーションを作成するのにfrpがなんら必要でないという趣旨には充分です">純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。</h3>
<h3 id="いずれにせよ状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり状態渡し結局のところ少なくとも現状のfrpもイベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので">いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)…..結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)……</h3>
<p>らしい。とにもかくにも、状態のあるアプリは、 <br>
関数型(状態渡し)で書けるらしい。FRPが関数型プログラミングで、 <br>
なんら必要でないという「趣旨」を示すために、 <br>
(状態渡し) <br>
に固執しているが、でもいちおう(状態渡し)の限界を別のひとから指摘されたから、それは一応発言する、でもなおFRPはあくまで否定。 <br>
まったくもってわけのわからない理由で。</p>
<p>えーっとさ、 <br>
<a href="http://okaml.blogspot.jp/">http://okaml.blogspot.jp/</a> のやつ。</p>
<p>君、前からいたよな?そのブログに、この@nonstarterの主張に呼応して、 <br>
状態渡しでのOCamlのお絵かきアプリ書いて「ほらみろ」とばかりにやらかしてるよな? <br>
@nonstarterの上記の発言に明らかに同調し、それをもって、こちらの主張を否定しているのは明白だよな?</p>
<p>ところが!ここにきて、</p>
<blockquote>
<p>以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。</p>
</blockquote>
<p>と来た。こういうのが、</p>
<h2 id="嘘ごまかし">嘘ごまかし</h2>
<p>だというんだ。</p>
<blockquote>
<p>?OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。</p>
</blockquote>
<p>へえ、つまり、実用的なアプリを書くには、<strong>OCamlでは関数型言語としては役不足であり適切ではない、不適切である</strong>ことをここに来て認めるんだ?</p>
<p>これ、こちらが最初からずーーっと主張していたことだけど? <br>
@nonstarter は</p>
<h2 id="追記20150530デスクトップアプリケーション-1">追記(2015/05/30):デスクトップアプリケーション??</h2>
<p>みたいな、「状態渡し」で書ける、FRPがなんら必要でない、という趣旨には充分だ、と宣い、 <br>
あたかもこちらが間違った主張をしているように「見せかけた」。</p>
<p>君はその頃から、</p>
<blockquote>
<p>?OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。</p>
</blockquote>
<p>という知見をもち、発言の訂正を促したのかい?</p>
<p>君がそのブログで書いたのは、@nonstarterの主張を擁護すべくOCamlによる関数型「状態渡し」のお絵かきアプリだ。</p>
<blockquote>
<p>以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。</p>
</blockquote>
<p>おいおい、冗談だろ?(苦笑 <br>
じゃあいったい何が、OCamlをもって、関数型で実用に足るGUIアプリの実装として適切で正常なんだ??</p>
<p>はい、その言い訳が続く</p>
<blockquote>
<p>書けないとか言うから反例として書いただけ。</p>
</blockquote>
<p>「反例」ってあのな。@nonstarterの「趣旨」は、</p>
<h3 id="もちろんocamlであれhaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません-1">もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。</h3>
<h3 id="純粋な関数プログラミングでguiアプリケーションを作成するのにfrpがなんら必要でないという趣旨には充分です-1">純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。</h3>
<p>だろ?これ誰が読んでも、「ああそうか、OCamlで状態渡しでなんでも書けるんだ」って思うだろう。このとき誰が</p>
<blockquote>
<p>以前の「状態渡し」のほうがOCaml上のGUIアプリの実装としては異常。</p>
</blockquote>
<p>なんてことを思うんだい?「書けないとか言うから反例として書いただけ」?嘘こけ。総体として、とにかく、@nonstarterの援護射撃をして、岡部が間違っているという「印象」を拡散できればそれでよかったんだろ?そういうのが、悪質で、嘘ごまかしだっていうんだ。</p>
<blockquote>
<p>OCamlは非純粋関数型なので、普通は副作用(破壊的代入を含む)を使う。FRPを含め、純粋関数型のGUIプログラミングがしたかったらHaskellのライブラリなりElmなり、それ用の適切な道具を使えば良い。</p>
</blockquote>
<p>うん、つまりOCamlで、関数型のGUIプログラミングをするには、不適切であると。だからさっさと認めろよな?</p>
<h2 id="関数型言語に関するfaq形式の一般的説明-qiita"><a href="http://qiita.com/esumii/items/ec589d138e72e22ea97e">「関数型言語」に関するFAQ形式の一般的説明 - Qiita</a></h2>
<p>住井@東北大の例のFAQにもこう書いてある。</p>
<h3 id="それだと入出力や状態stateすら表せないのでは">それだと入出力や状態(state)すら表せないのでは?</h3>
<blockquote>
<p>いいえ、純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。非常に簡単に言うと、例えばhello(x) = “Hello, ” + x + “!”みたいな関数で(これも文法は適当です)、文字列hogehogeを入力するとHello, hogehoge!と出力する、みたいなプログラムを書くことができます。 <br>
同様に、状態(の変化)についても、古い状態を引数として受け取り、新しい状態を戻り値として返す関数により表すことができます。</p>
</blockquote>
<p>この人物はOCamlのプログラマーであるが、関数型のおすすめの本としての各種教科書には、そのまさに、「普通は副作用(破壊的代入を含む)を使う」デスクトップアプリの例ばかり書かれていた。だから、おかしいだろう?といえば、この@nonstarterの状態渡しバンザイ、FRP必要なしネガキャンが不当に巻き起こされた。</p>
<p>「岡部のいうことがまちがっていた」という印象のみを拡散することにやっきになり、集団的に「お絵かきアプリが関数型で書けない」「破壊的代入だ」だのそういうことばかり喧伝していた。君らは嘘つきなんだよ。 <br>
誰が割りを食う?読者だろう?真面目に勉強したい初学者たちだろう?恥をしれよ。デマ集団。</p>
<p>だから、そういう嘘誤魔化しをやめろ、と。わからないですかね?自覚あるでしょ? <br>
ここでの命題は、極めてシンプルで明瞭で、それはただひとつ。</p>
<h2 id="関数型プログラミングocamlの状態渡しは実用的アプリのコードに耐えうるか">関数型プログラミング(OCaml)の「状態渡し」は実用的アプリのコードに耐えうるか?</h2>
<p>それだけ。そして前回のお題で、</p>
<p>状態渡し X <br>
であるということは、 <br>
さっそくもう、この程度の複雑さのGUIアプリについて、</p>
<h3 id="状態渡しでは書けなかった">「状態渡し」では書けなかった</h3>
<p>ということでよろしいですね?</p>
<p>逆に言うと、こちらががわざわざ手間をかけて、こういう連中の嘘、ごまかしについて <br>
指摘してやらないと、そのまま「逃げ切る」つもりでいるわけです。</p>
<p>つまり、大局的な構図としては、</p>
<p>1 私、岡部が、この一連の国内の自称関数型コミュニティの連中による嘘、ごまかしを指摘する。 <br>
2 それが、事実だと、薄々感づいてるjが、嘘、ごまかしの上塗りをして、あたかも岡部が間違っているような印象操作をする <br>
3 私がアホらしくなって、放棄するのを待つ</p>
<p>こんなところでしょう。 <br>
実際に <br>
3の私がアホらしくなって、放棄すれば、連中の逃げ切り勝ちです。つまり嘘、ごまかしを拡散したまま、読者に嘘ごまかしを信用させ、正しい批判を加えた岡部が間違っていると思わせ、自分たちの嘘、ごまかしが正しいと信じさせる。 </p>
<blockquote>
<p>自分から要求した「お絵かき」の「トイプログラム」すら1年もかかって自称FRP(実際にはFunctionalですらない命令型プログラム。</p>
</blockquote>
<p>「自分から要求した」とか、1年もかかって、とかいう要素は、上記の、この悪質な人物が、単に嘘誤魔化しを延々と続けてきたという上記の話なのでおわり。</p>
<p>次に、</p>
<blockquote>
<p>自称FRP(実際にはFunctionalですらない命令型プログラム。哲学とか時刻とか理屈をこねたり過去の値を保存したところで、ユーザから見て命令型の非単一代入であることに何ら変わりはない。</p>
</blockquote>
<p>これだけど、もう馬鹿に何度同じ話をしても同じだと痛感。</p>
<p>こちらとしては、もう、これ</p>
<h1 id="timeengineの-xt-xt-1-について"><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-xt-xt-1.html">TimeEngineの __x.t = __x.t + 1; について</a></h1>
<p>以上、噛み砕いて説明するのは、多分不可能だし、 <br>
「あーあー都合の悪いこと聞こえない」 <br>
と理屈もへったくれもなく、よりによってFRPについて「時刻とか理屈をこねたり」などと平気でいうオバカさん相手にはどうしようもないです。</p>
<blockquote>
<p>ちなみにその保存のしかただとJS処理系がガベコレできないのでメモリリークします。)でしか書けないのに、また他人に実装を要求する正当性は1ミリもない。</p>
</blockquote>
<p>こういう悪質な相手の「ちなみに」は、自分が上記のような理屈もへったくれもない、デタラメをまきちらして、説得力のない文章を書いてる直後に出るのが常套手段(この人物に限らないパターン)なので、最大限の注意が必要。まず、本論と関係ない、次に、主張の信ぴょう性がない。</p>
<p>「メモリリークします」ってあほかと。FRPは、たとえば、こういうTODOリストなど、全部のデータが必要な場合、そんな、FRP値が処理系によって知らない間にガベコレされたら、それは単にデータの損失なの。わかるかな?わからないかな?</p>
<p>最後に、</p>
<blockquote>
<p>また他人に実装を要求する正当性は1ミリもない。</p>
</blockquote>
<p>別に君に実装を要求した覚えはない。自分で、</p>
<blockquote>
<blockquote>
<p>ご指名ではないけど久々に書いてみました。OCamlもJSも詳しくないので細かいことは知らない。(追記:入力消すの忘れてたので修正。)</p>
</blockquote>
</blockquote>
<p>ひまだから、やってやったみたいなポーズでしゃしゃりでてきたんだろう?</p>
<p>しかも、すべて、例題が単純であることをよいことに、 <br>
できないことをあたかも簡単にできるように見せかける誤魔化しという連中の一貫した悪質な手口。</p>
<h2 id="状態渡しでは書けなかった-1">「状態渡し」では書けなかった</h2>
<p>今回は、きっちり宣言したとおり、「状態渡し」で書いたら複雑になるように、問題設定していたが、「状態渡し」でも書けるという問題の単純さを悪用し、<strong>「状態渡し」で書いたら複雑になる、と痛感</strong>したがゆえに、ルール違反の「状態渡し」なしので書いて、しかも、それが例外的、異常な実装だと言い訳し、前回まで状態渡しで、nonstarterを擁護していたのは、「反例」だから、とまた言い訳する。</p>
<blockquote>
<p>また他人に実装を要求する正当性は1ミリもない。</p>
</blockquote>
<p>というのは、上記のような自己都合で「状態渡し」なしのルール違反をした <br>
「状態渡し」のコードが書けなかったことを後ろめたいと自覚しているから、最後っ屁で、 <br>
ルール設定にいちゃもんつけてるんだね。</p>
<p>いやあのね、こっちが、嘘つけよ!と批判していて、 <br>
「OCaml」で、関数型で、実用的なアプリを、状態渡しで、FRPなしで、書ける!とさんざん反論していたのは、こちらでなく君らだから。</p>
<p>今回のTODOリスト、こんな、内部的にリストの状態を保持しない、画面に書きっぱなしの代物なんぞ、 <br>
内容をろくに管理も保存もなにもできないのは自明で、実用的ではない。</p>
<p>こんなことは、大前提として、つまり、アプリが状態を扱うという意味を大前提として「状態渡し」で書け、と条件付けたのに、 <br>
「状態」を扱えば煩雑になるとわかりきっているからそこから逃げて、誤魔化してこう書いたわけです。</p>
<blockquote>
<p>今回は「状態渡し」すら要らないので「お絵かき」より簡単。何をさせたかったのかまったくわからない。</p>
</blockquote>
<p>盗っ人猛々しいですね(苦笑</p>
<h2 id="関数型プログラミングocamlの状態渡しは実用的アプリの実装に耐えうるか-2">関数型プログラミング(OCaml)の「状態渡し」は実用的アプリの実装に耐えうるか?</h2>
<p>「状態渡し」で書けんのか? と問いただしている。 <br>
君らの誤魔化しを一個一個潰すことをしたい。</p>
<p>わかってるくせに、「状態渡し」で書けない卑怯な言い訳をして、あたかもこちらのせいにしているようなので、より「状態渡し」で書けるのか?というのを明確にするように、この延長で、 <br>
もう一段、例題のハードルをあげてやることにしましょう。</p>
<p>再度確認ですか、今回、上記のような大前提をもって、 <br>
「状態渡し」をもって書けという条件でしたので、 <br>
この人物は、この条件を満たせなかった、つまり課題をクリアできなかった、ということを確認しておきます。</p>
<p>そしてそれを踏まえながら、新たにこういう誤魔化しさえ通用しない、 <br>
つまり、アプリが単純であることをいいことに、 <br>
必要な要件を潰して、表面上だけは動作しているように見せかける、 <br>
という誤魔化しができないように、ハードル一段引き上げ、 <br>
状態を扱うしかないように、アプリを少し複雑にしてみます。 <br>
状態渡しでは煩雑にしかかけないようにハードルを設定する。</p>
<p>あたかもスケールするように喧伝している誤魔化しがある。では問題を複雑にしていって <br>
その誤魔化しの延長線上で、そのアプローチが破綻しないか? <br>
スケールするのか?</p>
<p>そういうことを確認しているにすぎない。</p>
<p>ちょっと複雑になったら通用しない、破綻する、ならそんなもんは「机上の空論だ」</p>
<p>そういうことを言っているにすぎない。</p>
<p>私が気に入らないのは、 <br>
この一連の国内の自称関数型コミュニティの連中による、悪質な手口 <br>
つまり、 <br>
本質とずらす、議論のすり替え、ひとりが誤魔化す、 <br>
あとの連中はその嘘、誤魔化しに気づいているが沈黙、そういう手口。</p>
<p>その嘘、誤魔化しによって、あたかも、まるで、私、岡部のほうがいい加減なことを主張している、 <br>
と初学者をはじめとする真摯にプログラミングを学びたいと考えている衆目、読者にむけて印象づけようとする。</p>
<p>こちらが黙っていると、「真理」について割を食ってる広い読者の犠牲のもとに、自分たちがただしいと嘘をついたまま、有耶無耶にしようとする。</p>
<p>しかし、こうやっていろいろ突っついてやると、そのうち必ずこの誤魔化している連中の馬脚が現れます。</p>
<p>ハードル上げによって、今回君、君らがごまかしたように、 <br>
「状態渡しで書け」ときちんと明示してるのに <br>
「状態渡しなしでも書けるから、状態渡しで書く必要がない」という論理をすり替えを無効化する。</p>
<p>そんな誤魔化しは許容されるはずもない。あたりまえだろう? <br>
「状態渡しでは書けない」あるいは「状態渡しで書くことは困難で煩雑である」 <br>
という論点に、改めて引き戻すことになる。</p>
<p>なんで、こっちがこんな明確化をわざわざせんといかんのか? <br>
それは君、君らが、誤魔化しをしているからだろう?ということです。 <br>
すぐバレるような嘘、誤魔化しをすんな、ってことです。 <br>
それをわざわざこっちが訂正しないと、その嘘、ごまかししたまま逃げ切るつもりだろう? <br>
その嘘、誤魔化しで割を食うのは誰だい?君らの嘘、ごまかしを真に受けて信じてしまった学習者だろう? <br>
ってことです。</p>
<p>ああもちろん</p>
<p>「指名されてないですが」などと、出てきた分際で、 <br>
もうどうしようもない、とおもったら、投げ出して逃げて結構ですよ? <br>
そのための「匿名ブログ」でしょうからね?恥のかき捨て結構じゃないですか。 <br>
嘘誤魔化し全開の自覚アリアリで中傷する相手は実名 <br>
自分は責任負わずにすむ匿名。いつもの悪質な手口です。 <br>
一体、誰が 、その学習者を欺く、嘘誤魔化しまみれで、人を中傷することだけが唯一の存在価値の <br>
悪質な捨てブログ書いてるんでしょうね?</p>
<p>毎度悪質ですね。</p>
<h1 id="課題">課題</h1>
<h2 id="前回書いたアプリtodoリストをそのまま拡張し複数のリストを扱えるようにせよ">前回書いたアプリ:ToDoリストをそのまま拡張し、複数のリストを扱えるようにせよ</h2>
<p>以下、こちらですでにJavaScript+TimeEngine+Reactをもって実装したライブデモ <br>
TimeEngine公式サイト <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
のDemo11 <br>
を提示しながら説明。</p>
<p>以下は動作中のスクリーンショット画像</p>
<h3 id="①-起動させた直後前回の仕様とほぼ同じであるがこれはデフォルトでlist1になっている">① 起動させた直後、前回の仕様とほぼ同じであるが、これはデフォルトで、<strong>[List#1]</strong>になっている。</h3>
<p><img src="https://raw.githubusercontent.com/TimeEngine/timeengine.github.io/master/images/todo1.png" alt="enter image description here" title=""></p>
<h3 id="②-newlistボタンをクリックすることで次のlist2を新規に作成できるこのように新規に作成されたリストは別のリストとは独立しながら同様の動作をするたとえばnewtodonボタンに表示されているnはそれぞれのリスト固有のカウント値である">② <strong>[NewList]</strong>ボタンをクリックすることで、次の<strong>[List#2]</strong>を新規に作成できる。このように新規に作成されたリストは、別のリストとは独立しながら同様の動作をする。たとえば、[NewToDo#N]ボタンに表示されているNはそれぞれのリスト固有のカウント値である。</h3>
<p><img src="https://raw.githubusercontent.com/TimeEngine/timeengine.github.io/master/images/todo2.png" alt="enter image description here" title=""></p>
<h3 id="③-すでに作成しているtodoリストについては上部のlist1やlist2ボタンをクリックすることで切り替え表示ができる">③ すでに作成しているToDoリストについては上部の<strong>[List#1]</strong>や<strong>[List#2]</strong>ボタンをクリックすることで切り替え表示ができる。</h3>
<p><img src="https://raw.githubusercontent.com/TimeEngine/timeengine.github.io/master/images/todo3.png" alt="enter image description here" title=""></p>
<h2 id="ソースコードindexjsx">ソースコード(index.jsx)</h2>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">const</span> TodoElement = () => {
<span class="hljs-keyword">const</span> ClockElement = __Element(__.intervalSeq(Immutable.Range(), <span class="hljs-number">100</span>)
.__(() => (<span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span>{moment().format('MMMM Do YYYY, h:mm:ss a')}<span class="hljs-tag"></<span class="hljs-title">div</span>></span>)));
const __fdList = __().__((val) => (__.log.t = val));
const __lists = __(true).__((__list) => (__fdList.t = __lists.length));
const ListofListElement = __Element(__([__lists])
.__(() => ((__lists).map((list, i) => (
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {() =></span> (__.log.t = __fdList.t = i)}>{'List#' + (i + 1)}<span class="hljs-tag"></<span class="hljs-title">button</span>></span>)))));
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) => (<span class="hljs-tag"><<span class="hljs-title">div</span>></span>
<span class="hljs-tag"><<span class="hljs-title">h4</span>></span>{'List#' + (__fdList.t + 1)}
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {<span class="hljs-attribute">onClickNL</span>}></span>{'NewList'}<span class="hljs-tag"></<span class="hljs-title">button</span>></span><span class="hljs-tag"></<span class="hljs-title">h4</span>></span>
{__lists[__fdList.t].map((item) => (<span class="hljs-tag"><<span class="hljs-title">li</span>></span>{item}<span class="hljs-tag"></<span class="hljs-title">li</span>></span>))}
<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">{value}</span> <span class="hljs-attribute">onChange</span>=<span class="hljs-value">{onChange}</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {<span class="hljs-attribute">onClick</span>}></span>{'NewToDo#' + (__lists[__fdList.t].length + 1)}<span class="hljs-tag"></<span class="hljs-title">button</span>></span><span class="hljs-tag"></<span class="hljs-title">div</span>></span>));
__.log.__(() => (__value.t = ""));
return __Element(__seqEl);
};
__lists.t = __(true); //new items-list
const __delay = __.intervalSeq(Immutable.Seq.of("started!"), 1000)
.__(() => (__.log.t = "showInput"));
return (<span class="hljs-tag"><<span class="hljs-title">div</span>></span><span class="hljs-tag"><<span class="hljs-title">h2</span>></span>ToDo<span class="hljs-tag"></<span class="hljs-title">h2</span>></span>{ClockElement}<span class="hljs-tag"><<span class="hljs-title">p</span>/></span>
{ListofListElement}<span class="hljs-tag"><<span class="hljs-title">p</span>/></span>{InputElement()}<span class="hljs-tag"></<span class="hljs-title">div</span>></span>);
};
const mount = ReactDOM.render(TodoElement(), document.getElementById('todo'));</span></code></pre>
<p>このコードは、前回示したコードに、要件が複雑になった差分だけ順当に、コードを積みましたにすぎません。GUIはFRPとReactで接続して書かれており、単に宣言型のコードが増えただけです。 <br>
命令型って言いたいだけの頭のおかしい指摘はあてはまりません。 <br>
こういうのをスケールする設計であると言います。</p>
<p>さて、例の人、人たちは、「あたかもなんでもできるような」今回の <br>
「状態渡しすら必要ない」とか言ってたコードの延長でどんなコードを書いてくれるんでしょうか? <br>
そろそろコードが、これまであなたがたが広い真摯な読者を欺くような形でやってきた、 <br>
あらゆる悪質な嘘誤魔化しが効かないレベルに突入してきました。 <br>
OCamlで、スケールする「関数型」の「状態渡し」のGUIアプリのコードを書いてください。</p>
<p>FRP必要ない、とかぶちあげてた@nonstarterを「擁護」あるいは結託してたんだから、FRP使うとかもちろんなしで。 <br>
純粋関数型の「状態渡し」で実用的なアプリを「なんら困難もなく」書けるんでしょ? <br>
FRPと複雑性は変わらんのでしたよね?じゃあ、当方のFRPのコードと同等以下の複雑性で、 <br>
関数型「状態渡し」をもって書けるはずです。 <br>
もっともらい適当な嘘ハッタリじゃあなければね。 <br>
さあやって見せてください。どうぞ。</p>
<p>なお、念の為ですが、「状態渡し」での素の実装が見たいわけなので、なんかGUIフレームワークの「タブ」切り替えライブラリみたいなもんを使って、また誤魔化さないでください。そういう議論ではない、くらいもうわかっているでしょう。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-55950261915731395852016-05-20T18:56:00.001+09:002016-05-20T18:58:03.884+09:00TimeEngineの __x.t = __x.t + 1; について<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/c.html">C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い</a></p>
<p>この辺の続きとなります。</p>
<p>特に、前回のエントリ</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine.html">TImeEngineは命令型でも破壊的代入でもない</a></p>
<p>の続きです。</p>
<p>前回、</p>
<hr>
<p>const <strong>items = </strong>(true); <br>
という、時間軸上の世界線の「定数」 const <br>
であるのならば、 <br>
「破壊的代入」なんておこりうるはずもない。 <br>
ということです。</p>
<p>「破壊的代入」がなされている、と批判した時点で、 <br>
その人物は、 <br>
FRPのValue ”OverTime” がイミュータブルな定数である <br>
という意味なんて、本当はこれっぽちも理解していない、ということが白日の下にさらされます。 <br>
つまり、中傷してる連中は、FRPの哲学的理解が足りないからそういうことが言えるのだ、ということですね。</p>
<hr>
<p>と説明しました。</p>
<p>それでもなお「どうしても理解できない人」はいます。まあ仕方ないです。 <br>
仕方ないですが、それはその人物の知的素養の問題であって、私の問題でもTimeEngineというFRPライブラリの問題でもありません。</p>
<p>執拗に繰り返されるのが、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a> <br>
で、すでに説明したこれです。</p>
<p>(再掲)</p>
<hr>
<p><a href="http://anond.hatelabo.jp/20160516192742">http://anond.hatelabo.jp/20160516192742</a></p>
<blockquote>
<p>実際、timeengine.js を読み込んだ状態で、以下のようになります。</p>
</blockquote>
<pre class="prettyprint"><code class=" hljs avrasm">> const __x = __()<span class="hljs-comment">;</span>
undefined
> __x<span class="hljs-preprocessor">.t</span> = <span class="hljs-number">1</span><span class="hljs-comment">;</span>
<span class="hljs-number">1</span>
> __x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span>
<span class="hljs-number">2</span>
> __x<span class="hljs-preprocessor">.t</span><span class="hljs-comment">;</span>
<span class="hljs-number">2</span></code></pre>
<blockquote>
<p>なお私を他の誰かと決めつけるのは、その方たちにご迷惑ですのでおやめください。 <br>
……と言っても聞き入れていただけるとは思えないので、私ももうこれ以上の書き込みはやめます。 <br>
できるだけ丁寧に技術的な誤りだけを指摘したつもりですが、やはり誹謗中傷しか返ってこないようで残念です。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160517094425">http://anond.hatelabo.jp/20160517094425</a></p>
<blockquote>
<p>kenokabe氏のコードでもマウスが動くたびに同じ__drawFrom.tへの破壊的代入が行われるんですがそれは</p>
</blockquote>
<p>などと書いているのですが、いま説明しているように、</p>
<pre class="prettyprint"><code class=" hljs vbscript"><span class="hljs-built_in">Date</span>.<span class="hljs-built_in">now</span> = <span class="hljs-built_in">Date</span>.<span class="hljs-built_in">now</span> + <span class="hljs-number">1</span></code></pre>
<p>というステートメントが、概念的な意味を成さないように、 <br>
=の両辺が等しいという、関数型プログラミングのパラダイムにおいては、</p>
<pre class="prettyprint"><code class=" hljs avrasm">__x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span></code></pre>
<p>というFRPライブラリの使用は概念的な意味を成しません。 <br>
なんでこういうことをするのか?というと、なんか悪意があるか、 <br>
それとも、FRPが「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
ということを全く理解していないから、こういう文句のつけかた、それこそ誹謗中傷をして平気なのでしょう。</p>
<p>あえてこの住井らしき人物がわざとやらかした「破壊的代入」という命令型パラダイムにおいて、考えてみると、この人物の意図によると、 <br>
「右辺の現在値」を「左辺の現在値」に代入するという命令型の時系列的意図しかありえないでしょうから、</p>
<p>右辺の現在値に1を加えて、改めて、左辺の現在地とする</p>
<p>ということです、つまり、左辺、右辺の現在時間が異なる、FRPライブラリにおいては、 <br>
<code>.t</code>によって表現される時刻による「時間軸上の値」は異なって当然であるということになります。</p>
<p>よって、</p>
<pre class="prettyprint"><code class=" hljs avrasm">__x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span></code></pre>
<p>というのは、 <br>
右辺を評価した現在時間における <br>
__x上のある値に1を加えたものを <br>
次の瞬間以降の <br>
__x上の値として更新する、という意味合いになります。</p>
<p>もちろん、これは、=の左右で値が異なるという命令型ステップの解釈であり、 <br>
そういう命令形パラダイムを大前提とした記法においては、TimeEngineの振る舞いはこう解釈される、 <br>
ということにすぎませんし、そのような記法を禁じるようなSanityCheckを実装しているわけではありません、 <br>
ご自由にどうぞ、といったところでしょうか。</p>
<hr>
<p>(再掲ここまで)</p>
<p>なんかよくわかりませんが、そんなに難しいこと言っていますかね?</p>
<p>同じことを言うと思いますが、また同じことを言いたいと思います。</p>
<p>まず、第一に、</p>
<p><code>__x</code> というのが、時間軸の世界線の無限リストで、 <br>
イミュータブルな定数である、</p>
<p><code>__x.t</code> というのが、<code>now</code> などで表される、それ以外では表しようがない「現在時刻」における、 <br>
<code>__x</code>上の分布値である、</p>
<p>という意味を理解しておれば、これらはすべてイミュータブルな定数なので、 <br>
「破壊的代入」など原理的に起こりえない、と自然に理解できる、ということです。</p>
<p>理解できないのならば、それはその人の哲学的側面における知性の問題であり、 <br>
そもそも時間にまつわる、関数型プログラミング、FRPのことなどははなっから諦めたほうが良い、ということです。まず、身の程をわきまえて、こちらを中傷することなどもっての他です。</p>
<p>次に、</p>
<p>関数型プログラミングとは、宣言型プログラミングなので、 <br>
根本的に、式を用意したならば、その両辺が等しい、という数学的宣言をすることと同じです。</p>
<p><code>__x.t = __x.t + 1;</code></p>
<p>という、方程式の左右で値が異なる「論理破綻」した記述をするのは、 <br>
そういう宣言を記述した、コーダーその人の責任です。 <br>
TimeEngineでは、そんなところまでSanityCheckするつもりもないですから、どうぞご勝手に、ということですが、こう書けるから、TimeEngineは命令形で、破壊的代入だ!</p>
<p>つまり、</p>
<blockquote>
<p>これは岡部健氏が著書で「論理破綻」と批判していた、命令型言語の破壊的代入そのものです。 <br>
できるだけ丁寧に技術的な誤りだけを指摘したつもりですが、やはり誹謗中傷しか返ってこないようで残念です。</p>
</blockquote>
<p>とか、表明するに至っては「頭がおかしい」としか思えません。</p>
<p>関数型、宣言型のパラダイムにおいて、= の両辺がことなる宣言をわざわざして、 <br>
破壊的代入を試みたたのは、この人であるし、FRPライブラリの領分でもなんでもないわけです。</p>
<p>「思い込みの激しい」人間に説明をするには、困難を極めるのですが、できるだけこの人物の意図を想像しながら、こちらもやってあげましょう。</p>
<p>まず、この人物の意図としては、</p>
<h2 id="命令型プログラミングをやりたい">命令型プログラミングをやりたい!</h2>
<p>というのがあるのでしょう。</p>
<p>繰り返しますが、</p>
<p><code>__x.t = __x.t + 1;</code></p>
<p>ってのは、両辺の値が明らかに異なっているので、論理破綻しており、 <br>
=の両辺の値が等しいと宣言することで、コーディングする関数型、宣言型のパラダイムからは逸脱しています。</p>
<p>次に、</p>
<h2 id="破壊的代入をしたい">破壊的代入をしたい!</h2>
<p>という強い意図が感じられます。</p>
<p>もちろん、=の両辺の値が等しいというパラダイムにおいては、そういう行為は意味を成さないし、そういうスタイルで書いてはいけないのですが、JavaScriptのネイティブな仕様としては、破壊的代入も自由にできるので、やろうと思えば可能です。もちろん、関数型プログラミングを志向するならやるべきではないのは自明です。でもこの人物は、破壊的代入をしたい!と駄々をこねているわけです。自由にさせておきましょう。 <br>
でもそうしたいというのは、FRPライブラリの責任でも設計者の私の責任でもなく、彼自身の強い希望なのです。私のせいだ、みたいなことは言わないでください。というか言われてますが、あほらしいですが。</p>
<p>JavaScriptのネイティブな仕様として、</p>
<p><code>__x.t = __x.t + 1;</code></p>
<p>と書いた場合、</p>
<p>右辺 __x.t + 1 <br>
が先に評価され、 <br>
左辺 __x.t </p>
<p>に代入されます。</p>
<p>この人物の強い意図として、</p>
<ul>
<li>命令型プログラミングをして</li>
<li>破壊的代入をして</li>
</ul>
<p>と、__x の挙動に興味がある、ということみたいなので、</p>
<pre class="prettyprint"><code class=" hljs avrasm"> const __x = __(true)<span class="hljs-comment">;</span>
__x<span class="hljs-preprocessor">.t</span> = <span class="hljs-number">99</span><span class="hljs-comment">;</span>
__x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span></code></pre>
<p>こんなコードを書いてみましょう。</p>
<p>FRP値のフラグを<code>true</code>とするのは、 <br>
この人物が、「破壊的代入」に興味があるからです。 <br>
つまり、 <br>
命令型のフローのあるコードを書いて、</p>
<p>破壊的代入前 <br>
破壊的代入後</p>
<p>という、 <br>
コードの上下 <br>
コードの左右 (方程式の左右)</p>
<p>の時間経過みたいなことを前提にしてコードを書きたがっているからです。</p>
<p>関数型、宣言型のスタイルにおいては、このような、 <br>
コードの上下、左右で、時間が経過するような概念は用いませんが、 <br>
彼がそうしたいと熱望しているわけです。好きにさせてあげましょう。</p>
<p>結果はどうなるか?というと、すでに書いています。</p>
<p>const <strong>x = </strong>(true); <br>
という、時間軸上の世界線の「定数」 const <br>
であるのならば、 <br>
「破壊的代入」なんておこりうるはずもない。 <br>
ということです。</p>
<pre class="prettyprint"><code class=" hljs avrasm"> const __x = __(true)<span class="hljs-comment">;</span>
__x<span class="hljs-preprocessor">.t</span> = <span class="hljs-number">99</span><span class="hljs-comment">;</span>
__x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span>
__<span class="hljs-preprocessor">.log</span><span class="hljs-preprocessor">.t</span> = __x[<span class="hljs-number">0</span>]<span class="hljs-comment">; //99</span>
__<span class="hljs-preprocessor">.log</span><span class="hljs-preprocessor">.t</span> = __x[<span class="hljs-number">1</span>]<span class="hljs-comment">; //100</span></code></pre>
<p>となります。</p>
<p>イミュータブルな時間軸上の世界線の「定数」 <br>
__x には、</p>
<p>その命令型のコードフロー時間における、 <br>
それぞれの分布値 <br>
__x.t <br>
が分布しています。</p>
<p>もうちょっと正確にいうと、 <br>
別の、__x.t に切り替わるまで、 <br>
直近の__x.t が継続して分布しています。</p>
<p>式の右辺を先に評価して、というこのコーダーの意図で、 <br>
その時点の、__x.t が読み出される。 <br>
一個上の行で評価された時間での、 __x.t = 99;というのがありますから、 <br>
それが得られています。それに1を加算して、 <br>
今度は、左辺の時間の、__x.t に値を代入します。</p>
<p>「破壊的代入」というのは、そういう行為です。 <br>
前あった、右辺の値を、 <br>
新たに、左辺の値を上書き破壊するように代入する。 <br>
だったら、「時間」が違うわけです。BeforeAfter 破壊前、破壊後。</p>
<p>当然、TimeEngineはその意図のとおり振る舞いますから、 <br>
結果、格納された集合値の__xの全体としては、 <br>
破壊前、破壊後と、この人物が、意図したであろう、2つの異なる時間の値が存在するはずです。</p>
<pre class="prettyprint"><code class=" hljs rust"> <span class="hljs-number">__</span>.<span class="hljs-keyword">log</span>.t = <span class="hljs-number">__</span>x[<span class="hljs-number">0</span>]; <span class="hljs-comment">//99</span>
<span class="hljs-number">__</span>.<span class="hljs-keyword">log</span>.t = <span class="hljs-number">__</span>x[<span class="hljs-number">1</span>]; <span class="hljs-comment">//100</span></code></pre>
<p>意図したとおりになってるじゃないですか?なんか問題あります? <br>
どこにも論理の破綻はない。</p>
<p>まあ、命令型であったとしても、かように、 <br>
= っていうのが、関数型、宣言型とは意味合いが異なる、 <br>
コードの上下、 <br>
式の両辺で時間が異なる、という自覚があればこのように整合的にコーディングすることは可能です。</p>
<p>まあしつこい中傷行為は、いい加減にしてほしいです。</p>
<p>おわり。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-829004462498697582016-05-20T13:31:00.001+09:002016-05-20T14:00:59.052+09:00TImeEngineは命令型でも破壊的代入でもない<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/c.html">C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い</a></p>
<p>この辺の続きとなります。</p>
<p>まず「課題」についてですが、いまのところ、私が知る限り、まだどこにもされていません。 <br>
念の為ですが、Twitterやら幼稚な念仏唱えているだけと一部馬鹿にされている病人が誹謗中傷連ねたいだけの2chスレの書き込みなんかいちいちチェックしてるわけもないので、万一そんなとこに書きなぐっても見てるわけもありません。</p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a> <br>
の「本来のFRP」による「お絵かきアプリ」っていったいどこにあるの?という課題については、 <br>
<a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a> <br>
と説明したとおりです。単なるごまかしです。</p>
<p><a href="http://anond.hatelabo.jp/20160520054338">http://anond.hatelabo.jp/20160520054338</a></p>
<blockquote>
<p><a href="http://anond.hatelabo.jp/20160517023637">http://anond.hatelabo.jp/20160517023637</a> <br>
>ライブラリユーザは現在時刻から状態への写像fを <br>
>参照透明な関数なりストリームなりで記述して、 <br>
>それを処理系が実際のシステム時刻t=0,1,2,…に適用して <br>
>状態f(0),f(1),f(2),…を得る <br>
はっきりと「処理系が」って書いてあるのに、K氏は本気で <br>
ユーザプログラムにf(0),f(1),f(2),…みたいなコードがないのが <br>
「反論」になると思ったのだろうか…… <br>
まさか本当に「処理系」という言葉がわからなかった??</p>
</blockquote>
<p>もちろん、わかっていますよ?それ込みです。</p>
<p>だから、その処理系のライブラリのソースコードのいったいどこに、 <br>
「実際のシステム時刻t=0,1,2,…」ってのをとって、 <br>
状態f(t)にしているところがあるんですか?</p>
<p>「これ以上は説明も回答もしない。」とか書いたのは、そこを有耶無耶にして誤魔化したいからでしょ?</p>
<p>タイマーイベント、あるいはあらゆるイベントの時点での、 <br>
ある値とるなら、それは単に普通のイベント駆動であって、 <br>
こちらが論じていた「現在時刻」はそれ以外のシンボルでは表現できない、という議論とも関係ないし、 <br>
FRPとも関係ないですよね?</p>
<p>ただ、「実際のシステム時刻t=0,1,2,…」という、それっぽい口ぶりで真似したかっただけですか?</p>
<p>「実際のシステム時刻t=0,1,2,…」という、時間軸のストリームの値は、 <br>
ライブラリ処理系ではなく、プログラマーレベルの目線で、 <br>
「時間を抽象化したファーストクラスな値」とするのがFRPで意味がでてくるのであって、 <br>
裏でイベントドリブンで、処理系「実際のシステム時刻t=0,1,2,…」とか、あんた何が言いたいの? <br>
誤魔化したいだけだよね?っていうことです。 <br>
そういう誤魔化しばかり書きなぐるのはもういい加減にしろ、っていうことです。</p>
<p>次に、</p>
<p>直近の、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p>ToDoの関数型GUIアプリについてもいまのところ無回答です。</p>
<p>前回、</p>
<blockquote>
<p>私のFRPライブラリは参照不透明?で、命令型の破壊的代入っていう中傷について、またしばらく後にエントリします。あたらしい課題つきで。</p>
</blockquote>
<p>とあたらしい課題を示唆したのですが、連中が出来もしないことを机上の空論を並べ立てていた、 <br>
という分水嶺となる良い課題だ、という意見をもらったこととや、 <br>
あたらしい課題を与えて、ペンディングされてる課題が未解決なのに、 <br>
つけ入るスキを与えるべきではない、議論が発散してしまい、 <br>
また誤魔化される余地が生まれる危険性がある、 <br>
という意見も頂いたので、当面上記の、ToDoリストアプリにもとづいて話を進めていきます。</p>
<p>さて、「命令型の破壊的代入っていう中傷」についてですが、前回いろいろいろ引用したのに加えて、 <br>
直近の中傷はこういう感じです。</p>
<p><a href="http://anond.hatelabo.jp/20160519135844">http://anond.hatelabo.jp/20160519135844</a></p>
<blockquote>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/ocamlgui-esumii-camloebanonstarter.html">http://kenokabe-techwriting.blogspot.com/2016/05/ocamlgui-esumii-camloebanonstarter.html</a> <br>
の自称関数型コードに出てくる <br>
__value.t = e.target.value <br>
__items.t = __value.t <br>
等々も、kenokabe氏の心の中では「時間軸でインデックスされた何か」なのかもしれないが、 <br>
客観的にはマウスクリック等のたびに同じメンバ変数__value.tや__items.tへの <br>
破壊的代入が何度も実行される命令型プログラムそのもの。 <br>
__valueや__itemsにconstがついていても、__value.tや__item.tはconstではない。</p>
</blockquote>
<p>ここでもういちど、</p>
<blockquote>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/ocamlgui-esumii-camloebanonstarter.html">http://kenokabe-techwriting.blogspot.com/2016/05/ocamlgui-esumii-camloebanonstarter.html</a> <br>
の自称関数型コード</p>
</blockquote>
<p>と中傷されている、 <br>
課題の私が書いたToDoリストアプリのコードを再掲しておきましょう。</p>
<pre class="prettyprint"><code class=" hljs lisp"><span class="hljs-list">(<span class="hljs-list">()</span> => {
'use strict'<span class="hljs-comment">;</span>
const TodoElement = <span class="hljs-list">()</span> => {
const ClockElement = __Element<span class="hljs-list">(<span class="hljs-title">__</span>
.intervalSeq<span class="hljs-list">(<span class="hljs-title">Immutable</span>.Range<span class="hljs-list">()</span>, <span class="hljs-number">100</span>)</span>
.__<span class="hljs-list">(<span class="hljs-list">()</span> => <span class="hljs-list">(<span class="hljs-title"><div></span>{moment<span class="hljs-list">()</span>.format<span class="hljs-list">('MMMM Do YYYY, h<span class="hljs-keyword">:mm</span><span class="hljs-keyword">:ss</span> a')</span>}</div>)</span>)</span>)</span><span class="hljs-comment">;</span>
const __items = __<span class="hljs-list">(<span class="hljs-title">true</span>)</span><span class="hljs-comment">;</span>
const ListElement = __Element<span class="hljs-list">(<span class="hljs-title">__</span><span class="hljs-list">([__items])</span>
.__<span class="hljs-list">(<span class="hljs-list">()</span> => <span class="hljs-list">(<span class="hljs-list">(<span class="hljs-title">__items</span>)</span>.map<span class="hljs-list">(<span class="hljs-list">(<span class="hljs-title">item</span>)</span> => <span class="hljs-list">(<span class="hljs-title"><li></span>{item}</li>)</span>)</span>)</span>)</span>)</span><span class="hljs-comment">;</span>
const InputElement = <span class="hljs-list">()</span> => {
const __value = __<span class="hljs-list">()</span><span class="hljs-comment">;</span>
const onChange = <span class="hljs-list">(<span class="hljs-title">e</span>)</span> => <span class="hljs-list">(<span class="hljs-title">__value</span>.<span class="hljs-literal">t</span> = e.target.value)</span><span class="hljs-comment">;</span>
const onClick = <span class="hljs-list">()</span> => <span class="hljs-list">(<span class="hljs-title">__</span>.log.<span class="hljs-literal">t</span> = __items.<span class="hljs-literal">t</span> = __value.<span class="hljs-literal">t</span>)</span><span class="hljs-comment">;</span>
const __seqEl = __<span class="hljs-list">([__value])</span>
.__<span class="hljs-list">(<span class="hljs-list">(<span class="hljs-title">value</span>)</span> => <span class="hljs-list">(<span class="hljs-title"><div></span>
<input type=<span class="hljs-string">"text"</span> value={value} onChange={onChange}/>
<button onClick = {onClick}>{'NewToDo#' + <span class="hljs-list">(<span class="hljs-title">__items</span>.length + <span class="hljs-number">1</span>)</span>}</button></div>)</span>)</span><span class="hljs-comment">;</span>
const dummy = __.log.__<span class="hljs-list">(<span class="hljs-list">()</span> => <span class="hljs-list">(<span class="hljs-title">__value</span>.<span class="hljs-literal">t</span> = <span class="hljs-string">""</span>)</span>)</span><span class="hljs-comment">;</span>
__.log.<span class="hljs-literal">t</span> = <span class="hljs-string">"started!"</span><span class="hljs-comment">;</span>
return __Element<span class="hljs-list">(<span class="hljs-title">__seqEl</span>)</span><span class="hljs-comment">;</span>
}<span class="hljs-comment">;</span>
return <span class="hljs-list">(<span class="hljs-title"><div><h2>ToDo</h2></span>
{ClockElement}<p/>
{ListElement}
{InputElement<span class="hljs-list">()</span>}</div>)</span><span class="hljs-comment">;</span>
}<span class="hljs-comment">;</span>
const mount = ReactDOM.render<span class="hljs-list">(<span class="hljs-title">TodoElement</span><span class="hljs-list">()</span>, document.getElementById<span class="hljs-list">('todo')</span>)</span><span class="hljs-comment">;</span>
})</span><span class="hljs-list">()</span><span class="hljs-comment">;</span></code></pre>
<p>まずね?<code>const</code>のお話なんですが、 <br>
もう散々繰り返しているとおり、これは <br>
ライブラリユーザのレベル、目線で、まぎれもなく定数です。 <br>
具体的には、時間軸をFRPで抽象化してファーストクラスにした値。 <br>
これも何度も説明しました。</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>っていうのは、 <br>
ミュータブルに見える「リストアイテム」を、 <br>
本来イミュータブルな時間軸において、 <br>
FRPで抽象化してファーストクラスにした値、のことです。</p>
<p>10分前に追加したある「リストアイテム」は、 <br>
イミュータブルな時間軸の世界線上で、その10分前のポイントに分布、 <br>
2分前に追加したある「リストアイテム」は、 <br>
イミュータブルな時間軸の世界線上で、その2分前のポイントに分布。 <br>
未来に追加されるであろう「リストアイテム」でさえ、 <br>
イミュータブルな時間軸の世界線上で、その未来方向のあるポイントに分布。</p>
<p>時間軸は無限リストであり、関数型プログラミングでは、無限があつかえるのと同じ原理で、 <br>
未来方向に広がっている無限リストでもこうやって抽象化できる、ということです。</p>
<p>中傷してる連中は、まずこの <br>
FirstClass Value “Over TIme” という概念をまず理解してんの? <br>
っていう疑念がある。多分できていない。</p>
<p>いずれにせよ、</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>とイミュータブルな定数として宣言してしまいます。</p>
<p>ほんでですね、</p>
<blockquote>
<p>__valueや__itemsにconstがついていても、__value.tや__item.tはconstではない。</p>
</blockquote>
<p>という主張についてなんですが、 <br>
以上のはなしを理解しておれば、 <br>
そのそれぞれ、つまり</p>
<p>10分前に追加したある「リストアイテム」は、 <br>
イミュータブルな時間軸の世界線上で、その10分前のポイントに分布、 <br>
2分前に追加したある「リストアイテム」は、 <br>
イミュータブルな時間軸の世界線上で、その2分前のポイントに分布。 <br>
未来に追加されるであろう「リストアイテム」でさえ、 <br>
イミュータブルな時間軸の世界線上で、その未来方向のあるポイントに分布。</p>
<p>という話を理解しておれば、それは原理的に同様に、イミュータブルである、 <br>
<code>const</code> である、ということが自然と理解できるはずです。</p>
<p>自然と理解できてない、ってことは、すなわち、上で言ってるような「意味」 <br>
がわかっていないということです。 <br>
時間軸がイミュータブルな無限ストリームで、 <br>
現在値というのは<code>t</code>であるとか、<code>now</code>であるとか、 <br>
そういうあるシンボルでしか表現できないものであって、こうするしかない、という意味が理解できないひとたちです。</p>
<p>たしかに、「ライブラリの実装下レベル」では、FRPにせよ、その他関数型にしても、 <br>
破壊的代入しまくるし、この<code>t</code>だって、オブジェクトのプロパティとして破壊的代入はされるわけです。</p>
<p>でも、いい加減しつこいんですよねー。 <br>
「ライブラリの実装下レベル」で、破壊的だの命令型だのいう、中傷。 <br>
だから、OCamlとかHaskellとか、あんたらの満足する純粋関数型ってのは、 <br>
言語実装レベル下で、純粋関数型でソースコード書かれてるの?C++とかで破壊的代入されてるだろう? <br>
という話です。もうしつこいし、いい加減にしてくれ、っていうのがまたあります。</p>
<p>あくまで、ライブラリユーザレベルにおいて、</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>(ちなみにこの__(true)については、後で話します。 <br>
trueがあろうがなかろうが、本題とは関係ないので、当面気にせずに)</p>
<p>というように、定数です。<code>t</code>が破壊的代入されている! <br>
とおもっているのは、上記のとおりそれは使い手の理解の問題であり、 <br>
ライブラリ下の実装と結びつけて、批判するのは、間違いです。</p>
<p>さて、実装の本題に戻ります。</p>
<p>イベント駆動において、 <br>
イミュータブルな定数 <br>
<code>__items</code> <br>
の時間軸上のそのイベントが発生した、ある時間Tにおける値(現在値)は、 <br>
<code>__items.t</code>で表現され、</p>
<p>それは、 別の <br>
イミュータブルな定数 <br>
<code>__value.t</code> <br>
の時間軸上のそのイベントが発生した、ある時間Tにおける値(現在値)は、 <br>
<code>__value.t</code>で表現される値と等しくなる、と宣言します。</p>
<p>これは断じて命令型ではないし、なんの「破壊的代入」も発生していない宣言である、 <br>
ということが理解できるでしょうか? <br>
理解してる人は良い。 <br>
延々と中傷している一連の連中はなんも理解していないということになります。</p>
<p>要するに、イミュータブルな時間軸の世界線において、 <br>
イベントが発生したそれぞれのポイントで、それぞれの値を順次格納していく、ということになります。</p>
<p>念の為ですが、便宜上「それぞれの値を順次格納していく」と書きましたが、 <br>
数学的には、決定論的に最初から決定されている、とみなす宣言文です。</p>
<p>時間軸を無限リストとして扱う、ということは、すなわち、 <br>
<strong>無限の未来方向までひっくるめて全部数学的な値として抽象化する</strong>ということなので、 <br>
便宜上言ったような、 <br>
時間の流れに従って「それぞれの値を順次格納していく」変数 <br>
ではなくて、 <br>
<strong>未来方向においても「それぞれの値を順次格納している」定数</strong> <br>
として扱っているということです。 <br>
変化しません。イミュータブルな定数です。 <br>
これが <br>
<strong>FRPのValue ”OverTime” がイミュータブルな定数である本当の意味</strong>です。よろしいでしょうか?</p>
<p>だから</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>という、時間軸上の世界線の「定数」 <code>const</code> <br>
であるのならば、 <br>
<strong>「破壊的代入」なんておこりうるはずもない。</strong> <br>
ということです。</p>
<p>「破壊的代入」がなされている、と批判した時点で、 <br>
その人物は、 <br>
FRPのValue ”OverTime” がイミュータブルな定数である <br>
という意味なんて、本当はこれっぽちも理解していない、ということが白日の下にさらされます。 <br>
つまり、中傷してる連中は、FRPの哲学的理解が足りないからそういうことが言えるのだ、ということですね。</p>
<p>かように、</p>
<p><code>__items</code></p>
<p>には、すべてのリストアイテムが、コードが宣言された瞬間に</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>とされた時点でもう「すでに」全部入っています。 <br>
FRP的には、そう見做されている、数学の定数です。</p>
<p>格納されているそれぞれの地点と1:1に対応しているのが、</p>
<pre class="prettyprint"><code class=" hljs avrasm"> const onClick = () => (__<span class="hljs-preprocessor">.log</span><span class="hljs-preprocessor">.t</span> = __items<span class="hljs-preprocessor">.t</span> = __value<span class="hljs-preprocessor">.t</span>)<span class="hljs-comment">;</span>
</code></pre>
<p>という、クリックイベントの宣言文です。</p>
<p>えーっとクリックイベントの宣言文って、命令型ですか?違うでしょ?</p>
<p>単に、これも <br>
イミュータブルな時間軸の世界線におけるマウスクリックの挙動の分布 <br>
と、 <br>
イミュータブルな時間軸の世界線におけるリストアイテムの分布 <br>
が一致している、という数学的な宣言にすぎません。</p>
<p>命令型というのは、 <br>
Step1 <br>
Step2 <br>
というように、コードの上下方向を利用して、評価させていくものであり、 <br>
上記の時間軸上の世界線の分布について、ある要素とある要素でマッピングして呼応させる、というのとまったく関係ありません。</p>
<p>このコードも、</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>このコードも、</p>
<pre class="prettyprint"><code class=" hljs avrasm"> const onClick = () => (__<span class="hljs-preprocessor">.log</span><span class="hljs-preprocessor">.t</span> = __items<span class="hljs-preprocessor">.t</span> = __value<span class="hljs-preprocessor">.t</span>)<span class="hljs-comment">;</span>
</code></pre>
<p>単に、 <br>
イミュータブルな時間軸の世界線における値の分布の宣言文であり、 <br>
コードの宣言においては何も評価されません。</p>
<p>断じて命令型の要素などない、ということです。よろしいですか?</p>
<p>さて、 <br>
<code>__items</code>というFRP定数には、 <br>
すべてのリストアイテムの値が時間軸上に分布して格納されています。</p>
<p>そのままでは、数学的な抽象的存在であり、 <br>
ユーザの目にもふれず<strong>「実用的なアプリ」</strong>として、役に立たないわけですから、 <br>
Reactを利用して、<strong>フロントエンドのDOM要素としてマッピング</strong>してやります。</p>
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-reserved">const</span> ListElement = __Element(__([__items])
.__<span class="hljs-function"><span class="hljs-params">(() => ((__items).map((item) => (<li>{item}</li>))))</span>);</span></code></pre>
<p>これもただ数学的な関係を宣言しているだけです。命令型の要素はどこにもありません。</p>
<p>おっと!</p>
<p><code>__items</code> の<code>t</code>が「破壊的代入」されて破壊されてしまったのなら、 <br>
いったいなぜ、このようなマッピングが可能になって、実際に、</p>
<p>TimeEngine公式サイト <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a></p>
<p>のDemo10 <br>
<img src="https://raw.githubusercontent.com/TimeEngine/timeengine.github.io/master/images/todo.png" alt="enter image description here" title=""></p>
<p>というように、動作してしまうのでしょうか!?</p>
<p>論より証拠。私が実装したFRPは、そのFRPの設計哲学どおりに挙動しているわけです。</p>
<p>命令型の要素なんて微塵もないし、破壊的代入をもって破壊されたのならば、 <br>
リストなんて列挙表示されてるはずがないだろう? <br>
でも実際には、破壊されずに全部きちんと表示されていますよね? <br>
ってことです。</p>
<p>もういいでしょうか?意味もわかってないのに、己の無知無理解を棚に上げて <br>
中傷するのはもういい加減にしてください。 <br>
というか、どなたがやってるんですかね?匿名で恥はかきすてで毎度結構なことですよね? <br>
岡部が、kenokabeが、と書き込むが、自分の名前はださずに、なんか複数でやってる。オモテにでてこいよ? <br>
と思う。</p>
<p>あと、なんでもいいから、さっさとこの課題のコード書いてみせてください。 <br>
「机上の空論」でないのならば。</p>
<p>さて、最後に、本論と関係ないことですが、テクニカルなことです。’</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>というように<code>true</code> オプションがかかっていますが、</p>
<p>他のコードなどでは、</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute"> const __a </span>=<span class="hljs-string"> __();</span></code></pre>
<p>というようになっています。</p>
<p>例えば「お絵かきアプリ」では、 <br>
イミュータブルな時間軸の世界線に分布する、 <br>
実行時点までの過去すべてのデータを保持すると、 <br>
現在時間が未来方向に進むにつれて、計算機上のメモリにデータが蓄積されていきますから、 <br>
メモリリークのような現象が起こります。</p>
<p>ほとんどの場合、「状態遷移」だけ扱いたいので、過去のデータは全部捨てていきます。 <br>
というか、ライブラリ実装上は、単に保持はしない。</p>
<pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword">const</span> __items = __(<span class="hljs-keyword">true</span>);</code></pre>
<p>とかオプションつけた場合、ちゃんと保持するし、別の宣言文をもってデータ全体にアクセスできますよ、ということです。</p>
<p>もちろん、「お絵かきアプリ」のFRP値で、オプションつけて、データ保持させると、 <br>
ドローしたすべてのストロークがデータとして蓄積されるし、 <br>
リプレイみたいなことも簡単にできます。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-44809638424387193582016-05-20T09:32:00.001+09:002016-05-20T10:02:37.756+09:00C言語は純粋関数型である。 「純粋関数型」と「参照透明性」国内の自称関数型コミュニティの胡散臭さと海外論調の違い<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p>この辺の続きとなります。</p>
<p>まず「課題」についてですが、いまのところ、私が知る限り、まだどこにもされていません。 <br>
念の為ですが、Twitterやら幼稚な念仏唱えているだけと一部馬鹿にされている病人が誹謗中傷連ねたいだけの2chスレの書き込みなんかいちいちチェックしてるわけもないので、万一そんなとこに書きなぐっても見てるわけもありません。</p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a> <br>
の「本来のFRP」による「お絵かきアプリ」っていったいどこにあるの?という課題については、 <br>
<a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a> <br>
と説明したとおりです。単なるごまかしです。</p>
<p>直近の、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p>ToDoの関数型GUIアプリについてもいまのところ無回答です。</p>
<p>2,3それらしい言い訳が</p>
<p><a href="http://anond.hatelabo.jp/20160519142942">http://anond.hatelabo.jp/20160519142942</a></p>
<blockquote>
<p>じゃあOCamlで純粋関数型や(本当の)FRPで複雑なGUIアプリが書けるかと言うと、 <br>
理論的には不可能ではないかもしれんが、もともと非純粋なので <br>
誰もそういうライブラリを整備してないから、ライブラリから作るのは <br>
まあ面倒だろうし、わざわざ非純粋関数型言語で純粋関数型のGUIを作る動機も <br>
現時点ではまずないだろう。これもすでに指摘されているとおり。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160520051838">http://anond.hatelabo.jp/20160520051838</a></p>
<blockquote>
<p>「状態渡し派」なんてレッテル張りも典型的な詭弁(藁人形論法)。 <br>
誰も状態渡しで何でも簡単に書けるなんて言ってないし、状態渡しで書くべきとも言ってない。 <br>
「お絵かきアプリ」には自称FRPが絶対に必要、という明らかに誤った主張に対する反例として <br>
nonstarter他が「状態渡し」を挙げただけ。 <br>
それなのにHaskellだから認めないとか、OCamlでも簡単だったから認めないとか…… <br>
自分で「FRPが必要」と断言して挙げた例題なのに。</p>
</blockquote>
<p>「やらない」「できない」言い訳を始めているようで非常にほほえましいですね。 <br>
<strong>ちなみにこの胡散臭い人物がいう「純粋関数型」については後述します。</strong></p>
<blockquote>
<p>「お絵かきアプリ」には自称FRPが絶対に必要、という明らかに誤った主張</p>
</blockquote>
<p>「実用的アプリ」を書ける、という観点において、 <br>
この程度の簡単なアプリなら書ける、書けたという誤魔化しがなされたにすぎません。</p>
<p><strong>「お絵かきアプリ」というのは、あくまで複雑なものが普通である「実用的アプリ」の具体例のひとつと</strong>して登場しただけで、</p>
<p><strong>その課題が「実用的なアプリ」というトピックにおいてどうも単純すぎたようだ、だからもうちょっと複雑な具体例で検討してみようか?</strong></p>
<p>、というのが現在進行している議論です。</p>
<p>「実用的アプリ」の具体例として単純すぎた実装が、連中のいう「純粋関数型」で書けたからといって、 <br>
「原理的」に複雑な「実用的アプリ」が書ける、わけもないですが、それが <br>
「実用的」な観点で、君ら誤魔化してるだろ?と言ってるわけです。</p>
<p>@nonstarterは、FRPでも結局は「状態渡し」と一緒で、実用的なアプリを関数型を書くのには問題があるのは一緒だ、とさらに、FRPにまで話を進めてもそれは一緒だ、とさらに大嘘を書いているので、</p>
<p>以上の2点の嘘ごまかしを証明しようというのが今のステップです。</p>
<p>「実用的」複雑なGUIアプリが書けるのか?というトピックにおいて、 <br>
こちらが単純すぎる課題を出してしまったことに便乗し、 <br>
「ほら書けただろ!」と、それ以上複雑になってくると通用しないことを自覚しながら、 <br>
「原理的」に問題ないというポーズだけ示し、 <br>
さらに、FRPでも一緒だ!と「誤魔化している」ことを批判されているのに、意味が伝わりませんかね? <br>
「机上の空論」であると。</p>
<p>「机上の空論」じゃ埒が明かないので、こちらは、 <br>
さらに複雑な課題において、証明してみせよ、と具体的なコードを示せと言ってる。</p>
<p><strong>君らのなかの「純粋関数型」君らののなかの「FRP」がどうであれ、</strong> <br>
<strong>こちらはすでに、コードを示した。</strong> <br>
君らは頑なに強弁してた、 <br>
<strong>Ocaml+状態渡し(FRPのメリットなんてないらしい)関数型でコードは示せない。</strong></p>
<p>それがすべてを物語っているだろう?<strong>君らの一連の関数型のGUI実用アプリのの言説なぞ机上の空論である</strong>と。</p>
<p>ちなみに、</p>
<h2 id="話題の岡部健kenokabeが自分のブログで凄いこと言ってる">『話題の岡部健(kenokabe)が自分のブログで凄いこと言ってる』</h2>
<p><a href="http://anond.hatelabo.jp/20160519214037">http://anond.hatelabo.jp/20160519214037</a></p>
<p>で、</p>
<blockquote>
<p>ttp://kenokabe-techwriting.blogspot.jp/ <br>
このブログエントリの昨日と本日日付の分を見ると、たくさんの増田の投稿がリンク付きで引用されている。 <br>
しかもよく見ると、個々の増田の投稿を、実在の学者やツイッターユーザーが行ったと決めつけてるフシがあるんだよね。 <br>
自説を否定する増田に対して憤慨してる様子なんだけど、文脈からするとどうも「駱駝」っていう人物が投稿していると言いたげなんだよね。「あなた」とか「君ら」という言葉からすると。 <br>
というか、完全にそれを前提にブログを書いているんだどう見ても。 <br>
増田の投稿に対して憶測で特定の人物だと決めつけてこういうエントリ書くような奴は初めて見た。 <br>
あと学者の「住井」って人物にも噛みついている様子なんだけど、過去のエントリを見るとこの岡部、駱駝・住井両名に対してよくわからない挑戦状みたいなエントリを何の前触れもなくアップロードしてるんだよ。 <br>
内容からすると、やはり誰が書いたのか正体が見えない投稿を、その両名が行ったと決めつけてるようなんだよね。 <br>
このタイトルも凄い、 <br>
Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について <br>
どこの厨房だよと思ったらどうも真剣に書いてるみたいなんだよね。 <br>
第三者による書き込み <br>
<a href="http://anond.hatelabo.jp/20160518171946">http://anond.hatelabo.jp/20160518171946</a> <br>
って言ってるけど、これ岡部氏本人による自己弁護だよねぇ・・・・。一体何をしたらここまで常軌を逸した発言に及ぶんだ。</p>
</blockquote>
<p>という <br>
ttp://kenokabe-techwriting.blogspot.jp/</p>
<p>という2ch記法ではじまる、たいへんわかりやすい印象操作工作活動をあいかわらずやらかしています。 <br>
さっそく、突っ込みも入っているようですが、</p>
<p>「実在の学者」</p>
<p>とか、普通こんな不自然な言い草します?(笑) <br>
これは、「実在のベンゴシ」と、ほうぼうでお経のように唱えていると小馬鹿にされている、まさに、</p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p>この構成員の口癖そのものです。いろいろワキが甘いですね。書き込みの癖って隠せないですよね?</p>
<p>誹謗中傷集団の構成員が、 <br>
事情通をアピールしながら、</p>
<blockquote>
<p>文脈からするとどうも「駱駝」っていう人物が投稿していると言いたげなんだよね。「あなた」とか「君ら」という言葉からすると。</p>
<p>憶測で特定の人物だと決めつけてこういうエントリ書くような奴は初めて見た。</p>
<p>あと学者の「住井」って人物にも噛みついている様子なんだけど、過去のエントリを見るとこの岡部、駱駝・住井両名に対してよくわからない挑戦状みたいなエントリを何の前触れもなくアップロードしてるんだよ。</p>
</blockquote>
<p>とか、「今初めて知りました感」を演出している。</p>
<p>「背景に詳しい事情通」なのに「今初めて知りました感」を演出。 <br>
こういうのを「自作自演」っていうんでしょ?いつも工作活動ごくろうさまです。</p>
<p>さて、最後に</p>
<blockquote>
<p>第三者による書き込み <br>
<a href="http://anond.hatelabo.jp/20160518171946">http://anond.hatelabo.jp/20160518171946</a></p>
<p>って言ってるけど、これ岡部氏本人による自己弁護だよねぇ・・・・。一体何をしたらここまで常軌を逸した発言に及ぶんだ。</p>
</blockquote>
<p>違いますよ。第三者です。自分が自作自演の常習だから、といって、 <br>
「自分たちに都合の悪い岡部への弁護」は「岡部の自作自演」みたいな都合の良い決め付けはやめなさい。</p>
<p>全部のやりとりを引用すると</p>
<p><a href="http://anond.hatelabo.jp/20160518164005">http://anond.hatelabo.jp/20160518164005</a></p>
<blockquote>
<p>状態を変数に持つ必要はない、というところは伝わってるのかな <br>
状態を引数で与えて新たな状態を得る、という形で書ける、と <br>
そのほうが関数型的、というと反発するんだろうけど <br>
岡部氏もやろうと思えばそういう風に書けるんじゃないの?</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160518170332">http://anond.hatelabo.jp/20160518170332</a></p>
<blockquote>
<p>そんな「状態渡し」の話はもう周回遅れでとっくに終わってる。 <br>
複雑なGUIアプリを関数型で「状態渡し」で書いたら、そのうちスケールしなくなる、ってのは例の当事者が認めてて、 <br>
FRPに話がようやく移ったのが今。 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-frp.html">http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-frp.html</a></p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160518171946">http://anond.hatelabo.jp/20160518171946</a></p>
<blockquote>
<p>まあお絵かきは綺麗に書けるってことでいいんじゃないの? <br>
そんで岡部氏のFRPでは綺麗に書けて、状態渡し派の関数型には書けない次なるお題でとどめを刺せばいいんでは?</p>
</blockquote>
<p>と言う感じです。</p>
<p>岡部は孤立している、要するにそういう図式を堅持したい、という魂胆はいつもミエミエでわかりやすいですが、自分の信じたい世界を作り上げる、自分の都合の悪い真実については、岡部の妄想というのもわかりやすいです。 <br>
「実在の学者」とか、毎日「実在のベンゴシ」がどうたら異常なお経唱えてるから、不自然だと気づかないんですよ?病気?</p>
<h1 id="純粋関数型">純粋関数型</h1>
<p>他にもこんな書き込みがあります。</p>
<p><a href="http://anond.hatelabo.jp/20160519175956">http://anond.hatelabo.jp/20160519175956</a></p>
<blockquote>
<p>岡部さん曰わくは、「ぼくの主張に同調的な国内の学者たちは、 <br>
自称関数型コミュニティの圧力を恐れて、表立って肯定できない」とのことです。 <br>
また、 <br>
「nonstarter氏や住井教授のようなエントリの内容は、日本国内でのみ少数の合意が得られてるに過ぎず、海外では主流ではない。 <br>
僕の理解こそが世界的合意を得られており、stakuoverflowでmapとreduceの理解が出来ていないような質問をしたのは、海外のレベルを探るためである」 <br>
という趣旨の主張もあるようです</p>
</blockquote>
<p>それに対してさっそくついたトラックバックを引用すると</p>
<p><a href="http://anond.hatelabo.jp/20160520072553">http://anond.hatelabo.jp/20160520072553</a></p>
<blockquote>
<p>観測できる事実として、岡部さんと住井さん、nonstarteさんの振る舞いが目立ってきた頃から、 <br>
国内ネットでは、地雷、滅多なことを言わないほうがいいという風潮がありました。 <br>
しかも、「純粋関数型」が何か?というさえ、海外では関数型プログラミング界隈の著名人、 <br>
たとえば岡部さんが引き合いに出す論文のエリオットはじめ、合意が取れていません。 <br>
<a href="http://conal.net/blog/posts/the-c-language-is-purely-functiona">http://conal.net/blog/posts/the-c-language-is-purely-functiona</a> <br>
「nonstarter氏や住井教授のようなエントリの内容は、日本国内でのみ少数の合意が得られてるに過ぎず、海外では主流ではない。」 <br>
よって、これは岡部さんのほうが公平な現実について発言しており、が正しいと判断します。 <br>
住井さんをはじめ、岡部さんが批判する相手は、議論となっている関数型プログラミングの定義などが、まるで世界的に合意がされており岡部さんのみが異端だという主張ばかりしており、あまり信用できません。</p>
</blockquote>
<p>そのとおりです。</p>
<p>私が 住井 @東北大をはじめとする自称関数型コミュニティによる言説が非常に胡散臭いとおもうのは、 <br>
例の関数型PGの一般的説明、なるものもそうですし、まるで学術的にコンセンサスがとれており、 <br>
自分の言っていることが正しい、と断定的に論じているところです。</p>
<p><a href="http://conal.net/blog/posts/the-c-language-is-purely-functiona">http://conal.net/blog/posts/the-c-language-is-purely-functiona</a> </p>
<p>というのは、知らなかったですが、</p>
<h2 id="the-c-language-is-purely-functional">The C language is purely functional</h2>
<p>「純粋関数型」についての議論です。2009年5月時点の投稿</p>
<p>Conal Elliottについては、私もその発言について信頼しており引用してみます。</p>
<blockquote>
<p>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</p>
<p>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.</p>
</blockquote>
<p>要約すると、</p>
<blockquote>
<p>Robert Fischer’のポスト ー Scalaは関数型プログラミング言語ではない、についてTwitterやReddit(海外の活発な掲示板)で、ちょっとしたリアクションがあった <br>
James Iryは、同じ理由でErlangは関数型ではない、という結論も出せる、答えた。</p>
<p>自分の最初の考えとしては、Haskell、(IOモナド) も関数型言語ではないとサジェストしたいというものだった。しかしかわりに、C言語も純粋関数型であるということをここで説明しようと思う。</p>
</blockquote>
<p>(中略)リンク先読んでください</p>
<h3 id="what-about-haskell最後部分じゃあhaskellはどうなの純粋関数型か">What about Haskell?(最後部分)じゃあHaskellはどうなの?(純粋関数型か?)</h3>
<blockquote>
<p>Which leads to the question: is Haskell+IO a purely functional programming language?</p>
<p>Sure it is, even as much as its predecessor C (more precisely, cpp+C). <br>
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.)</p>
<p>I must then respond that, in that case, even C programming is only technically pure. <br>
Which is absurd.</p>
<p>これはある質問にたどりつく:じゃあHaskell+IOというのは、純粋関数型言語なのか?</p>
<p>もちろんそうだ。そしてその先行者であるC(正確に言うとC++)も同じ程度にそうなのだが。</p>
<p>訳知り者はこう文句言うことだろう:Haskell+IOのみが唯一「テクニカル」に純粋である、と。</p>
<p>なら私はこう返すしか無い、ではその場合、Cプログラムのみが唯一唯一「テクニカル」に純粋である、と。 <br>
馬鹿げている。</p>
</blockquote>
<p>コメント欄もふくめて、要するに明確な合意に至っていない、ということは普通にわかります。</p>
<p>住井その他の日本国内の自称関数型コミュニティの胡散臭い言動の根本的な問題は、素人全般、学習者にむけて、まるで学会で明確な合意がなされており確固たる「一般的説明」があり、私のような「別の意見」を表明すると、「勉強しろ」だの「独自見解」で「合意と違う」という嘘を平気で押し付けてくることです。</p>
<p>実際に「参照透明性」についても、</p>
<p><a href="http://stackoverflow.com/questions/210835/what-is-referential-transparency">http://stackoverflow.com/questions/210835/what-is-referential-transparency</a></p>
<p>で示されているように、関数型プログラマーと、意味論とは食い違うことが明確化されていたり、</p>
<h2 id="purity-vs-referential-transparency">Purity vs Referential transparency</h2>
<p><a href="http://stackoverflow.com/questions/4865616/purity-vs-referential-transparency?rq=1">http://stackoverflow.com/questions/4865616/purity-vs-referential-transparency?rq=1</a></p>
<blockquote>
<p>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.</p>
<p>純粋性 vs 参照透明性</p>
<p>これらの用語は、別のものと定義されているようだ、しかし、自分はいつもお互いがお互いを暗喩的に意味しているように考えている。つまり、「ある表現が参照透明であって、純粋でない」というケースがおもいつかないし、逆方向についてもそうだ。</p>
</blockquote>
<p>あと、Wikipedia(英語版)のデタラメな説明への疑念、が質問者によって表明されており、</p>
<blockquote>
<p>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.</p>
<p>なんか、その純粋性と参照透明性についての違いみたいなものを理解できる、もっと単純な方法はないのか?「違い」みたいなものがあれば、明確に表現している例を教えてくれるとありがたい。</p>
</blockquote>
<h2 id="もっとも支持を集めた答え">もっとも支持を集めた答え</h2>
<blockquote>
<p>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.)</p>
<p>もし、自分の知り合いの3人の理論家を集めたら、少なくとも、2人は、「参照透明性」という用語について合意しない。そして、自分が若い学生だった頃、自分の担当教師は、「参照透明性」というものが、少なくとも、3つの異なる意味で使われていることを説明する論文を渡してくれた・・・</p>
<p>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.</p>
<p>わからない、でも、アドバイスできることとして、「あきらめなさい」、なぜならば、インテリ言語学者の少数集団でさえ、それが何を意味するのか合意できていない。 <br>
「参照透明性」っていう用語は役立たずだ。だから使うな。</p>
</blockquote>
<p>・・・・という感じです。</p>
<p>実際そこらじゅうで見るのが、 <br>
「純粋関数型」っていう概念を「参照透明性」という用語、概念をもって説明しようとするものであり、わかったようなわかってないような人らを量産しています。</p>
<p>その上、たとえば、</p>
<p><a href="http://anond.hatelabo.jp/20160516112619">http://anond.hatelabo.jp/20160516112619</a></p>
<blockquote>
<p>kenokabeさんの心の中ではそうなのかもしれませんが、ライブラリの<strong>ユーザから客観的に見れば(分析哲学ではなく関数型言語の意味で)参照不透明なので</strong>、<strong>関数型プログラミングのメリットは享受できない</strong>、命令型の破壊的代入と等価ですね。</p>
</blockquote>
<p>はい、この「訳知り顔」の誰かさんも、また偉そうに、 <br>
参照不透明だから→関数型プログラミングではない、論法を取っています。 <br>
えーっとそれっていったいどういう意味? <br>
あなたの言うこと、世界的に合意されているの? <br>
「あなたの心の中」以外でまともな説明はされているの?</p>
<p>(分析哲学ではなく関数型言語の意味で)参照不透明、と()つけたのは、多分、Qiitaでも話題になっていた、</p>
<p><a href="http://stackoverflow.com/questions/210835/what-is-referential-transparency">http://stackoverflow.com/questions/210835/what-is-referential-transparency</a></p>
<p>これを警戒しているのでしょうが、実際 <br>
「関数型言語での参照透明性」っていうのと <br>
「分析哲学での参照透明性」の違い、なんて、まともに合意なんてされていません。</p>
<p>この人物も適当に <br>
「(分析哲学ではなく関数型言語の意味で)参照不透明」とか、「この人物の心の中」での「参照透明性」を語っているにすぎません。 <br>
わからないことを、あたかもわかっているように断じる、これがこの連中の悪い癖です。</p>
<p>ああ、ちなみに、この</p>
<p>私のFRPライブラリは参照不透明?で、命令型の破壊的代入っていう中傷について、またしばらく後にエントリします。あたらしい課題つきで。</p>
<p>というか、さっさと、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/ocamlgui-esumii-camloebanonstarter.html">OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて</a></p>
<p>これやってくださいね?OCamlで状態渡しで、あ、やっぱり、できない、でよろしいんですね?</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-87155723995660646512016-05-19T01:55:00.001+09:002016-05-19T09:15:38.091+09:00OCamlでの関数型コードのGUIアプリ課題 あらあためて、住井 英二郎@esumii (東北大)、らくだの卯之助@camloeba、@nonstarterその他へむけて<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/frp_18.html">「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの</a></p>
<p>この辺の続きとなります。 <br>
この際、成り行き上かなり「気が向いた」ことと、延々と悪質な連中の(真性の天然の可能性もあるにはあるが、相手は複数であるし、総体としては多分わかって誤魔化している)誤魔化しがまかり通っていることを再確認したし、いろいろ中傷(嘘,誤魔化しをしている自覚があれば批判でなく中傷だ)してる君らに、改めて課題を出しておこうと思います。いろいろはっきりすることでしょう。</p>
<p>第三者による書き込み</p>
<p><a href="http://anond.hatelabo.jp/20160518171946">http://anond.hatelabo.jp/20160518171946</a></p>
<blockquote>
<p>まあお絵かきは綺麗に書けるってことでいいんじゃないの? <br>
<strong>そんで岡部氏のFRPでは綺麗に書けて、状態渡し派の関数型には書けない次なるお題でとどめを刺せばいいんでは?</strong></p>
</blockquote>
<p>を目撃して、「なるほどそのとおりだ」と思ったこともあります。また、「お絵かきアプリ」にしても、直近の自作FRPライブラリ=TimeEngine公開後も、こちらから提示するまでもない、と思っていた、というか連中の妄想、思い込み度合いを見くびっていたことがあり、この際きちんと白黒つけるべきだと思いました。</p>
<p>無理なら別にやらなくていい。多分無理だろうし。君らが言い連ねているのは、机上の空論だから。 <br>
机上の空論じゃない、と証明できる場合のみ、今回の課題をクリアしてみせてくれれば良い。</p>
<p>その前に、この「机上の空論」の議論について、今回の課題にむけて、これまでの経緯の復習も兼ねて、重複、再掲する部分多々ある形式で、前提をまとめてみます。</p>
<p>まず最初に、そもそもの大前提だけれど、私にいろいろ文句垂れてくるOCamlのプログラマー複数人を中心とする連中にむけて、私は、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p>と題するエントリにおいて、こう書いた。</p>
<p>再掲</p>
<hr>
<p>素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??</p>
<p><strong>机上 = Desktop デスクトップのアプリをOCamlで書いて見せてくださいよ。議論はしなくて良いから。</strong></p>
<p>「疑似科学者」なんて罵倒するなら、自分で証明しろ、って思いますね。 <br>
さあどうぞ。</p>
<p>個人的に、OCamlを振り回して、国内で関数型プログラミングで、なんかこういう、私の主張にたいしても上から目線で偉そうにごちゃごちゃ文句いってくる連中が、GUIアプリ書いてる事象を目撃したことがこれまで一度もない。 <br>
なんで?</p>
<p>まあ、技術者ならば、科学的精神をリスペクトするならば、 <br>
らくだの卯之助@camloebaさん、あなたが自身の関数型プログラミングのスキルが「机上の空論」でないことを示してください。</p>
<hr>
<p>再掲おわり <br>
以上を受けて、</p>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a></p>
<p>においても、</p>
<h2 id="追記20150530デスクトップアプリケーション">追記(2015/05/30):デスクトップアプリケーション??</h2>
<blockquote>
<p>(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。</p>
</blockquote>
<p>と、@nonstarter なる正体不明の自称教育関係者が書いており、</p>
<p>「OCamlで「お絵かきロジック」を実装してみせよと要求する」ときちんと要件は理解しているようでした。</p>
<p>しかし、</p>
<blockquote>
<p>もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。</p>
</blockquote>
<p>と言いながら、なぜか急にHaskellのコードが貼り付けらら得ており、Haskellのお絵かきアプリのコードしか書いていない。また、なにかと、elmのコードを持ち出してくる。 <br>
あのね、OCamlの関数型のコーダに向かって、OCamlで実用的なアプリを書けるのか?と確認しているのに。</p>
<p><a href="http://kenokabe-techwriting.blogspot.com/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a>にもすでに書いたけれど、</p>
<blockquote>
<p>(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)</p>
</blockquote>
<p>とまた「原理的に不可能でない」などという「机上の空論」を自覚ない天然なのか、わざとやってるのかわらからないけれど、繰り返している。 <br>
さらに畳み掛けるように、</p>
<blockquote>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<p>というように、とにもかくにも、(状態渡し)に固執しながら、でもいちおう(状態渡し)の限界を別のひとから指摘されたから、それは一応発現する、でもなおFRPの否定にやっきになる、まったくもってわけのわからない理由で。</p>
<p>大事なポイントは、「(状態渡し)」で時間遷移していく、複雑なことが普通である実用的アプリケーションを書こうとすると、</p>
<ul>
<li><p>状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる</p></li>
<li><p>そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い</p></li>
</ul>
<p>ということです。まあこの捨てアカウントの人物はその程度の理解と自覚はしっかりあるようですし、ここまでは言ってる意味はわかるし、普通に正しい(それ以降は全部間違っていますが)。</p>
<p>彼が言ってる正しい部分をまさに私は指摘している。それは根本的に、時間遷移の概念を関数型のパラダイムに抽象化したFRPを適用していないのが問題なのであって、あんたらはそんなことは一切触れずに、まるで、「(状態渡し)」で最終的になんでもできるかのように、初学者に向けても説明してるじゃないか、というか、実際、OCamlで実用的なデスクトップアプリを書いてるのみたことないけど、できるの?そんなに言うなら書いて見せてよ?、、、というところまでが、私の「問題提起」なのでした。</p>
<p>ここまでは当然この胡散臭い捨てアカウントも理解しているようですが、続いて、</p>
<blockquote>
<p>結局のところ少なくとも現状のFRPも本質的には銀の弾丸にはならないと言わなければなりません</p>
</blockquote>
<p>(多分何がなんでも自分の理解を超える要素は否定したいと大風呂敷を広げる) <br>
一応とってつけた理由:</p>
<blockquote>
<p>(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)</p>
</blockquote>
<p>???????意味不明。 <br>
まあ、この人物がFRPが何たるか理解していないのは、ほぼ確実でしょう。 <br>
FRPの本質は「時間軸」のプログラミング言語上での抽象化であり、なんかわけわかりませんが、この一連の議論で、FRPという言葉さえでてくるも、「時間」とか言っているのが私ただひとりだけ、という非常にわけのわからない、もとい、ある意味、連中がどういう知見レベルをもって当方を批判、あるいは中傷しているのかが非常にわかりやすい状況です。</p>
<p>念の為ですが、TimeEngineのプロジェクトgithub.io ページ <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
にも書いていますが、1997年の論文で、<a href="http://dl.acm.org/citation.cfm?id=258973">http://dl.acm.org/citation.cfm?id=258973</a></p>
<blockquote>
<p><strong>Fran (Functional Reactive Animation)</strong> 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. <strong>Behaviors are time-varying, reactive values,</strong> while events are sets of arbitrarily complex conditions, </p>
</blockquote>
<p>Fran (Functional Reactive Animation) として、初めてFRPを明示的にプログラミングパラダイムとして導入したことで知られているConal Elliottは、 <br>
<a href="http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming">http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming</a> <br>
において、こう宣言しています。</p>
<blockquote>
<p>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. <br>
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”.</p>
</blockquote>
<p>面倒なんで全部訳しませんが、ポイントは、</p>
<ul>
<li>FRP is about - “datatypes that represent a value ‘over time’ “</li>
<li>Dynamic/evolving values (i.e., values “over time”) are first class values in themselves. </li>
</ul>
<p>FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、 <br>
ということです。</p>
<p>したがって、 <br>
「いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのこと」とか、そういうおはなしとは全く別の話題ですし、 <br>
FRPでは「(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくる)」なる言及は、FRPのパラダイムを論じる上で意味を成しません。</p>
<blockquote>
<p>(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<p>これもどういう意味なのか全く意味がわかりません。 <br>
とにかく、力づくで理屈を捻じ曲げても、とにかくFRPという彼にとっては新しい未知の概念の導入なんて無意味だ、ということを力説したいという熱意だけは伝わってきます。</p>
<blockquote>
<p>ちなみに、大した意味はありませんが、敢えてFRPライブラリ(Reactive-Banana)を使うとこうなります:</p>
</blockquote>
<p>大した意味がないどころか、FRPライブラリを導入するということは、時間軸上の展開している値をファーストクラスにして、時間発展する系を関数型プログラミングの枠組みで統一的に取り扱えるようにする、という甚大なパラダイムの変化であり、大きな意味があります。 <br>
</p>
<blockquote>
<p>FRPライブラリを使ってもコードが先のものと殆ど変わらないことに注意してください。要するにこれらのコードの本質は状態遷移を純粋な関数(ここではeTrans)で表現するところにあり、イベントストリームやシグナル・ビヘイビアといったFRP特有の要素を用いるか否かにはないということが示されています。</p>
</blockquote>
<p>そりゃさ、この程度ならば「殆ど変わらない」のだが、とりもなおさず君自身が言ってたとおり、</p>
<ul>
<li><p>状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる</p></li>
<li><p>そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い</p></li>
</ul>
<p>という状況が顕在化するばするほど、「殆ど変わらない」どころか、本質的な違いが顕在化する。</p>
<p>まず批判ありきで私個人を中傷するにとどまらず、何も知らんくせに、FRPの意味もわかってないくせに、批判ありきのFRP不要論の大風呂敷を広げる、適当な屁理屈をとってつけて読者を惑わせて恥ずかしくないの?と思う。自称大学の教職にある捨てアカウントらしいが、知的誠実さが少しでも残っているのならば、ただちに修正することをおすすめする。言っても無駄でしょうが。どうせ捨てアカウントだし、こちらを中傷し放題で、自分は間違ったデマを垂れ流しても、恥はかき捨てで大変結構ですね。割を食うのは学習者です。まあやっぱり恥を知ってほしいです。</p>
<p>私が一貫して酷評している、 <br>
<a href="http://qiita.com/esumii/items/ec589d138e72e22ea97e">「関数型言語」に関するFAQ形式の一般的説明</a> <br>
においても、</p>
<h3 id="それだと入出力や状態stateすら表せないのでは">それだと入出力や状態(state)すら表せないのでは?</h3>
<blockquote>
<p>いいえ、純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。</p>
</blockquote>
<p>と、(状態渡し)の関数型プログラミングで、なんでもできるように書いているが、どこまで本当なんでしょうか?複雑なのがあたりまえの実用的なアプリには通用しない、ってちゃんと初学者に教えていますか?教えていないでしょ?</p>
<p>したがって、改めて、東北大学の住井 英二郎@esumii、らくだの卯之助@camloeba あるいは、 <br>
@nonstarterらへのOCamlのデスクトップ(Web)アプリの宿題を出したいと思う。</p>
<p>繰り返し念の為ですが、もちろん別に義務なんてないし、多分出来ないとおもうから、無理してやる必要もない。やらない、ということが一つの答えとなるから。</p>
<h1 id="課題">課題</h1>
<h3 id="todolistという単純なguiアプリを書け">ToDoListという単純なGUIアプリを書け。</h3>
<p>ちょっといろいろ考えましたが、状態の更新があるGUIアプリとして <br>
適度に複雑で、適度に単純な課題を選択しました。</p>
<p>適度に複雑、というのは、前々回の「カウンターアプリ」にしろ、 <br>
前回の「お絵かきアプリ」については、課題が単純すぎて、 <br>
連中が誤魔化せたので、今回はそれ以上に、誤魔化しにくい程度に複雑である、ということです。</p>
<p>第三者による書き込み</p>
<p><a href="http://anond.hatelabo.jp/20160518171946">http://anond.hatelabo.jp/20160518171946</a></p>
<blockquote>
<p>まあお絵かきは綺麗に書けるってことでいいんじゃないの? <br>
<strong>そんで岡部氏のFRPでは綺麗に書けて、状態渡し派の関数型には書けない次なるお題でとどめを刺せばいいんでは?</strong></p>
</blockquote>
<p>で提起されるような要件のとおり、ある程度の複雑さのハードルを満たしながら、当方のFRPのアプローチでは極めてシンプルに記述できることを示せる程度に単純な課題です。</p>
<h2 id="念の為に付随要件ocamlの状態渡しによる関数型で実装せよ">念の為に付随要件、OCamlの状態渡しによる関数型で実装せよ</h2>
<ul>
<li><p>OCaml で君らがお題目唱えているとおり、(状態渡し)の関数型のコードで書くこと。これまで君らが誤魔化してきたように、HaskellやElmなど他の言語を「都合よくつまみ食い」してはならない。</p></li>
<li><p>FRPのメリットなんてない、とかぶちあげているみたいなので、たとえFRPのメリットをようやく今更途中で気づいたとしても、間違ってもOCamlのFRPライブラリなんかを検索して探し出して、そのFRPライブラリを利用して書いてはならない。あくまでも(状態渡し)の関数型コードで書くこと。</p></li>
</ul>
<p>これは、君らが延々とこちらの主張を押さえ込むように強弁してきた要件なので、当たり前。出来なきゃ、その時点で君らの嘘が確定する。以上の条件に反しなければ別にどんなライブラリを使おうが自由。</p>
<h2 id="当方はjavascripttimeenginereactをもってfrpで実装します">当方は、JavaScript+TimeEngine+Reactをもって、FRPで実装します</h2>
<p>JavaScript(いろいろ君らが関数型プログラミングの文脈で否定してきた言語) <br>
+FRPライブラリTimeEngine <br>
(いろいろ君らが真のFRPでなく破壊的代入だの命令型だの適当に中傷している当方によるライブラリ) <br>
+React(FRPの末端(View)を担う、君らが否定的なJavaScriptでは今時デファクトのFBによるフロントエンドライブラリ)</p>
<p>をもって実装。</p>
<h2 id="すでに実装しているのでアプリの詳細要件の提示を兼ねて">すでに実装しているので、アプリの詳細要件の提示を兼ねて</h2>
<p>TimeEngine公式サイト <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a></p>
<p>のDemo10</p>
<p>以下は動作中のスクリーンショット画像</p>
<p><img src="https://raw.githubusercontent.com/TimeEngine/timeengine.github.io/master/images/todo.png" alt="enter image description here" title=""></p>
<p>極めて簡易なToDoリストの基本的動作で</p>
<p>1.ユーザからのToDo項目のテクスト入力を受付け <br>
2. ボタンを押すことによって、内容が確定し上記リストに順次追加される <br>
3. 入力欄は自動的にクリアされ、ボタン上には次のカウントが(#2,#3など)にアップデート表示される <br>
4. アプリタイトル直下に適当なフォーマットで現在時刻を表示させる <br>
5. アプリのスタートや入力確定項目のデバッグログをコンソールに表示させる</p>
<h3 id="indexjsx">index.jsx</h3>
<pre class="prettyprint"><code class="language-js hljs ">(() => {
<span class="hljs-string">'use strict'</span>;
<span class="hljs-keyword">const</span> TodoElement = () => {
<span class="hljs-keyword">const</span> ClockElement = __Element(__
.intervalSeq(Immutable.Range(), <span class="hljs-number">100</span>)
.__(() => (<span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span>{moment().format('MMMM Do YYYY, h:mm:ss a')}<span class="hljs-tag"></<span class="hljs-title">div</span>></span>)));
const __items = __(true);
const ListElement = __Element(__([__items])
.__(() => ((__items).map((item) => (<span class="hljs-tag"><<span class="hljs-title">li</span>></span>{item}<span class="hljs-tag"></<span class="hljs-title">li</span>></span>)))));
const InputElement = () => {
const __value = __();
const onChange = (e) => (__value.t = e.target.value);
const onClick = () => (__.log.t = __items.t = __value.t);
const __seqEl = __([__value])
.__((value) => (<span class="hljs-tag"><<span class="hljs-title">div</span>></span>
<span class="hljs-tag"><<span class="hljs-title">input</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">{value}</span> <span class="hljs-attribute">onChange</span>=<span class="hljs-value">{onChange}</span>/></span>
<span class="hljs-tag"><<span class="hljs-title">button</span> <span class="hljs-attribute">onClick</span> = {<span class="hljs-attribute">onClick</span>}></span>{'NewToDo#' + (__items.length + 1)}<span class="hljs-tag"></<span class="hljs-title">button</span>></span><span class="hljs-tag"></<span class="hljs-title">div</span>></span>));
const dummy = __.log.__(() => (__value.t = ""));
__.log.t = "started!";
return __Element(__seqEl);
};
return (<span class="hljs-tag"><<span class="hljs-title">div</span>></span><span class="hljs-tag"><<span class="hljs-title">h2</span>></span>ToDo<span class="hljs-tag"></<span class="hljs-title">h2</span>></span>
{ClockElement}<span class="hljs-tag"><<span class="hljs-title">p</span>/></span>
{ListElement}
{InputElement()}<span class="hljs-tag"></<span class="hljs-title">div</span>></span>);
};
const mount = ReactDOM.render(TodoElement(), document.getElementById('todo'));
})();
</span></code></pre>
<p><strong>基本、すべて<code>const</code>のみのFRPコードです。</strong> <br>
念の為ですが、</p>
<p><a href="http://anond.hatelabo.jp/20160514005947">http://anond.hatelabo.jp/20160514005947</a></p>
<blockquote>
<p>kenokabe氏のコードは破壊的代入バリバリの命令型プログラムそのもの</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160515231526">http://anond.hatelabo.jp/20160515231526</a></p>
<blockquote>
<p>またすさまじいスパゲッティコード <br>
kenokabeさんのコードはライブラリの内部実装だけでなく、ライブラリのユーザに見えるレベルでも <br>
もろに命令型の破壊的代入ですね。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160516112619">http://anond.hatelabo.jp/20160516112619</a></p>
<blockquote>
<p>kenokabeさんの心の中ではそうなのかもしれませんが、ライブラリのユーザから客観的に見れば(分析哲学ではなく関数型言語の意味で)参照不透明なので、関数型プログラミングのメリットは享受できない、命令型の破壊的代入と等価ですね。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160517094425">http://anond.hatelabo.jp/20160517094425</a></p>
<blockquote>
<p>kenokabe氏のコードでもマウスが動くたびに同じ__drawFrom.tへの破壊的代入が行われるんですがそれは</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160516192742">http://anond.hatelabo.jp/20160516192742</a></p>
<blockquote>
<p>これは岡部健氏が著書で「論理破綻」と批判していた、命令型言語の破壊的代入そのものです。</p>
</blockquote>
<p><strong>命令型の破壊的代入と等価と思うのは、あなたの本来の意味におけるFRPにたいする哲学的理解あるいは概念の理解が足りないからです。</strong> <br>
<strong>関数型プログラミング、そしてFRPのメリットを享受しています。</strong> <br>
<strong>「論理破綻」などどこにもありません。ただのFRPです。</strong></p>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b</a></p>
<blockquote>
<p>JavaScriptか、少なくともその処理系が、関数型プログラミングに不適切です。@nonstarter</p>
<p>なお上の事は kenokabe の関数型言語に対する歪んだ理解の原因の一つは、末尾最適化のない JavaScript 実装を使う事に固執したためであるという事も意味します。 @yataketa9056</p>
<p>岡部氏の著書やコードは拝見しましたが、実用的なGUIアプリはありません。また、ReactやFRP以前に岡部氏のJavaScriptコードは無意味に複雑・冗長で、失礼ながらまさに「スパゲッティ」と言わざるを得ません。 @Lambada</p>
<p>kenokabeさんに代わって(もちろん変数の破壊的更新を伴わない純粋にFRPなJavaScriptコードで)実装されると一連のご主張に説得力が多少は増すかと思いますのでとてもお勧めです。 @nonstarter</p>
<p>JavaScriptでのFRPなんか仰々しく広める暇があったら、 @nonstarter</p>
<p>すでに述べたとおり2です。私がElmコードを示した理由は、単にJavaScriptよりもFRPに適しているからです @Lambada</p>
<p>素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。@nonstarter</p>
</blockquote>
<p>まあ、その他枚挙に暇がなくキリがないので、この程度にしておきますが、 <br>
好き勝手な言い分のJavaScriptをもって、好き勝手な言い分のFRPで関数型プログラミングしたことと、FRPと極めて親和性の高いJavaScriptのフロントエンドとしてのReactのおかげで、かなり楽にコーディングできました。</p>
<p>ではOCamlでFRPを使わない関数型プログラミングでの実装のコードを見れる日は来るんでしょうか? <br>
できたら知らせてください。お互いのコードを比較して精査してみましょう。どんなコードが出てくるんでしょうか?</p>
<p>精査して、簡潔さにおいて比較しうるに足る代物が出せたのなら、次のレベルに進めましょう。これでもまだ「状態渡し」で誤魔化しきれるかもしれないから。その懸念だけがある。</p>
<p>あああと、駱駝に言っておきますが、自分が不慣れな理解できないコードを眺めて「スパゲッティ・コード」と侮辱するのは悪い癖です。止めなさい。そして、「無意味に複雑・冗長」だと思うなら、ハッタリでないのなら、切り詰めて簡約したコードをさっと出しましょう。今回も「無意味に複雑・冗長」な「スパゲッティ・コード」と思うのならば、どの部分がそうなのか?明示した上で書き直したものを見せてください。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-13063459610011784622016-05-18T16:01:00.001+09:002016-05-18T16:12:23.358+09:00「これ以上は説明も回答もしない。」という嘘説明のFRPの基本原理コードなるもの<p>前回のエントリ記事、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2016/05/frp.html">本来のFRPを理解せず中傷を重ねる連中への再度宿題</a> <br>
にて、</p>
<p>以下再掲</p>
<hr>
<p><a href="http://anond.hatelabo.jp/20160516113354">http://anond.hatelabo.jp/20160516113354</a></p>
<blockquote>
<p>関数型って時間はパラメータで与えて結果を得るんじゃないの</p>
<blockquote>
<p>刻々と変化する「現在時間」を抽象化したインデックス</p>
</blockquote>
<p>を変数で持ってたら、命令型じゃないの</p>
</blockquote>
<p>だとか、</p>
<p><a href="http://anond.hatelabo.jp/20160517022608">http://anond.hatelabo.jp/20160517022608</a></p>
<blockquote>
<p>それをユーザから見て命令型変数への破壊的代入ではなく <br>
参照透明な関数型インターフェースで実現するのが <br>
いわゆるモナドや(誰かの独自解釈ではない本来の)FRP。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160517023637">http://anond.hatelabo.jp/20160517023637</a></p>
<blockquote>
<p>ライブラリユーザは現在時刻から状態への写像fを <br>
参照透明な関数なりストリームなりで記述して、 <br>
それを処理系が実際のシステム時刻t=0,1,2,…に適用して <br>
状態f(0),f(1),f(2),…を得る、という本来のFRPの基本原理</p>
</blockquote>
<p>とか、君独自の勘違いFRPの解釈「本来のFRPの基本原理」で、書けるもんなら、 <br>
そのインデックスで、 <br>
システム時刻t=0,1,2,…に適用して状態f(0),f(1),f(2),…を得るという本来のFRPの基本原理で、 <br>
現在の状態を表せるとするFRP方式で、「お絵かきアプリ」をささっと実装してみせてください。</p>
<p><code>Date.now()</code>であれ、 <br>
<code>__a.t</code>であれ、 <br>
「現在時間」というのは、本来的に「それ以外のシンボル」では表現できないので、 <br>
どういう魔法を使うのかたいへん興味があります。</p>
<p>以上、「本来のFRP 」を理解しておらず、出来もしない絵空事、机上の空論をあいも変わらず垂れ流してる例の自称関数型コミュニティへの宿題でした。</p>
<hr>
<p>再掲終わり</p>
<p>と、「宿題」を出したところ、早速反応があったようです。</p>
<p><a href="http://anond.hatelabo.jp/20160517162141">http://anond.hatelabo.jp/20160517162141</a></p>
<blockquote>
<p>nonstarter氏をはじめもう1年ぐらい前から何度も示されてるんですが(以下無限ループ)</p>
</blockquote>
<p>はい、嘘ですね。そんな彼ら独自の主張の路線のFRPコードなどどこにも示されていません。</p>
<p>連中の書き込み、 <br>
<a href="http://anond.hatelabo.jp/20160518122300">http://anond.hatelabo.jp/20160518122300</a> <br>
によると、 <br>
具体例は以下らしいです(笑)</p>
<blockquote>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b</a> <br>
main = playBanana disp colour freq gen <br>
<a href="https://hackage.haskell.org/package/gloss-banana-0.1.0.4/docs/src/Graphics-Gloss-Interface-FRP-ReactiveBanana.html">https://hackage.haskell.org/package/gloss-banana-0.1.0.4/docs/src/Graphics-Gloss-Interface-FRP-ReactiveBanana.html</a> <br>
playIO display colour frequency () <br>
(\ _ → readIORef pictureref) <br>
(\ ev _ → () <<script type="math/tex" id="MathJax-Element-282"> event ev)
(\ time _ → () <</script> tick time) <br>
<a href="https://hackage.haskell.org/package/gloss-1.10.1.1/docs/src/Graphics-Gloss-Interface-IO-Game.html">https://hackage.haskell.org/package/gloss-1.10.1.1/docs/src/Graphics-Gloss-Interface-IO-Game.html</a> <br>
playIO display backColor simResolution <br>
worldStart worldToPicture worldHandleEvent worldAdvance <br>
= playWithBackendIO defaultBackendState <br>
display backColor simResolution <br>
worldStart worldToPicture worldHandleEvent worldAdvance <br>
False <br>
<a href="https://hackage.haskell.org/package/gloss-1.10.1.1/docs/src/Graphics-Gloss-Internals-Interface-Game.html">https://hackage.haskell.org/package/gloss-1.10.1.1/docs/src/Graphics-Gloss-Internals-Interface-Game.html</a> <br>
, Callback.Idle (callback_simulate_idle <br>
stateSR animateSR (readIORef viewSR) <br>
worldSR (\_ -> worldAdvance) <br>
singleStepTime) <br>
これ以上は説明も回答もしない。</p>
</blockquote>
<p>いやあのね、「これ以上は説明も回答もしない」って、そもそもこちらの「宿題」の説明にも回答にもなっておらないわけで、それ以上無理というのなら、まあ「想定の範囲内」で、案の定、適当ないつもの机上の空論だった、ということが、万人に追認される、証明されて、はいここまで終わり、ということで、 <br>
これ以上デマを流さない、という諦めの宣言とも取れるので、それは大変歓迎されることです。</p>
<p>一応、連中のハッタリ、嘘を精査して確認、証明していきましょう。</p>
<p>まず、冒頭の、</p>
<blockquote>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b</a> <br>
main = playBanana disp colour freq gen</p>
</blockquote>
<p>これですが、 <br>
この書き込みが意図するとこであろう、リンク先 <br>
『関数型プログラミングに目覚めた!』のレビュー(Day-1) <br>
の@nonstarter という捨てアカウントによる記事の該当部分は以下です。</p>
<blockquote>
<p>ちなみに、大した意味はありませんが、敢えてFRPライブラリ(Reactive-Banana)を使うとこうなります:</p>
</blockquote>
<pre class="prettyprint"><code class=" hljs avrasm">ReactiveBananaDrawingCanvas<span class="hljs-preprocessor">.hs</span>
import Data<span class="hljs-preprocessor">.Monoid</span> (mconcat)
import Reactive<span class="hljs-preprocessor">.Banana</span> (accumB)
import Graphics<span class="hljs-preprocessor">.Gloss</span><span class="hljs-preprocessor">.Interface</span><span class="hljs-preprocessor">.Pure</span><span class="hljs-preprocessor">.Game</span>
import Graphics<span class="hljs-preprocessor">.Gloss</span><span class="hljs-preprocessor">.Interface</span><span class="hljs-preprocessor">.FRP</span><span class="hljs-preprocessor">.ReactiveBanana</span> (playBanana)
main = playBanana disp colour freq gen
where
disp = (InWindow <span class="hljs-string">"Drawing Canvas"</span> (<span class="hljs-number">400</span>, <span class="hljs-number">400</span>) (<span class="hljs-number">40</span>, <span class="hljs-number">40</span>))
colour = white
freq = <span class="hljs-number">100</span>
gen deltaTime = return . fmap draw . accumB (False,[],[]) . fmap eTrans
draw (_, path, paths) = mconcat $ map line $ path:paths
eTrans (EventKey (MouseButton LeftButton) Down _ _ ) (_, path, paths) = (True, path, paths)
eTrans (EventKey (MouseButton LeftButton) Up _ _ ) (_, path, paths) = (False, [], path:paths)
eTrans (EventMotion pos) (True, path, paths) = (True, pos:path, paths)
eTrans _ world = world</code></pre>
<blockquote>
<p>FRPライブラリを使ってもコードが先のものと殆ど変わらないことに注意してください。要するにこれらのコードの本質は状態遷移を純粋な関数(ここではeTrans)で表現するところにあり、イベントストリームやシグナル・ビヘイビアといったFRP特有の要素を用いるか否かにはないということが示されています。</p>
</blockquote>
<hr>
<p>まず、何度も書いてますが、なんでOCamlで書けないんだ?ってことがあります。 <br>
そもそもこちらの投げかけが、ごちゃごちゃ文句言うなら「Ocamlで机上の空論じゃないこと示せ」とかいうのに、いちいちHaskellのライブラリ頼みだっていうのが、語るに落ちる状態を明確に表しています。</p>
<p>さて、コードについてですが、</p>
<blockquote>
<p>gen deltaTime = return . fmap draw . accumB (False,[],[]) . fmap eTrans</p>
</blockquote>
<p>という行で、<code>deltaTime</code> デルタタイム、つまりここでなんか、タイマーのインターバルとってるっぽいですが、結局、</p>
<blockquote>
<p>EventKey (MouseButton LeftButton) Down</p>
</blockquote>
<p>とか、やってることは、そのまマウスイベントを流してるだけで、いったいどこに、</p>
<p><a href="http://anond.hatelabo.jp/20160517023637">http://anond.hatelabo.jp/20160517023637</a></p>
<blockquote>
<p>ライブラリユーザは現在時刻から状態への写像fを <br>
参照透明な関数なりストリームなりで記述して、 <br>
それを処理系が実際のシステム時刻t=0,1,2,…に適用して <br>
状態f(0),f(1),f(2),…を得る、という本来のFRPの基本原理</p>
</blockquote>
<p>その「システム時刻t=0,1,2…」というインデックスから、 <br>
状態f(0),f(1),f(2),…を得るとかいう、彼らの言う「FRPの基本原理」みたいなもんがあるんですかね?(笑</p>
<p>残りは全部、使ってるライブラリのソースコードからfrequencyやリフレッシュレートやら、timerの解像度っぽいことをアピールしてるみたいですが、</p>
<p>タイマーの解像度設定しながらマウスイベントを同時にとってなんかやることと、</p>
<blockquote>
<p>実際のシステム時刻t=0,1,2,…に適用して <br>
状態f(0),f(1),f(2),…を得る、という本来のFRPの基本原理</p>
</blockquote>
<p>ってまったく違うでしょ? <br>
誤魔化すなと。</p>
<p>@nonstarterの書いたコードのどこに、<strong>「実際のシステム時刻t=0,1,2,…」</strong>をとった形跡があるのか? <br>
その<strong>実際のシステム時刻t</strong>のストリームのFRPの値はどこ? <br>
そしてどこに、<strong>状態f(t)</strong>とし取得している形跡があるのか?ってことです。</p>
<p>そんなもんはどこにも存在しない。 <br>
やってるのは、ただマウスイベントからFRP変数に流してるだけ。</p>
<p>まあ無理筋でいつもの、デタラメ、誤魔化しをやって、嘘でもなんでも、その場さえつくろえばいい、という考え方の連中なんで、真面目に受け取る学習者が被害を受ける毎度の害悪行為です。 <br>
わかってやってて、こうやって追求されると返しようがないこともわかってるので、 <br>
「これ以上は説明も回答もしない。」と予め逃げる予告をしている。</p>
<p>いやいや、あのね、こんなもんは嘘をつくだけ害悪で、こっちがこうやって逐一労力かけて指摘しないと、 <br>
思わせぶりのハッタリ行為になんか正しい意味がある、ああそうなんだ・・・ <br>
と信じてしまう人がでることをわかってわざとやってるんだろ? <br>
いい加減にしろよと。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-19028193661856043222016-05-17T11:41:00.001+09:002016-05-17T14:31:03.794+09:00本来のFRPを理解せず中傷を重ねる連中への再度宿題<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/05/timeengine-frp.html">TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)</a>について、</p>
<p>はてラボはてな匿名ダイアリーで、またいろいろ思い込みの激しい勘違いした批判が行われているので引用しながら、ひとつひとつ反論していきます。</p>
<p>ちなみに、今回も東北大の住井 英二郎@esumii、 <br>
自分が読み解けないFRPライブラリの実装について「スパゲッティ・コード」と書きなぐるだけの <br>
らくだの卯之助@camloebaも居るようです。オモテで名前出してやったら?卑怯者が、というところです。</p>
<hr>
<p><a href="http://anond.hatelabo.jp/20160517094425">http://anond.hatelabo.jp/20160517094425</a></p>
<blockquote>
<p>kenokabe氏のコードでもマウスが動くたびに同じ__drawFrom.tへの破壊的代入が行われるんですがそれは</p>
</blockquote>
<p>..</p>
<p><a href="http://anond.hatelabo.jp/20160517022608">http://anond.hatelabo.jp/20160517022608</a></p>
<blockquote>
<p>それをユーザから見て命令型変数への破壊的代入ではなく <br>
参照透明な関数型インターフェースで実現するのが <br>
いわゆるモナドや(誰かの独自解釈ではない本来の)FRP。 <br>
<a href="http://elm-lang.org/examples/time">http://elm-lang.org/examples/time</a></p>
</blockquote>
<pre class="prettyprint"><code class=" hljs mel">view : Model -&gt; Html Msg
view model =
let
<span class="hljs-keyword">angle</span> =
turns (Time.inMinutes model)
handX =
toString (<span class="hljs-number">50</span> + <span class="hljs-number">40</span> * <span class="hljs-keyword">cos</span> <span class="hljs-keyword">angle</span>)
handY =
toString (<span class="hljs-number">50</span> + <span class="hljs-number">40</span> * <span class="hljs-keyword">sin</span> <span class="hljs-keyword">angle</span>)
<span class="hljs-keyword">in</span>
svg [ viewBox <span class="hljs-string">"0 0 100 100"</span>, width <span class="hljs-string">"300px"</span> ]
[ <span class="hljs-keyword">circle</span> [ cx <span class="hljs-string">"50"</span>, cy <span class="hljs-string">"50"</span>, r <span class="hljs-string">"45"</span>, fill <span class="hljs-string">"#0B79CE"</span> ] []
, line [ x1 <span class="hljs-string">"50"</span>, y1 <span class="hljs-string">"50"</span>, x2 handX, y2 handY, <span class="hljs-keyword">stroke</span> <span class="hljs-string">"#023963"</span> ] []
]
</code></pre>
<blockquote>
<p>HaskellのライブラリもElmのような言語も、サンプルもJavaScript実装も <br>
ググればWikipediaで出てくるレベル。 <br>
<a href="https://en.wikipedia.org/wiki/Functional_reactive_programming#Implementations">https://en.wikipedia.org/wiki/Functional_reactive_programming#Implementations</a></p>
</blockquote>
<hr>
<p>まず、これなんですが、</p>
<blockquote>
<p>いわゆるモナドや(誰かの独自解釈ではない本来の)FRP。</p>
</blockquote>
<p>「(誰かの独自解釈)」というのは、おそらくこの投稿をした自分自身のことを自嘲的に言ってるのだと判断するしかないですが、 <br>
(誰かの独自解釈ではない本来の)FRP、というのは、ここで最前から書いておるように、再掲すると、</p>
<hr>
<p>念の為ですが、TimeEngineのプロジェクトgithub.io ページ <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
にも書いていますが、1997年の論文で、<a href="http://dl.acm.org/citation.cfm?id=258973">http://dl.acm.org/citation.cfm?id=258973</a></p>
<blockquote>
<p><strong>Fran (Functional Reactive Animation)</strong> 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. <strong>Behaviors are time-varying, reactive values,</strong> while events are sets of arbitrarily complex conditions, </p>
</blockquote>
<p>Fran (Functional Reactive Animation) として、初めてFRPを明示的にプログラミングパラダイムとして導入したことで知られているConal Elliottは、 <br>
<a href="http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming">http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming</a> <br>
において、こう宣言しています。</p>
<blockquote>
<p>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. <br>
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”.</p>
</blockquote>
<p>面倒なんで全部訳しませんが、ポイントは、</p>
<ul>
<li>FRP is about - “datatypes that represent a value ‘over time’ “</li>
<li>Dynamic/evolving values (i.e., values “over time”) are first class values in themselves. </li>
</ul>
<p>FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、 <br>
ということです。</p>
<hr>
<p>これで間違いありません。 <br>
私の以前から解釈しているFRPの特性とは、Conal Elliottが1997年に実装して発表し、 <br>
その後も各所で解説していて、 <br>
<a href="http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming">http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming</a> <br>
においても広くその見解の妥当性が認められているFRPの特性、概念と一致しています。</p>
<p>TimeEngineは、この <br>
FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、 <br>
ということを簡潔に実装したFRPライブラリです。</p>
<p>ちなみに、</p>
<blockquote>
<blockquote>
<p>HaskellのライブラリもElmのような言語も、サンプルもJavaScript実装も <br>
ググればWikipediaで出てくるレベル。 <br>
<a href="https://en.wikipedia.org/wiki/Functional_reactive_programming#Implementations">https://en.wikipedia.org/wiki/Functional_reactive_programming#Implementations</a></p>
</blockquote>
</blockquote>
<p>という「レベル」なるものについてですが、この多くは、 <br>
FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、 <br>
という「本来のFRPのパラダイム」が中心でなかったり、本末転倒なものが多く紛れ込んでおり、 <br>
「ググればWikipediaで出てくるレベル」というのが惨憺たる状況である多くの例のひとつであるといえます。</p>
<p>たとえば、この人物がいう(おそらく匿名で繰り返し言ってる)「Elmのような言語」ですが、 <br>
海外の掲示板では以前から</p>
<blockquote>
<p>Neither Rx nor Elm are FRP. If you want FRP, look at Conal Elliott’s work.</p>
</blockquote>
<p>「RxもElmもFRPではない。FRPがほしけりゃ、Conal Elliottの仕事を見ろ」 <br>
などと「本来のFRP」とのパラダイムのズレが指摘されていました。 <br>
パラダイムっていうものは、かようにWikipediaのリストごときで十把一絡げに簡単に論じれるようなものではなく、 <br>
関数型、オブジェクト指向しかり、たいがい論争に発展するようなものであり、 <br>
いろいろ意見を言うのは結構だが、そんなググってWikipediaのリストで「レベル」がどうのこうの断じるのは、この人物のレベルの底が知れるというものです。まあ、例の東北大の住井にしろ、あいかわらずいつもの匿名による発信なんで、文責も負わない、恥もかき捨てで結構なことですよね(笑</p>
<p>次に、</p>
<blockquote>
<p>命令型変数への破壊的代入</p>
</blockquote>
<p>とかいう、まあ、上記で示した本来のFRPの「意味」ってのを理解してないので、こういうことを平気で言えるんでしょうが、</p>
<p>TimeEngineによる、たとえば、</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute">const __a </span>=<span class="hljs-string"> __();</span></code></pre>
<p>として、定義されたものは、上記のとおり、 <br>
「動的に時間発展する値(つまり時間軸上の値)はファーストクラス」 <br>
であり、その集合のうちの現在時間を指し示すものが、 <br>
<code>__a.t</code>です。</p>
<p>JavaScriptの<a href="https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0ahUKEwiO3cTu_t_MAhXEMqYKHYAsAekQFggcMAA&url=https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date&usg=AFQjCNHxFcnh8oqX4Hy4iP9q9pnlF7xt2w&sig2=Zf4xG_wJDLkYEUkHyfx_Mw">Date</a>で考えれば、</p>
<p><code>Date.now()</code> <br>
であり、「現在時間」というのは、本来的に「それ以外のシンボル」では表現できません。</p>
<p><code>__a</code> というのは、 <br>
「動的に時間発展する値(つまり時間軸上の値)はファーストクラス」 <br>
という集合値であり、名実ともに、Constantでイミュータブルな値です。 <br>
そのうちの「現在時間」というのは、「読み出した時点」で一意に自明的に決定されるわけで、 <br>
<code>__a.t</code>というのは、</p>
<blockquote>
<p>命令型変数</p>
</blockquote>
<p>でもなければ、「破壊的代入」するものでもありません。</p>
<p>たとえば、それこそ東北大の住井らしき人物がまた匿名で、</p>
<p><a href="http://anond.hatelabo.jp/20160516112619">http://anond.hatelabo.jp/20160516112619</a></p>
<blockquote>
<p>kenokabeさんの心の中ではそうなのかもしれませんが、ライブラリのユーザから客観的に見れば(分析哲学ではなく関数型言語の意味で)参照不透明なので、関数型プログラミングのメリットは享受できない、命令型の破壊的代入と等価ですね。</p>
</blockquote>
<p>であるとか、</p>
<p><a href="http://anond.hatelabo.jp/20160516192742">http://anond.hatelabo.jp/20160516192742</a></p>
<blockquote>
<p>実際、timeengine.js を読み込んだ状態で、以下のようになります。</p>
</blockquote>
<pre class="prettyprint"><code class=" hljs avrasm">> const __x = __()<span class="hljs-comment">;</span>
undefined
> __x<span class="hljs-preprocessor">.t</span> = <span class="hljs-number">1</span><span class="hljs-comment">;</span>
<span class="hljs-number">1</span>
> __x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span>
<span class="hljs-number">2</span>
> __x<span class="hljs-preprocessor">.t</span><span class="hljs-comment">;</span>
<span class="hljs-number">2</span></code></pre>
<blockquote>
<p>これは岡部健氏が著書で「論理破綻」と批判していた、命令型言語の破壊的代入そのものです。 <br>
なお私を他の誰かと決めつけるのは、その方たちにご迷惑ですのでおやめください。 <br>
……と言っても聞き入れていただけるとは思えないので、私ももうこれ以上の書き込みはやめます。 <br>
できるだけ丁寧に技術的な誤りだけを指摘したつもりですが、やはり誹謗中傷しか返ってこないようで残念です。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160517094425">http://anond.hatelabo.jp/20160517094425</a></p>
<p>などと書いているのですが、いま説明しているように、</p>
<pre class="prettyprint"><code class=" hljs vbscript"><span class="hljs-built_in">Date</span>.<span class="hljs-built_in">now</span> = <span class="hljs-built_in">Date</span>.<span class="hljs-built_in">now</span> + <span class="hljs-number">1</span></code></pre>
<p>というステートメントが、概念的な意味を成さないように、 <br>
=の両辺が等しいという、関数型プログラミングのパラダイムにおいては、</p>
<pre class="prettyprint"><code class=" hljs avrasm">__x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span></code></pre>
<p>というFRPライブラリの使用は概念的な意味を成しません。 <br>
なんでこういうことをするのか?というと、なんか悪意があるか、 <br>
それとも、FRPが「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
ということを全く理解していないから、こういう文句のつけかた、それこそ誹謗中傷をして平気なのでしょう。</p>
<p>あえてこの住井らしき人物がわざとやらかした「破壊的代入」という命令型パラダイムにおいて、考えてみると、この人物の意図によると、 <br>
「右辺の現在値」を「左辺の現在値」に代入するという命令型の時系列的意図しかありえないでしょうから、</p>
<p>右辺の現在値に1を加えて、改めて、左辺の現在地とする</p>
<p>ということです、つまり、左辺、右辺の現在時間が異なる、FRPライブラリにおいては、 <br>
<code>.t</code>によって表現される時刻による「時間軸上の値」は異なって当然であるということになります。</p>
<p>よって、</p>
<pre class="prettyprint"><code class=" hljs avrasm">__x<span class="hljs-preprocessor">.t</span> = __x<span class="hljs-preprocessor">.t</span> + <span class="hljs-number">1</span><span class="hljs-comment">;</span></code></pre>
<p>というのは、 <br>
右辺を評価した現在時間における <br>
__x上のある値に1を加えたものを <br>
次の瞬間以降の <br>
__x上の値として更新する、という意味合いになります。</p>
<p>もちろん、これは、=の左右で値が異なるという命令型ステップの解釈であり、 <br>
そういう命令形パラダイムを大前提とした記法においては、TimeEngineの振る舞いはこう解釈される、 <br>
ということにすぎませんし、そのような記法を禁じるようなSanityCheckを実装しているわけではありません、 <br>
ご自由にどうぞ、といったところでしょうか。</p>
<p>また、</p>
<p>次に、</p>
<p><a href="http://anond.hatelabo.jp/20160516113354">http://anond.hatelabo.jp/20160516113354</a></p>
<blockquote>
<p>関数型って時間はパラメータで与えて結果を得るんじゃないの</p>
<blockquote>
<p>刻々と変化する「現在時間」を抽象化したインデックス</p>
</blockquote>
<p>を変数で持ってたら、命令型じゃないの</p>
</blockquote>
<p>などという意味不明な書き込みもあります。</p>
<p>「お絵かきアプリ」みたいな <br>
「現在時間におけるマウス座標」を保持するときには、</p>
<p><code>Date.now()</code> <br>
であり、「現在時間」というのは、本来的に「それ以外のシンボル」では表現できません。</p>
<p>と書いたとおり、 <br>
「>>刻々と変化する「現在時間」を抽象化したインデックス」 <br>
つまり、<code>now</code>やら<code>t</code>以外では、原理的に不可能です。</p>
<p>さーて、この勘違いした連中がいったいどういう魔法を使って <br>
「現在時間における状態」について <br>
「関数型って時間はパラメータで与えて結果を得る」のか是非見てみたいものです。 <br>
100%無理でしょうが(苦笑</p>
<p>「関数型って時間はパラメータで与えて結果を得る」とか書いてるってことは、 <br>
もはや、限定された「状態渡し」ではない、「この連中なりの独自解釈におけるFFP」のお話をしているつもりなのでしょうから、 <br>
FRPをつかって、「関数型って時間はパラメータで与えて結果を得る」という設計で、 <br>
お絵かきアプリを実装してみせてください。これが当方からのこの連中への課題ということになります。</p>
<p>さて、この件について、「非常に悪質な誤魔化し」が現在進行中であることも当然抑えておかなければなりません。それがすなわち、冒頭に示したコードです。</p>
<blockquote>
<p>それをユーザから見て命令型変数への破壊的代入ではなく <br>
参照透明な関数型インターフェースで実現するのが <br>
いわゆるモナドや(誰かの独自解釈ではない本来の)FRP。 <br>
<a href="http://elm-lang.org/examples/time">http://elm-lang.org/examples/time</a></p>
</blockquote>
<pre class="prettyprint"><code class=" hljs mel">view : Model -&gt; Html Msg
view model =
let
<span class="hljs-keyword">angle</span> =
turns (Time.inMinutes model)
handX =
toString (<span class="hljs-number">50</span> + <span class="hljs-number">40</span> * <span class="hljs-keyword">cos</span> <span class="hljs-keyword">angle</span>)
handY =
toString (<span class="hljs-number">50</span> + <span class="hljs-number">40</span> * <span class="hljs-keyword">sin</span> <span class="hljs-keyword">angle</span>)
<span class="hljs-keyword">in</span>
svg [ viewBox <span class="hljs-string">"0 0 100 100"</span>, width <span class="hljs-string">"300px"</span> ]
[ <span class="hljs-keyword">circle</span> [ cx <span class="hljs-string">"50"</span>, cy <span class="hljs-string">"50"</span>, r <span class="hljs-string">"45"</span>, fill <span class="hljs-string">"#0B79CE"</span> ] []
, line [ x1 <span class="hljs-string">"50"</span>, y1 <span class="hljs-string">"50"</span>, x2 handX, y2 handY, <span class="hljs-keyword">stroke</span> <span class="hljs-string">"#023963"</span> ] []
]
</code></pre>
<p>これは、アナログ時計のコードなんですが、 <br>
アナログ時計のコードって、「現在時間」を表現していますが、 <br>
現在の状態について、「時間はパラメータで与えて結果を得る」コードでもなんでもありません。</p>
<p>この時間の離散値を得た上で、FRPに流し込むというのは、 <br>
TimeEngineで、前からさんざんやっていて、それはだから、物理の斜方投射のDemoでもっと高度な形でやっているわけです。</p>
<p><a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
の <br>
Demo #3ですね。</p>
<pre class="prettyprint"><code class=" hljs coffeescript"><span class="hljs-reserved">const</span> t = __
.intervalSeq(Immutable.Range(), <span class="hljs-number">10</span>)
.__<span class="hljs-function"><span class="hljs-params">((count) => (count * <span class="hljs-number">10</span> / <span class="hljs-number">1000</span>))</span>;
<span class="hljs-title">const</span> <span class="hljs-title">x</span> = <span class="hljs-title">__</span><span class="hljs-params">([t])</span>.<span class="hljs-title">__</span><span class="hljs-params">(([t]) => V0 * Math.cos(THETA) * t)</span>;
<span class="hljs-title">const</span> <span class="hljs-title">y</span> = <span class="hljs-title">__</span><span class="hljs-params">([t])</span>.<span class="hljs-title">__</span><span class="hljs-params">(([t]) => V0 * Math.sin(THETA) * t - <span class="hljs-number">1</span> / <span class="hljs-number">2</span> * G * Math.pow(t, <span class="hljs-number">2</span>))</span>;</span></code></pre>
<p>というわけで、Immutable.jsの無限ストリームを10マイクロセカンド解像度で、時間軸にマップして <br>
<code>const t</code> を得ています。</p>
<p>このなんか嬉しそうに貼り付けてきたアナログ時計っていうのは、ようするにそれの劣化版でしょ? <br>
それでですね。こういう時刻の離散値ストリームを本来のFRP値として、このように、</p>
<p><code>const t</code>として表現することなんて普通にできるわけですが、 <br>
この<code>t</code>をもって「現在時間値」を表現することは「不可能」です。 <br>
だって、<code>t</code>が表すのは、「動的に時間発展する値(つまり時間軸上の値)」でしかないわけで、 <br>
「現在値」というのは、それ以外のシンボルでは表しようがない、 <br>
なにかカウントされたインデックスで表せるわけがないわけで、それを抽象化したものを<code>.t</code>とし、 <br>
<code>t.t</code>とするしか方法はありません。</p>
<p>TimeEngineは当然私が自分自身で実装したので仕掛けは熟知していますが、 <br>
この、</p>
<pre class="prettyprint"><code class=" hljs perl">const t = _<span class="hljs-number">_</span>
.intervalSe<span class="hljs-string">q(Immutable.Range()</span>, <span class="hljs-number">10</span>)
._<span class="hljs-number">_</span>((count) => (count * <span class="hljs-number">10</span> / <span class="hljs-number">1000</span>));</code></pre>
<p>というのは、根本的には、SetIntervalもしくはSetTimeoutのラッパーで、 <br>
タイマーのイベントドリブンの周期をImmutable.jsの無限ストリームで表現しています。</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute">angle </span>=<span class="hljs-string">
turns (Time.inMinutes model)</span></code></pre>
<p>もこれは、根本的には、タイマーのイベントドリブンです。</p>
<p>タイマーのイベントドリブンでやってるのと、 <br>
マウスのイベントドリブンでやってるのは同じだし、</p>
<blockquote>
<p>システム時刻t=0,1,2,…に適用して状態f(0),f(1),f(2),…を得る</p>
</blockquote>
<p>なんて動作はこのアナログ時計のコードはやっていません。</p>
<p>実際に、私は「お絵かきアプリ」のトイコードを書くときに、 <br>
<code>const t</code> なんてものをインデックスとして取得することなどしていません。 <br>
それは単に、根源的にはタイマーイベントであり、 <br>
マウスのアプリは、マウスのイベントでアプリは挙動するからです。 <br>
アナログ時計のアプリが、タイマーのイベントを取るのは当たり前で、 <br>
それは、</p>
<blockquote>
<p>システム時刻t=0,1,2,…に適用して状態f(0),f(1),f(2),…を得る</p>
</blockquote>
<p>という「FRPの根本原理(笑)」だから、そうなってる、わけもありません。</p>
<p>現在の状態は、システム時刻のインデックスでやるのが、関数型で、FRP、とか、まあ大嘘で、 <br>
この連中が無知と勘違いでデマや嘘を垂れ流している様子にはいい加減辟易しています。</p>
<p>“</p>
<p><a href="http://anond.hatelabo.jp/20160517023637">http://anond.hatelabo.jp/20160517023637</a></p>
<blockquote>
<p>命令型プログラムをFRPとか言ってる人が決定的に理解していない点は、 <br>
ライブラリユーザは現在時刻から状態への写像fを <br>
参照透明な関数なりストリームなりで記述して、 <br>
それを処理系が実際のシステム時刻t=0,1,2,…に適用して <br>
状態f(0),f(1),f(2),…を得る、という本来のFRPの基本原理だと思う。 <br>
まさに実装は命令的だけど(誰かさんもそこは正しい)、 <br>
ライブラリユーザは参照透明な関数型の記述が可能。</p>
</blockquote>
<p>うんだから、この人物が言う「本来のFRPの基本原理」というのは完全に間違っているし、 <br>
書き換えてあげると、 <br>
処理系の実際のシステム時刻t=0,1,2,…を <br>
- FRP is about - “datatypes that represent a value ‘over time’ ” <br>
- Dynamic/evolving values (i.e., values “over time”) are first class values in themselves. </p>
<p>FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、</p>
<p>という時間軸上にマップして、</p>
<pre class="prettyprint"><code class=" hljs perl">const t = _<span class="hljs-number">_</span>
.intervalSe<span class="hljs-string">q(Immutable.Range()</span>, <span class="hljs-number">10</span>)
._<span class="hljs-number">_</span>((count) => (count * <span class="hljs-number">10</span> / <span class="hljs-number">1000</span>));</code></pre>
<p>別の状態に再度マップする、</p>
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-reserved">const</span> x = __<span class="hljs-function"><span class="hljs-params">([t])</span>.<span class="hljs-title">__</span><span class="hljs-params">(([t]) => V0 * Math.cos(THETA) * t)</span>;
<span class="hljs-title">const</span> <span class="hljs-title">y</span> = <span class="hljs-title">__</span><span class="hljs-params">([t])</span>.<span class="hljs-title">__</span><span class="hljs-params">(([t]) => V0 * Math.sin(THETA) * t - <span class="hljs-number">1</span> / <span class="hljs-number">2</span> * G * Math.pow(t, <span class="hljs-number">2</span>))</span>;</span></code></pre>
<p>ことくらいは、こっちはとっくの昔にやってみせているわけ。いいかな?</p>
<p>そうじゃなくて、ここでの問題は、再三いいますが、</p>
<p><a href="http://anond.hatelabo.jp/20160516113354">http://anond.hatelabo.jp/20160516113354</a></p>
<blockquote>
<p>関数型って時間はパラメータで与えて結果を得るんじゃないの</p>
<blockquote>
<p>刻々と変化する「現在時間」を抽象化したインデックス</p>
</blockquote>
<p>を変数で持ってたら、命令型じゃないの</p>
</blockquote>
<p>だとか、</p>
<p><a href="http://anond.hatelabo.jp/20160517022608">http://anond.hatelabo.jp/20160517022608</a></p>
<blockquote>
<p>それをユーザから見て命令型変数への破壊的代入ではなく <br>
参照透明な関数型インターフェースで実現するのが <br>
いわゆるモナドや(誰かの独自解釈ではない本来の)FRP。</p>
</blockquote>
<p><a href="http://anond.hatelabo.jp/20160517023637">http://anond.hatelabo.jp/20160517023637</a></p>
<blockquote>
<p>ライブラリユーザは現在時刻から状態への写像fを <br>
参照透明な関数なりストリームなりで記述して、 <br>
それを処理系が実際のシステム時刻t=0,1,2,…に適用して <br>
状態f(0),f(1),f(2),…を得る、という本来のFRPの基本原理</p>
</blockquote>
<p>とか、君独自の勘違いFRPの解釈「本来のFRPの基本原理」で、書けるもんなら、 <br>
そのインデックスで、 <br>
システム時刻t=0,1,2,…に適用して状態f(0),f(1),f(2),…を得るという本来のFRPの基本原理で、 <br>
現在の状態を表せるとするFRP方式で、「お絵かきアプリ」をささっと実装してみせてください。</p>
<p><code>Date.now()</code>であれ、 <br>
<code>__a.t</code>であれ、 <br>
「現在時間」というのは、本来的に「それ以外のシンボル」では表現できないので、 <br>
どういう魔法を使うのかたいへん興味があります。</p>
<p>以上、「本来のFRP 」を理解しておらず、出来もしない絵空事、机上の空論をあいも変わらず垂れ流してる例の自称関数型コミュニティへの宿題でした。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-30923617856757761032016-05-06T23:04:00.001+09:002016-05-08T12:46:23.541+09:00TimeEngine お絵かきアプリ(関数型リアクティブプログラミング/FRPのトイプログラム)<p>TimeEngine <br>
<a href="https://www.npmjs.com/package/timeengine">https://www.npmjs.com/package/timeengine</a> <br>
<a href="https://github.com/TimeEngine/timeengine">https://github.com/TimeEngine/timeengine</a> <br>
プロジェクトgithub.io ページ <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
の「素朴実在論」の画像リンクなどが切れていたので、メンテナンスついでに <br>
お絵かきアプリのLIVE-DEMOを追加しました。</p>
<h2 id="demo-9">Demo #9</h2>
<h3 id="simple-draw">Simple Draw</h3>
<p>のところに</p>
<h1 id="draw-here">DRAW HERE ↓</h1>
<p>として実装したCanvasを埋め込んでいます。</p>
<p>念の為にソースコードを再掲:</p>
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-reserved">const</span> canvas = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'canvas1'</span>);
<span class="hljs-reserved">const</span> ctx = canvas.getContext(<span class="hljs-string">'2d'</span>);
<span class="hljs-reserved">const</span> __mouseDown = __();
<span class="hljs-reserved">const</span> __drawFrom = __();
<span class="hljs-reserved">const</span> __drawTo = __()
.__(
<span class="hljs-function"><span class="hljs-params">(val)</span> =></span> {
ctx.beginPath();
ctx.moveTo(__drawFrom.t.x, __drawFrom.t.y);
ctx.lineTo(val.x, val.y);
ctx.closePath();
ctx.stroke();
__drawFrom.t = val;
<span class="hljs-keyword">return</span> val;
}
);
canvas.<span class="hljs-function"><span class="hljs-title">onmousedown</span> = <span class="hljs-params">(e)</span> =></span> {
__mouseDown.t = <span class="hljs-number">1</span>;
__drawFrom.t = {
<span class="hljs-attribute">x</span>: e.clientX,
<span class="hljs-attribute">y</span>: e.clientY
};
};
canvas.<span class="hljs-function"><span class="hljs-title">onmouseup</span> = <span class="hljs-params">(e)</span> =></span> {
__mouseDown.t = <span class="hljs-number">0</span>;
};
canvas.<span class="hljs-function"><span class="hljs-title">onmousemove</span> = <span class="hljs-params">(e)</span> =></span> {
<span class="hljs-keyword">if</span> (__mouseDown.t === <span class="hljs-number">1</span>) {
__drawTo.t = {
<span class="hljs-attribute">x</span>: e.clientX,
<span class="hljs-attribute">y</span>: e.clientY
};
}
};</code></pre>
<p>なぜ今、「お絵かきアプリ」なのかというと、まあ以前から何かとあちらこちらであることないこと吹聴して当方を中傷誹謗してきた住井 英二郎@esumii、らくだの卯之助@camloebaなどが存在していて(こちらは文句言われてることに気がつくまでこの関数型プログラミング界隈のろくでもない連中のことなど知らんかった)、彼らがOCamlに傾倒しているのは勝手だし、結構なことだが、まあお世辞にも一般的に実用的なアプリの範疇で普及しているとは言い難いOCamlのようなプログラミング言語をもって、広く一般的なプログラマあるいはこれから実用的なアプリを書こうとしようと勉強している初学者に向けて、まるでその延長線上で実用的なアプリが書けるかのようなトーンでいろいろ言っていることに苦言を呈したことがありました。つまり、入門者が一生懸命やったって「出口」が見えにくい、ということです。</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<blockquote>
<p>個人的に、OCamlを振り回して、国内で関数型プログラミングで、なんかこういう、私の主張にたいしても上から目線で偉そうにごちゃごちゃ文句いってくる連中が、GUIアプリ書いてる事象を目撃したことがこれまで一度もない。 <br>
なんで?</p>
</blockquote>
<p>そういうことです。</p>
<p>そうすると、まあ嘘くさい喧伝への批判、つまり実用的なスキームにおけるポテンシャルの限界という、彼らが初学者にはけして(正直に)語らない要素はの指摘は彼らにとっては触れられたくない、気に入らない要素であるわけで、 <br>
<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b</a> <br>
例の当方への批判記事に即座に <br>
<em>追記(2015/05/30):デスクトップアプリケーション??</em></p>
<p>という追記が@nonstarterなる捨てアカウントの人物よりなされました。(基本、著作について著者の実名をもって批判する際にこのように匿名の捨てアカウントで批判するのは、卑怯だと思いますし、住井 英二郎@esumii、らくだの卯之助@camloebaについても、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2016/01/qiita-esumiicamloeba8.html">Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について</a>というように、極めて卑劣な手段をもって、当方に「対抗」しようとしているとか、もうこの関数型プログラミングにまつわる連中の姿勢、行動の一切合切が胡散臭く、単なる「関数型プログラミングコミュニティ」とかいうろくでもない縄張り意識を守りたいがためになんか攻撃してくる、程度のことでしょう。)</p>
<blockquote>
<p>著者はブログで@camloebaさんや@esumiiさんにデスクトップアプリケーションをOCamlで作成するように求めているようです。著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません(当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。 <br>
(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)</p>
</blockquote>
<p>まず、「単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません」ということですが、彼自身自覚したコメントで突っ込みがあるように、「OCaml の全ての GUI ライブラリは状態は副作用を使うことを前提にメインループが設計されている」わけで、そんなことは、巷のOCamlの関数型の本のくせに実用むけ章になった途端に破壊的代入しまくりで「なんじゃこれ、関数型じゃないし」と私が書いて、連中がなんか怒っちゃたくだりでもう終わってる話です。</p>
<p>追記の後半部分の(追記)は重要で、まさに語るに落ちるという感じで興味深いです。</p>
<blockquote>
<p>原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。</p>
</blockquote>
<p>とか、こちらはそもそも実用的な観点から、そんなもんは無理筋だ、という論旨の展開をしておるのに、「原理的に不可能でないなら」「という趣旨には十分です。」と、また机上の空論ぶりを全開に吐露したり、「またこの主張自体はHaskellでのコードによっても充分に示されています。」とか、なんでOCamlの実用的な限界を論じているのにHaskellのコードによってでしか「充分に示されない」のか?とかツッコミどころが満載で、非常におもしろいです。</p>
<p>もう一度確認すると、私の基本的な観察としては、</p>
<blockquote>
<p>個人的に、OCamlを振り回して、国内で関数型プログラミングで、なんかこういう、私の主張にたいしても上から目線で偉そうにごちゃごちゃ文句いってくる連中が、GUIアプリ書いてる事象を目撃したことがこれまで一度もない。 <br>
なんで?</p>
</blockquote>
<p>というのがあるのですが、この第三者が指摘したとおり、既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難であろう、ことは状況をざっと見れば誰でもすぐにわかります。</p>
<p>そりゃチューリング完全なプログラミング言語であれば「原理的」に実現不可能なプログラミング課題というのは存在しないのですが、「原理的」とか机上の空論のおはなしではなくて、実際上の観点から言うと、OCamlというのは、そもそもそういう入出力が発生する時間遷移することが主題の実用的なデスクトップアプリケーションの実現にまったく熱心ではない言語環境である、程度の共通理解は得られるでしょう。</p>
<p>OCamlは関数型プログラミング言語を標榜している一方で、GUI関連になると明らかに非関数型でしか書けない解説で満ち溢れていて、複雑なGUI、入出力の段になると関数型で書くことが困難な自覚はあるっぽい。「既存のGUIライブラリを前提にスケールするコードを書こうとするとOCamlでは困難」。しかし何故か、FAQ.入出力は「純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。」などと、ぶちあげるだけはぶちあげて、将来的にその言葉を信じてついていった学習者が壁にぶち当たることはけして解説されていない、という胡散臭い状況があるわけです。</p>
<p>こういった問題の象徴として出てきたのがこの「お絵かきロジック」あるいは「お絵かきアプリ」です。 <br>
関数型プログラミングの文脈からいくと、あくまで原理的でも机上の空論でもない関数型プログラミングとしての軸をとると、関数型リアクティブプログラミング(FRP)が必要になります。</p>
<p>今回私が自作のFRPライブラリのDEMOコードとして追加した、当記事の冒頭のお絵かきアプリのコードは極めて簡潔ですが、簡潔に書けるのはあくまでもFRPで設計してるからです。念の為ですが、すべての値は、<code>const</code>となっています。</p>
<p>さて、@nonstarterなる捨てアカウントの人物の言い分によると、</p>
<blockquote>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<p>だそうです。 <br>
まったくわけのわからない言い分ですね。</p>
<p>大事なポイントは、「(状態渡し)」で時間遷移していく、複雑なことが普通である実用的アプリケーションを書こうとすると、</p>
<ul>
<li><p>状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる</p></li>
<li><p>そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い</p></li>
</ul>
<p>ということです。まあこの捨てアカウントの人物はその程度の理解と自覚はしっかりあるようですし、ここまでは言ってる意味はわかるし、普通に正しい(それ以降は全部間違っていますが)。</p>
<p>彼が言ってる正しい部分をまさに私は指摘している。それは根本的に、時間遷移の概念を関数型のパラダイムに抽象化したFRPを適用していないのが問題なのであって、あんたらはそんなことは一切触れずに、まるで、「(状態渡し)」で最終的になんでもできるかのように、初学者に向けても説明してるじゃないか、というか、実際、OCamlで実用的なデスクトップアプリを書いてるのみたことないけど、できるの?そんなに言うなら書いて見せてよ?、、、というところまでが、私の「問題提起」なのでした。</p>
<p>ここまでは当然この胡散臭い捨てアカウントも理解しているようですが、続いて、</p>
<blockquote>
<p>結局のところ少なくとも現状のFRPも本質的には銀の弾丸にはならないと言わなければなりません</p>
</blockquote>
<p>(多分何がなんでも自分の理解を超える要素は否定したいと大風呂敷を広げる) <br>
一応とってつけた理由:</p>
<blockquote>
<p>(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)</p>
</blockquote>
<p>???????意味不明。 <br>
まあ、この人物がFRPが何たるか理解していないのは、ほぼ確実でしょう。 <br>
FRPの本質は「時間軸」のプログラミング言語上での抽象化であり、なんかわけわかりませんが、この一連の議論で、FRPという言葉さえでてくるも、「時間」とか言っているのが私ただひとりだけ、という非常にわけのわからない、もとい、ある意味、連中がどういう知見レベルをもって当方を批判、あるいは中傷しているのかが非常にわかりやすい状況です。</p>
<p>念の為ですが、TimeEngineのプロジェクトgithub.io ページ <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
にも書いていますが、1997年の論文で、<a href="http://dl.acm.org/citation.cfm?id=258973">http://dl.acm.org/citation.cfm?id=258973</a></p>
<blockquote>
<p><strong>Fran (Functional Reactive Animation)</strong> 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. <strong>Behaviors are time-varying, reactive values,</strong> while events are sets of arbitrarily complex conditions, </p>
</blockquote>
<p>Fran (Functional Reactive Animation) として、初めてFRPを明示的にプログラミングパラダイムとして導入したことで知られているConal Elliottは、 <br>
<a href="http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming">http://stackoverflow.com/questions/1028250/what-is-functional-reactive-programming</a> <br>
において、こう宣言しています。</p>
<blockquote>
<p>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. <br>
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”.</p>
</blockquote>
<p>面倒なんで全部訳しませんが、ポイントは、</p>
<ul>
<li>FRP is about - “datatypes that represent a value ‘over time’ “</li>
<li>Dynamic/evolving values (i.e., values “over time”) are first class values in themselves. </li>
</ul>
<p>FRPは「時間軸上の値を表現したデータタイプ」についてのパラダイムである、 <br>
動的に時間発展する値(つまり時間軸上の値)はファーストクラスである、 <br>
ということです。</p>
<p>したがって、 <br>
「いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのこと」とか、そういうおはなしとは全く別の話題ですし、 <br>
FRPでは「(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくる)」なる言及は、FRPのパラダイムを論じる上で意味を成しません。</p>
<blockquote>
<p>(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<p>これもどういう意味なのか全く意味がわかりません。 <br>
とにかく、力づくで理屈を捻じ曲げても、とにかくFRPという彼にとっては新しい未知の概念の導入なんて無意味だ、ということを力説したいという熱意だけは伝わってきます。</p>
<blockquote>
<p>ちなみに、大した意味はありませんが、敢えてFRPライブラリ(Reactive-Banana)を使うとこうなります:</p>
</blockquote>
<p>大した意味がないどころか、FRPライブラリを導入するということは、時間軸上の展開している値をファーストクラスにして、時間発展する系を関数型プログラミングの枠組みで統一的に取り扱えるようにする、という甚大なパラダイムの変化であり、大きな意味があります。 <br>
</p>
<blockquote>
<p>FRPライブラリを使ってもコードが先のものと殆ど変わらないことに注意してください。要するにこれらのコードの本質は状態遷移を純粋な関数(ここではeTrans)で表現するところにあり、イベントストリームやシグナル・ビヘイビアといったFRP特有の要素を用いるか否かにはないということが示されています。</p>
</blockquote>
<p>そりゃさ、この程度ならば「殆ど変わらない」のだが、とりもなおさず君自身が言ってたとおり、</p>
<ul>
<li><p>状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる</p></li>
<li><p>そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い</p></li>
</ul>
<p>という状況が顕在化するばするほど、「殆ど変わらない」どころか、本質的な違いが顕在化する。</p>
<p>まず批判ありきで私個人を中傷するにとどまらず、何も知らんくせに、FRPの意味もわかってないくせに、批判ありきのFRP不要論の大風呂敷を広げる、適当な屁理屈をとってつけて読者を惑わせて恥ずかしくないの?と思う。自称大学の教職にある捨てアカウントらしいが、知的誠実さが少しでも残っているのならば、ただちに修正することをおすすめする。言っても無駄でしょうが。どうせ捨てアカウントだし、こちらを中傷し放題で、自分は間違ったデマを垂れ流しても、恥はかき捨てで大変結構ですね。割を食うのは学習者です。まあやっぱり恥を知ってほしいです。</p>
<p>FRPは、時間発展する系の時間軸上の値をファーストクラスにして扱うというパラダイムであり、TimeEngineは、時間軸上の値をJavaScriptのファーストクラスとして提供する、FRPライブラリとして開発しました。</p>
<p>お絵かきアプリのLIVE-DEMOですが、明確な設計思想、つまり <br>
時間軸上の値をJavaScriptのファーストクラスとして提供する <br>
という設計思想をもって自分で開発したFRPライブラリを使って、</p>
<ol>
<li>mouseイベントからFRPの値に表現</li>
<li>FRPの値の構成をcanvasと接続する</li>
</ol>
<p>というだけですから、簡潔かつ、設計もコーディングも単純、つまり簡単です。 <br>
実質コーディング時間は10分程度だったんじゃないでしょうか? <br>
実際に、プロジェクトgithub.io ページ <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
に列挙している他の、たとえばカウントアプリのほうがよほど複雑なわけで、これは一番簡単な部類に入ります。</p>
<p>ぶっちゃけ、TImeEngineの各DEMOのプレゼンテーションだけでも、お絵かきアプリは一番カンタンな部類だということはわかりそうなものですが、 <br>
こういう胡散臭い連中は、「言い聞かせてもわからない」「自分に都合の良い、相手に都合が悪くなりそうな設定を信じたいように信じる」病人なので、</p>
<blockquote>
<p>ところで岡部はいつになったら彼の言う「お絵かきロジック」を破壊的代入を用いない関数型のJavaScriptで書いてみせるんだろうか。 <br>
そんなトイプログラムのコードも示せないとなると岡部のCS理解とコーディング能力は推して知るべしということになるわけだが。</p>
</blockquote>
<p>だとか、</p>
<blockquote>
<p>目が潰れそうなスパゲティコードだが、これでは「お絵かきロジック」のようなトイコードすら関数型で書けはしないということは岡部健自身が一番よくわかっているだろう。お前さんがDate.now()で岡部がかいた恥をほじくり返して晒すのは死者に鞭打つようなものだ。もし反論したければ、お前さんがこのオモシロ timeengine で「お絵かきロジック」を関数型で書いてみせてくれればいいのだよ。簡単だろう(笑う)。まあ、できやしないのはわかりきっているのだが(とはいえそれができないのは岡部のせいなので気に病む必要はない)。</p>
</blockquote>
<p>だとか、</p>
<blockquote>
<p>こうして絶対にコードを書かずにいつまでも逃げまわるのであったwww</p>
</blockquote>
<p>だとか、言ってるようで、頭痛が痛くなってきます。 <br>
まあ、TimeEngine自体を開発するのは、かなり大変でしたが、冒頭のコードみたいなお絵かきアプリを書くのは、かなり簡単です。</p>
<p>これが簡単な作業だとわからない連中に向かって、簡単なコードをついでにUPしなかったのは、「ほんとうにしょうもない」と心底思っていたからです。</p>
<p>いやこの10分でかけるコードを書くのに、1年くらいかかった!とか、またしょうもない中傷、妄想を続けるのは自由です。 <br>
実際「2ヶ月たってもお絵かきアプリを書けない」「3ヶ月たってもお絵かきアプリを書けない」とか、延々と中傷していましたね?中傷というか、ナイーブに本気でそう思ってったぽいのは、知見レベルが低いのか、思いこみの強い病的な性向によるものなのか、いずれにせよかなり気持ち悪いです。</p>
<p>実際、簡単なコードだ、とUPして見せて理解できるのかさえもよくわかりませんが、少なくともこんなもんが難しい課題だと少しでも思ってるのは本当にJavaScriptでFRPを書くのが困難だ、と本気で思ってればそういう気持ちになりえるのかな?とは想像可能です。が、正直頭のおかしい連中のことはよくわかりません。 <br>
今後もこれまでと変わらず、自分が信じたいことだけ信じて、初学者を惑わすデマを拡散していってください。</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p>OCamlで書かれた「お絵かきデスクトップアプリ」に関しては、らくだの卯之助@camloebaあたりがUPした、ガッタガタのそれこそトイアプリを見ましたが、私がまともなもんを見る日は来るのでしょうか?</p>
<h4 id="らくだの卯之助camloebaさんあなたが自身の関数型プログラミングのスキルが机上の空論でないことを示せ">らくだの卯之助@camloebaさん、あなたが自身の関数型プログラミングのスキルが「机上の空論」でないことを示せ。</h4>
<p>という投げかけには、示されていない、無回答であるということになります。非常にしょうもないことですが、改めて連中のノリを観察すると、本気で、こちらが「お絵かきアプリ」を書かない、というか、あほらしいので書くまでもなく放置していることを心の拠り所にしていたっぽいので、今回改めて、明示的にもう一度、ボールを投げ返しておきます。</p>
<p>そういえば、<a href="http://qiita.com/esumii/items/ec589d138e72e22ea97e">「関数型言語」に関するFAQ形式の一般的説明</a> <br>
にも、</p>
<h4 id="それだと入出力や状態stateすら表せないのでは">それだと入出力や状態(state)すら表せないのでは?</h4>
<blockquote>
<p>いいえ、純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。</p>
</blockquote>
<p>と、すでに引用した@nonstarterなる捨てアカウントの人物の言い分</p>
<blockquote>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)’</p>
</blockquote>
<p>と全く同じことが書かれており、住井@esumii が語る、関数型プログラミングの、時間遷移する複雑なアプリの実用性は、すべて(状態渡し)一点で処理しようとしているように見えます。少なくとも私は、 <br>
@nonstarterはもとより、らくだの卯之助@camloeba、住井@esumii その他とりまきの自称関数型コミュニティの連中が「動的に時間発展する値を、時間軸上の静的な値として俯瞰し、ファーストクラスとして扱う」というコンテクストにおける正しいFRPの文脈で話しているのは一度たりとも見たことがありません。</p>
<p>まあデタラメな知識でFRPがなんたるか理解せず、意味不明な言説をもってFRPの導入の妥当性を全力で否定した上で、(状態渡し)一点ばりの問題点</p>
<ul>
<li><p>状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になる</p></li>
<li><p>そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多い</p></li>
</ul>
<p>と宣言しているということは、連中のOCamlでのコーディングの実用性は、上記が上限だということになります。そういうことですよね?(笑)</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-4260191296595714922016-03-21T14:41:00.001+09:002016-03-21T14:42:59.882+09:00ベイズ推定、条件付き確率について多世界解釈と参考資料の追加など<p>前回、<a href="http://kenokabe-techwriting.blogspot.jp/2016/03/blog-post.html">ベイズ導入とベイズ統計的機械学習参考書の紹介など</a> <br>
で、筆者が考えうる限りもっとも簡潔なベイズ推定の概念導入を試みましたが、それなりの反応をいただきました。</p>
<p>やはり疑問、というか納得しにくい、納得した上で先に進みにくいのがベイズの定理であるようで、それが自然だとも思います。</p>
<p>「なんかひっかかる」「納得しにくい」という概念が現れたときは、そこは素通りすべきではないと思います。ほとんどの場合そこには大きな発想、パラダイムの転換(コペルニクス的転換)またブレイクスルーが存在していて、そこを突き詰めて考察することはとても有意義で楽しいことです。また逆にそういうパラダイムの差異を曖昧にしたまま腑に落ちないまま先に進むと苦労するのは自分だとも思います。</p>
<p>実際、ベイズ理論は、義務教育で習う統計学の発想、理念、哲学とは異なり、またイメージしにくいものだと思います。</p>
<p>義務教育で習うスタンダードな統計学は、ネイマンとピアソン、という人たちが体系構築したもので、「ネイマン=ピアソンの頻度主義統計学」とか呼ばれているようです。 <br>
彼らが思いっきり糾弾して表舞台(学会)から一旦放逐してしまった、近年大復活を遂げているのが、ベイズという人が考えたベイズ統計学というわけですが、何が異なるのか?</p>
<p>ここは実際かなり哲学的な思索になるわけで、筆者自身は結構そういうことは突き詰めて考えないと先に進みたくないわけで、自分なりに考えた結果、多分ほかではあんまり言われていない考え方をシェアしたいと思います。</p>
<p>キーワードは、現実(という世界)、観測、条件付き確率です。</p>
<p>1が出る可能性が100%のサイコロは存在するか?(歪みもないのに)</p>
<p>という思考実験をしてみます。 <br>
厳密な議論はさておき「ネイマン=ピアソンの頻度主義統計学」では、歪みがないんだから、無限回数試行(サイコロふってみること)をすれば、大数の法則で確率1/6に収束するはずだ、これが「真の確率」である、みたいなことを論じます。まあ学校でだいたいこういう感じで習ったと思います。そういうことです。</p>
<p>一方で、ベイズ統計学では確率とは「観測された事象」によって決まるという考え方をしています。 <br>
1が出る可能性が100%のサイコロは存在するか?(歪みもないのに) <br>
答えYes。 <br>
たとえば、買ってきたばかりのサイコロをふって10回連続で1が出ることはあります。(1/6)の10乗の確率でそうなります。しかしそれは「極まれでたまたま」であって、次は1じゃないだろうとか100回ふったらさすがに1が出ないだろう、みたいになるわけですが、100回連続でふっても(1/6)の100乗の確率で「ありえる」わけです。 <br>
年末ジャンボ宝くじを1枚だけ買って、1等が当たる確率は2,000万分の1らしいですが、1枚だけ買っても当たる人は当たるわけで、その人にとっては当選確率100%になるわけです。だって当たったんだから。</p>
<p>「確率」というのは、「ネイマン=ピアソンの頻度主義統計学」のように、そういう人らが「こうだ」と厳密に定義することも可能ですが、別の解釈も可能な余地があるように思えます。「ネイマン=ピアソンの頻度主義統計学」は「客観確率」、「ベイズ統計学」はここで少し例を出した雰囲気からなんとなくわかるかもしれませんが「主観確率」と呼ばれたりします。</p>
<p>数学っていうのはもちろん、そもそも人間と関係なくアプリオリに存在していて、プラトンが論ずるように「イデア」として「客観」として存在しているわけで、その意味ではこの「主観確率」っていうのは何?ってことになります。少なくとも自分はこの「主観確率」っていう分類表現がどうも気に食わない。じゃあどう解釈するか?</p>
<p>ポイントは「観測」です。現代物理学、量子力学を勉強していると、どうもこの「観測」っていうのが「やっかい」もの扱いされているとわかってきます。</p>
<p>量子力学は、シュレディンガー方程式で記述される波動関数の確率密度によって量子の存在確率が決まるんですが、人間が観測した時点で、その波動関数っていうのは「崩壊」「収束」して1個の点に決まります。まあ、確率統計で構築されている美しい理論が、人間が観測した時点で急にその確率っていうのがどっか行ってしまって「波動関数の収束」という摩訶不思議な現象が起こります。当時、超天才のフォン・ノイマンが、ここを徹底的に追求して、結局、量子力学の理論体系からは「波動関数の収束」なんて現象はどうやっても導出できない!ってことを数学的に証明してしまいます。理論は非常に美しくて整合性もある正しそうだ、でも数学的にありえないことが実際起こっている、結局「人間の意識が波動関数を収縮させる」ということを主張しました。現在では、まあ理由はどうであれ、とにかく収束する、追求しないという「コペンハーゲン解釈」というのがあります。今でも一線の物理学者の多数が支持している解釈かどうなのかは知りませんが、少し昔までは多分これが標準的な解釈だったんでしょう。</p>
<p>一方で、エヴェレットという人が「観測者だけ特別扱いで波動関数の確率の枠組みに入れていないのはおかしくない?」という至極当然の発想で、突き詰めたのが「エヴェレットの多世界解釈」です。 <br>
これはつまり、観測者自身も波動関数の確率的存在と考えれば、どこにも観測対象の波動関数の収束みたいなおかしなことが起こる余地はない、理論的に整合が取れている、ということです。 <br>
まあ、意識を創発する物質としての人間の脳という観測主体が、量子力学の理論どおりシュレディンガー方程式で記述されるままの波動方程式によって表現されている確率的存在であるならば、それぞれの分布局所で「観測対象が1点に収束している!」と対応する現象が起こってるんでしょ?じゃあそれで矛盾がないじゃない、という考え方です。</p>
<p>意識を創発する物質としての人間の脳という観測主体が確率的に存在している、観測される対象(客体)も確率的に存在している、それぞれ重ね合わさって、「観測対象が1点に収束している!」とそれぞれ辻褄があっている、ってことは、すなわち世界が複数重ね合わさって存在してるってことです。 <br>
まあ、普通は信じられませんよね。でも論理的に否定するのは不可能で、論理的にはむしろこっちの多世界解釈のほうがよっぽど辻褄があっています。そもそも「波動関数の収束」みたいな解決不能な問題が解決されている、ってことでこっちのほうが正しそうだ、と私は思うし、今時はかなり多くの(気の利いている)理論物理学者はコペンハーゲン解釈ではなく、多世界解釈じゃないんでしょうか?一般にこれは<a href="https://ja.wikipedia.org/wiki/%E7%B4%A0%E6%9C%B4%E5%AE%9F%E5%9C%A8%E8%AB%96">素朴実在論</a>では「直感」に反する考え方なので、いろいろ理由をつけて否定する人もいるでしょうが、それは理性でもなんでもなく、結局否定することなんて不可能だということくらいのコンセンサスはさすがにできており、だからこそ「コペンハーゲン解釈」「多世界解釈」どちらでもすきな解釈でどうぞ?みたいなことになってるわけです。真実は多世界であったとしても、多世界間は相互作用なんてない(はず)なので、実験で確認することは不可能であり、すなわち反証可能な科学理論としては成立しません。だから科学「理論」の範疇でなく「解釈」の問題です。</p>
<p>多世界解釈は<a href="https://ja.wikipedia.org/wiki/%E6%B1%BA%E5%AE%9A%E8%AB%96">決定論</a>です。一般に馴染みがある、思いっきり俗な言い方をすると運命論みたいなものです。最初からすべては決まっている。 <br>
Wikipediaでも</p>
<blockquote>
<p>だが、20世紀になると、量子力学におけるコペンハーゲン解釈によって、宇宙は原子下のレベル、量子レベルであまねく確率的であるという説が有力となった。</p>
</blockquote>
<p>などと書かれていて、「だから未来は決まっていない」「人間は自分の意志で自由に未来を書き換えられる!」というBackToTheFuture的な世界観がポピュラーなわけですが、ぶっちゃけ、そんな「自由意志」みたいな、物理法則を超越した魔法みたいな事象はないです。意思、意識はこのベイズ理論の先にある「強い人工知能」によって発現すると、現在ほとんどの研究者は確信しており、そうなったら「意識」というか「自己認識」と言う現象も数学的構造あるいは計算結果だと証明されることになるでしょう。</p>
<p>世界は量子力学によって確率統計的に記述されているが、波動関数のランダムな確率的な収束がおこって偶然に決まるのではなく、波動関数で表現されている統計値は宇宙に「もれなく全部」決定的に展開されており、我々はその一部のみを知覚する世界のひとつにいる、ということです。</p>
<p>「波動関数」っていうのはこの世に数学的構造としてひとつしかなくて、それが時間も空間も超越した多世界にわーっとまたがっている、広がっている、その局地局地がある世界のある時間、そしてそこに存在する我々、我々の意識、ということになります。そういうのがいっぱいある、ということです。これが多世界解釈。 <br>
コペンハーゲン解釈では、この観測できる世界がまず存在する、まあ素朴実在論の素朴な発想です。そこになんかしらないが、波動関数という数学的「近似」理論があるみたい、それがなんかわからないけど、なんかのきっかけで収束する。この世界にこの波動関数はひとつ!みたいなことになります。間違っていると思いますが。素朴だし。</p>
<p>とこういう「多世界解釈」「決定論」としての哲学的足場が私にはまずあります。 <br>
これを前提に「確率論」というのは当然解釈していくわけです。</p>
<p>「ネイマン=ピアソンの頻度主義統計学」の根本的な問題点は、素朴実在論に基づいた「この世界はたったひとつ!」という暗黙の了解、大前提があることです。だから「真の値」とは「神様だけが知っている値」とか、「真の値が存在するが、私達が知る事ができるのは、真の値に近いと思われる値、それがサンプルから計算した平均値や標準偏差だ」みたいな議論になります。まあ日常の主観的には「この世界はたったひとつ!」という気持ちで生活してもまったく問題は発生しないわけですが、数学で突き詰めて考えるときに、果たしてこういう大前提を無条件に暗黙の了解として受け入れて良いのか?といえば良くないと思っています。</p>
<p>多世界解釈を採択する私の世界観からすると、こういう「ネイマン=ピアソンの頻度主義統計学」による「真の値」とは、「時間も空間も超越した多世界にわーっとまたがっている、広がっている、「波動関数」としてこの世に数学的構造として存在している確率分布の最尤値」のことです。</p>
<p>我々がたまたまこの世界で、たまたま観測する、観測できる事象とは、無限の多世界に存在するうち、たまたま今ここで意識を創発していると感じている、という意識がある自分が観測した「今ここでの値」という限定された局所的な値でしかありません。</p>
<p>その「今ここでの値」というローカル値というのは、当然、シュレディンガー方程式の波動関数によって規定される確率分布のどこかにある一つの値であって、確率分布に従って「他にもいっぱい」「今ここでの値」っていうのが決定論的に最初から存在しているわけです。</p>
<p>もうちょっと平たく言うと、 <br>
1が出る可能性が100%のサイコロは存在するか?(歪みもないのに) <br>
答えYes。</p>
<p>たしかに歪みがないわけですから、多数回試行すれば、1−6までかなり平均的に出るような「世界」のほうが多世界グループのなかでも圧倒的に多いでしょう。しかしながら、多世界が無限に広がっているわけで、たまたまこの「世界」は「なんだかよくわからないけど、このサイコロは歪みがないのに1ばかり連続して出る!」という世界かもしれません。</p>
<p>あなたが年末ジャンボ宝くじを1枚だけ購入して、「案の定ハズレた!」とあなたが思ってる世界のほうが圧倒的に多いわけですが、「なんだかよくわからないけど、当選したぞ!奇跡だ!」とおもっている世界は2000万分の1の確率で存在するわけです。どこかに。存在しない?なんで?2000万分の1の当選確率であるならば、フェアに考えてそういう確率分布になっているはずです。もちろん、その多世界のうち、「今そこにいるあなた」の脳も確率分布に従って波動関数の重ね合わせで存在しており、意識もそれに呼応しているわけで、その意識において、「なんだかよくわからないけど、当選したぞ!奇跡だ!」と感じる事象になっている確率は2000万分の1にすぎません。</p>
<p>ある事象ひとつをとっても、無限に存在する多世界は、ある波動関数で規定される確率分布ですから、その曲線の山の最も高いところが最も存在確率が高い、つまり世界の数が一番多いです。 <br>
そういう多世界のうち世界の数が一番多いだろう(世界の存在確率が一番高いだろう)っていうポイントを「最尤値」と呼びます。</p>
<p>簡単のために次元を落として、オモテウラのコインで考えます。(2面のサイコロっていうのと一緒)(最初からコインの例に統一すればよかったかもしれない)</p>
<p>ネイマン=ピアソンの頻度主義統計学では、オモテが出る確率θは五分五分、1/2=0.5ですね。</p>
<p>一方で、ベイズ統計学ではこんな「オモテが出る確率θは1/2=0.5」みたいな多世界の「最尤値」=「真の値」は初期設定では論じることは不可能です。科学実験としてそんな多世界の全部は到底観測不能だからです。</p>
<p>世界は量子力学の波動関数の確率分布ですべて記述されているのです。まあ、多世界のうち存在確率が一番高いのは、たぶん、θは1/2=0.5、となっている世界だろうね!みたいな確率分布議論しかできません。そして、この世界は、その一番存在確率の高い世界に落とし込まれている可能性が高いから、多分、この世界でもθは1/2=0.5が最尤値となってる確率分布なんじゃない?みたいなことです。</p>
<p>しかし、実際に試行してみて、連続でオモテしか観測されなかった場合、 <br>
「おいおい、どうやらこの今自分が生息してる世界は、超多数派のθ1/2=0.5が最尤値の世界のパターンじゃなかったようだ、珍しいね!」ってことになります。 <br>
宝くじの例で言い換えると、 <br>
「おいおい、当選確率2000万分の一の存在確率が超低い世界なのに、なんか知らないけど、実際にこの世界で当選しちゃったので、この世界はたまたまその存在確率が超低い世界だったみたい!」みたいなことが起こりうるわけです。</p>
<p>今一体何を考えているのか?というと、「確率の確率」を考えています。 <br>
ネイマン=ピアソンの頻度主義統計学では「世界はただひとつ」であり、 <br>
この世界の「真の確率」もただひとつ、であるわけですが、 <br>
ベイズ統計学は多世界解釈であるという見解では、「世界は無数に存在する」ので、 <br>
それぞれの世界ごとに、それぞれ確率が存在する、無数に、と解釈できます。</p>
<p>無数に存在するであろう世界のそれぞれの確率を俯瞰的にみて統計的に確率分布で考える、「確率の確率」「確率分布の確率分布」を考えるということがベイズ統計学では可能です。</p>
<p>コインを実際に試行してみて、連続でオモテしか観測されなかった場合は、その世界の観測値に従って <br>
オモテしかでない確率、つまりオモテ確率100%、θ=1が最大値、最尤値になります。 <br>
ベイズ推定では、コイン試行の「確率の確率分布」はベータ分布(サイコロなら一般化された多変数のディリクレ分布になる)になり、二次元グラフに表すと、ある世界(この世界)のある時間(観測時点)で、観測結果がオモテ100%だった場合のオモテが出る確率θの分布は、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-218">
2 \theta
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/0/07/2x.png" alt="enter image description here" title=""></p>
<p>です。オモテ確率0%、θ=0のときの確率は0になっています。少なくとももう1回はオモテが出たという事象が観測されてしまっているわけで、オモテ確率0%、θ=0というのはもう「絶対にない」ということになります。</p>
<p>さらに連続してオモテが観測されたとき、確率θの分布は、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-219">
3\theta^2
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/3/32/3x%5E2.png" alt="enter image description here" title=""></p>
<p>に変化します。</p>
<p>さらに3回連続でオモテが観測された確率θの分布は、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-94">
4\theta^3
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/bc/4x%5E3.png" alt="enter image description here" title=""></p>
<p>というように、オモテ確率θ=100%の度合いがどんどん強まっていくことが確認できます。</p>
<p>このまま、「たまたま」オモテしかでない世界だった場合、この延長でどんどん、θの何乗っていうのが1個ずつ増えていってオモテ確率θ=1グラフの度合いが急激になっていくわけです。</p>
<p>さて、仮に、もし次の試行でウラが出たらこの確率分布はどのように変化するでしょうか?</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-229">
20\theta^3(1-\theta)
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/4/40/20x%5E3%281-x%29.png" alt="enter image description here" title=""> <br>
<br>
こうなります。</p>
<p>もう、オモテ確率θ=100%というのは、実験、観測で少なくとも、もう1回ウラが出てしまったので、 <br>
オモテ確率θ=100%っていうのは「絶対ありえない」0%だ、言い換えると、θ=1.0となる確率はゼロである、というように確率分布が更新されてしまいました。とはいえ当初の実験で3回連続でオモテが観測されていたので、なおオモテ確率のほうが高い分布となっています。</p>
<p>それを打ち消すように、さらにウラが連続して9回出た場合。</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-599">
2860\theta^3(1-\theta)^9
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/e/e4/2860%281-x%29%5E9x%5E3.png" alt="enter image description here" title=""></p>
<p>というように確率分布は観測結果に応じて変化していきます。</p>
<p>さらに試行を重ね、オモテ30回、ウラ30回と均等に出るという事象が観測された場合。 <br>
<script type="math/tex; mode=display" id="MathJax-Element-600">
7214139475456546864 (1 - \theta)^{30} \theta^{30}
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/4/43/7214139475456546864_%281_-_x%29%5E30_x%5E30.png" alt="enter image description here" title=""></p>
<p>かなり「ネイマン=ピアソンの頻度主義統計学」が云うところのいわゆる「真の値」である確率θ=1/2=0.5が際立った確率分布となっています。</p>
<p>多世界が「観測」によって波動関数が収束したように見えることは、ベイズ更新の確率分布をグラフに表したときの領域分割として幾何的にイメージして理解できます。</p>
<p>念の為にまず超基本的な確率のことがらと用語を復習しておきましょう。</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(<span class="hljs-literal">A</span>,B) = P(<span class="hljs-literal">A</span>) x P(B|<span class="hljs-literal">A</span>)</code></pre>
<p>「同時確率」P(A,B)は、 <br>
事象の確率P(A) に <br>
「条件付き確率」P(B|A)を掛ければ求められる(確率の乗法定理)。</p>
<p>言い換えると、 <br>
事象の確率P(A)に掛ければ <br>
「同時確率」P(A,B)になるような確率のことを <br>
「条件付き確率」P(B|A)と定義する。</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(B|<span class="hljs-literal">A</span>) = P(<span class="hljs-literal">A</span>,B) / P(<span class="hljs-literal">A</span>) </code></pre>
<p>条件付き確率と確率の乗法定理は、 <br>
定義として表裏一体で同じ概念をそれぞれ逆方向で命名したものです。</p>
<p>非常に単純なことしか言ってないのですが、非常に単純だということがわかりにくい人は、 <br>
前回の記事のトランプの例を参照すれば良いでしょう。</p>
<pre class="prettyprint"><code class=" hljs 1c">カードが黒 ■
カードが赤 □
と表記し、
カードのマーク(スート)の強さは
♠ > ♡ > ♢ > ♣なので、
上位2つを ↑
下位2つを ↓
とグループわけして表記することにする。
<span class="hljs-string">| | ■ | □ | </span>
+---<span class="hljs-string">|---|---+</span>
<span class="hljs-string">| ↑ | ♠ | ♡ |</span>
<span class="hljs-string">| ↓ | ♣ | ♢ |</span></code></pre>
<p>Aはカードの色2択(図の横軸) <br>
Bはカードのスートの強弱2択(図の縦軸)</p>
<p>カードの色、黒赤同じ割合の2択の事象の確率</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute">P(A)</span>=<span class="hljs-string">1/2</span></code></pre>
<p>で、 <br>
カードの色が確定した事象について、さらにそこから、 <br>
スートの強弱の同じ割合の2択の事象があるので、 <br>
条件付き確率</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute"> P(B|A) </span>=<span class="hljs-string">1/2</span></code></pre>
<p>となっています。ここまでが大前提。 <br>
さて、</p>
<p>♠というスートの存在確率は、 <br>
カード色=黒 <br>
その上なおかつ <br>
カード強弱=強い <br>
という「条件つき確率」からの「同時確率」で表現できます。</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(<span class="hljs-literal">A</span>,B) = P(<span class="hljs-literal">A</span>) x P(B|<span class="hljs-literal">A</span>)
<span class="hljs-number">1</span>/<span class="hljs-number">4</span> = <span class="hljs-number">1</span>/<span class="hljs-number">2</span> x <span class="hljs-number">1</span>/<span class="hljs-number">2</span> </code></pre>
<p>そしてよくよく考えてみると興味深いことに、 <br>
カードの色A、スートの強弱Bを入れ替えてもまったく同じ論理で、</p>
<p>♠というスートの存在確率は、 <br>
カード強弱=強い <br>
その上なおかつ <br>
カード色=黒 <br>
という「条件つき確率」からの「同時確率」で表現できます。</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(<span class="hljs-literal">A</span>,B) = P(B) x P(<span class="hljs-literal">A</span>|B)</code></pre>
<p>なので、「同時確率」P(A,B)について接続してまとめると</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(<span class="hljs-literal">A</span>) x P(B|<span class="hljs-literal">A</span>) = P(B) x P(<span class="hljs-literal">A</span>|B)</code></pre>
<p>4つの確率の関係式があります。 <br>
簡潔なこの4つの確率の関係式から深淵な理論が導出されてしまう。</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(B|<span class="hljs-literal">A</span>) = P(B) x P(<span class="hljs-literal">A</span>|B) / P(<span class="hljs-literal">A</span>)</code></pre>
<p>単に移項しただけなのですが、 <br>
この式の形が「ベイズの定理」と特別扱いされて呼ばれています。</p>
<p>ベイズの理論は式を見ての通り徹頭徹尾「条件付き確率についての理論」であると言えます。 <br>
ベイズの理論を理解する事は、「条件付き確率」とは何か?を理解することと同じです。 <br>
もちろん、こうすればこうなる、ほら使えるでしょ?と道具の使い方だけを学ぶことは可能ですが、 <br>
道具の使い方を理解していることは理論の理解ではありませんし、後々苦労するし応用もまったく効かないでしょう。</p>
<p>じゃあ、「条件付き確率」っていうのは多世界解釈において一体どういう意味なんだろう? <br>
と考えてみると、いやいやそれ以前にそもそも「確率」ってなんのことだったんだろう? <br>
と再確認する作業が必要です。</p>
<p>ものごとが「起こる」か「起こらないか」というときに、「可能性」という言葉を使います。 <br>
ものごとが起こらないことが観測され確定したときに「可能性が消えた」という言葉遣いをします。</p>
<p>これはすなわちある時点まで不確定であったものが、確定した、ということで、最初から論じている量子力学のコペンハーゲン解釈(この世界は眼の前にある世界唯一つ)で、波動関数がなんか理由がわからないけど、追求するのはあきらめてとにかく事実として収束する、という現象がある、という意味そのものです。(素朴実在論)</p>
<p>一方で、多世界解釈においてはそもそもそんな不確定事象などは存在せず、最初からぜんぶまるごと決定論的に決定されて世界はただそこに存在していて、我々が観測して「事象が確定した!」と思い込んでいるのは、実際のところ我々の脳もその可能性の一つの世界に波動方程式の確率分布のひとつとして存在しており、それぞれの多世界で「観察」した結果「事象が確定した!」と思っているという哲学的立場でした。(プラトニズム)</p>
<p>別の言い方をすると、可能性は消えない、ひとつの可能性を観測した場合、また別の可能性を観測している世界が無数に存在する、世界がそこで分岐したとみなされる。</p>
<p>「分岐」するというと動的な印象がありますが、実際は最初からそのように決定されている数学的構造です。波動関数がそのような確率密度の分布となっており、そのどの部分で切り取って見るか?ということに対応します。</p>
<p>確率とは事象の存在の割合です。世界の存在確率=多世界に含まれている、ある多世界の割合。’ <br>
多世界の分量は無限個ある(多分)ので、世界の量は割合でしか表すことはできません。 <br>
ブラウザの利用総数なんてわからないけれども、ブラウザ利用シェアは自サイトのアクセス分析から割り出せるみたいなことです。 <br>
Chrome7ブラウザからのアクセスは全アクセスのうち70%みたいに。 <br>
「こんなパターンの世界が全多世界のうち70%のシェアを占めている」 <br>
「こんなパターンの世界の存在確率は70%=0.7である」ということになります。</p>
<p>こういう多世界解釈の世界観でベイズ理論はどう解釈できるか?ということを追求してみます。</p>
<p>ベイズの定理</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(B|<span class="hljs-literal">A</span>) = P(B) x P(<span class="hljs-literal">A</span>|B) / P(<span class="hljs-literal">A</span>)</code></pre>
<p>ベイズ理論風に記号を書き直す <br>
AをEvidence(証拠、観測値、データ(の確率分布)) <br>
BをHypothesis(仮説(の確率分布)) <br>
と書き換えて、</p>
<pre class="prettyprint"><code class=" hljs mathematica">P(H|<span class="hljs-keyword">E</span>) = P(H,<span class="hljs-keyword">E</span>) / P(<span class="hljs-keyword">E</span>)
= P(H) x P(<span class="hljs-keyword">E</span>|H) / P(<span class="hljs-keyword">E</span>)</code></pre>
<p>この確率と条件付き確率の関係式を多世界解釈の立場から「理解」して「イメージ」できることを目標とします。 <br>
ベイズの定理の式がこうだから論理的にこうなる、という説明の組み立てはしない、すべきではないので、いったんこの目標を確認した上で、最後に統合します。</p>
<p>すでに上のほうで一回説明を試みた、コイン投下の試行について思考実験します。 <br>
まず多世界があります。その無限に広がる多世界のうち「今これからコインの実験をしよう!」とあるコインを用意した世界がそのなかに存在しています。そしてもちろん「コイン?なにそれ?」というまったくこの試行に無関係の世界がその他無限に存在していますが、そこは関係ないので今回切り捨てます。 <br>
あるコインについてだけの多世界にまず絞り込みます。これを「全事象」と初期設定します。わかりますね?</p>
<p>これからそのひとつのコインに関する多世界にまたがって思考実験していくわけですが、あるひとつの世界のなかで科学的な実験を行った場合、観測可能なのはたかだかその世界に所属しているコインひとつだけです。 <br>
それ以外の他の世界に所属している科学実験のことは絶対に観測不可能です。知る手段はありません。それぞれの世界の観測は独立しています。</p>
<p>ただし、量子力学がものがたるように、世界は量子力学の波動関数の確率分布ですべて記述されています。数学を通じて多世界にまがたる確率分布の議論をすることが可能ですし、それをやってるのが量子力学であるといえます。</p>
<p>それぞれの世界にはそれぞれの世界特有の観測結果や確率がありますが、多世界なので、前述したとおり、Chrome7ブラウザからのアクセスは全アクセスのうち70%みたいに、 <br>
「こんなパターンの世界が全多世界のうち70%のシェアを占めている」 <br>
「こんなパターンの世界の存在確率は70%=0.7である」という話ができます。 <br>
「確率の確率」です。もうちょっというとシェアの話なので、確率の確率分布の話ができます。</p>
<p>逆に言うと、多世界について我々が数学を通じて話せるのは、多世界の「確率の確率分布」以外にはありません。その話しかできないし、その話だけを徹頭徹尾しているのがベイズ統計学です。</p>
<p>あるコインについてのみ切り出した多世界の全事象を以下のように表現することとします。</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/c/c5/Plot%281,_%28x,_0,_1%29.png" alt="enter image description here" title=""></p>
<p>横軸は0-1.0 の確率 <br>
縦軸も0-1.0 の確率 <br>
確率の確率のグラフです。 <br>
全事象は確率100%なので、掛け合わせると1.0になっています。</p>
<p>このグラフでは、確率の確率分布が視覚的に把握できます。 <br>
現在よく見ると、y=1 で直線が引かれており、 <br>
xとyともに0-1区間の領域で四角形になっていますね。 <br>
この領域があるコインについてのみ切り出した多世界の全事象で1となっています。 <br>
全事象のシェアは100%ということです。</p>
<p>ここで、コインを1回投げます。 <br>
ある世界ではオモテが出た。ある世界ではウラが出た。 <br>
コインを投げると、その観測結果を境界として多世界が分岐します。</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>このように分割されます。</p>
<p>y=x という直線で四角形の領域が半分に分割されました。 <br>
1回目の試行でオモテが出たほうの多世界グループと <br>
1回目の試行でウラが出たほうの多世界グループと <br>
に多世界全事象が半分に分割されました。</p>
<p>右下の三角形の領域がオモテ世界で、この世界の目線からすると、 <br>
1回目の試行でオモテが出た、という観測結果が確定したことにより、 <br>
1回目の試行でウラがでる、という「可能性は消滅した」ということになります。</p>
<p>しかしながら、「可能性は消滅などしない」というのが多世界解釈でした。 <br>
オモテ世界から消滅したように見えた、可能世界であるウラ世界は、 <br>
このグラフの左上の三角形の領域です。 <br>
彼らからすると、可能性が消滅したように見えるのはむしろオモテ世界のほうです。 <br>
<br>
全領域 <br>
y=1 <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/c/c5/Plot%281,_%28x,_0,_1%29.png" alt="enter image description here" title=""></p>
<p>から <br>
オモテ世界の領域 <br>
y = x <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>を引き算してやると、 <br>
ウラ世界の領域 <br>
y = 1 - x </p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/a/a0/1-x.png" alt="enter image description here" title=""></p>
<p>左上の三角形の領域(の面積)がちょうど上下ひっくり返って明示的な確率の関数として計算して表現できます。 <br>
ちなみにこれは全領域1のうちの割合なんぼという話なので、 <br>
「確率の密度」という解釈ができるので、「確率密度関数」と呼ばれています。</p>
<p>全領域1のうちの割合なんぼという「確率の密度」を総計していけば、当然 <br>
全領域1のうちの割合なんぼが計算できるので、 <br>
「確率密度関数」を積分すれば確率になります。</p>
<p>2回目の試行をします。 <br>
1回目の試行と2回目の試行はコインを投げるということでまったく同じことの繰り返しです。</p>
<p>つまり、世界をコインを投げることによってまた</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>このように分岐させてしまうわけです。 <br>
ただし!分岐するのは、すでに分岐してしまった世界の延長で分岐します。すでに分岐してしまった世界がふたたび統合されたり、なかったこと、チャラになることはありません。最初から決定されているであろう多世界の分岐構造をひたすら辿っていく確認作業をやっているだけなので、分岐をたどっていったはずなのに、元の分岐がチャラになったという動的な変更は起こりえない、ということです。</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>を前提とした上で、</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>で、さらにまた分岐する。これはすなわち「条件付き確率」のアレをやっているということです。</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(<span class="hljs-literal">A</span>,B) = P(B) x P(<span class="hljs-literal">A</span>|B)</code></pre>
<p>前提となる事象に「条件付き確率」を乗算すれば、「同時確率」すなわち「分岐後の世界の確率」が得られる。</p>
<p>実は最初に、 <br>
全領域 <br>
y=1 <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/c/c5/Plot%281,_%28x,_0,_1%29.png" alt="enter image description here" title=""></p>
<p>に「条件付き確率」 <br>
y = x <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>y = 1 かける xと乗算した結果、 <br>
y = x <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>になっていたのでした。</p>
<p>すでに世界は、 <br>
1回目オモテ世界 <br>
1回目ウラ世界 <br>
のふたつに分岐されてしまっていますが、全パターンの分岐を辿るのはしんどいので、 <br>
当面、1回目オモテ世界の延長の分岐だけを探ることとします。</p>
<p>1回目オモテ世界の延長で、 <br>
1回目オモテ世界を前提に、条件付き確率の乗法定理を適用し</p>
<pre class="prettyprint"><code class=" hljs autohotkey">P(<span class="hljs-literal">A</span>,B) = P(B) x P(<span class="hljs-literal">A</span>|B)</code></pre>
<p>今回さらにまたxを乗算するので、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-967">
y = x^2
</script></p>
<p>で分岐(グラフが分割)されます。</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/Xx%5E2.png" alt="enter image description here" title=""></p>
<p>y=x で表される確率密度関数の領域をさらにまた、y=x で表される確率密度関数で表される条件付き確率という「割合」をもって分割したら、乗算して二次関数となって分割されることになります。</p>
<p>1回目オモテ世界の延長で、 <br>
オモテ連続2回世界は、一番右下の三角形が凹んだような領域に分類されます。</p>
<p>これは、最初の方で説明した、</p>
<hr>
<p>さらに連続してオモテが観測されたとき、確率θの分布は、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-991">
3\theta^2
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/3/32/3x%5E2.png" alt="enter image description here" title=""></p>
<p>に変化します。</p>
<hr>
<p>と同じですね。係数の3がないのは、今回分岐大元のコイン多世界全事象=1のままで考えているからです。これはあとでどうせまた説明することになります。</p>
<p>じゃあ、その世界から可能性が消滅したように見えて実は別の世界に分岐されている、 <br>
1回目オモテ世界 <br>
2回目ウラ世界 <br>
という世界は、グラフ中央の三日月みたいな領域に分類されています。</p>
<p>すでにやったように、単なる引き算でもうちょっと明示的に確率密度関数として表現できますから、</p>
<p>y=x から 二次関数を引き算してみる、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-739">
y = x - x^2
</script></p>
<p>変形すると</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2135">
y = x (1- x)
</script></p>
<p>これもどっかでみたことありますね?</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/7/72/1x%281-x%29.png" alt="enter image description here" title=""></p>
<p>例のベータ分布になってしまいました。 <br>
1回目オモテ <br>
2回目ウラ <br>
というイーブンの観測結果であると、最尤度0.5のベータ分布です。</p>
<p>ここで、念の為に確認ですが、 <br>
我々が数学を通じて多世界について語れるのは、せいぜい確率の確率分布でしかありません。 <br>
このように多世界の初期設定をして、そこから観測結果に応じて多世界の分岐をたどっていったとしても、その世界自体も、また次なる分岐に備える、確率分布で記述されている多世界でしかありません。</p>
<p>多世界→多世界→多世界→多世界→多世界→</p>
<p>と延々と連なっているので、事象観測後の分岐した世界で語れるのは、 <br>
分岐前と同じような確率の確率分布のはなしだけです。</p>
<p>さて、さらに多世界分岐の探求をつづけます。 <br>
<script type="math/tex; mode=display" id="MathJax-Element-2136">
y = x^2
</script></p>
<p>で分岐(グラフが分割)</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/Xx%5E2.png" alt="enter image description here" title=""></p>
<p>されましたが、そのうち、オモテ連続2回世界の延長の分岐を探ります。 <br>
グラフでいうと、一番右下の三角形が凹んだ領域のことです。</p>
<p>オモテ連続2回世界の延長を前提とし、 <br>
また同じ試行の <br>
「条件付き確率」 <br>
y = x <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>によって世界が分割されるので、 <br>
<script type="math/tex; mode=display" id="MathJax-Element-2137">
y = x^3
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/6/6c/Xx%5E2x%5E3.png" alt="enter image description here" title=""></p>
<p>となります。</p>
<p>オモテ連続2回世界の延長で、分岐したもう片方の <br>
3回目ウラ世界は、 <br>
グラフの一番細い三日月みたいな領域に分類されています。</p>
<p>オモテ連続2回世界ー 3回目オモテ世界 という引き算で確率密度関数を求めると、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-1073">
y = x^2 -x^3
</script></p>
<p>変形すると</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-1178">
y = x ^2(1- x)
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/b5/X%5E2-x%5E3.png" alt="enter image description here" title=""></p>
<p>これも当然のごとくベータ分布になっていますね。</p>
<p>もうあとは同じことの繰り返しが延々と続きます。 <br>
そしてすべての分岐のパターンで限りなく世界が分岐、分割され細分化していきます。</p>
<p>最初の方で確認した</p>
<hr>
<p>それを打ち消すように、さらにウラが連続して9回出た場合。</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-1680">
2860\theta^3(1-\theta)^9
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/e/e4/2860%281-x%29%5E9x%5E3.png" alt="enter image description here" title=""></p>
<p>というように確率分布は観測結果に応じて変化していきます。</p>
<p>さらに試行を重ね、オモテ30回、ウラ30回と均等に出るという事象が観測された場合。 <br>
<script type="math/tex; mode=display" id="MathJax-Element-1681">
7214139475456546864 (1 - \theta)^{30} \theta^{30}
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/4/43/7214139475456546864_%281_-_x%29%5E30_x%5E30.png" alt="enter image description here" title=""></p>
<hr>
<p>以上のような確率分布になるような観測結果をもつ世界はこの全事象の分岐(領域の分割)の先のいずれかのひとつとして存在しています。</p>
<p>だいたい世界観のイメージは伝わったと思いますので、観測による多世界の分岐現象がベイズの定理でどう表現されているか確認します。</p>
<p>Evidence(証拠、観測値、データ(の確率分布)) <br>
Hypothesis(仮説(の確率分布))</p>
<pre class="prettyprint"><code class=" hljs mathematica">P(H|<span class="hljs-keyword">E</span>) = P(H,<span class="hljs-keyword">E</span>) / P(<span class="hljs-keyword">E</span>)
= P(H) x P(<span class="hljs-keyword">E</span>|H) / P(<span class="hljs-keyword">E</span>)</code></pre>
<p>というものでした。</p>
<p>モデルケースとして、以下を再掲します。</p>
<hr>
<p><script type="math/tex; mode=display" id="MathJax-Element-1718">
y = x^2
</script></p>
<p>で分岐(グラフが分割)</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/Xx%5E2.png" alt="enter image description here" title=""></p>
<p>されましたが、そのうち、オモテ連続2回世界の延長の分岐を探ります。 <br>
グラフでいうと、一番右下の三角形が凹んだ領域のことです。</p>
<p>オモテ連続2回世界の延長を前提とし、 <br>
また同じ試行の <br>
「条件付き確率」 <br>
y = x <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/1/19/X-graph.png" alt="enter image description here" title=""></p>
<p>によって世界が分割されるので、 <br>
<script type="math/tex; mode=display" id="MathJax-Element-1719">
y = x^3
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/6/6c/Xx%5E2x%5E3.png" alt="enter image description here" title=""></p>
<hr>
<p>以上を例にとって考えてみると、</p>
<p>1.事前確率(分布) <br>
<script type="math/tex; mode=display" id="MathJax-Element-1720">
P(H)= x^2
</script> <br>
観測によって分岐される前の前提となる世界の分布 <br>
この場合は、オモテ連続2回世界がP(H)という事前確率分布になっている</p>
<p>2.観測(分布) 一般的には「尤度(Likelihood)」という用語になっている <br>
<script type="math/tex; mode=display" id="MathJax-Element-1721">
P(E|H)= x
</script> <br>
観測による分岐前を前提とした条件付き確率の分布、 <br>
事前確率(分布)であるP(H)を前提としたときの観測データEvidenceの確率分布 <br>
この場合は、試行データ=オモテ</p>
<p>3.事後確率(分布)</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-1732">
P(H|E) = x^3
</script> <br>
観測データEvidenceによって分岐した後の世界の確率分布、 <br>
これは、観測データEvidenceを前提とした条件付き確率の分布として表現されている <br>
この場合は、オモテ連続3回世界の確率分布が得られた</p>
<p>さて、最後に、ベイズの定理</p>
<pre class="prettyprint"><code class=" hljs mathematica">P(H|<span class="hljs-keyword">E</span>) = P(H) x P(<span class="hljs-keyword">E</span>|H) / P(<span class="hljs-keyword">E</span>)</code></pre>
<p>4つ目の確率分布である、 P(E)です。 <br>
初見では <br>
「これこそがEvidenceの確率なのだから観測のなにかの分布なんだろう?」 <br>
と勘違いしてしまいますが、すでに確認したとおり、観測に該当するのは <br>
世界が分岐する前の、事前確率分布P(H)を前提とした、 <br>
条件つき確率分布であるP(E|H)のほうでした。</p>
<p>今回、多世界解釈に基づいて、 <br>
あるコインを試行するときの多世界の全部を全事象1として、 <br>
それが観測によって分岐、分割されていくという現象を調べました。</p>
<p>その結果、世界が分岐し、確率密度のグラフ領域が分割された先のひとつには、 <br>
たとえば、オモテ1回ウラ1回のイーブンな観測が得られた世界の確率分布が、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2110">
y = x (1- x)
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/7/72/1x%281-x%29.png" alt="enter image description here" title=""></p>
<p>このようになっていることも確かめられました。</p>
<p>この確率分布は、あくまで、 <br>
あるコインを試行するときの多世界の全部を全事象1としたときのグラフのうち</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/Xx%5E2.png" alt="enter image description here" title=""></p>
<p>中央の三日月のような領域として分割された割合です。</p>
<p>さあここで、よくわかった、でももう多世界全部の事象のことは関係ないや、この分岐した世界ローカルで考えたい!という立場を取る方針にした場合、 <br>
あるいは、 <br>
多世界分岐後の新たなる多世界の出発点として、この分布こそが今ここにあるコイン試行世界のすべてであり、原点である、という方針にした場合、 <br>
つまり、 <br>
多世界の全事象、全領域 <br>
<script type="math/tex; mode=display" id="MathJax-Element-2111">
y = 1
</script> <br>
<img src="https://upload.wikimedia.org/wikipedia/commons/c/c5/Plot%281,_%28x,_0,_1%29.png" alt="enter image description here" title=""></p>
<p>ではなく、 <br>
多世界の全事象、全領域</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2221">
y = x (1- x)
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/7/72/1x%281-x%29.png" alt="enter image description here" title=""></p>
<p>という初期設定にリセットしたい場合、 <br>
この確率密度関数の積分値が1となるように調整しなおさなければなりません。</p>
<p>これを「正規化(Normalization)」と言い、これは量子力学の波動関数でも同じ操作が必要になります。確率っていうのはしょせん、何かを基準とした割合のことなんで、どこを基準に取るか?っていうので値を調整する必要がでてきます。 <br>
ちなみに、ベイズ理論において、この確率密度関数の積分っていうのがめちゃくちゃ面倒くさい場合が多くて、うまい近似の手法でやったり、代数的な計算はあきらめてMCMCというモンテカルロ・シミュレーション(サンプリング)の手法でやったり、いろいろ工夫があってこういう積分の計算方法だけで一大研究課題となっています。</p>
<p>今回のケースでは、世界をベータ分布の連鎖で分割していったので、かなりはっきりとした代数のルールがあり、積分する必要はありません。(自然な共役分布) <br>
しかし、その代わり、その操作の履歴データが必要となります。</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-1995">
p=2,q=2
</script></p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2107">
(p + q - 1)! / (p - 1)! (q - 1)! =6
</script></p>
<p>というベータ関数にまつわる公式を利用すると、 <br>
全多世界事象1のうち、</p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/b/be/Xx%5E2.png" alt="enter image description here" title=""></p>
<p>三日月部分の世界の領域の割合は、1/6である、ということがわかります。 <br>
これが、全事象1のうちEvidenceの割合なので、P(E)の値となります。</p>
<p>じゃあ、P(E)が全事象となるようにリセットしたい、正規化したいならば、 <br>
全事象1のうちEvidenceの割合であるP(E)で割り算すればリセットできますね。</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2100">
y = x (1- x)
</script></p>
<p>を正規化すると、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2497">
y = x (1- x) / (1/6)
</script> <br>
<script type="math/tex; mode=display" id="MathJax-Element-2498">
= 6 x(1- x)
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/1/10/6x%281-x%29.png" alt="enter image description here" title=""></p>
<p>係数が1から6に増えたことによりグラフの領域が拡大されたことが確認できます。</p>
<p>4.全事象のうちの事後確率(分布)の確率</p>
<p>P(E) とは最初設定した全事象にたいする、事後分布P(H|E)の確率 <br>
これは多世界分岐(ベイズ更新)のすべての履歴が必要となる。 <br>
あるいは履歴なしでは積分して1になるような値を求める必要があるので、計算が一番やっかい。 <br>
P(H|E)を全事象としてリセットする正規化のために必要。</p>
<p>ベータ分布で <br>
<script type="math/tex; mode=display" id="MathJax-Element-2499">
P(H|E) = x^3
</script></p>
<p>のモデルケースでは、 <br>
<script type="math/tex; mode=display" id="MathJax-Element-2500">
P(E) = 1/4
</script></p>
<p>となり、</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-2505">
P(H|E) =x (1- x)
</script></p>
<p>のモデルケースでは、 <br>
<script type="math/tex; mode=display" id="MathJax-Element-2506">
P(E) = 1/6
</script></p>
<p>になる。</p>
<p>以上で、</p>
<p>ベイズの定理</p>
<pre class="prettyprint"><code class=" hljs mathematica">P(H|<span class="hljs-keyword">E</span>) = P(H) x P(<span class="hljs-keyword">E</span>|H) / P(<span class="hljs-keyword">E</span>)</code></pre>
<p>の4つの確率(分布)がすべて出揃いました。</p>
<p>ある確率分布で記述されている多世界があり、データを観測し、それに応じて世界が分岐し、確率(シェア、領域の割合)が分割され、分岐後の多世界がそれぞれ持つ確率分布を得る、ということをベイズ更新(Bayesian Updating)といいます。量子力学の多世界解釈すれば、ということですが。</p>
<p>いずれにせよ、この観測結果を反映するベイズ更新が連鎖構造になっています。 <br>
量子力学の確率分布であらわされる多世界が観測結果を反映して分岐している構造と1:1に呼応しています。</p>
<hr>
<p>さらに試行を重ね、オモテ30回、ウラ30回と均等に出るという事象が観測された場合。 <br>
<script type="math/tex; mode=display" id="MathJax-Element-3382">
7214139475456546864 (1 - \theta)^{30} \theta^{30}
</script></p>
<p><img src="https://upload.wikimedia.org/wikipedia/commons/4/43/7214139475456546864_%281_-_x%29%5E30_x%5E30.png" alt="enter image description here" title=""></p>
<hr>
<p>という様に、係数がめちゃくちゃ大きな値となっているのは、そもそもの全事象から世界が分割されまくった確率分布をリセットして正規化したからだ、という自然な解釈ができます。</p>
<p>以上は、コインの試行についてベータ分布になる、というのはどこにでも普通に書かれている知見ですが、量子力学の確率理論、特に多世界解釈で、ベイズ理論を俯瞰してみればどういう意味だろう?というのは筆者のオリジナルです。別にどこか他のどなたが同じ解説をしているかもしれませんが、よくわかりません。 <br>
特に、ベイズ理論を確率分布に適用した場合についての尤度(Likelihood)について納得できる解説が見当たらなかったのですが、こう俯瞰したら納得できたということです。また、ベイズ統計学について、「主観確率」であるとか「あいまいな推定ができる」とか、「信念の度合いが表現できる」とか事例を示されたとしても、それが数式のイメージとして腑に落ちることはありませんでした。 <br>
また、世紀をまたいで継続している、「ネイマン=ピアソンの頻度主義統計学」とベイズ統計学の論争は、根本的にはこのコペンハーゲン解釈と多世界解釈の問題があると考えています。 <br>
そして念の為ですが、今回書いたような多世界解釈の哲学的立場は、素朴実在論では到底受け入れられないために不当な心理的反発を招きやすいのですが、これはもちろん私の独自哲学でもなんでもありません。今回あくまで多世界解釈の哲学的立場をそのまま援用してベイズ統計学を解釈してみた、という論理的帰結にすぎません。量子力学において波動関数(確率密度関数)で量子の存在確率が定まる、それは観測という行為にリンクしているというのは、ベイズ更新の特徴そのものであり、照らし合わせてみると案の定自然に解釈できた、ということにすぎません。</p>
<p>基本的に義務教育あるいは高等教育であっても多世界解釈を教えることは「何かと面倒くさい」ことのようで、理由とすれば素朴実在論的世界観が妨害しているとしか思えないのですが、その一方で素朴実在論と相容れない相対性理論、量子力学は学習する必要はあります。</p>
<p>その際、いずれにせよ「観測の結果、可能性が消えた」と普段発している言葉の意味はいったいどういうことなのか?というのは別段ベイズ統計学に限らず義務教育で習う局面であっても誰でもが一度は考えたことがあるかもしれません。「観測の結果、可能性が消えた」というのは量子力学の波動関数の収束に他ならず、これはコペンハーゲン解釈では理論的に破綻していることは数学的に証明されています。理論内からけして導出できない現象について理論の外に大業な名前をもって原理の追加する、ことがまかり通るのであればあらゆるオカルト現象も同様に、なんか大業な名前をつけてそういう原理の法則であると言ってしまえばすむわけなので、これは科学ではないだろうと訝しく思っています。</p>
<p>この「観測の結果、可能性が消えた」というのは、実際ベイズ更新の解説で多用されていること、あと、ベイズ理論から展開されるベイズ統計学的機械学習が最近主流になりつつありますが、次にどの方向に進めばスムーズに楽しくすすめるのか?過去の自分の経験を踏まえながら少し紹介します。</p>
<p>今回紹介したとおり、ベイズ推定はデータを観測して条件付き確率で確率分布をアップデートする連鎖構造になっています。この簡潔な連鎖構造を応用していくらでも複雑な構造化が可能なのですが、視覚的に表現する体系が確立されていて、グラフィカルモデルといいます。 <br>
グラフィカルモデルのノードひとつひとつが条件付き確率からのベイズ推定であり、グラフィカルモデルのネットワーク構造はベイズ推定のネットワークです。 <br>
矢印ある有向ならばいわゆるベイジアンネットワークであり、無向ならマルコフ確率場です。 <br>
マルコフ確率場とだけ聞くとなんか面倒くさそうだな、と思うんですが、構造としてはこちらのほうがベイジアンネットワークよりもシンプルで、まあベイズで連想記憶とかやる場合はこちらを確実に使うでしょう。あとコンピュータビジョン。</p>
<p>逆にグラフィカルモデルの「ことば」が理解できないと、たいていの本を読むとき必ず挫折してしまうので、ベイズの基本を徹底的に学習したその次はグラフィカルモデルに進むというのがおすすめです。</p>
<p>PRMLはベイズ統計学に基づいたグラフィカルモデルと生成モデルの体系的な説明が以前から評価を得た大きな理由だと思いますが、</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4621061224" scrolling="no"></iframe>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4621061240" scrolling="no"></iframe>
<p>著者のビショップ教授もグラフィカルモデルは導入として特別扱いしているようで、</p>
<p>PRMLの8章グラフィカルモデルだけは無償でPDFダウンロードできるようになっていたり、 <br>
<a href="http://research.microsoft.com/en-us/um/people/cmbishop/prml/">http://research.microsoft.com/en-us/um/people/cmbishop/prml/</a> <br>
Contents list and sample chapter (Chapter 8: Graphical Models) in PDF format. <br>
<a href="http://research.microsoft.com/en-us/um/people/cmbishop/prml/pdf/Bishop-PRML-sample.pdf">http://research.microsoft.com/en-us/um/people/cmbishop/prml/pdf/Bishop-PRML-sample.pdf</a></p>
<p>サマースクールでもその無償PDFをテクストとして、数学とりのぞいたバージョンの導入レクチャーをやっていてYouTubeで閲覧できます。見なきゃ損のコンテンツ。 <br>
講義のスライドもダウンロードできます。 <br>
<a href="http://mlss.tuebingen.mpg.de/2013/bishop_slides.pdf">http://mlss.tuebingen.mpg.de/2013/bishop_slides.pdf</a></p>
<p>非常にいたれりつくせりで、英語も聞き取りやすいのですが、耳障りが良すぎて寝る人が多い気がします。</p>
<p>Graphical Models 1 - Christopher Bishop - MLSS 2013 Tübingen <br>
<a href="https://www.youtube.com/watch?v=ju1Grt2hdko">https://www.youtube.com/watch?v=ju1Grt2hdko</a></p>
<p>Graphical Models 2 - Christopher Bishop - MLSS 2013 Tübingen <br>
<a href="https://www.youtube.com/watch?v=c0AWH5UFyOk">https://www.youtube.com/watch?v=c0AWH5UFyOk</a></p>
<p>Graphical Models 3 - Christopher Bishop - MLSS 2013 Tübingen <br>
<a href="https://www.youtube.com/watch?v=QJSEQeH40hM">https://www.youtube.com/watch?v=QJSEQeH40hM</a></p>
<p>このビショップ講義でも、グラフィカルモデルの基本としてのベイズ推定で「可能性が消える」話をたくさんしています。上のスライドみれば多分それはすぐわかるでしょう。</p>
<p>あとYoutubeで <br>
Graphical Modelsで検索すれば、この界隈の著名人によるグラフィカルモデルの講義が沢山あります。Daphne Kollerとか。 <br>
<a href="https://www.youtube.com/watch?v=WPSQfOkb1M8&list=PL50E6E80E8525B59C">https://www.youtube.com/watch?v=WPSQfOkb1M8&list=PL50E6E80E8525B59C</a> <br>
こっちは「長い」膨大な量で自分もまだ全部見れていません。</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=0262013193" scrolling="no"></iframe>
<p>もちろん、前回紹介したサイモン・プリンスの <br>
「ベイズ推定とグラフィカルモデル:コンピュータビジョン基礎」</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=1107011795" scrolling="no"></iframe>
<p>もこの流れとなります。これも実質日本語訳の秀逸なオンライン講義が広島大のToru Tamaki 先生のレクチャーで見れるのでした。実際これはオンライン講義のほうがわかりやすくて、本読むのより随分楽です。</p>
<p>最近多いですねこういう優良な無料学習コンテンツが。 <br>
こういう秀逸なコンテンツを複数あわせて読む、聞く、見ると、多分最短で結構なところまで進めるんじゃないでしょうか。</p>
<p>本は速読したり、スキャン的な読解が可能で、内容が薄いとオンラインビデオチュートリアルなんかより本のほうが便利なんですが、思ったのはこういう一般にはとっつきにくい内容であるほど、著者は書籍より内容を一般向けに噛み砕いて非常に熱心に親切に教えようとする人が多いってことです。ああこれならもう本文読まなくていいんじゃない?という感じだったり、そう思ってから本文読むと、楽に読めたり、もちろん数式などはさっきのPRML8章みたいに、書籍には書いてあるみたいなことがあるんですが、どっちにせよ先にオンライン見たほうが良いと思います。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-65610555726630594092016-03-09T23:59:00.001+09:002016-03-11T01:26:53.857+09:00ベイズ導入とベイズ統計的機械学習参考書の紹介など<p>最近の機械学習のあらゆる教科書に必ずといって良いほど、最初のほうの章を割いて解説(紹介)されているのがベイズ統計学です。</p>
<p>ベイズ理論は簡潔な「ベイズの定理」から展開される非常に美しい理論体系で、 <br>
それゆえrobust(堅牢)で応用範囲が想像を絶するほど豊かです。 <br>
昨今もろに統計学的データサイエンス化してしまった機械学習、人工知能の研究の根幹となる理論であり、実用、応用で道具として使えればそれで良いというノリでさらりと終わらされてしまう(と自分は見てて思う)のはもったいないと思いつつ、巷の説明が非常に難解なので、ベイズ推定の概念の導入の導入として、考えうるかぎり一番かんたんな説明を試みます。</p>
<pre class="prettyprint"><code class=" hljs 1c">トランプのカードを考える。
カードが黒 ■
カードが赤 □
と表記し、
カードのマーク(スート)の強さは
♠ > ♡ > ♢ > ♣なので、
上位2つを ↑
下位2つを ↓
とグループわけして表記することにする。
<span class="hljs-string">| | ■ | □ | </span>
+---<span class="hljs-string">|---|---+</span>
<span class="hljs-string">| ↑ | ♠ | ♡ |</span>
<span class="hljs-string">| ↓ | ♣ | ♢ |</span>
ジョーカーを除外した<span class="hljs-number">13</span>x4=<span class="hljs-number">52</span>枚のデッキからカード<span class="hljs-number">1</span>枚引いたとき、
カードが♠である確率を`
(♠)
と表記することにする。
♠♡♢♣のうち♠である確率は
(♠) = <span class="hljs-number">1</span>/<span class="hljs-number">4</span>
カードが■である確率は、
(■) = <span class="hljs-number">1</span>/<span class="hljs-number">2</span>
カードが↑である確率は、
(↑) = <span class="hljs-number">1</span>/<span class="hljs-number">2</span>
♠は、■かつ↑なので、
同時確率(♠) = (■∩↑)
カードが■のとき、それが♠であるという、条件付き確率
(♠<span class="hljs-string">|■) = 1/2</span>
カードが↑のとき、それが♠であるという、条件付き確率
(♠<span class="hljs-string">|↑) = 1/2</span>
まとめると、
(♠) = (■∩↑) = (■) x (♠<span class="hljs-string">|■) </span>
= (↑) x (♠<span class="hljs-string">|↑)</span>
(<span class="hljs-number">1</span>/<span class="hljs-number">4</span>) = (<span class="hljs-number">1</span>/<span class="hljs-number">2</span>) x (<span class="hljs-number">1</span>/<span class="hljs-number">2</span>)
= (<span class="hljs-number">1</span>/<span class="hljs-number">2</span>) x (<span class="hljs-number">1</span>/<span class="hljs-number">2</span>)
移項すると、
(♠<span class="hljs-string">|■) = (♠) / (■) </span>
もしくは、
(♠<span class="hljs-string">|↑) = (♠) / (↑) </span>
という関係が成り立つ。
(<span class="hljs-number">1</span>/<span class="hljs-number">2</span>) = (<span class="hljs-number">1</span>/<span class="hljs-number">4</span>)/ (<span class="hljs-number">1</span>/<span class="hljs-number">2</span>)
これは、デッキからカード<span class="hljs-number">1</span>枚引いたとき、
そのカードが♠である確率
(♠) = <span class="hljs-number">1</span>/<span class="hljs-number">4</span>
が、裏向けたまま「カードの色は黒(■)ですよ」と情報を与えられたことにより、
可能性は、♠♣に限定されてしまい、
カードが■のとき、それが♠であるという、条件付き確率
(♠<span class="hljs-string">|■) = 1/2</span>
に収束したと解釈できる。
(♠) = <span class="hljs-number">1</span>/<span class="hljs-number">4</span>
という「事前確率」が
(♠<span class="hljs-string">|■) = 1/2</span>
という「事後確率」へと更新された現象を
「ベイズ更新」と呼ぶ。
同じように、デッキからカード<span class="hljs-number">1</span>枚引いたとき、
そのカードが♠である確率
(♠) = <span class="hljs-number">1</span>/<span class="hljs-number">4</span>
が、裏向けたまま「カードのマークは上位(↑)ですよ」と情報を与えられたことにより、
可能性は、♠♡に限定されてしまい、
カードが↑のとき、それが♠であるという、条件付き確率
(♠<span class="hljs-string">|↑) = 1/2</span>
に収束したと解釈できる。</code></pre>
<p>もう少し複雑なケース。</p>
<pre class="prettyprint"><code class=" hljs ruby">アウトレットセンターのある店舗で、
顧客の購入動向を統計的に分析することにした。
店舗に立ち寄る顧客が商品購入する確率は<span class="hljs-number">10</span>%である。
購入する場合を <span class="hljs-variable">$
</span>購入しない場合を ~
と表記すると
(<span class="hljs-variable">$)</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">1</span>)
(~) = (<span class="hljs-number">0</span>.<span class="hljs-number">9</span>)
となる。
商品購入する顧客が店員に声掛けする確率は <span class="hljs-number">70</span>%
商品購入しない顧客が店員に声掛けする確率は <span class="hljs-number">20</span>%
顧客が店員に声掛けする事象を ☻
顧客が店員に声掛けしない事象を ☹
と表記すると、
商品購入確率からの声掛けの条件付き確率は、
(☻|<span class="hljs-variable">$)</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">7</span>)
(☹|<span class="hljs-variable">$)</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">3</span>)
(☻|~) = (<span class="hljs-number">0</span>.<span class="hljs-number">2</span>)
(☹|~) = (<span class="hljs-number">0</span>.<span class="hljs-number">8</span>)
となる。
| | <span class="hljs-variable">$ </span> | ~ |
+---|-----|-----+
| ☻ | <span class="hljs-variable">$∩</span>☻ | ~∩☻ |
| ☹ | <span class="hljs-variable">$∩</span>☹ | ~∩☹ |
という<span class="hljs-number">4</span>パターンの組み合わせを考慮しながら、
以下のように、すべての確率を洗い出すことができる。
(<span class="hljs-variable">$∩</span>☻) = (<span class="hljs-variable">$)</span> x (☻|<span class="hljs-variable">$)</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">1</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">7</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">07</span>
= (☻) x (<span class="hljs-variable">$|</span>☻) = (<span class="hljs-number">0</span>.<span class="hljs-number">25</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">28</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">07</span>
(<span class="hljs-variable">$∩</span>☹) = (<span class="hljs-variable">$)</span> x (☹|<span class="hljs-variable">$)</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">1</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">3</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">03</span>
= (☹) x (<span class="hljs-variable">$|</span>☹) = (<span class="hljs-number">0</span>.<span class="hljs-number">75</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">04</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">03</span>
(~∩☻) = (~) x (☻|~) = (<span class="hljs-number">0</span>.<span class="hljs-number">9</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">2</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">18</span>
= (☻) x (~|☻) = (<span class="hljs-number">0</span>.<span class="hljs-number">25</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">72</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">18</span>
(~∩☹) = (~) x (☹|~) = (<span class="hljs-number">0</span>.<span class="hljs-number">9</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">8</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">72</span>
= (☹) x (~|☹) = (<span class="hljs-number">0</span>.<span class="hljs-number">75</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">96</span>) = <span class="hljs-number">0</span>.<span class="hljs-number">72</span>
このうち、たとえば最初の式、
(<span class="hljs-variable">$∩</span>☻) =
(<span class="hljs-variable">$)</span> x (☻|<span class="hljs-variable">$)</span> = (☻) x (<span class="hljs-variable">$|</span>☻)
という条件付き確率の関係性に着目して、
(<span class="hljs-variable">$|</span>☻) = (<span class="hljs-variable">$)</span> x (☻|<span class="hljs-variable">$)</span> / (☻)
(<span class="hljs-number">0</span>.<span class="hljs-number">28</span>) = (<span class="hljs-number">0</span>.<span class="hljs-number">1</span>) x (<span class="hljs-number">0</span>.<span class="hljs-number">7</span>) / (<span class="hljs-number">0</span>.<span class="hljs-number">25</span>)
と整理しなおしてみる。
左辺の(<span class="hljs-variable">$|</span>☻) は、
顧客が店員に声掛けした場合の商品購入確率という条件付き確率である。
ある顧客が入店した際に、
「彼女が商品を購入するかどうか?」という確率は当初
(<span class="hljs-variable">$)</span> = (<span class="hljs-number">0</span>.<span class="hljs-number">1</span>)
であったのが、
彼女が店員に声掛けした、という事象が確定した途端に、
彼女の商品購入確率(<span class="hljs-variable">$)</span>が、声掛け(☻)の情報獲得によって
(<span class="hljs-variable">$|</span>☻) = (<span class="hljs-number">0</span>.<span class="hljs-number">28</span>)
つまり、<span class="hljs-number">10</span>% → <span class="hljs-number">28</span>% にupdate(更新)された、と解釈できる。
これが<span class="hljs-constant">Bayesian</span> <span class="hljs-constant">Updating</span>「ベイズ更新」である。
(<span class="hljs-variable">$)</span>→(<span class="hljs-constant">Hypothesis</span>)仮説
(☻)→(<span class="hljs-constant">Evidence</span>)証拠・データ
とし、
(<span class="hljs-variable">$|</span>☻) = (<span class="hljs-variable">$)</span> x (☻|<span class="hljs-variable">$)</span> / (☻) をそのまま
(<span class="hljs-constant">H</span>|<span class="hljs-constant">E</span>) = (<span class="hljs-constant">H</span>) x (<span class="hljs-constant">E</span>|<span class="hljs-constant">H</span>) / (<span class="hljs-constant">E</span>) と書き換え、さらに
<span class="hljs-constant">Probability</span>(確率)のことであると明示する記法で
<span class="hljs-constant">P</span>(<span class="hljs-constant">H</span>|<span class="hljs-constant">E</span>) = <span class="hljs-constant">P</span>(<span class="hljs-constant">H</span>) x <span class="hljs-constant">P</span>(<span class="hljs-constant">E</span>|<span class="hljs-constant">H</span>) / <span class="hljs-constant">P</span>(<span class="hljs-constant">E</span>)
と定義されていることが多い。(ベイズの定理・ベイズ推定)
<span class="hljs-constant">P</span>(<span class="hljs-constant">E</span>|<span class="hljs-constant">H</span>)は、<span class="hljs-constant">Likelihood</span>(尤もらしさ)、日本語では「尤度(ゆうど)」と呼ばれている。
<span class="hljs-constant">P</span>(<span class="hljs-constant">H</span>|<span class="hljs-constant">E</span>) = <span class="hljs-constant">P</span>(<span class="hljs-constant">H</span>) x <span class="hljs-constant">P</span>(<span class="hljs-constant">E</span>|<span class="hljs-constant">H</span>) / <span class="hljs-constant">P</span>(<span class="hljs-constant">E</span>)
で、
<span class="hljs-constant">P</span>(<span class="hljs-constant">H</span>)は<span class="hljs-constant">Prior</span>、日本語では「事前確率」
<span class="hljs-constant">P</span>(<span class="hljs-constant">H</span>|<span class="hljs-constant">E</span>)は<span class="hljs-constant">Posterior</span>、日本語では「事後確率」
<span class="hljs-constant">Posterior</span> ∝ <span class="hljs-constant">Prior</span> x <span class="hljs-constant">Likelihood</span>
の関係が成り立ち、何度も<span class="hljs-constant">Update</span>できる。
ベイズ更新の繰り返しを利用して、事象の確率を推定することをベイズ推定と呼ぶ。
各パラメータには、確率だけでなく、確率分布、確率の確率分布、
さらに「確率分布」も確率変数と見なして、確率分布の確率分布、
など柔軟に適用でき自由度が無限に高い。</code></pre>
<p>導入記事おわり。</p>
<p>以下、ついでに随想と参考書の紹介。</p>
<p>ではそもそも最初の「事前確率」はどうするのか?というのは、実は一大問題で、ベイズ理論がデータサイエンス、機械学習と結びつく際の根幹となる問題。 <br>
おそらく、昨今注目されている深層学習(ディープラーニング)(というバズワード)もこのベイズ更新の事前確率の初期値の問題に還元されてしまいます。</p>
<p>ディープラーニングって何がディープなのか?というと、要するにディープな多層構造のニューラルネットワークであるということで、 <br>
畳み込みニューラルネットワーク(Convolutional Neural Networks: CNN) <br>
ディープボルツマンマシン(Boltzmann machine)などで構成されています。 <br>
ボルツマンマシンも、ホップフィールド・ネットワークで、大元はアソシアトロンで、ととにかく、まだこの段階では「ニューラルネットワーク」全開。 <br>
しかし、ニューラルネットワークという脳のニューロン、シナプスのモデル化は、もうまもなくすべてベイズ理論に還元されてしまって「古典化」するとしか思えないし、多分そうなります。</p>
<h2 id="ニューラルネットワークはどこへ行った">ニューラルネットワークはどこへ行った?</h2>
<p>自分が機械学習というか人工知能に興味を持って勉強し始めたのは、そもそもは小学生のころ「<a href="http://www.amazon.co.jp/gp/product/4883170802/ref=as_li_ss_tl?ie=UTF8&camp=247&creative=7399&creativeASIN=4883170802&linkCode=as2&tag=tedlearner-22">マッチ箱の脳(AI)</a><img src="http://ir-jp.amazon-adsystem.com/e/ir?t=tedlearner-22&l=as2&o=9&a=4883170802" width="1" height="1" border="0" alt="">」をBASICで実装したり、ということからはじまりますが、もうちょっとちゃんとした本を読んだのは、平成元年のころ、さっきのアソシアトロンの発案者のひとり中野馨 先生が監修した『入門と実習 ニューロコンピュータ』</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4874083080" scrolling="no"></iframe>
<p>というものでした。当時、日本語では多分この本くらいしか機械学習の本なんて存在しなかったと思います。 <br>
この本にはガッツリ脳のニューロン、シナプスのによる学習機構のこと紙面の半分くらいを割いて書かれていました。学習とは、脳のシナプスの可塑性によって成し遂げられる、シナプス可塑性は<a href="https://ja.wikipedia.org/wiki/%E3%83%98%E3%83%83%E3%83%96%E3%81%AE%E6%B3%95%E5%89%87">ヘッブの法則</a>がある、ということで、現在までの機械学習の研究の多くはこの系譜にあります。アソシアトロンはもろにこのヘブ則をモデル化して連想記憶を実現したものです。</p>
<p>そもそも最初は、脳のシナプスの可塑性をモデル化した形式ニューロンが神経生理学者によって提唱され、これはチューリング完全の計算能力を持つ、バラ色の未来が予期されるということで、単純パーセプトロンが実装されたわけですが、これは期待に反してチューリング完全ではありませんでした。入力層と出力層のみの2層からなるパーセプロトンはではXORなどの線形非分離な問題は絶対に学習できないことが指摘されます。いわゆる「XOR問題」。いくら形式ニューロンの組み合わせで原理的にチューリング完全でも、学習機構の制限によってできない。パーセプトロンまでは脳のニューラルネットのモデル化でしたが、XOR問題あたりでニューラルネットと線形回帰の等価性の数学的証明など研究が著しく進みます。このあたりが機械学習が統計学に還元される萌芽でしょう。 <br>
実は単純パーセプトロンでも人口ニューロンの活性化関数に一次関数ではなくて二次関数以上を採用すればXOR問題は解けるという話もあるんですが、そもそも一次関数にこだわっているのは、シナプスの可塑性の原理にあるっぽいです。自然をリスペクトしているのかどうかはわかりません。しかし単純パーセプトロンさえ。その割には学習機構にヘブ則もへったくれもない、一回数学世界に還元したような学習機構がダブルスタンダードで、当時の自分はこの辺が特に??でした。</p>
<p>パーセプトロンのXOR問題以降その後10年ぐらい人工知能ブームが停滞します。希望って大事ですね。その後、線形分離不可能なXOR問題を解決しチューリング完全にすべく、多層で学習を可能にしたバックプロパゲーション(誤差逆伝播学習法)機能つきの多層パーセプトロンが地道に研究しつづけていた人たちによって発明されます。もうこの頃は、人口ニューロンの活性化関数が連続で微分可能でないといけない、確率的最急降下法だとか、完全に脳のニューロモデル、ヘブ則とかぶっちぎっていました。人間の脳神経細胞が微分とかしているわけがないので、ニューラルネットをモデル化しながら統計的学習手法とかやってるダブスタな潮流を眺めながら「何かが完全におかしい」と感じた当時の自分が機械学習の学習に完全に興味を失ってしまったのでした。まあ今でもディープラーニングと言いながらディープな階層、CNN、ボルツマンマシンだとニューラルネットやっているわけで、Googleネコ概念認識の実験にしてもいまだニューラルネットです。その実装の方向性は違うと思っていますが、要するにニューラルネットのクラスタ化と各クラスタでの特徴抽出(次元削減)がキモのようで、この辺はすべてニューラルネットでなく抽象化したベイズ統計に還元、一元化できるはずです。</p>
<p>特にまるで別分野で発展してきた、自然言語解析方面でのデータサイエンス界隈の知見の集積がものすごくて、そこでの最先端はもちろんベイズ理論で、特にクラスタリング、生成モデルで、ノンパラメトリックベイズ法、階層ディリクレ過程が衝撃的です。(ベイズ推定の最初の「事前確率」はどうするのか?) <br>
ディープラーニングのクラスタ化自体を教師なし学習させるのが課題だと思うのですが、もうすぐ誰かがこの辺全部統合して、そこからさらに研究、実装の進化が加速すると予想します。画像認識でも<a href="http://qiita.com/tn1031/items/b536189127b67b9c11b3">階層ディリクレ過程とマルコフ確率場を利用した教師なし画像領域分割</a>とか、すでに、どうやるか?ではなく、もう日本人でも優秀な人が誰がすぐやるか?のフェイズのブレイクスルーが山積みだと思います。</p>
<h2 id="参考書の紹介など">参考書の紹介など</h2>
<p>以上、ニューラルネットはすでに古典的モデルであり、もれなくすべてベイズ統計に還元できる、ということを強調しました。歴史的な研究として学ぶのは良いと思うのですが、既存のニューラルネットを改善して、、、という研究の方向性はかなり筋が悪いと信じます。ニューラルネットは現在非常にとっちらかっていて、今後100%統計学的なデータサイエンス特にベイズ統計に一元化されるべきですし多分そうなっていくでしょう。 <br>
その意味で、非常に良いと思ったのが、結構最近の教科書、Prince本です。</p>
<p>Computer vision: <br>
models, learning and inference <br>
Simon J.D. Prince <br>
July 7, 2012</p>
<p>です。 <br>
この本ではもはやニューラルネットやバックプロパゲーションなどそういうものは一切出てきません。100%ベイズです。 <br>
しかも、なんと個人使用に限り、無料で公式サイトからダウンロードできます。 <br>
<a href="http://www.computervisionmodels.com/">http://www.computervisionmodels.com/</a> <br>
紙の本で買いたい人は、Amazonで10000円くらいで買えます。和訳の本はありません。</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=1107011795" scrolling="no"></iframe>
<p>しかし、更に素晴らしいのは、 <br>
公式サイトに、 <br>
Japanese Video Lectures by Toru Tamaki <br>
とあるので、見てみると、 <br>
<a href="https://www.youtube.com/channel/UCirqYKKjRztDywdQXLDYYAg">https://www.youtube.com/channel/UCirqYKKjRztDywdQXLDYYAg</a> <br>
<a href="https://www.youtube.com/playlist?list=PLDVKrmVEl_WtGqMo6OWBiK7P9IsTPmTjO">https://www.youtube.com/playlist?list=PLDVKrmVEl_WtGqMo6OWBiK7P9IsTPmTjO</a> <br>
<a href="https://www.udemy.com/computervision/learn/">https://www.udemy.com/computervision/learn/</a> <br>
と、広島大のToru Tamaki先生によるオンライン講義があり、ほぼ実質和訳として視聴できます。通して拝見しましたが、わかりやすいし透明黒板での動画とか教育に熱意を感じます。ものすごい準備と撮影に時間、手間がかかっていることでしょう。この人は素晴らしいです。Prince本もそうですが、正直、なんでこんな良質なものがネットで読めたり、視聴できるのかよくわかりません。Udemyのほうでは、Prince本の前半部分だけで、後半は有料配信なんだろうか、と思っていましたが、上述のとおりYoutubeで後半もあります。</p>
<p>Princeはベイジアンですが、上述のノンパラメトリックベイズモデルについては残念ながら語っていません。 <br>
その意味で必読なのが、通称「続パタ」です。</p>
<p>石井健一郎,上田修功:続・わかりやすいパターン認識(教師なし学習入門),pp. 326,オーム社(2014)です。</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=427421530X" scrolling="no"></iframe>
<p>11章ではノンパラメトリックベイズモデルの基礎となるディリクレ過程やその実現例となる Chinese RestaurantProcess や Pitman-Yor 過程などについて丁寧に解説され、12 章では,ディリクレ過程混合モデルとその学習法について解説し,クラスタ数が未知の場合のクラスタリングの具体的な方法について説明されています。ノンパラメトリックベイズモデルについて国内で詳しく解析された書籍はほとんどないので、この本の評価が高いとすれば、それが理由でしょう。 <br>
もちろんこれも、第1章 ベイズ統計学からはじまる全力のベイジアン本です。11 ~ 13 章について主に執筆を担当している上田氏は現在,NTTコミュニケーション科学基礎研究所において「機械学習・データ科学センター」センター長でおられるようです。</p>
<p>最後にパターン認識と機械学習 - ベイズ理論による統計的予測(Pattern Recognition and Machine Learning)=PRML通称Bishop本 </p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4621061224" scrolling="no"></iframe>
<p>これもベイズ本ですが、テクストとして網羅的であろうとして、いろんなことも書いてあります。たとえばサポートベクトルマシン(SVM)とかは一過性のものだと思いますのであんまり興味は出ません。内容もさすがにちょっと古くなってきています。ただ必読書。</p>
<p>ベイズ入門者向け</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4478013322" scrolling="no"></iframe>
<p>超最近出た本。通り一辺倒の数式説明ではなく、「考え方」「概念」の解説に情熱がある著者で、シンパシーもあり。多分一番入門者向け。しかしちゃんと最終的にベータ分布あたりまで到達している。</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=4816351817" scrolling="no"></iframe>
<p>「完全独習」と合わせて読むと相互補完できて良いと思う。</p>
<iframe src="http://rcm-fe.amazon-adsystem.com/e/cm?lt1=_blank&bc1=000000&IS2=1&bg1=FFFFFF&fc1=000000&lc1=0000FF&t=tedlearner-22&o=9&p=8&l=as4&m=amazon&f=ifr&ref=ss_til&asins=432012362X" scrolling="no"></iframe>
<p>「パターン認識と機械学習」(PRML本)と並ぶ、機械学習定番書。 <br>
しかしあくまでタイトル通り、統計的学習の基礎 ―データマイニング・推論・予測の教科書。 <br>
最初に紹介した、Computer vision: <br>
models, learning and inference <br>
Simon J.D. Princeがざっと流してしまっている数学要素をよりきちんと解説しているので、Prince本の理解を深めるという意味でも必読。</p>
<p>この日本語訳は15000円ほどと高価だが、原書は <br>
スタンフォード大の公式サイトから、これもPDFの無料ダウンロードあり。 <br>
<a href="http://statweb.stanford.edu/~tibs/ElemStatLearn/">http://statweb.stanford.edu/~tibs/ElemStatLearn/</a> <br>
</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-20146213540913544782016-02-10T17:35:00.001+09:002016-02-10T18:55:00.058+09:00Dockerじゃないsystemd-nspawn+machinectlが非常に良い<p><a href="http://kenokabe-techwriting.blogspot.jp/2016/01/qiita-esumiicamloeba8.html">前回</a>、</p>
<blockquote>
<p>自作FRPライブラリTimeEngineをブラッシュアップして <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
を公開しました。 <br>
次回は、その日本語訳、 <br>
Reactの応用技術、あるいはReact再入門についての記事をUPしますのでお楽しみに!</p>
</blockquote>
<p>と書いていたのですが、Dockerじゃないsystemd-nspawn+machinectlが非常に良い、ので予定を変更して、こちらを先にエントリします。いろいろ印象を忘れないうちに。TimeEngineに関してはとりあえず自分がすでに英文で書いたものを和訳してどこかにUPしておいたほうが、何か別展開や国内のためになるかな程度のことなのでお急ぎの方は上記リンクから英文読んでください。そちらも全部仕上がっているとは言えないですし、行き届いていないところをセルフチェックするために和訳もしておこうという感じです。</p>
<h1 id="実用的で枯れた技術コンテナ">実用的で枯れた技術「コンテナ」</h1>
<p>UNIX/Linuxの世界では、OSのコンテナ技術はずいぶんと昔から存在していました。</p>
<p><a href="http://www.nttdata.com/jp/ja/insights/trend_keyword/2014091101.html">Dockerの持つ意味とこれから起こること(NTT DATA)</a></p>
<blockquote>
<p>実用的で枯れた技術「コンテナ」 <br>
メインフレームや商用UNIXの世界では、コンテナ型仮想化技術は古くから使われていました。Solaris Containers, HP-UX Containersなど、アプリケーションの実行環境とワークロードを安全かつ低オーバーヘッドで分離することを目的としたこれらの技術は、ミッションクリティカル領域での事例も十分あり、20世紀の時代から使われている極めて実用的で枯れた技術でした。ところが、Linuxの世界でコンテナ技術は長らく脚光を浴びることがありませんでした。コンテナ技術不遇の時代、Linuxの世界で「実行環境とワークロードを安全に分離する」のは、ソフトウエアによるハードウエアのエミュレーション、すなわち、仮想マシンを動作させる仮想化技術が主たる役割を担ってきました。クラウドサービス、特にIaaSの実用化は世の中の仮想マシンの数を爆発的に増大させました。スモールスタートが可能、需要に応じて迅速にリソース量を変化させられる、低レイヤーの運用管理はクラウド事業者におまかせ、スケールメリットによる圧倒的低コスト……流行らないわけがありません。 <br>
“ご注文は仮想マシンでよろしかったでしょうか?” <br>
そんな中、整備が遅れていたLinuxカーネルのコンテナ技術(namespaces, cgroups)が出揃い、さらに、それをフル活用したDocker参考1がリリースされてから、多くの人が気付きはじめました。当初やりたいことは、「実行環境とワークロードを安全に分離する」ことであり、「ハードウエアをエミュレーションする」ことは、その手段として最適だったのか?もっと軽量で取り扱いしやすい方法があったのではないか?と。</p>
</blockquote>
<p>私はLinux使う前はOracleに買収される前のSunMicrosystemsが全力で開発していたSolarisをデスクトップ環境でも愛用していて、その頃は、他のOSの追随を許さないZONE(Solarisコンテナ)もある、ZFSもある、ものすごい先進的なOSだ!ということでLinuxなぞ使いたくなかった時期がありました。 <br>
もちろんLinuxを試したり、またSolarisに戻ったりと試行錯誤していたのですが、SunがOracleに買収されていろいろ残念なことになったり、LinuxはLinuxでしぶとく進化を続けたりして結局Solarisには戻らなくなってしまいました。開発元のSunは、Solarisコンテナ、ZFS、VirtualBoxなど、単一の会社で素晴らしい技術を世に先んじてリリースするという、技術力が傑出していた素晴らしい会社でした。</p>
<h1 id="仮想化がなぜ素晴らしいのか">仮想化がなぜ素晴らしいのか?</h1>
<p>色々言われていますが、大局的観点からいうと、それはハードウェア=物質的制約からの開放である、と言えます。</p>
<p>根本的には、「情報処理」というのは、情報を処理するのであって、ハードウェアを処理する行為ではありません。ハードウェアというのは情報処理のために必要な手段であり、土台にすぎず、情報処理の目的ではありません。必要なハードウェアは物質なので物質的な制約が存在しています。まず、物質としての固有の厳然たる単位が存在します。つまり、このサーバ一台と別のサーバを繋げて、それぞれメモリがいくらでドライブが、、、などなど諸々の制約があり、それぞれの単位にはそれぞれ物質としての経済的コストもかかります。</p>
<p>この情報処理として本質なマネージメントではないハードウェアのレイヤーの上位のレイヤーで抽象化して、一切合切の物質的わずらわしさから開放されたい、開放しよう、というのが「仮想化」であるということになります。</p>
<p>Sunの技術者が開発した先進的なファイルシステムであるZFSもHDDやらのファイルストレージというハードウェアの仮想化です。Windowsでは、今でもなおファイルシステムの構造が今でも、Cドライブが根本とかそういうことになっているわけですが、そもそもUNIXでは、ドライブという物質的概念は抽象化されて常にルートディレクトリが根本です。物理的なドライブは各ディレクトリに「仮想化」されてマウントできる、という設計思想になっています。しかしこの場合であっても、なおあらかじめボリュームから切り出すパーティションのサイズを決め打ちして各ディレクトリに配分する、というのは、どの程度配分すれば十分なのか?また無駄にならないのか?と決め打ちするだけのある種の知見や職人技が必要とされ、ある種の思い切りというか勇気が必要な作業でもあります。これをストレージプールというハードウェアの論理的集合体としてまとめて、臨機応変にファイルシステムに配分できるようにしたのがZFSです。</p>
<p>結局のところ、ZFSにせよVMWare,VirtualBoxにせよコンテナにせよ、ハードウェアを先に全部まとめて後から論理的にリソースを配分するという仮想化技術は、まったく同じ設計思想に基づいています。</p>
<h1 id="古くて新しいコンテナ仮想化dockerで新たなアプリケーション配布スタイルへ">古くて新しいコンテナ仮想化~Dockerで新たなアプリケーション配布スタイルへ~</h1>
<p>(<a href="http://www.nttdata.com/jp/ja/insights/trend_keyword/2014090401.html">NTT DATA</a>)</p>
<p><img src="http://www.nttdata.com/jp/ja/insights/trend_keyword/img/2014090401/fig_diagram01.png" alt="enter image description here" title=""></p>
<p>という認識が、Dokcerの普及によって広く一般的になりつつある、気もするのですが、旧来からあったUNIXのコンテナ技術であるSolarisゾーンはVMwareなどのようにハードウェアをエミュレートするものではないものの、1つのSolarisカーネル上で複数のSolarisを動作させる複数の仮想 Solaris環境です。</p>
<p>Dockerは1コンテナ=1アプリ=1プロセスのような設計思想ですが、旧来のSolaris的コンテナ技術からいえば、結構極端である、と言えます。</p>
<p>SolarisやLinuxのように同じカーネルを共用出来る場合は、ハードウェア仮想化というのは必要ではなく、コンテナ仮想化のほうが効率的なのでコンテナのほうを使いたいわけですが、SolarisゾーンみたいなのがUNIX系のコンテナだと思っていた自分にとっては、1コンテナ=1アプリ=1プロセスだ、というDockerの設計思想による制約は個人的には馴染みません。</p>
<p>もちろん、Dockerには1アプリがコンテナの粒度に統一してそれを配布する、というパッケージングによるマーケティング、人気の理由があるわけですが、人気があって普及しているからといって技術的に優れているわけではなく、それは単にそのような設計思想がトレンドに馴染んだということにすぎません。 <br>
Dockerはコンテナはアプリであり、データはデータ・ボリュームに分離すべきであり、そのオプションと利用法がどうとか、<a href="http://postd.cc/docker-ssh-considered-evil/">Dockerコンテナ内でsshdを実行してはいけない理由</a>があって、HOWTOがあったりと、手軽さのための設計思想が、柔軟性、自由度をあまりにも制約しすぎていて使いづらい技術だな、というのが私の印象です。</p>
<h1 id="microsoft-azure-クラウドマシン上でのコンテナ">MicroSoft Azure クラウドマシン上でのコンテナ</h1>
<p>ということで、触ってはみたが、まったくハマれなかったDockerですが、最近Azureのクラウドマシンで、Arch-Linuxのサーバを建てたいと思って調べてみましたが、ローリングアップデートリリースなArchはサーバ界でいまいち人気ないようでイメージが存在しませんでした。そこで、CoreOS+DockerコンテナでArchインストールすればいいやとおもって、とりあえずやってみたのですが、やはりコレジャナイ感が半端なく、別の方策、より従来のコンテナ技術らしい派閥のUbuntu+LXD( LXC)コンテナをトライしようとしましたが、やはりArchはまったく人気がないようでイメージが存在しませんでした。もちろん多分自分でイメージを構築するとかやり方は存在するんでしょうが、わからないし、結構大変な気がして何のために作業をやっているのかわからない危険性を感じました。そうやって調べているうちに発見したのが、systemd-nspawn+machinectlという選択肢でした。</p>
<h1 id="dockerじゃないsystemd-nspawnmachinectlが非常に良い-1">Dockerじゃないsystemd-nspawn+machinectlが非常に良い</h1>
<p><a href="http://www.geeks-dev.com/docker%E3%82%88%E3%82%8A%E6%9F%94%E8%BB%9F%E3%81%AA%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E5%9E%8B%E4%BB%AE%E6%83%B3%E5%8C%96systemd-nspawn%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F/">Dockerより柔軟なコンテナ型仮想化 systemd-nspawn を使ってみた</a></p>
<blockquote>
<p>Docker の愚痴 <br>
Dockerはコンテナ内でのsystemdに問題があり、systemctlでサービスの起動ができません。 <br>
というより本来そんな操作で動かすものじゃない・・・。 <br>
なんとか動かす手順もあるんですが、まぁ〜〜〜これが面倒くSay YO ☆ <br>
そもそもDockerは1コンテナ=1プロセスにすべきみたいな思想を掲げているんですが、この辺が私に合わない。 <br>
進歩の激しいOSS界で1コンテナ=1プロセスなんて無謀というか意味あんのっていうか。 <br>
規模の大きいサービスを1つだけ動かすみたいな場合はそれの方がいいでしょうけど、個人、もしくは少人数でそんな細切れコンテナ管理したくはないかな。 <br>
Dockerが合わない、わからないって人は大抵この話題ですよね。 <br>
どうせチューニングは必要になるんだし、それならコンテナに一時的に入ってイジったほうが手っ取り早くない? <br>
んで色々イジってたら面倒臭くなるんだって。 <br>
まぁメールとかDBとかスタンダードなものは分けたい気持ちはわからんでもないですよ。</p>
</blockquote>
<p><a href="http://www.geeks-dev.com/systemd-nspawn%E3%82%92%E6%B4%BB%E7%94%A8%E3%81%97%E3%81%A6vps%E3%81%AE%E6%A7%8B%E6%88%90%E3%82%92%E6%A0%B9%E5%BA%95%E3%81%8B%E3%82%89%E8%A6%8B%E7%9B%B4%E3%81%97%E3%81%9F/">systemd-nspawnを活用してVPSの構成を根底から見直した</a></p>
<p><a href="http://www.geeks-dev.com/systemd-nspawn%E3%81%A7%E4%BD%BF%E3%81%86machinectl%E3%81%8C%E7%B4%A0%E6%99%B4%E3%82%89%E3%81%97%E3%81%84%E4%BA%8B%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%9F/">systemd-nspawnで使うmachinectlが素晴らしい事になってた</a></p>
<p>systemd-nspawn+machinectlで検索しても日本語は皆無に近い状況のなかの記事です。</p>
<p>非常に良いのに、あんまりにも周知されていない人気のなさを憂いた、というのがこのエントリの動機でもあります。</p>
<p>Dockerは過大評価、systemd-nspawnは過小評価されている。まあ確かに前者はブレイクして、後者は新規ではあるんですが、新規であっても目ざとく発見して客観的評価が得意そうな技術世界も世間の流れに追随するだけの人の子、というのは常々感じる不条理ではあります。</p>
<p>ちなみに、比較的認知されているCoreOSの開発者がDockerじゃないフルのコンテナ技術として開発したのが、systemd-nspawnベースのRocket ですがイマイチ人気出ません。あんまり良くないようでベースのsystemd-nspawnそのままが進化しているのでより不要感が半端ない状況のようです。</p>
<blockquote>
<p>あぁ、そうそう最近rocket(rkt)の最新版を試しましたが、ぶっちゃけsystemd-nspawnが肌に合う人には向きません。 <br>
manifestファイル?これ利点ある?ないよね。 <br>
今から利点作るの? <br>
まさかまたsupervisor使わせるの・・・? <br>
なんてダサいんだろう。 <br>
enterさせるくせに一々これに稼働させるプロセス書かないといかんのかい? <br>
しかもaciも偉そうに規格化だの言ってるけど、ただmanifestファイルとrootfsをtarで固めてるだけ。 <br>
当然runするのにも展開しなきゃいけないもんだから初動が糞遅い。 <br>
便利さはDocker未満で柔軟さはsystemd-nspawn未満ですかね。 <br>
全然期待していたものとは違いました。 <br>
systemd-nspawn好きでrktが安定したら移行しようとか思ってた人は早々に諦めた方が良いです。</p>
</blockquote>
<p>npmライブラリの開発でもなんでもそうですが、依存する技術は、ソリッドでミニマルで基本的なものに限定したほうが、コントロール不能な外部要因としてのバグに翻弄されることもないし、rktじゃなくて、ベースのsystemd-nspawnで良いと思います。</p>
<h1 id="systemd-nspawnmachinectlが非常に良いところ">systemd-nspawn+machinectlが非常に良いところ</h1>
<hr>
<ul>
<li><p>設計思想 <br>
1コンテナ=1アプリ=1プロセスのような設計思想の縛りが存在せず、柔軟で自由。 <br>
従来、本来のコンテナとしての設計。</p></li>
<li><p>スタンダード <br>
Linuxディストロの主流となったsystemdの一部として存在している、LinuxOSプロセス管理そのものの派生機能である。systemdベースのUbuntu,Debian,Arch,CentOSなどで使える。標準化的に問題なし。systemdの開発者であるLennart Poetteringが開発している。いわば謹製で純粋。</p></li>
<li><p>バグ、安定性、信頼性 <br>
設計思想もそうだが、そもそもLinuxOSプロセス管理そのものの派生機能なので、バグの存在、安定性もろもろDockerその他よりもかなり信頼できる。</p></li>
<li><p>新規性 <br>
systemd自体がLinux世界で普及したのは比較的最近のことであり、さらに、systemd-nspawnというコンテナ技術が登場したのもかなり最近。現在活発に開発が進んでおり進化が早い。</p>
<blockquote>
<p><a href="http://www.geeks-dev.com/systemd-nspawn%E3%81%A7%E4%BD%BF%E3%81%86machinectl%E3%81%8C%E7%B4%A0%E6%99%B4%E3%82%89%E3%81%97%E3%81%84%E4%BA%8B%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%9F/">systemd-nspawnで使うmachinectlが素晴らしい事になってた</a> <br>
なんとpull-tar,pull-raw,pull-dkrがあるじゃあないですか。 <br>
これらは/usr/lib/machinesにダウンロードしてsystemd-nspawnで使える状態にするみたいですね。 <br>
pull-dkrはその名の通り、docker hubなどからdockerイメージを引っ張ってこれちゃう。 <br>
machinectl pull-dkr –verify=no base/archlinux –dkr-index-url=<a href="https://index.docker.io">https://index.docker.io</a> <br>
こんな感じで。 <br>
ちょっとこれ凄くない? </p>
</blockquote></li>
</ul>
<p>という新規性もあるのですが、最初は確かにすごいな、と感じたのですが、いじっているうちに、不要かな、と思いました。個人的にこのDockerで一段と普及した、コンテナのイメージ⇔コンテナのワークフローが非常に煩雑で馴染みません。</p>
<ul>
<li><p>ミニマルでシンプル、だからパワフル <br>
というのが設計でもっとも重要だと常に感じます。systemd-nspawnはそれなので、イメージなんちゃらとかあんまりいらんなあ、という感じ。</p></li>
<li><p>統合性、透明性 <br>
というのは、誤解されやすいワーディングではあるのですが、とにかく強くそう感じます。 <br>
systemd-nspawnは、systemdeの一部として、同じ設計思想で同じ技術者によって開発されている技術なので、systemdと完全に統合されています。たとえば、上記引用記事の「Docker の愚痴」にもあるとおり、Dockerではコンテナ環境としてここに問題アリなのですが、systemd-nspawnではコンテナのなかでsystemdサービスはsystemctlで普通にenable,startして隔離してコントロールできます。「プロセスツリーや様々な IPC サブシステム、ホスト・ドメイン名も完全に仮想化」されます。カーネル共用しているコンテナなのでsystemdもホストと共用するしかない、というのはまったく事実でなく、非常に美しいです。</p></li>
</ul>
<p><a href="https://wiki.archlinuxjp.org/index.php/Systemd-nspawn">https://wiki.archlinuxjp.org/index.php/Systemd-nspawn</a></p>
<blockquote>
<p>systemd-nspawn は chroot コマンドに似ていますが、chroot を強化したものです。 <br>
systemd-nspawn を使えば軽量な名前空間コンテナでコマンドや OS を実行することができます。ファイルシステム構造だけでなく、プロセスツリーや様々な IPC サブシステム、ホスト・ドメイン名も完全に仮想化するため chroot よりも強力です。 <br>
systemd-nspawn は /sys, /proc/sys, /sys/fs/selinux などのコンテナの様々なカーネルインターフェイスへのアクセスを読み取り専用に制限します。コンテナの中からネットワークインターフェイスやシステムクロックを変更することは出来ません。デバイスノードを作成することも不可能です。コンテナの中からホスト環境を再起動することはできず、カーネルモジュールをロードすることも制限されます。 <br>
仕組みとしては Lxc-systemd や Libvirt-lxc と異なり、とてもシンプルなツールで設定を行います。</p>
</blockquote>
<p>「chroot を強化したもの」という様式でファイルシステム構造を隔離するというのは、既存のホストOSの一部として安全に隔離されており、なお普通にホストでディレクトリ降りたらchrootで管理しているファイルシステムなので、透明に管理できます。つまり、Dockerコンテナ内のファイルを操作するには!?データボリュームが・・・というツール固有のオペレーションは一切不要で、透明にアクセスできます。逆に、隔離されたコンテナ内からホストのファイルを操作したい、という場合に、はじめてchrootの強化機能としてのsystemd-nspawnの役割が出てきます。</p>
<p>ネットワーク管理も、VMWareなどのハードウェアParavirtualizationに類似していて、ホストのイーサネット、ブリッジアダプターがゲストで仮想化されて渡されます。</p>
<p><code>systemd-nspawn -h</code>すると該当部分はこんな感じ。</p>
<pre class="prettyprint"><code class=" hljs livecodeserver"> <span class="hljs-comment">--private-network Disable network in container</span>
<span class="hljs-comment">--network-interface=INTERFACE</span>
Assign <span class="hljs-operator">an</span> existing network interface <span class="hljs-built_in">to</span> <span class="hljs-operator">the</span>
container
<span class="hljs-comment">--network-macvlan=INTERFACE</span>
Create <span class="hljs-operator">a</span> macvlan network interface based <span class="hljs-command"><span class="hljs-keyword">on</span> <span class="hljs-title">an</span></span>
existing network interface <span class="hljs-built_in">to</span> <span class="hljs-operator">the</span> container
<span class="hljs-comment">--network-ipvlan=INTERFACE</span>
Create <span class="hljs-operator">a</span> ipvlan network interface based <span class="hljs-command"><span class="hljs-keyword">on</span> <span class="hljs-title">an</span></span>
existing network interface <span class="hljs-built_in">to</span> <span class="hljs-operator">the</span> container
-n <span class="hljs-comment">--network-veth Add a virtual ethernet connection between host</span>
<span class="hljs-operator">and</span> container
<span class="hljs-comment">--network-bridge=INTERFACE</span>
Add <span class="hljs-operator">a</span> virtual ethernet connection between host
<span class="hljs-operator">and</span> container <span class="hljs-operator">and</span> <span class="hljs-built_in">add</span> <span class="hljs-keyword">it</span> <span class="hljs-built_in">to</span> <span class="hljs-operator">an</span> existing bridge <span class="hljs-command"><span class="hljs-keyword">on</span></span>
<span class="hljs-operator">the</span> host
-p <span class="hljs-comment">--port=[PROTOCOL:]HOSTPORT[:CONTAINERPORT]</span>
Expose <span class="hljs-operator">a</span> container IP port <span class="hljs-command"><span class="hljs-keyword">on</span> <span class="hljs-title">the</span> <span class="hljs-title">host</span></span>
</code></pre>
<p>もちろん、コンテナOS内の隔離された環境でSSHサーバ建てるなり自由にやれば良いわけで、一切の制約はありません。</p>
<hr>
<p>以上、適当に列挙してみましたが、非常に良いです。 <br>
はじめてVMWareでOSの仮想化を体験した感慨が、Linuxのコンテナ仮想化でふたたび得られたという感じ。</p>
<p>仮想化がなぜ素晴らしいのか?というところでまとめましたが、Linuxのオペレーションにおいて、ハードウェアの抽象化は恩恵があるのですがVMWareなどのハードウェアParavirtualization、EC2、Azure <br>
などのクラウドマシンによる仮想化は、まだパフォーマンスのオーバーヘッド、そしてクラウド上ではコストがかかります。しかし、systemd-nspawnコンテナを使えば、同等の体感が、コンテナというパフォーマンスのオーバーヘッドが極小の技術で可能になったのはメリットが甚大です。</p>
<h1 id="systemd-nspawnでubuntuserverホストのコンテナでarch仮想マシンを起動してみよう">systemd-nspawnでUbuntuServerホストのコンテナでArch仮想マシンを起動してみよう</h1>
<p>結局、今回やりたかったことはこれです。 <br>
Azureのクラウドマシンで、Arch-Linuxのサーバを建てたいと思ったが、イメージも存在せずサポートもされていなかったので、UbuntuServer15.10のコンテナ内で、Archを起動したい。 <br>
UbuntuServerは、systemdベースでよくメンテナンスされており、カーネルバージョンが新しかったので選択。</p>
<blockquote>
<p>systemd-nspawn は chroot コマンドに似ていますが、chroot を強化したものです。</p>
</blockquote>
<p>と言う感じで、従来の既存技術の延長で、透明に管理できてしまいます。これが大きい。 <br>
つまりDockerのように固有のフォーマットのイメージをpullするには?また作成するには?とか新規に技術を習得すべき固有の仕様は全くないです。</p>
<p>ArchLinuxを使っているギークはArch-Linuxをインストールする場合、皆chrootでベースシステムの設定していくわけで、そのままやれば良い。</p>
<p><a href="https://wiki.archlinuxjp.org/index.php/%E6%97%A2%E5%AD%98%E3%81%AE_Linux_%E3%81%8B%E3%82%89%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB#.E6.96.B9.E6.B3.95_1:_.E3.83.96.E3.83.BC.E3.83.88.E3.82.B9.E3.83.88.E3.83.A9.E3.83.83.E3.83.97.E3.82.A4.E3.83.A1.E3.83.BC.E3.82.B8.E3.82.92.E4.BD.BF.E3.81.86">Archのダウンロードサイトには、ブートストラップファイルがある</a>ので、ファイルをダウンロードして、適当なディレクトリで解凍して、ルートファイルシステムそのものをコンテナイメージとします。</p>
<pre class="prettyprint"><code class=" hljs haskell"><span class="hljs-preprocessor"># ken at kenubuntu07 in /zfspool/arch1 [7:59:18]</span>
$ l
<span class="hljs-title">total</span> <span class="hljs-number">55</span>K
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">16</span> root root <span class="hljs-number">21</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span>:<span class="hljs-number">09</span> .
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">3</span> root root <span class="hljs-number">5</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">07</span>:<span class="hljs-number">42</span> ..
<span class="hljs-title">lrwxrwxrwx</span> <span class="hljs-number">1</span> root root <span class="hljs-number">7</span> <span class="hljs-type">Sep</span> <span class="hljs-number">30</span> <span class="hljs-number">19</span>:<span class="hljs-number">17</span> bin -> usr/bin
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">5</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span>:<span class="hljs-number">09</span> boot
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Feb</span> <span class="hljs-number">1</span> <span class="hljs-number">15</span>:<span class="hljs-number">43</span> dev
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">38</span> root root <span class="hljs-number">95</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span>:<span class="hljs-number">35</span> etc
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">3</span> root root <span class="hljs-number">3</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span>:<span class="hljs-number">02</span> home
<span class="hljs-title">lrwxrwxrwx</span> <span class="hljs-number">1</span> root root <span class="hljs-number">7</span> <span class="hljs-type">Sep</span> <span class="hljs-number">30</span> <span class="hljs-number">19</span>:<span class="hljs-number">17</span> lib -> usr/lib
<span class="hljs-title">lrwxrwxrwx</span> <span class="hljs-number">1</span> root root <span class="hljs-number">7</span> <span class="hljs-type">Sep</span> <span class="hljs-number">30</span> <span class="hljs-number">19</span>:<span class="hljs-number">17</span> lib64 -> usr/lib
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Sep</span> <span class="hljs-number">30</span> <span class="hljs-number">19</span>:<span class="hljs-number">17</span> mnt
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Sep</span> <span class="hljs-number">30</span> <span class="hljs-number">19</span>:<span class="hljs-number">17</span> opt
<span class="hljs-title">dr</span>-xr-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Feb</span> <span class="hljs-number">1</span> <span class="hljs-number">15</span>:<span class="hljs-number">43</span> <span class="hljs-keyword">proc</span>
-rw-r<span class="hljs-comment">--r-- 1 root root 1.3K Feb 1 15:43 README</span>
<span class="hljs-title">drwxr</span>-x<span class="hljs-comment">--- 3 root root 4 Feb 10 00:06 root</span>
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Feb</span> <span class="hljs-number">1</span> <span class="hljs-number">15</span>:<span class="hljs-number">43</span> run
<span class="hljs-title">lrwxrwxrwx</span> <span class="hljs-number">1</span> root root <span class="hljs-number">7</span> <span class="hljs-type">Sep</span> <span class="hljs-number">30</span> <span class="hljs-number">19</span>:<span class="hljs-number">17</span> sbin -> usr/bin
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">4</span> root root <span class="hljs-number">4</span> <span class="hljs-type">Feb</span> <span class="hljs-number">9</span> <span class="hljs-number">23</span>:<span class="hljs-number">57</span> srv
<span class="hljs-title">dr</span>-xr-xr-x <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Feb</span> <span class="hljs-number">1</span> <span class="hljs-number">15</span>:<span class="hljs-number">43</span> sys
<span class="hljs-title">drwxrwxrwt</span> <span class="hljs-number">2</span> root root <span class="hljs-number">2</span> <span class="hljs-type">Feb</span> <span class="hljs-number">1</span> <span class="hljs-number">15</span>:<span class="hljs-number">43</span> tmp
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">8</span> root root <span class="hljs-number">10</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span>:<span class="hljs-number">09</span> usr
<span class="hljs-title">drwxr</span>-xr-x <span class="hljs-number">12</span> root root <span class="hljs-number">16</span> <span class="hljs-type">Feb</span> <span class="hljs-number">10</span> <span class="hljs-number">00</span>:<span class="hljs-number">09</span> var
</code></pre>
<p>ディレクトリが、<code>/zfspool/arch1</code>となっているのは、 <br>
AzureのUbuntuサーバにデータ用ディスクとして128GのSSDドライブを別途用意して、 <br>
UbuntuにZFS-Linuxをインストールし、/dev/sdc全体をZFSのプールにしてマウントした</p>
<pre class="prettyprint"><code class=" hljs bash">$ <span class="hljs-built_in">sudo</span> zpool create zfspool /dev/sdc</code></pre>
<p>からです。</p>
<p>次に、Ubuntu15.10サーバにはあらかじめlxcbr0というブリッジアダプタが存在していたので、それをコンテナのネットワークブリッジアダプタとして利用するオプションを加えながら、上記ディレクトリを指定して「仮想マシン」をブートします。</p>
<pre class="prettyprint"><code class="language-shell hljs brainfuck"><span class="hljs-comment">$</span> <span class="hljs-comment">sudo</span> <span class="hljs-comment">systemd</span><span class="hljs-literal">-</span><span class="hljs-comment">nspawn</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">directory=/zfspool/arch1</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">network</span><span class="hljs-literal">-</span><span class="hljs-comment">bridge=lxcbr0</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">boot</span>
</code></pre>
<pre class="prettyprint"><code class=" hljs sql">Spawning container arch1 on /zfspool/arch1.
Press ^] three times within 1s to kill container.
Failed to <span class="hljs-operator"><span class="hljs-keyword">create</span> directory /zfspool/arch1/sys/fs/selinux: <span class="hljs-keyword">Read</span>-<span class="hljs-keyword">only</span> file system
Failed <span class="hljs-keyword">to</span> <span class="hljs-keyword">create</span> directory /zfspool/arch1/sys/fs/selinux: <span class="hljs-keyword">Read</span>-<span class="hljs-keyword">only</span> file system
/etc/localtime <span class="hljs-keyword">is</span> <span class="hljs-keyword">not</span> a symlink, <span class="hljs-keyword">not</span> updating container timezone.
systemd <span class="hljs-number">228</span> running <span class="hljs-keyword">in</span> system mode. (+PAM -AUDIT -SELINUX -IMA -APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization systemd-nspawn.
Detected architecture x86-<span class="hljs-number">64.</span>
Welcome <span class="hljs-keyword">to</span> Arch Linux!
Failed <span class="hljs-keyword">to</span> install release agent, ignoring: File <span class="hljs-keyword">exists</span>
display-manager.service: Cannot <span class="hljs-keyword">add</span> dependency job, ignoring: Unit display-manager.service failed <span class="hljs-keyword">to</span> <span class="hljs-keyword">load</span>: <span class="hljs-keyword">No</span> such file <span class="hljs-keyword">or</span> directory.
[ OK ] Listening <span class="hljs-keyword">on</span> Network Service Netlink Socket.
[ OK ] Reached target Remote File Systems.
[ OK ] Started Dispatch Password Requests <span class="hljs-keyword">to</span> Console Directory Watch.
[ OK ] Listening <span class="hljs-keyword">on</span> LVM2 metadata daemon socket.
[ OK ] Created slice <span class="hljs-keyword">User</span> <span class="hljs-keyword">and</span> <span class="hljs-keyword">Session</span> Slice.
[ OK ] Started Forward Password Requests <span class="hljs-keyword">to</span> Wall Directory Watch.
[ OK ] Listening <span class="hljs-keyword">on</span> Device-mapper event daemon FIFOs.
[ OK ] Listening <span class="hljs-keyword">on</span> Journal Socket (/dev/log).
[ OK ] Listening <span class="hljs-keyword">on</span> Journal Socket.
[ OK ] Created slice System Slice.
[ OK ] Created slice system-getty.slice.
Mounting FUSE Control File System...
Mounting Huge Pages File System...
[ OK ] Reached target Swap.
Starting Journal Service...
Mounting POSIX Message Queue File System...
[ OK ] Listening <span class="hljs-keyword">on</span> /dev/initctl Compatibility Named Pipe.
Starting Remount Root <span class="hljs-keyword">and</span> Kernel File Systems...
[ OK ] Reached target Encrypted Volumes.
[ OK ] Reached target Paths.
[ OK ] Reached target Slices.
[ OK ] Mounted FUSE Control File System.
[ OK ] Mounted Huge Pages File System.
[ OK ] Mounted POSIX Message Queue File System.
[ OK ] Started Remount Root <span class="hljs-keyword">and</span> Kernel File Systems.
[ OK ] Reached target <span class="hljs-keyword">Local</span> File Systems (Pre).
[ OK ] Reached target <span class="hljs-keyword">Local</span> File Systems.
Starting <span class="hljs-keyword">Load</span>/Save Random Seed...
[ OK ] Started <span class="hljs-keyword">Load</span>/Save Random Seed.
[ OK ] Started Journal Service.
Starting Flush Journal <span class="hljs-keyword">to</span> Persistent Storage...
[ OK ] Started Flush Journal <span class="hljs-keyword">to</span> Persistent Storage.
Starting <span class="hljs-keyword">Create</span> Volatile Files <span class="hljs-keyword">and</span> Directories...
[FAILED] Failed <span class="hljs-keyword">to</span> <span class="hljs-keyword">start</span> <span class="hljs-keyword">Create</span> Volatile Files <span class="hljs-keyword">and</span> Directories.
See <span class="hljs-string">'systemctl status systemd-tmpfiles-setup.service'</span> <span class="hljs-keyword">for</span> details.
Starting <span class="hljs-keyword">Update</span> UTMP about System Boot/Shutdown...
[ OK ] Started <span class="hljs-keyword">Update</span> UTMP about System Boot/Shutdown.
[ OK ] Reached target System Initialization.
[ OK ] Started Daily verification <span class="hljs-keyword">of</span> password <span class="hljs-keyword">and</span> <span class="hljs-keyword">group</span> files.
[ OK ] Started Daily rotation <span class="hljs-keyword">of</span> log files.
[ OK ] Listening <span class="hljs-keyword">on</span> D-Bus System Message Bus Socket.
[ OK ] Reached target Sockets.
[ OK ] Started Daily Cleanup <span class="hljs-keyword">of</span> <span class="hljs-keyword">Temporary</span> Directories.
[ OK ] Started Daily man-db cache <span class="hljs-keyword">update</span>.
[ OK ] Reached target Timers.
[ OK ] Reached target Basic System.
Starting Login Service...
[ OK ] Started D-Bus System Message Bus.
Starting Network Service...
Starting Permit <span class="hljs-keyword">User</span> Sessions...
[ OK ] Started Login Service.
[ OK ] Started Permit <span class="hljs-keyword">User</span> Sessions.
[ OK ] Started Console Getty.
[ OK ] Reached target Login Prompts.
[ OK ] Started Network Service.
[ OK ] Reached target Network.
Starting Network Name Resolution...
[ OK ] Started Network Name Resolution.
[ OK ] Reached target Multi-<span class="hljs-keyword">User</span> System.
[ OK ] Reached target Graphical Interface.
Arch Linux <span class="hljs-number">4.2</span><span class="hljs-number">.0</span>-<span class="hljs-number">27</span>-generic (console)
arch1 login:
</span></code></pre>
<p>美しいですね。 <br>
コンテナであっても、まるでVMWareの仮想マシンのブートを見ているようです。しかもコンテナなので、ブートは一瞬です。(今回Azureで作成したクラウドマシンのスペックで1秒以内)</p>
<p>Systemdと完全に統合されているので、隔離された仮想マシンで隔離されたSystemdのサービスが起動されています。</p>
<blockquote>
<p>[FAILED] Failed to start Create Volatile Files and Directories.</p>
</blockquote>
<p>という、Systemdの最近のバージョンのバグによるファイルシステムとの相性問題まで忠実に再現されているというオマケつき。 <br>
あとは、このArchブートストラップのファイルシステムの延長線上にPacmanでArchのフルシステムを構築していけばよいです。通常のArchインストールのように、インストールスクリプトなどを利用して、ここから外のターゲットディレクトリに向けて構築するのは不要なので、このchrootディレクトリのまま適当にベースシステムインストールして育てていきます。</p>
<p>通常のArchインストールのように、ネットワーク設定では普通に</p>
<pre class="prettyprint"><code class=" hljs vala"><span class="hljs-preprocessor"># systemctl enable systemd-networkd systemd-resolved</span></code></pre>
<p>このように、SystemdUnitを<code>systemctl enable</code>していきます。</p>
<h1 id="machinectlによるコンテナマシン管理">machinectlによるコンテナマシン管理</h1>
<p>systemd-nspawnに付随するユーティリティ<code>machinectl</code>が存在しています。</p>
<pre class="prettyprint"><code class=" hljs livecodeserver">$ machinectl -h
machinectl [OPTIONS...] {COMMAND} ...
Send control commands <span class="hljs-built_in">to</span> <span class="hljs-operator">or</span> query <span class="hljs-operator">the</span> virtual machine <span class="hljs-operator">and</span> container
registration manager.
-h <span class="hljs-comment">--help Show this help</span>
<span class="hljs-comment">--version Show package version</span>
<span class="hljs-comment">--no-pager Do not pipe output into a pager</span>
<span class="hljs-comment">--no-legend Do not show the headers and footers</span>
<span class="hljs-comment">--no-ask-password Do not ask for system passwords</span>
-H <span class="hljs-comment">--host=[USER@]HOST Operate on remote host</span>
-M <span class="hljs-comment">--machine=CONTAINER Operate on local container</span>
-p <span class="hljs-comment">--property=NAME Show only properties by this name</span>
-q <span class="hljs-comment">--quiet Suppress output</span>
-<span class="hljs-operator">a</span> <span class="hljs-comment">--all Show all properties, including empty ones</span>
-l <span class="hljs-comment">--full Do not ellipsize output</span>
<span class="hljs-comment">--kill-who=WHO Who to send signal to</span>
-s <span class="hljs-comment">--signal=SIGNAL Which signal to send</span>
<span class="hljs-comment">--uid=USER Specify user ID to invoke shell as</span>
<span class="hljs-comment">--setenv=VAR=VALUE Add an environment variable for shell</span>
<span class="hljs-comment">--read-only Create read-only bind mount</span>
<span class="hljs-comment">--mkdir Create directory before bind mounting, if missing</span>
-n <span class="hljs-comment">--lines=INTEGER Number of journal entries to show</span>
-o <span class="hljs-comment">--output=STRING Change journal output mode (short,</span>
<span class="hljs-keyword">short</span>-monotonic, verbose, export, json,
json-pretty, json-sse, cat)
<span class="hljs-comment">--verify=MODE Verification mode for downloaded images (no,</span>
checksum, signature)
<span class="hljs-comment">--force Download image even if already exists</span>
<span class="hljs-comment">--dkr-index-url=URL Specify the index URL to use for DKR image</span>
downloads
Machine Commands:
list List running VMs <span class="hljs-operator">and</span> containers
status NAME... Show VM/container details
show [NAME...] Show properties <span class="hljs-operator">of</span> <span class="hljs-constant">one</span> <span class="hljs-operator">or</span> more VMs/containers
start NAME... Start container <span class="hljs-keyword">as</span> <span class="hljs-operator">a</span> service
login [NAME] Get <span class="hljs-operator">a</span> login prompt <span class="hljs-operator">in</span> <span class="hljs-operator">a</span> container <span class="hljs-operator">or</span> <span class="hljs-command"><span class="hljs-keyword">on</span> <span class="hljs-title">the</span></span>
<span class="hljs-built_in">local</span> host
<span class="hljs-built_in">shell</span> [[USER@]NAME [COMMAND...]]
Invoke <span class="hljs-operator">a</span> <span class="hljs-built_in">shell</span> (<span class="hljs-operator">or</span> other <span class="hljs-command"><span class="hljs-keyword">command</span>) <span class="hljs-title">in</span> <span class="hljs-title">a</span> <span class="hljs-title">container</span></span>
<span class="hljs-operator">or</span> <span class="hljs-command"><span class="hljs-keyword">on</span> <span class="hljs-title">the</span> <span class="hljs-title">local</span> <span class="hljs-title">host</span></span>
enable NAME... Enable automatic container start <span class="hljs-keyword">at</span> boot
disable NAME... Disable automatic container start <span class="hljs-keyword">at</span> boot
poweroff NAME... Power off <span class="hljs-constant">one</span> <span class="hljs-operator">or</span> more containers
reboot NAME... Reboot <span class="hljs-constant">one</span> <span class="hljs-operator">or</span> more containers
terminate NAME... Terminate <span class="hljs-constant">one</span> <span class="hljs-operator">or</span> more VMs/containers
<span class="hljs-built_in">kill</span> NAME... Send signal <span class="hljs-built_in">to</span> processes <span class="hljs-operator">of</span> <span class="hljs-operator">a</span> VM/container
copy-<span class="hljs-built_in">to</span> NAME PATH [PATH] Copy <span class="hljs-built_in">files</span> <span class="hljs-built_in">from</span> <span class="hljs-operator">the</span> host <span class="hljs-built_in">to</span> <span class="hljs-operator">a</span> container
copy-<span class="hljs-built_in">from</span> NAME PATH [PATH] Copy <span class="hljs-built_in">files</span> <span class="hljs-built_in">from</span> <span class="hljs-operator">a</span> container <span class="hljs-built_in">to</span> <span class="hljs-operator">the</span> host
bind NAME PATH [PATH] Bind mount <span class="hljs-operator">a</span> path <span class="hljs-built_in">from</span> <span class="hljs-operator">the</span> host <span class="hljs-keyword">into</span> <span class="hljs-operator">a</span> container
Image Commands:
list-images Show available container <span class="hljs-operator">and</span> VM images
image-status [NAME...] Show image details
show-image [NAME...] Show properties <span class="hljs-operator">of</span> image
clone NAME NAME Clone <span class="hljs-operator">an</span> image
<span class="hljs-built_in">rename</span> NAME NAME Rename <span class="hljs-operator">an</span> image
<span class="hljs-built_in">read</span>-only NAME [BOOL] Mark <span class="hljs-operator">or</span> unmark image <span class="hljs-built_in">read</span>-only
remove NAME... Remove <span class="hljs-operator">an</span> image
<span class="hljs-built_in">set</span>-limit [NAME] BYTES Set image <span class="hljs-operator">or</span> pool size limit (disk quota)
Image Transfer Commands:
pull-tar <span class="hljs-built_in">URL</span> [NAME] Download <span class="hljs-operator">a</span> TAR container image
pull-raw <span class="hljs-built_in">URL</span> [NAME] Download <span class="hljs-operator">a</span> RAW container <span class="hljs-operator">or</span> VM image
pull-dkr REMOTE [NAME] Download <span class="hljs-operator">a</span> DKR container image
import-tar FILE [NAME] Import <span class="hljs-operator">a</span> <span class="hljs-built_in">local</span> TAR container image
import-raw FILE [NAME] Import <span class="hljs-operator">a</span> <span class="hljs-built_in">local</span> RAW container <span class="hljs-operator">or</span> VM image
export-tar NAME [FILE] Export <span class="hljs-operator">a</span> TAR container image locally
export-raw NAME [FILE] Export <span class="hljs-operator">a</span> RAW container <span class="hljs-operator">or</span> VM image locally
list-transfers Show list <span class="hljs-operator">of</span> downloads <span class="hljs-operator">in</span> progress
<span class="hljs-built_in">cancel</span>-transfer Cancel <span class="hljs-operator">a</span> download
</code></pre>
<p>このコマンドで、コンテナマシンを <br>
<code>poweroff</code>したり、 <code>reboot</code>したりできます。 <br>
まさにVMWareの仮想マシンそのもの。美しいですね。. </p>
<p>ホストから</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-variable">$ </span>machinectl status arch1</code></pre>
<p>と叩いてやると、コンテナマシンのIPやらSystemdのUnitツリーやら諸々の情報が確認できます。</p>
<pre class="prettyprint"><code class=" hljs avrasm">arch1
Since: Wed <span class="hljs-number">2016</span>-<span class="hljs-number">02</span>-<span class="hljs-number">10</span> <span class="hljs-number">07</span>:<span class="hljs-number">42</span>:<span class="hljs-number">52</span> UTC<span class="hljs-comment">; 33min ago</span>
Leader: <span class="hljs-number">27171</span> (systemd)
Service: nspawn<span class="hljs-comment">; class container</span>
Root: /zfspool/arch1
Iface: lxcbr0
Address: <span class="hljs-number">10.0</span><span class="hljs-number">.3</span><span class="hljs-number">.149</span>
<span class="hljs-number">169.254</span><span class="hljs-number">.173</span><span class="hljs-number">.34</span>
fe80::<span class="hljs-number">3433</span>:<span class="hljs-number">76</span>ff:fed0:b73a%<span class="hljs-number">3</span>
OS: Arch Linux
Unit: machine-arch1<span class="hljs-preprocessor">.scope</span>
├─init<span class="hljs-preprocessor">.scope</span>
│ └─<span class="hljs-number">27171</span> /usr/lib/systemd/systemd
└─system<span class="hljs-preprocessor">.slice</span>
├─dbus<span class="hljs-preprocessor">.service</span>
│ └─<span class="hljs-number">27219</span> /usr/bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
├─systemd-journald<span class="hljs-preprocessor">.service</span>
│ └─<span class="hljs-number">27203</span> /usr/lib/systemd/systemd-journald
├─systemd-resolved<span class="hljs-preprocessor">.service</span>
│ └─<span class="hljs-number">27224</span> /usr/lib/systemd/systemd-resolved
├─systemd-logind<span class="hljs-preprocessor">.service</span>
│ └─<span class="hljs-number">27218</span> /usr/lib/systemd/systemd-logind
├─systemd-networkd<span class="hljs-preprocessor">.service</span>
│ └─<span class="hljs-number">27220</span> /usr/lib/systemd/systemd-networkd
└─console-getty<span class="hljs-preprocessor">.service</span>
└─<span class="hljs-number">27223</span> /sbin/agetty --noclear --keep-baud console <span class="hljs-number">115200</span> <span class="hljs-number">38400</span> <span class="hljs-number">9600</span> vt220
Feb <span class="hljs-number">10</span> <span class="hljs-number">07</span>:<span class="hljs-number">42</span>:<span class="hljs-number">52</span> kenubuntu07 systemd[<span class="hljs-number">1</span>]: Started Container arch1.
</code></pre>
<p>コンテナマシンをシャットダウン(パワーオフ)してみます。 <br>
ホストで以下のように叩きます。</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-variable">$ </span>machinectl poweroff arch1</code></pre>
<pre class="prettyprint"><code class=" hljs mathematica">[ OK ] Stopped target Graphical Interface.
[ OK ] <span class="hljs-keyword">Removed</span> slice system-getty.slice.
[ OK ] Stopped target Timers.
[ OK ] Stopped Daily Cleanup of <span class="hljs-keyword">Temporary</span> Directories.
[ OK ] Stopped Session <span class="hljs-number">28</span> of user ken.
Starting Generate shutdown-ramfs...
[ OK ] Stopped target Multi-User System.
Stopping Network Name Resolution...
[ OK ] Stopped target Login Prompts.
Stopping Console Getty...
[ OK ] Stopped Daily rotation of log files.
[ OK ] Stopped Daily verification of password and group files.
[ OK ] Stopped Daily man-db cache update.
Stopping User Manager for UID <span class="hljs-number">1000.</span>..
[ OK ] Stopped Console Getty.
[ OK ] Stopped Network Name Resolution.
[ OK ] Stopped User Manager for UID <span class="hljs-number">1000.</span>
[ OK ] <span class="hljs-keyword">Removed</span> slice User Slice of ken.
Stopping Login Service...
[ OK ] Stopped target Network.
Stopping Network Service...
Stopping Permit User Sessions...
[ OK ] Stopped Login Service.
[ OK ] Stopped Permit User Sessions.
[ OK ] Stopped target Remote <span class="hljs-keyword">File</span> Systems.
[ OK ] Stopped Network Service.
Stopping <span class="hljs-keyword">D</span>-Bus System <span class="hljs-keyword">Message</span> Bus...
[ OK ] Stopped <span class="hljs-keyword">D</span>-Bus System <span class="hljs-keyword">Message</span> Bus.
[ OK ] Stopped target Basic System.
[ OK ] Stopped target Slices.
[ OK ] <span class="hljs-keyword">Removed</span> slice User and Session Slice.
[ OK ] Stopped target Paths.
[ OK ] Stopped <span class="hljs-keyword">Dispatch</span> Password Requests to Console <span class="hljs-keyword">Directory</span> Watch.
[ OK ] Stopped <span class="hljs-keyword">Forward</span> Password Requests to Wall <span class="hljs-keyword">Directory</span> Watch.
[ OK ] Stopped target Sockets.
[ OK ] <span class="hljs-keyword">Closed</span> <span class="hljs-keyword">D</span>-Bus System <span class="hljs-keyword">Message</span> Bus <span class="hljs-keyword">Socket</span>.
[ OK ] Stopped target System <span class="hljs-keyword">Initialization</span>.
Stopping Load/<span class="hljs-keyword">Save</span> <span class="hljs-keyword">Random</span> Seed...
Stopping <span class="hljs-keyword">Update</span> UTMP about System Boot/Shutdown...
[ OK ] Stopped target Encrypted Volumes.
[ OK ] Stopped target Swap.
[ OK ] Stopped target Local <span class="hljs-keyword">File</span> Systems.
Unmounting /proc/sys/kernel/random/boot_id...
Unmounting /run/systemd/nspawn/incoming...
Unmounting /run/user/<span class="hljs-number">1000.</span>..
Unmounting <span class="hljs-keyword">Temporary</span> <span class="hljs-keyword">Directory</span>...
[ OK ] Stopped Load/<span class="hljs-keyword">Save</span> <span class="hljs-keyword">Random</span> Seed.
[ OK ] Stopped <span class="hljs-keyword">Update</span> UTMP about System Boot/Shutdown.
[ OK ] Unmounted /proc/sys/kernel/random/boot_id.
[ OK ] Unmounted /run/systemd/nspawn/incoming.
[ OK ] Unmounted <span class="hljs-keyword">Temporary</span> <span class="hljs-keyword">Directory</span>.
[ OK ] Unmounted /run/user/<span class="hljs-number">1000.</span>
[ OK ] Reached target Unmount <span class="hljs-keyword">All</span> Filesystems.
[ OK ] Stopped target Local <span class="hljs-keyword">File</span> Systems (Pre).
[ OK ] Stopped Remount <span class="hljs-keyword">Root</span> and Kernel <span class="hljs-keyword">File</span> Systems.
[ OK ] Started Generate shutdown-ramfs.
[ OK ] Reached target Shutdown.
Sending SIGTERM to remaining processes...
Sending SIGKILL to remaining processes...
Powering off.
Container arch1 has been shut down.
</code></pre>
<p>美しいですね。もちろんシャットダウンも一瞬です。</p>
<h1 id="セキュリティ">セキュリティ</h1>
<p><a href="https://coreos.com/blog/qa-with-lennart-systemd/">https://coreos.com/blog/qa-with-lennart-systemd/</a></p>
<p>September 16, 2015のインタビューで、systemd projectの開発者Lennart Poetteringによれば、すでにproduction readyだそうです。実務に耐えます。</p>
<blockquote>
<p>systemd also contains the systemd-nspawn container manager. It’s a relatively minimal, yet powerful implementation of a container manager. Initially we wrote it for testing purposes, but nowadays we consider it ready for many production uses. In fact CoreOS’ rkt container tool makes use of it as the lower level container backend.</p>
</blockquote>
<h1 id="クラウドマシンvpsやvpnの構成の再考">クラウドマシン、VPSやVPNの構成の再考</h1>
<p><a href="http://qiita.com/to_obara/items/0622bdc5cacaa2758057">dockerでvpnサーバーをたてる</a>技を駆使していたり、クラウドベースでVPNやってる場合でも、systemd-nspawnで構成を全部見直したくなる人もいるでしょう。</p>
<p>個人的には、Azureのクラウドマシンでコストを睨みながら無闇矢鱈にサーバインスタンス増やしていろいろやるよりも、1台のクラウドマシンを建てて、そのなかのコンテナマシンで構成したほうがよりハードウェアからの開放という至上命題としての仮想化として、リソースとコストに無駄がない優れた解法だなと感じています。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-78869278417602777972016-01-29T09:14:00.001+09:002016-01-30T04:34:21.486+09:00Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について<p>まず、こういうエントリをあげるのは非常に面倒くさいし不快です。状況証拠を列挙するために該当部分を掘り出す作業自体が不快であるし、書いて時間を費やすことも不快です。</p>
<p>しかし不正な行為があり、特に私を被害者としてそれが行われた場合それは必ず公表します。面倒だな、と思っていて時期が遅くなったとしても必ずそれはケジメとして公表し、記録に残します。</p>
<p>Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷集団のなかで「8賢者」とかアホなことをやってる件について公表します。</p>
<p>最初に断っておかなければいけませんが、この案件について「物的証拠」は存在しません。以上の事実については、私がああこれはこう推察の上断定して間違いないな、と私個人による「断定」主観を出るものではありません。読者がそれをどう評価するかは、読者の自由ですし、特に名前をあげられた当人、そして彼らを引き入れた犯罪者集団連中にとっては「証拠はあるのか?」で返してくるのがワンパターンの常套手段なので、それは最初に断っておきます。</p>
<p>また、最初から幼稚で愚かな感情で自身の名誉を毀損する行為など行わなければよいのに、と思うわけですが、それを公表されて、名誉毀損になる、と思うのであれば、</p>
<p>1.公表されて困るようなことは、最初からしなければよい。</p>
<p>2.君等が合流した集団は、私が名誉毀損、侮辱で刑事告訴したあとも、警察にバレないように犯行を重ねたいがために、不正アクセス機器をもって身元を隠して2ちゃんねるで中傷誹謗、名誉毀損を続けたような犯罪者集団だ。そういう事実も知らないではなかろう。その首謀者から幼稚な「ミッション」の「コードネーム」など割り振られて、その集団的中傷誹謗行為に加担するなど、言語道断であり、社会的に許容されるものではない。共謀、犯人隠蔽という犯罪にも該当する。つまり、この記事は君らの公表されたら困るような恥ずべき行為、あるいは犯罪に抵触する行為についての告発文であって、根本的に社会的正義の理念から公表する。その被害当事者が文責のある私であるということ。あたりまえであるが、このような正当な憲法に定められる言論の自由は、犯罪の告発は刑法に定める名誉毀損行為から除外される。</p>
<p>3.念の為であるが、Webでの対等な言論を約束する。事実関係もふくめ当人からの(メールで、君等のいつもの「俺じゃない、本人は迷惑でしょう」みたいな言い訳する2chレスやらTwitterなんぞいちいち読んでいない)反論があればこの記事に併記する。裏でコソコソ覆面かぶって石投げてくるような卑怯な真似をしでかすんじゃなくて、表に出てこい。対抗原理の法理は担保する。</p>
<p>連中が、私に「反目」した背景となる事象については、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/03/qiita.html">関数型プログラミングとQiita界隈の騒動について</a>に書いています。</p>
<p>一部再掲しながら確認すると、 <br>
まず、私が関数型プログラミングについての記事をQiitaに書いていた頃、今は、アカウントも記事も抹消されているので、公には確認できませんが、こんな不躾なコメントが上から目線で其の記事に投稿されました。</p>
<blockquote>
<p>私はあなたの指導教官ではないし、教える義務もありませんので、これ以上の努力はいたしません。最低限の指摘はすでに終了しています。 <br>
幸いなことに世の中には、すぐれた書籍があふれております。いい世の中です。ぜひ、一読することをおすすめしたします。 <br>
この分野に関わりたいのであれば、避けては通れないコンピュータサイエンスの基本ばかりです。 <br>
[1] “Structure and Interpretation of Computer Programs” <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-1.html#titlepage">http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-1.html#titlepage</a> <br>
[2] “Introduction to the Theory of Computation” <a href="http://www.amazon.co.jp/Introduction-Theory-Computation-Michael-Sipser/dp/113318779X">http://www.amazon.co.jp/Introduction-Theory-Computation-Michael-Sipser/dp/113318779X</a> <br>
[3] “Types and Programming Languages” <a href="http://www.amazon.co.jp/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091">http://www.amazon.co.jp/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091</a> <br>
以上を参考文献として上げる理由を以下に述べておきます。 <br>
[1] - Kenokabe さんは、評価(eval) と 関数呼び出し(apply) の基本的区別がついていないようです。私がこれまで出会ってきた学生ならば、これらの区別は100人中100人が学習によりできるようになります。Kenokabe さんの中における「評価」と、100人中100人が共通の語彙として相互理解している「評価」がどのように異なるか、ぜひ、SICP を読むことをおすすめします。 <br>
[2] - Kenokabe さんは、コンピュータプログラミングにおいて「計算」するということがどういうことかその原理を理解していないようです。この本は、「計算」するとはどういうことか?時間と空間との関係についてもきちんと数学的な証明をもって述べています。ぜひ一読を。 <br>
[3] - λ計算についての深い知識はここでの議論ではそれほど必要ないかと思われますがやはり身につけておいたほうが今後は他人とのコミュニケーションがスムーズになると思われます。</p>
<p>出展: <a href="https://mitpress.mit.edu/sicp/full-text/sicp/book/node77.html">https://mitpress.mit.edu/sicp/full-text/sicp/book/node77.html</a> <br>
これらを読んだ結果、</p>
<blockquote>
<p>評価(eval) と 関数呼び出し(apply) の基本的区別、についてですが、 <br>
両者は原理的に全く同じものです。</p>
</blockquote>
<p>そのような判断をしたのであれば、「私がこれまで出会ってきた識者ならば、これらの区別は 101 中100人が学習によりできるようになります」と私はこれからは言わなければいけないようです。 <br>
どちらの認識が正しいかということは問題にしておりません。とてもユニークな解釈をする方だなと思って感心しております。</p>
</blockquote>
<p>まず技術的内容の指摘ですが、この[1]の指摘は誤りで、それを誤りだと私が反論したコメントを引用して皮肉を重ねたこの人物は間違っています。</p>
<p>それは<a href="http://kenokabe-techwriting.blogspot.jp/2015/03/qiita.html">関数型プログラミングとQiita界隈の騒動について</a>に説明していますし、もうお名前も出してよいと思いますが、私が書いた本を購入して読んでいただいた上、メールで感想をお寄せいただいた、日本マイクロソフトの荒井省三氏(<a href="http://www.amazon.co.jp/%E8%8D%92%E4%BA%95-%E7%9C%81%E4%B8%89/e/B004LVA9Y6">『実践 F# 関数型プログラミング入門』の著者</a>)も、</p>
<blockquote>
<p><strong>SICPが説明する、eval と applyは岡部様の指摘の通り私も本質は同じものだと思います。</strong>が、SICPはEvalutorの説明として、eval と apply を分離しています。この意味は、岡部様は当然のことと理解していると思いますが、Evalutorを実装する人達に対して用語として分離した方が理解しやすいと考えているというのが私の理解です。</p>
</blockquote>
<p>と、著書や記事での読者へむけた「説明の仕方」としての留保はありながら、SICPの該当文の解釈、技術的意味あいについては、私と同じ理解でおられるようです。 <br>
自分のほうがヤブから棒に謝った技術的指摘を上から押し付けるように学生への指導だのなんだの言いながら偉そうにし、こちらの考えを述べると、</p>
<p>「<strong>これらの区別は 101 中100人が学習によりできるようになります」と私はこれからは言わなければいけないようです。</strong> 」</p>
<p>だの、間違っている人間の分際で無礼な言動を働く。 <br>
ここで問題とするのは技術的是非ではなく、上記私のQiita記事によせられた上から目線の不躾なコメントの言葉遣いですが、</p>
<blockquote>
<p>私はあなたの指導教官ではないし、教える義務もありません <br>
この分野に関わりたいのであれば <br>
コンピュータサイエンスの基本ばかりです。 <br>
私がこれまで出会ってきた学生ならば、これらの区別は100人中100人が学習によりできるようになります。</p>
</blockquote>
<p>という部分です、この言葉遣いから、この人物(Qiita捨てアカウント) <br>
<a href="http://qiita.com/ycombinator">http://qiita.com/ycombinator</a> <br>
は、「大学の情報工学系の教授職にいる人物」であると推察できます。 <br>
<strong>私は、これ、いまもしつこく2ちゃんねるで書き込んだりしている、東北大学の住井 英二郎@esumiiさんだと思っているのですが、違うのですかね?これまで一度も反論もないようですし、ご本人にとっては有耶無耶にしたい事象ながら実質認めてしまっているのでしょうか?</strong></p>
<p>たとえば、そのコメントの後も、私が「関数型とオブジェクト指向は対立する概念である」と主張したことにあてつけ、</p>
<h4 id="faq-オブジェクト指向と関数型は対立していますか">FAQ オブジェクト指向と関数型は対立していますか?</h4>
<blockquote>
<p>Eijiro Sumii @esumii <br>
「関数型言語」に関するFAQ形式の一般的説明(on demandに加筆修正します) </p>
<p>ytb @ytb_at_twt 2015年1月27日 <br>
kenokabe騒動はすみい先生がこういうエントリを出された時点で、結果的に世のためとなったようです。 <br>
QT @esumii: 「関数型言語」に関するFAQ形式の一般的説明(on demandに加筆修正します) on @Qiita <a href="http://qiita.com/esumii/items/ec589d138e72e22ea97e">http://qiita.com/esumii/items/ec589d138e72e22ea97e</a> …</p>
</blockquote>
<p>などと、私が、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/03/qiita.html">関数型プログラミングとQiita界隈の騒動について</a> や <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/07/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか? の続き</a> <br>
で批判している記事は、間違った情報を堂々と流布しているわけですが、また確認しながら補足すると、</p>
<p>FAQ オブジェクト指向と関数型は対立していますか? <br>
「いいえ」 <br>
と断言しているので、どんなものかと読み進めてみると、文章の最後には <br>
<a href="http://qiita.com/esumii/items/ec589d138e72e22ea97e#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A8%E9%96%A2%E6%95%B0%E5%9E%8B%E3%81%AF%E5%AF%BE%E7%AB%8B%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B">上の記述はあくまで理論の話です。紹介記事の冒頭に書いたとおり、「単純な関数型言語に、複雑なオブジェクト指向はいらない」という考え方もあります(私個人の好みもそれに近く、OCamlのOはほとんど使っていません。参考リンク:「オブジェクトは OCaml の鬼子」)。</a>のような、言い逃れのような玉虫色のわけのわからない事でお茶を濁されてしまい、馬鹿をみるのは、真面目に読んで混乱して終わった学習者だけなので、こういう説明は止めてもらいたいです。</p>
<p>そもそも、<strong>「上の記述はあくまで理論の話です」というオチのようだが、「オブジェクト指向」というのは、そもそも「理論」ではありません。文字通り「指向」、パラダイムであって、理論ではない。 こんなものは、どこでも書かれている初歩的な知識。</strong></p>
<p><strong>「直交・独立な概念」。文中にある、このFPvsOPの議論のそこら中で大変重宝されているようにみえる常套句であるが、非常に「トリッキーな概念」であるので要注意。</strong>というか、はっきり言うと単なる我田引水の「誤魔化し」である。なぜならば、あらゆる概念において、どの角度で切って分析するか?によって、常に「直交・独立な概念」を切り出すことが可能であるから。</p>
<p><a href="%28http://qiita.com/esumii/items/ec589d138e72e22ea97e#%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E3%81%A8%E9%96%A2%E6%95%B0%E5%9E%8B%E3%81%AF%E5%AF%BE%E7%AB%8B%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B%29">要するに、オブジェクトの状態を破壊的に更新するか(命令型)、新しい状態を持つオブジェクトを作り直して返すか(関数型)というだけの違いです</a></p>
<p>「だけの違い」でなく、理論ではない指向、パラダイムとしてのオブジェクト指向にとってそこは大きな違いであり、その断面で分析すると「直交・独立な概念」ではありえない、と言うことだって簡単にできる。パラダイム、指向の対比において、「直交・独立な概念」などと相手が言い出したときは、其の人は単に論理的思考能力に劣るか、なんらかの誘導したい帰結に無自覚、其の両方か疑うべきでしょう。 <br>
理論ではなく、パラダイム、指向の話で、他のパラダイムとの際をひたすら有耶無耶にっすることに努め、玉虫色を強調するほど愚かなことはない。なぜこういうことが起こるのか?というと、そもそも、FPvsOPというのはよく知られた対立軸であり、周囲に波風を起こしたくない(特に和を尊しとする我々日本人には顕著)、穏当に、というバイアスと、論者の「保身」がある。割を食うのは常に真面目に勉強したいと思う学習者である。小中高、あるいは大学でそのような曖昧な説明しかしない愚かな教師にあたって迷惑を被った人も多いと思います。</p>
<p>あと、なんかよく存じ上げないけど、この住井氏は、同じOCamlコーダーのよしみなのか、らくだの卯之助@camloeba氏とたいへん仲がよろしいようです。</p>
<p>彼は、</p>
<blockquote>
<p>らくだの卯之助@camloeba <br>
疑似科学者と論争はしませんよ。議論にならないし最後は勝手に勝利宣言するだけですから。 <br>
5:22 AM - 26 May 2015 <br>
<a href="https://twitter.com/camloeba/status/603174342256566274">https://twitter.com/camloeba/status/603174342256566274</a></p>
</blockquote>
<p>とか、私がこのブログ記事に書いたことに反応してなんか書いているようですが、どうも、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/01/blog-post_28.html">量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説01</a>にあてつけた発言のようです。</p>
<p>まあ、まさに似非科学者でないのならば、この記事はタイトル通り科学哲学史、あるいは、物理学(Physics)そのものではなく、形而上学(Metaphysics)</p>
<blockquote>
<p>感覚ないし経験を超え出でた世界を真実在とし、その世界の普遍的な原理について理性的な思惟によって認識しようとする学問ないし哲学の一分野である[1][2][3]。世界の根本的な成り立ちの理由(世界の根本原因)や、物や人間の存在の理由や意味など、見たり確かめたりできないものについて考える[4]。(Wikipedia)</p>
</blockquote>
<p>のおはなしであると理解くらいはできる素養はあるはずですが、残念ながら、彼はそういう形而上学的議論の素養はなく、「疑似科学者」と罵倒するのが関の山であるようです。もちろん、</p>
<blockquote>
<p>感覚ないし経験を超え出でた世界を真実在とし、その世界の普遍的な原理について理性的な思惟によって認識しよう</p>
</blockquote>
<p>とする議論を理解するでもなく、せいぜいおそらく彼の世界観は、 <br>
「素朴実在論」</p>
<blockquote>
<p><strong>子供などが持っている素朴な実在論である。また大人などでも、哲学を学んだことがない一般人が抱きがちな実在観</strong>である[1]。 <br>
<strong>素朴実在論が哲学者によって未熟だと烙印を押される</strong>のは、一つには、上の木の葉の例で言えば、木の葉は夕日の中や薄暗がりの中では黒かったりし、ミドリ色として決まっている木の葉があるわけではない、ということからでもある[1]。 <br>
人間というのは素朴な状態なままだと、自分が肉眼で感じられた内容をそのまま存在すると信じ、反対に、見えないものは存在していないと思い込む傾向がある。(Wikipedia)</p>
</blockquote>
<p>なのでしょう。幼稚で素朴なことです。科学哲学史を「科学」としか認識できず、メタ概念である形而上学的議論(MetaPhysics)を物理学(Phjysics)としか認知することができず、「疑似科学者」としか反応できないのは要するにそういうことです。素朴ですね。</p>
<p>さて、とりあえず(他にも5名ほどQiiita関連でやらかしている連中もいるようだけど)この、私に何かと妥当な批判というより「中傷」領域に踏み込むように反目を続けておられる東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏ですが、このような現象を、頭のおかしい中傷誹謗犯罪者連中が見逃すわけはありません。</p>
<p>念の為ですが、連中のサイコパス的メンタリティがQiita関連でいうとどんなものか?引用すると、</p>
<pre class="prettyprint"><code class=" hljs markdown">302 :名無しさん@ゴーゴーゴーゴー!:2015/12/17(木) 12:29:33.62 ID:ktTs04a3
>君はどうでもいいよ。
だまされる奴が毛ひとりであれば、それでいいんだよ。
君は信じなくても、毛はなぜか信じるんだ。
<span class="hljs-strong">**彼の特性を把握し、思い通りにコントロールするのは射精と同じぐらい気持ちいいんだよ。**</span>
ある意味彼と俺は通じてるんだろうね。
本当に、よく踊ってくれたわ。
>303 :名無しさん@ゴーゴーゴーゴー!:2015/12/17(木) 12:34:47.82 ID:ktTs04a3
奴がQiitaでアカウントをいくつもとりまくって、癇癪起こして処分されるのも、
全部俺が描いた絵。
別に信じてもらえなくてもいいけどさ。
Wikipediaでアカウントとりまくった過去があるなら、そうなるようにコントロールする方法があると、
俺は春頃から考え続けていた。
我ながら笑えるぐらい踊ってくれたよ。
<span class="hljs-strong">**堪えられない。**</span>
<span class="hljs-strong">**人を支配するの、ほんと、楽しい。**</span></code></pre>
<p>なんか、そういうことらしいです。やたら「射精」だとか「勃起」だとか下半身ネタとひも付けながら、 <br>
「快楽」として私を支配して貶める遊びが楽しいみたいです。異常者ですね。 <br>
ちなみにこの異常者は、 <br>
人を支配したくて、Wikipediaの管理者になったが、<a href="https://ja.wikipedia.org/wiki/Wikipedia%E2%80%90%E3%83%8E%E3%83%BC%E3%83%88:%E7%AE%A1%E7%90%86%E8%80%85%E3%81%AE%E8%A7%A3%E4%BB%BB/%EF%BC%AE%EF%BD%89%EF%BC%AB%EF%BD%85_20080110">その横暴がコミュニティの目にあまり</a>、<a href="https://ja.wikipedia.org/wiki/Wikipedia:%E7%AE%A1%E7%90%86%E8%80%85%E3%81%AE%E8%A7%A3%E4%BB%BB/%EF%BC%AE%EF%BD%89%EF%BC%AB%EF%BD%85_20080110">管理者権限を剥奪された、NIKE</a>です。NIkeについては、犯罪集団のメンバーリスト流出の書き込みでまた名前が出てきます。</p>
<p>あとこういう感じ、非常に下劣で異常者まるだしの書き込みのオンパレードです↓</p>
<pre class="prettyprint"><code class=" hljs autohotkey"><span class="hljs-number">164</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">08</span>(火) <span class="hljs-number">15</span>:<span class="hljs-number">49</span>:<span class="hljs-number">04.49</span> ID:taWKsmcP
祝 毛本amazonから検索されなくなる
直URLでは見えるものの、 岡部健や毛の壁、関数型プログラミング などの単語で検索されなくなった様だ
<span class="hljs-label">http:</span>//i.imgur.com/aTetiZt.jpg
<span class="hljs-label">http:</span>//i.imgur.com/xGxlQe0.jpg
<span class="hljs-label">http:</span>//i.imgur.com/EuwuVyR.jpg
<span class="hljs-label">http:</span>//i.imgur.com/aoE6HQt.jpg
コレは事実として記録されるべきだろう
<span class="hljs-number">165</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">08</span>(火) <span class="hljs-number">16</span>:<span class="hljs-number">35</span>:<span class="hljs-number">09.00</span> ID:<span class="hljs-number">1</span>ags9+tn
>><span class="hljs-number">164</span>
今日は祝杯上げないとな
<span class="hljs-number">166</span> :Newbie伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">08</span>(火) <span class="hljs-number">18</span>:<span class="hljs-number">14</span>:<span class="hljs-number">35.11</span> ID:TBndtfrq
油断せず気を引き締めて参りましょう!
<span class="hljs-number">167</span> :Newbie伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">08</span>(火) <span class="hljs-number">18</span>:<span class="hljs-number">16</span>:<span class="hljs-number">35.73</span> ID:TBndtfrq
<span class="hljs-label"> ,.-―: ̄`ー::::::::::</span>、
<span class="hljs-label"> /::::::::::::.::::::::::::::::::::::::::::`::</span>、、
<span class="hljs-label"> /::::::::::::::::::::::::::::::::::::::::::::::::::::::</span>`、
<span class="hljs-label"> l::::::::::::::::::::::::::::::::::::::::</span><span class="hljs-comment">;':l:::::::::::\::l </span>
<span class="hljs-label"> l:::::::::::::::::::::::::::::::::,,::::::::</span><span class="hljs-comment">;-,:,::::::::::::::::l </span>
<span class="hljs-label"> l::::::::::::::::,_,.::::</span>,'<span class="hljs-comment">;::::::;:::::: :: l ::::::::::::::l </span>
<span class="hljs-label"> l::::::::::/-/:::/-ニ,.::::/=,./::::::::::</span>l
<span class="hljs-label"> ヽ::::</span> ´、ひ> <span class="hljs-comment">;: l .<ひ>' 、::::::::/ </span>
<span class="hljs-label"> ヽ:::::  ̄ .)::</span><span class="hljs-comment">; l  ̄ l::::/ </span>
<span class="hljs-label"> 、:::::.. /:::</span><span class="hljs-comment">; .,-、 l:::/、 </span>
<span class="hljs-label"> :::::::: ゝヽ- ー' 、 l::</span>/,
,:、:: / ,--、,-.、_ l / <ツヨシさん、どうぞ!
<span class="hljs-label"> 、::</span>、 `ー ̄-' /
<span class="hljs-label"> 、::</span>ヽ /:
ヽ/⌒<span class="hljs-escape">``</span>ーi ヽ
<span class="hljs-label"> / / ’ ヽ \ :,∴・゜・゜・:</span>,∴・゜・゜・
<span class="hljs-label"> / /ヽ、 、ヽ \ :,∴・゜・゜・:∴~・:,゜・∴~・:</span>・∴・
<span class="hljs-label"> / / | )\ ,.:∴~・:,゜・~・:,゜・ :,∴,゜・~・:</span>,゜・・∴・゜゜・
<span class="hljs-label"> / / ,r つ~~‘∴・゜゜・・∴~・:</span>,゜・・∴・゜゜・∴~゜゜゜ ~ m
<span class="hljs-label"> 彡 cノ _ノ⌒| (:::):::</span>)、 レへ) ../~ ̄ ̄ ̄ ̄ヽ/⌒⌒⌒ヽ|.|っ
`ー-、 | |―、ヽ、 \ ピュッ ( ε /∴ | _____ /⌒/⌒ヽ
ヽi | \ ヽ ) ( (` ´) @) (____/ .. _
ヽ_ノ <span class="hljs-escape">`ー</span>―' |―◎-◎― /ミ|───,,___,/ ヽ
(  ̄ ̄ ̄ ̄Y )
\____/
</code></pre>
<p>で、この</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">166</span> :<span class="hljs-constant">Newbie</span>伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/08(火) <span class="hljs-number">18</span><span class="hljs-symbol">:</span><span class="hljs-number">14</span><span class="hljs-symbol">:</span><span class="hljs-number">35.11</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:TBndtfrq</span>
油断せず気を引き締めて参りましょう! </code></pre>
<p>みたいな、しょうもない中傷誹謗チームの「コードネーム」として、幼稚でくだらない仲間意識全開アピールしているわけですが、Newbieの名のとおり、Qiitaの件から新たに加わりました。</p>
<p>これ、連中が、Qiitaで反目するメンツを犯罪者集団にリクルートした、 <br>
「8賢者」「ウィザード組」だとかまたアホみたいに書いてるのを目撃しました。 <br>
で、しばらくすると、</p>
<p>【弱者を放置して】赤木智弘30【アイマスラブ】 <br>
<a href="http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19">http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19</a> </p>
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-number">19</span> 名無しさん@社会人 <span class="hljs-number">2015</span>/<span class="hljs-number">11</span>/<span class="hljs-number">03</span>(火) <span class="hljs-number">21</span>:<span class="hljs-number">00</span>:<span class="hljs-number">52.89</span>
<span class="hljs-number">369</span> :M7<span class="hljs-number">.74</span>(catv?):<span class="hljs-number">2015</span>/<span class="hljs-number">11</span>/<span class="hljs-number">03</span>(火) <span class="hljs-number">12</span>:<span class="hljs-number">06</span>:<span class="hljs-number">52.44</span> ID:gYJokkH60
投稿者: 俺 (ID:<span class="hljs-number">0001</span>) 投稿日時:<span class="hljs-number">15</span>年 <span class="hljs-number">10</span>月 <span class="hljs-number">11</span>日 <span class="hljs-number">14</span>:<span class="hljs-number">09</span>
なので、当面は以下の通りで行きます。
いかんせん、Qiita以降の奴しか知らないので、不慣れなところはレギュラーが極力、バックアップ願います。
<span class="hljs-number">8</span>賢枠 (暫定) <span class="hljs-number">2015</span>/<span class="hljs-number">10</span>/<span class="hljs-number">02</span>
・スキルハンターの鷹
・知の答弁人田中
・思考のゼロ除算ボレロ
・辣腕ギークのキャメル
・知のオーバーフロー加藤
・AIG(A-Jiro <span class="hljs-keyword">is</span> Guru)
・菅本・ザ・ストリートプログラマー
・(空席)
以上。 </code></pre>
<p>こういう情報が「流出」しました。</p>
<pre class="prettyprint"><code class=" hljs ">いかんせん、Qiita以降の奴しか知らないので、不慣れなところはレギュラーが極力、バックアップ願います。 </code></pre>
<p>「流出した」と観察する理由は、この2ちゃんねるのスレッドで攻撃対象になっているらしい、赤木智弘@T_akagi というのも、彼らと同じ不正アクセスなんでもやりほうだいの犯罪者チームのメンバーで、最近どうも仲間割れしたみたいで、叩いてるのが元仲間で、その報復と警告として、赤木智弘自身が自分と関係なさそうな新参者リクルートの内部情報を一部漏らして、脅しているようだからです。</p>
<p>これは私にメールで以前から情報提供してくれた人がいて知りました。 <br>
以前からこういう、仲間割れによる、報復としての情報漏えいは散見されていて、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">611</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) <span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">02</span><span class="hljs-symbol">:</span><span class="hljs-number">53.19</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:IDnv9qd00</span>
勲章ってどうやったら貰えるんだ?
主要メンバー一覧
★は獲得勲章数
【フロント(直接部隊)】
・ちくわ <span class="hljs-variable">@tikuwa_zero</span> = <span class="hljs-variable">@tikuwa_ore</span>
・おはぎさん ★★★★★★★★★★★★★ 細見幸市<span class="hljs-variable">@ohagiya</span>
・田所さん ★★★ 八島良太
・松下さん ★★★★★★★★★ 野田憲太郎=松下ゆうこ <span class="hljs-variable">@matusita2012</span>
・久松さん ★★★ 久間知毅<span class="hljs-variable">@HisamaTomoki</span>
・遠野さん ★★★★★★ 渡邉<span class="hljs-variable">@markwat1</span>(<span class="hljs-constant">IT</span>技術者 <span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>不正アクセス首謀)
・ムタさん ★★★★★★★★★★ 牟田信明 <span class="hljs-variable">@mutamac</span>
・田中さん ★★★★★★★★★★ 佐藤田中忠夫 <span class="hljs-variable">@mfpc_mfpc</span>
・ありさん ★★★★★ あり <span class="hljs-constant">Twitter</span>アカウント忘れた
・micさん ★★★★★★ 阿部道生<span class="hljs-variable">@mic_ab</span> (鶴見大学歯学部講師)
・ニジノさん ★★★★★ ニジノスキー
・トミーさん ★★★★★★★★★★ ねこぱんち<span class="hljs-variable">@Dynamite_Tommy</span>
・プロミスさん ★★★★★★★★★★★★★★★ <span class="hljs-variable">@Promised_Land12</span>
<span class="hljs-number">612</span> :提督:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) <span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">03</span><span class="hljs-symbol">:</span><span class="hljs-number">40.70</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:Zcmx65eH0</span>
<span class="hljs-number">1919</span>-<span class="hljs-number">072</span>
<span class="hljs-constant">Level</span>.<span class="hljs-number">4</span>
緊急事態が発生した 号令あるまで任務は控えられたし
<span class="hljs-number">613</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) <span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span><span class="hljs-symbol">:</span><span class="hljs-number">11.05</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:IDnv9qd00</span>
【フロント(遠距離狙撃)】
・蛇さん ★★★★★★★★★★★★ スネーク 中野大介 コニカミノルタ勤務
・アキンドーさん ★★★★★★★★★★ 久保憲俊 <span class="hljs-variable">@akindoh</span>
・ビフさん(引退) ★★ 3年前の震災後そういう人いた
・ランドさん ★★★ ランドルフ
・池田(昭)さん ★ 知らない
・月さん ★★★★★★★★ 月琴 <span class="hljs-variable">@tukikoto</span>
・宇月さん ★★★★★ フリーダム宇月 佐々木俊尚 (ジャーナリスト)
・楊さん ★★★★★ 筑波大学の大学生
・シグナムさん ★★★★★★ <span class="hljs-variable">@StrikerS_Signum</span>
・ぎゃおちゃん ★★★★ ぎゃおおお <span class="hljs-variable">@gyaooo</span>
・末永さん ★★★★★★★★★★★ 悶絶青年スエナガ 青木和律
<span class="hljs-number">614</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) <span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">05</span><span class="hljs-symbol">:</span><span class="hljs-number">11.94</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:IDnv9qd00</span>
【後方支援】
・谷岡さん ★★★★★★★ 大山 hiro oyama
・池田(信)さん ★ なんか細見が池田信夫氏にメールしたと書いてた
・ずんさん ★ <span class="hljs-variable">@zungyo</span> <span class="hljs-variable">@akindoh</span> 夫婦の友達
・芦田先生 ★★ あの芦田先生か。細見がメールしたと書いていた
・安田さん ★★★★ 安田 <span class="hljs-constant">Twitter</span>アカウント忘れた
・畠野先生 ★★★★ 王道を往くナイスガイ畠野 菊池誠 大阪大学教授
・アマ先生 ★★★★ 東海アマが味方だとアピールしていた
・教授 ★★★★★★ 偽教授
・ビヨ師匠 ★ <span class="hljs-constant">Beyond</span> 悪徳商法マニアックス、<span class="hljs-constant">Yourpedia</span>管理者、運営者
・<span class="hljs-constant">Nike</span>さん ★★★★★★★ <span class="hljs-constant">Nike</span> <span class="hljs-constant">Wikipedia</span>の過去の管理者
【幽霊部員】
・事実上<span class="hljs-number">2</span>ヶ月以上活動実績の無い方 <span class="hljs-number">22</span>名
(<span class="hljs-number">3</span>/<span class="hljs-number">13</span>現在) <span class="hljs-number">2</span>ch・<span class="hljs-constant">Twitter</span>等転載厳禁
<span class="hljs-number">615</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) <span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">05</span><span class="hljs-symbol">:</span><span class="hljs-number">49.82</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:IDnv9qd00</span>
>><span class="hljs-number">612</span>
緊急事態とはなんで御座候?
<span class="hljs-number">616</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) <span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">06</span><span class="hljs-symbol">:</span>09.<span class="hljs-number">06</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:Zcmx65eH0</span>
<span class="hljs-constant">Nike</span>氏、すまんが至急メール確認願う </code></pre>
<p>こんなこともありました。 <br>
・宇月さん ★★★★★ フリーダム宇月 <strong>佐々木俊尚 (ジャーナリスト)</strong> <br>
・畠野先生 ★★★★ 王道を往くナイスガイ畠野 <strong>菊池誠 大阪大学教授</strong> <br>
・micさん ★★★★★★ <strong>阿部道生@mic_ab (鶴見大学歯学部講師)</strong></p>
<p>という、IT界では、たいした情報を書かない名の知れた例のITジャーナリストや、 <br>
大阪大学、鶴見大学の教授もいます。 <br>
はい、もちろん物的証拠はないですが、Qiiita以前に、東北大震災の放射能被害のTwitterでの騒動みたいのがあって、そこで例のごとく反目した私にとってはわかりやすいメンツのリクルート活動について、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">125</span> :ダンディー山田 ◆<span class="hljs-number">6</span>NdDvH3KR2 :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">24</span>(火) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">30</span><span class="hljs-symbol">:</span><span class="hljs-number">16.37</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:x0zQ+ky7</span>
こんにちわ!久々にこのスレを拝見しましたが、相変わらずケン坊は大ハッスルのようで失禁するほど笑わせて頂きましたw
噂によると(私は部外者なので詳しくは存じませんが)、ケン坊はもう署には巡礼していないそうで、
しかもお説教までされても言うことをきかないそうですwww
もう一押しです、<span class="hljs-constant">KNKB48</span>もようやく<span class="hljs-number">40</span>人揃ったようですし、これはもう<span class="hljs-number">48</span>を襲名しても構わないでしょうw (半分はほぼ頭数要員みたいなものですがw)
**フロントのメンバーの方々、引き続きよろしくお願いします。 **
**昨日より佐々木さんも参戦いただきました。**
大事なのは先日みなさんにメールしたように、
ヒットアンドアウェー戦法の心構えです。
disっては逃げ、disっては逃げ、これが肝要ですw
正々堂々と、綺麗にdisっていやらし~くやっつけましょうww
<span class="hljs-number">126</span> :ダンディー山田 ◆<span class="hljs-number">6</span>NdDvH3KR2 :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">24</span>(火) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">31</span><span class="hljs-symbol">:</span><span class="hljs-number">59.65</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:x0zQ+ky7</span>
業務連絡・**ちくわ殿、牟田殿、佐々木さんのレッドマインのアカウントの手配をお願いします**
</code></pre>
<p>この「ダンディー山田」本名、細見幸市は、天然でベラベラ内情をしゃべる情報源です。連中が、その流出した情報と符号する「<strong>KNKB48もようやく40人揃ったようですし、これはもう48を襲名しても構わないでしょうw (半分はほぼ頭数要員みたいなものですがw)</strong>」ということを書いていて、2chに「<strong>佐々木さん</strong>」をリクルートしている書いているとの情報を、メールで教えてもらったり、まあ私とネット上で反目するとみなして連中がリクルートする「佐々木さん」はひとりしかいませんし、</p>
<p>そうやって「アカウント手配」してめでたく「コードネーム」をもらった当人の佐々木氏が、</p>
<pre class="prettyprint"><code class=" hljs autohotkey"><span class="hljs-number">895</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span>:<span class="hljs-number">26</span> ID:zblJOCii
確かに、これは匂いますね。気配を感じます。
粘着軍vs異常者岡部のライブバトル、めったにない好機。興味深い
<span class="hljs-number">896</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span>:<span class="hljs-number">27</span> ID:zblJOCii
人
ノ⌒ 丿
<span class="hljs-label"> _/ ::</span>(
<span class="hljs-label"> / :::::::</span>\
<span class="hljs-label"> ( :::::::</span><span class="hljs-comment">;;;;;;;)</span>
<span class="hljs-label"> \_―― ̄ ̄::::::::::</span>\
<span class="hljs-label"> ノ ̄ ::::::::::::::::::::::</span>)
<span class="hljs-label"> ( ::::::::::::::</span><span class="hljs-comment">;;;;;;;;;;;;人</span>
<span class="hljs-label"> / ̄――――― ̄ ̄::::::::</span>\
<span class="hljs-label"> ( :::::::::::::::::::::::::::::::::</span>)
<span class="hljs-label"> \__::::::::::::::::::</span><span class="hljs-comment">;;;;;;;;;;;;;;;;;;;;;;;;ノ</span>
<span class="hljs-label"> ,.-―: ̄`ー::::::::::</span>、
<span class="hljs-label"> /::::::::::::.::::::::::::::::::::::::::::`::</span>、、
<span class="hljs-label"> /::::::::::::::::::::::::::::::::::::::::::::::::::::::</span>`、
<span class="hljs-label"> l::::::::::::::::::::::::::::::::::::::::</span><span class="hljs-comment">;':l:::::::::::\::l</span>
<span class="hljs-label"> l:::::::::::::::::::::::::::::::::,,::::::::</span><span class="hljs-comment">;-,:,::::::::::::::::l</span>
<span class="hljs-label"> l::::::::::::::::,_,.::::</span>,'<span class="hljs-comment">;::::::;:::::: :: l ::::::::::::::l</span>
<span class="hljs-label"> l::::::::::/-/:::/-ニ,.::::/=,./::::::::::</span>l
<span class="hljs-label"> ヽ::::</span> ´、ひ> <span class="hljs-comment">;: l .<ひ>' 、::::::::/</span>
<span class="hljs-label"> ヽ:::::  ̄ .)::</span><span class="hljs-comment">; l  ̄ l::::/ </span>
<span class="hljs-label"> 、:::::.. /:::</span><span class="hljs-comment">; .,-、 l:::/、</span>
<span class="hljs-label"> ,―:::::::: ゝヽ- ー' 、 l::</span>/,、ヽ
<span class="hljs-label"> l,、,、,,:、:: / ,--、,-.、_ l /::::::</span>,、,、l
<span class="hljs-label"> l,、,、,、,、,、::、 `ー ̄-' /:::::::::::</span>,、,、l
<span class="hljs-label"> l,、,、,、,、,、,、::ヽ /::::::::</span>、,、,、,、,ノ:\
<span class="hljs-number">897</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span>:<span class="hljs-number">29</span> ID:zblJOCii
私自身の経験から言わせてもらうと、刑事告訴だの通報だのと吠えているばかりの人は、なんらその行動を起こせていませんね。
普通、民訴だの刑訴だのをする人は黙って粛々と進め、相手に対策のスキを与えませんから。
ただ、それにしてもこの人の場合は異常ですね。通用しなかったのに、その後も多人数を相手に刑事告訴だのとほら口を叩いている。
ある意味、貴重なサンプルです。興味深い
<span class="hljs-number">898</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span>:<span class="hljs-number">31</span> ID:zblJOCii
私はあくまで取材の一環として見ていますからブログに書かれることは無いでしょうが、
書かれた人への取材が無いとアンフェアかもしれませんね。
何人かインタビューしてみたいのですが、どうしたものか・・・
<span class="hljs-number">900</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span>:<span class="hljs-number">35</span> ID:zblJOCii
よくわからないのですが、「モットンさん」がどうして「Twitterのmotokenさん」に
結びつくのでしょう。「勇み足」ではありませんか? 異常者岡部さんにしてもこれはない
<span class="hljs-number">901</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span>:<span class="hljs-number">36</span> ID:zblJOCii
さらに言うと、「毛チンポさん」とは誰の事なのか?
これも謎です</code></pre>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">121</span> :フリーダム宇月 ◆wK5afSYrKU :<span class="hljs-number">2014</span>/<span class="hljs-number">02</span>/09(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">29</span><span class="hljs-symbol">:</span><span class="hljs-number">57.54</span>
<span class="hljs-constant">ID</span><span class="hljs-symbol">:takAxm5s0</span>この人の観察を始めて3ヶ月以上が経ちますが、勉強になっています。とても興味深く、それが尽きることはありません。
あなたには老婆心ながら「まっすぐと批判に向き合え」という言葉を贈りたい。
あなたは自分に都合の悪い言説があれば、それを罵倒という位置づけにして逃げようとする悪い癖がある。
批判は批判としてきっちり向き合わねば。
確かに時はまさに「多様性」の時代。標準モデルの時代ではない。
というより「標準」の定義はもう変わってしまっているから、あなたのような頭のおかしな人が大声出しても構わない。
しかし、最低限のボトム・ラインとしてここは譲れない。批判と向き合ってください。
あと、マスコミから取材の申し込みが来ているという話は空想でしょう。かなり当たってみましたが、
知ってる人間は居ませんでしたから。嘘だけは頂けません。</code></pre>
<pre class="prettyprint"><code class=" hljs ">494 :フリーダム宇月 ◆wK5afSYrKU :2014/03/31(月) 16:26:39.74 ID:6YFX+ckm0
チンポさんのところには、マスコミの連絡も無ければ、
応援のメール一通届いていないはず。この言い訳がどうなるのか、興味深い。
497 :名無しさん@ゴーゴーゴーゴー!:2014/03/31(月) 16:28:13.80 ID:6YFX+ckm0
おめーみたいなトーシロにジャーナリズムを語る資格ねーんだよ、ボケ
500 :フリーダム宇月 ◆wK5afSYrKU :2014/03/31(月) 16:29:51.34 ID:6YFX+ckm0
>>497
私もそう思う。 </code></pre>
<p>その他枚挙に暇がありませんが、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">898</span> フリーダム宇月 ◆wK5afSYrKU <span class="hljs-number">2014</span>/<span class="hljs-number">01</span>/<span class="hljs-number">19</span> <span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">31</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:zblJOCii</span>
私はあくまで取材の一環として見ていますからブログに書かれることは無いでしょうが、
書かれた人への取材が無いとアンフェアかもしれませんね。
何人かインタビューしてみたいのですが、どうしたものか・・・</code></pre>
<p>とやたらめったら、取材やらインタビューだのジャーナリストアピールしまくっていたり、 <br>
慣れない2chの書き込みで書き込みIDを同一の、 <code>ID:6YFX+ckm0</code> で自作自演失敗しながら、「<strong>トーシロにジャーナリズムを語る資格ねーんだよ、ボケ</strong> 」とか書いているのをみると、ああ佐々木俊尚さん、ダークサイドだなあ、バレないと思ってるのか、ジャーナリストのプロのアピールしたいのかわけがわからないけど、アホなことやってるなあとしか思うしかないわけです。</p>
<p>ちなみにマスコミ関係者から当時TwitterのDMで本件に問い合わせがあったのは紛れもない事実です。たんに佐々木俊尚氏の周辺には該当しなかったということにすぎません。</p>
<p>フリーダム宇月=佐々木俊尚が犯罪者集団に合流した頃、この集団が犯罪者集団であることが、はっきり確かめられました。 <br>
概要を告発している、2ちゃんねるのレスを引用すると、ようするに</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">564</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/08(火) 08<span class="hljs-symbol">:</span><span class="hljs-number">32</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span>.<span class="hljs-number">20</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:ym+FU4yh0</span>
他人のネットワークの<span class="hljs-constant">WEP</span>キーを解読して不正アクセス・<span class="hljs-constant">IP</span>偽装をして、
岡部氏を毛の壁と揶揄するスレに誹謗中傷の書き込みをするなど
電波法違反・不正アクセス禁止法違反に該当する重大な犯罪行為だ。</code></pre>
<p>こういうことです。昨年、この犯罪行為で電波法違反容疑で逮捕された事件がありました。</p>
<p><a href="http://www.sankei.com/premium/news/150630/prm1506300003-n1.html">【衝撃事件の核心】狙われる自宅の無線LAN ただ乗り簡単、犯罪に巻き込まれる可能性</a></p>
<blockquote>
<p>お宅の無線LAN、勝手に使われていませんか-。他人の無線LANを“ただ乗り”したなどとして、警視庁と愛媛県警が6月、電波法違反容疑で、松山市和泉南の無職、藤田浩史被告(30)=不正アクセス禁止法違反罪などで公判中=を再逮捕した。ただ乗りによる摘発は全国で初めて。企業や一般家庭にも普及している通信手段だが、セキュリティーが甘いと「便利な犯罪インフラ」になってしまう。 <br>
藤田容疑者の逮捕容疑は昨年6月11日、自宅で電波法が定める上限の9倍の電波を出力する無線LANアダプターを設置。解析したパスワードで他人のLANに不正接続して無断利用したとしている。同庁サイバー犯罪対策課によると「自分の家のルーターに接続したつもりだった」などと容疑を否認している。 <br>
多くの無線LANは通信が暗号化されパスワードを入力しないと接続できない。同課によると、藤田容疑者は解析ソフトを利用してパスワードを突破。自宅から数十メートル離れた家に住む無関係な男性方のLANをただ乗りしインターネットに接続していた。 <br>
ただ乗りすると接続者の身元がわかりにくくなる。藤田容疑者は昨年2~6月、男性方のLANに90回以上接続し、発信元を隠蔽してインターネットバンキングの不正送金などを行っていた。 <br>
無線LANの悪用をめぐっては大阪府警が22年、電波法が定める上限の数十倍の出力があるLANアダプターを販売したとして、電波法違反(無線局の開設)幇(ほう)助(じょ)容疑で逮捕したケースがある。 <br>
このほか、ただ乗りによるサイバー犯罪を摘発した例はあるが、ただ乗りそのものを摘発したのは初の事例となった。同法の「無線通信の秘密窃要」に該当すると判断された。</p>
</blockquote>
<p>私を中傷誹謗する2chスレで、連中はこう書き込みます。</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">960</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">14</span><span class="hljs-symbol">:</span><span class="hljs-number">40</span><span class="hljs-symbol">:</span><span class="hljs-number">36.42</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:ZRi6pesJ0</span>
フリー<span class="hljs-constant">WiFi</span>スポット?そんな生ぬるいことするかw
そもそもな、フリーの<span class="hljs-constant">WiFi</span>スポットでは<span class="hljs-number">2</span>chには滅多に書き込めないのよ
田所・遠野兄貴から全員に伝達のあった必殺技で、切り抜けるのさ
具体的には言えないがな
中国様様だぜ
</code></pre>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">111</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">28</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span>.<span class="hljs-number">35</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:QPgAfJBC</span>
ぎゃははは、ポンコツよ、中国のプロキシだと?<span class="hljs-number">90</span>年代の厨房かよ(笑い)
お前はあの時から時間が止まっているのか?
<span class="hljs-number">2</span>chってのはな、海外の串経由も殆どブロックされてんだよ
中国ってのはな、中国のある「製品」の事だよ、バーカ(大笑い)
もっとも「ローテク」のお前には何のことだかわかるまい
<span class="hljs-number">112</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">38</span><span class="hljs-symbol">:</span><span class="hljs-number">32.16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:X88cDqd0</span>
あいつ、<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>も知らん情弱とは思わなかったわw
<span class="hljs-number">48</span>のメンバーは去年の春頃から全員使ってるってのにww
<span class="hljs-number">113</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">39</span><span class="hljs-symbol">:</span><span class="hljs-number">22.70</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:X88cDqd0</span>
中国のproxy(笑)
また奴の名言が一つ生まれたね
<span class="hljs-number">114</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">45</span><span class="hljs-symbol">:</span><span class="hljs-number">20.36</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:byF1CbSI</span>
電波法や不正アクセス禁止法に引っかかるんじゃないのか?
<span class="hljs-number">115</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">49</span><span class="hljs-symbol">:</span><span class="hljs-number">49.06</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:goYep8EX</span>
「使用」すればね。
<span class="hljs-number">116</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">51</span><span class="hljs-symbol">:</span><span class="hljs-number">19.03</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:byF1CbSI</span>
一応通報しとくか
<span class="hljs-number">117</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">41</span><span class="hljs-symbol">:</span><span class="hljs-number">06</span>.<span class="hljs-number">16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:goYep8EX</span>
キャハハハハハハw
<span class="hljs-number">118</span> :<span class="hljs-constant">Dynamite</span>&<span class="hljs-constant">Tommy</span>:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">45</span><span class="hljs-symbol">:</span><span class="hljs-number">37.13</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:/zvW9sth</span>
こちらではおひさ!
おはぎ屋さん、大変なことになってるね、あの脱毛さんw ビビり過ぎて脱毛が進行しなきゃいいんだけどw
<span class="hljs-number">119</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">48</span><span class="hljs-symbol">:</span><span class="hljs-number">27.69</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7X
粘着軍には<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>を使って他人のネットワークに不正アクセスして岡部氏を誹謗中傷する書き込みをしていたという疑惑が浮上した。
岡部氏が警察の事情聴取の際にこの不正アクセスの疑惑を主張して、
もし疑惑が事実だとしたなら名誉毀損どころの話ではない。
<span class="hljs-number">120</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">56</span><span class="hljs-symbol">:</span><span class="hljs-number">24.46</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:QItJGM/M</span>
>><span class="hljs-number">119</span>
あなた、粘着軍だの岡部氏だの、いきなり何を言い出しているのよww
誰よそれw
<span class="hljs-number">121</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">59</span><span class="hljs-symbol">:</span><span class="hljs-number">38.44</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:XpkQBxH7</span>
<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>は不正な使い方をしなければ、不正アクセス禁止法にはひっかからない
やーいやーい、お尻ペンペン~(爆笑)なんにもできない~
<span class="hljs-number">122</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">02</span><span class="hljs-symbol">:</span><span class="hljs-number">33.80</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">5</span>Oc9Qm3F
<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>ってガンダムのアレか?
とググって噴いたw
とりあえず<span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7Xは検索も出来ないドアホってのは分かったわw
<span class="hljs-number">123</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">03</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span>.<span class="hljs-number">34</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:ktIKKto0</span>
そもそも<span class="hljs-constant">GSKY</span>に限らず、無線<span class="hljs-constant">LAN</span>の<span class="hljs-constant">AP</span>のタダ乗りは違法ではないw
パスワードも暗号化もしていない<span class="hljs-constant">AP</span>設置者がマヌケなのだ
利用者に抜かりは無いだろうさ
<span class="hljs-number">124</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span><span class="hljs-symbol">:</span><span class="hljs-number">38.39</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:QItJGM/M</span>
ああ、<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>ってガンダムの<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>か。
俺はてっきりゲイ位置情報コミュニティーの<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>のことだと思ってたww
<span class="hljs-number">125</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">05</span><span class="hljs-symbol">:</span>09.<span class="hljs-number">88</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:QItJGM/M</span>
>><span class="hljs-number">119</span>は一体何を言ってるんだ??よくわからん。岡部氏って誰だ?
<span class="hljs-number">126</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">05</span><span class="hljs-symbol">:</span><span class="hljs-number">22.32</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7X
暗号解読してアクセスしてたらアウト!
仮にパスワード設定してなかったとしても、他人のネットワークから誹謗中傷の書き込みをしてたらアウト。
<span class="hljs-number">127</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">07</span><span class="hljs-symbol">:</span><span class="hljs-number">11.84</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7X
>><span class="hljs-number">125</span>
いまさらとぼけても無駄無駄無駄w
岡部氏はすでにこの件をエントリに掲載している。
あとは警察の事情聴取で全て話せば粘着軍は犯罪者だよ。
<span class="hljs-number">128</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">10</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span>.<span class="hljs-number">56</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:QItJGM/M</span>
>暗号解読してアクセスしてたらアウト!
当たり前だろ、そんなもんwwww
<span class="hljs-number">129</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">11</span><span class="hljs-symbol">:</span><span class="hljs-number">06</span>.<span class="hljs-number">06</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7X
こうなった以上、警察は本気で捜査するぞ、どうすんだ、お前ら?w
<span class="hljs-number">130</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">15.83</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
来ました。
確かに匂いますね。しかも懲りないことに、今度は名指しで不正アクセスの犯罪者扱いですか
また名誉棄損が<span class="hljs-number">1</span>件増えますね。興味深い
<span class="hljs-number">131</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">41.11</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7X
>><span class="hljs-number">130</span>
お前も捜査対象になるだろうから準備しといたほうがいいんじゃないか?
<span class="hljs-number">132</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">46.35</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
私は名も無い一市民ですが、本件はとても興味深く取材させて頂いております
本当に面白いコンテンツです
<span class="hljs-number">133</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">14</span><span class="hljs-symbol">:</span><span class="hljs-number">28.75</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
>><span class="hljs-number">131</span>
私は傍観者ですから高みの見物です。捜査対象、なかなか出来ない経験です。興味深いです
<span class="hljs-number">134</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">16</span><span class="hljs-symbol">:</span><span class="hljs-number">35.98</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
すでに草稿はかなり仕上がっているので、あとは決着がつくのを待つのみです
早くレポートしたくてたまりません。
<span class="hljs-number">135</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">17</span><span class="hljs-symbol">:</span><span class="hljs-number">15.16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
メールなんて見ていませんよ。私は知りません
<span class="hljs-number">136</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">03</span>(木) <span class="hljs-number">00</span><span class="hljs-symbol">:</span><span class="hljs-number">11</span><span class="hljs-symbol">:</span><span class="hljs-number">16.77</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:knzHr4Y+</span>
何人も、不正アクセス行為をしてはならない(<span class="hljs-number">3</span>条)。これに違反した者は、<span class="hljs-number">3</span>年以下の懲役又は<span class="hljs-number">100</span>万円以下の罰金に処せられる(<span class="hljs-number">11</span>条)
<span class="hljs-number">137</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">03</span>(木) <span class="hljs-number">00</span><span class="hljs-symbol">:</span><span class="hljs-number">18</span><span class="hljs-symbol">:</span><span class="hljs-number">16.16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">4</span>utH5lMS
どんどん自分で自分を追いつめるチンポ汁氏、ますます目が離せない
<span class="hljs-number">138</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">03</span>(木) <span class="hljs-number">00</span><span class="hljs-symbol">:</span><span class="hljs-number">25</span><span class="hljs-symbol">:</span><span class="hljs-number">03</span>.<span class="hljs-number">83</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:knzHr4Y+</span>
名誉毀損どころじゃなくなったな。
不正アクセス禁止法違反容疑とあらば警察の家宅捜索があるかもしれないぞ。 </code></pre>
<p>ここで、</p>
<pre class="prettyprint"><code class=" hljs ruby">中国ってのはな、中国のある「製品」の事だよ、バーカ(大笑い)
もっとも「ローテク」のお前には何のことだかわかるまい
<span class="hljs-number">112</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">38</span><span class="hljs-symbol">:</span><span class="hljs-number">32.16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:X88cDqd0</span>
あいつ、<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>も知らん情弱とは思わなかったわw
<span class="hljs-number">48</span>のメンバーは去年の春頃から全員使ってるってのにww</code></pre>
<p>と「48のメンバーは去年の春頃から全員使ってる」中国のある「製品」「G-Sky」というのは、 <br>
Gsky GS-27USB <br>
<a href="http://getnews.jp/archives/36778">http://getnews.jp/archives/36778</a></p>
<p><img src="http://px1img.getnews.jp/img/archives/img_8674.jpg" alt="" title=""></p>
<p>のことです。 <br>
電波法違反容疑で逮捕された事件で悪用されていた機器はこれかそれに類する機器です。</p>
<p>そして、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">130</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">15.83</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
来ました。
確かに匂いますね。しかも懲りないことに、今度は名指しで不正アクセスの犯罪者扱いですか
また名誉棄損が<span class="hljs-number">1</span>件増えますね。興味深い
<span class="hljs-number">131</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">41.11</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:</span><span class="hljs-number">1</span>SJT7G7X
>><span class="hljs-number">130</span>
お前も捜査対象になるだろうから準備しといたほうがいいんじゃないか?
<span class="hljs-number">132</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">46.35</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
私は名も無い一市民ですが、本件はとても興味深く取材させて頂いております
本当に面白いコンテンツです
<span class="hljs-number">133</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">14</span><span class="hljs-symbol">:</span><span class="hljs-number">28.75</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
>><span class="hljs-number">131</span>
私は傍観者ですから高みの見物です。捜査対象、なかなか出来ない経験です。興味深いです
<span class="hljs-number">134</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">16</span><span class="hljs-symbol">:</span><span class="hljs-number">35.98</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
すでに草稿はかなり仕上がっているので、あとは決着がつくのを待つのみです
早くレポートしたくてたまりません。
<span class="hljs-number">135</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">17</span><span class="hljs-symbol">:</span><span class="hljs-number">15.16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:rtXLSHUN</span>
メールなんて見ていませんよ。私は知りません</code></pre>
<blockquote>
<p>私は名も無い一市民ですが、本件はとても興味深く取材させて頂いております <br>
すでに草稿はかなり仕上がっているので、あとは決着がつくのを待つのみです <br>
早くレポートしたくてたまりません。</p>
</blockquote>
<p>という書き込みをしている、ID:rtXLSHUNですが、これは、佐々木俊尚です。</p>
<p>私がそれで「確定だ」と思ったのは、</p>
<blockquote>
<p>メールなんて見ていませんよ。私は知りません</p>
</blockquote>
<p>というくだりです。メールといえば、私は佐々木さんに本件でメールしていて、 <br>
即座に、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">633</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/09(水) 08<span class="hljs-symbol">:</span><span class="hljs-number">02</span><span class="hljs-symbol">:</span><span class="hljs-number">37.20</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:yamBpwtw0</span>
また支離滅裂な文章を・・・
文書化能力の欠如が著しい。トレーニングが必要ですよ。
助けになる本は沢山あります。探して読みましょう。 </code></pre>
<p>と2chで「お返事」がありました。</p>
<p>以上の書き込み以前に、 <br>
【弱者を放置して】赤木智弘30【アイマスラブ】 <br>
<a href="http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19">http://yomogi.2ch.net/test/read.cgi/sociology/1445809895/19</a> <br>
で仲間割れした犯罪者仲間から叩かれて、牽制するために、Qiita界隈からの新参者(ウィザード組、8賢者)のリクルート情報を内部暴露したのは、赤木智弘@T_akagi という人物ですが、 <br>
この人物は、(少なくとも当時)ネットアクセス費も捻出できない生活苦であったようで、その内情をまたベラベラしゃべっていました。</p>
<p><strong>ナベさんには感謝、感謝だよw 俺にはタダ乗りネット環境はありがたい</strong> </p>
<p>この ID:Y5sG/5y0 <br>
は、ナベさん=渡邊 昌之 @markwat1 <br>
UNIXの技術者で、著作も有ります。こいつが不正アクセス機器を仲間にばらまいた首謀です。 <br>
<a href="http://www.amazon.co.jp/%E6%B8%A1%E9%82%8A-%E6%98%8C%E4%B9%8B/e/B005GKD5NI">http://www.amazon.co.jp/%E6%B8%A1%E9%82%8A-%E6%98%8C%E4%B9%8B/e/B005GKD5NI</a></p>
<p>三浦ゴウ ◆C93WWgXd.E <br>
は 赤木智弘 @T_akagi</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">72</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">55</span><span class="hljs-symbol">:</span><span class="hljs-number">22.13</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:Y5sG/</span><span class="hljs-number">5</span>y<span class="hljs-number">0</span>
<span class="hljs-constant">MINIX</span>復権~期待期待~
(*過去、<span class="hljs-constant">MINIX</span>についての<span class="hljs-constant">Twitter</span>の発言に渡邉が因縁つけてきたことがある
彼は<span class="hljs-constant">UNIX</span>、<span class="hljs-constant">LINUX</span>系の技術者であり著作もある。)
<span class="hljs-number">73</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">16</span><span class="hljs-symbol">:</span><span class="hljs-number">01</span><span class="hljs-symbol">:</span><span class="hljs-number">07</span>.<span class="hljs-number">94</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:Y5sG/</span><span class="hljs-number">5</span>y<span class="hljs-number">0</span>
ほれほれ、「国際照会」やってみろよ
クライアントのネットワークからの書き込みでよ、プロキシも<span class="hljs-constant">FW</span>もログ管理はザル、 端末数は<span class="hljs-number">500</span>以上、最高の環境だぜw
(*クライアントのネットワークから不正アクセスしていることを技術者視点から自慢)
<span class="hljs-number">74</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">16</span><span class="hljs-symbol">:</span><span class="hljs-number">03</span><span class="hljs-symbol">:</span><span class="hljs-number">56.09</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:Y5sG/</span><span class="hljs-number">5</span>y<span class="hljs-number">0</span>
やっぱりネットは野良<span class="hljs-constant">AP</span>と客のネットワークからに限るぜ
野良<span class="hljs-constant">AP</span>と<span class="hljs-constant">WEP</span>キー解読はフロントメンバーの基本としてレクチャーだ
(*クライアントのネットワークから不正アクセスしている
<span class="hljs-constant">WEP</span>キー解読するのも違法 <span class="hljs-constant">KNKB</span>「フロントメンバー」に伝授したのはこの渡邉)
<span class="hljs-number">78</span> :三浦ゴウ ◆<span class="hljs-constant">C93WWgXd</span>.<span class="hljs-constant">E</span> :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">20.13</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:lCfgYBp4</span>
>><span class="hljs-number">74</span>
ナベさんには感謝、感謝だよw 俺にはタダ乗りネット環境はありがたい
それはそうと、あいつもかなりおとなしくなったね。
都合が悪くなったらダンマリだもんなぁ。あんなもんだよ、ネットでは威勢はいいが、
リアルでの議論を持ちかけたらとんずら。解りやすいわ。
それと、<span class="hljs-constant">AA</span>なんだけどさ、<span class="hljs-constant">AA</span>エディタ使うと便利だよ。メモ帳とかでは難しい
(*「ナベさん」と>><span class="hljs-number">74</span>に話しかけるのは、もちろん
<span class="hljs-number">74</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">16</span><span class="hljs-symbol">:</span><span class="hljs-number">03</span><span class="hljs-symbol">:</span><span class="hljs-number">56.09</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:Y5sG/</span><span class="hljs-number">5</span>y<span class="hljs-number">0</span>
が渡邊 昌之 <span class="hljs-variable">@markwat1</span> であるからである。
ナベさんには感謝、感謝だよw
俺にはタダ乗りネット環境はありがたい
ということは、「<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>」は渡邉が無償配布しまくったということになる。)
<span class="hljs-number">80</span> :三浦ゴウ ◆<span class="hljs-constant">C93WWgXd</span>.<span class="hljs-constant">E</span> :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">02</span>.<span class="hljs-number">39</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:lCfgYBp4</span>
基地街ギーク、なーにが「気が向いたら自由に更新する、消滅することはない。」だぁ?ww
松下氏などの顔写真は載せても、おはぎ屋氏の記事は「控えめ」なのはどうしてなんだい?ww
「やばいことを自覚」しているからだよな?ww
お前はちゃんと「計算尽くしの恫喝」をしているんだよ。チンピラっていうんだよ、こういうのは。
「勝てそうな相手にだけ威勢が良い」んだわ。わかりやすいね。
ま、お前は俺らフロントには写真どころか記事すら書けないわけで、これからも一方的に行くぜ。
ざまーみろ。お前は「火遊びが過ぎた」んだよ。
<span class="hljs-number">81</span> :三浦ゴウ ◆<span class="hljs-constant">C93WWgXd</span>.<span class="hljs-constant">E</span> :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">20.84</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:lCfgYBp4</span>
おら、東京に来て俺と議論する話は無視かぁ?wユースト配信でフェアなタイマンやろうぜ?
ああ?wま、ボッコボコだけどなw
(*赤木智弘は、やたら僕に東京に来てロフトで議論しろと挑発する)
<span class="hljs-number">82</span> :三浦ゴウ ◆<span class="hljs-constant">C93WWgXd</span>.<span class="hljs-constant">E</span> :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">21</span><span class="hljs-symbol">:</span><span class="hljs-number">39.27</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:lCfgYBp4</span>
基地街よ、クリスマスはどうするんだぁ?w
スネーク軍にきっちり報告してもらうからなww
<span class="hljs-number">83</span> :三浦ゴウ ◆<span class="hljs-constant">C93WWgXd</span>.<span class="hljs-constant">E</span> :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">24</span><span class="hljs-symbol">:</span><span class="hljs-number">27.13</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:lCfgYBp4</span>
こっちには本職の法の専門家がついてるんだよ。やれるもんなら、やってみな!
(*赤木智弘は、は矢部<span class="hljs-variable">@motoken_tw</span>と親しい。
本職の法の専門家とは無論、矢部のことであり、
結託していることを誇示。)
<span class="hljs-number">84</span> :三浦ゴウ ◆<span class="hljs-constant">C93WWgXd</span>.<span class="hljs-constant">E</span> :<span class="hljs-number">2013</span>/<span class="hljs-number">12</span>/<span class="hljs-number">22</span>(日) <span class="hljs-number">20</span><span class="hljs-symbol">:</span><span class="hljs-number">25</span><span class="hljs-symbol">:</span><span class="hljs-number">14.87</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:lCfgYBp4</span>
知的障害ブログww それは言い過ぎだよはぎさんww
(*「はぎさん」とは、もちろん「おはぎさん」おはぎ屋 細見幸市<span class="hljs-variable">@ohagiya</span> のこと)</code></pre>
<p><strong>ナベさんには感謝、感謝だよw 俺にはタダ乗りネット環境はありがたい</strong> </p>
<p><strong>こっちには本職の法の専門家がついてるんだよ。やれるもんなら、やってみな!</strong></p>
<p>あとこの本職の法の専門家がついている、っていうのはTwitter界隈で悪名高い、元検事のモトケン @motoken_tw 矢部善朗のことです。当時、赤木智弘とは親しくTwitterでやりとりしていました。今は例によってどうも仲間割れしているようです。</p>
<p>しかし、</p>
<pre class="prettyprint"><code class=" hljs ruby">中国ってのはな、中国のある「製品」の事だよ、バーカ(大笑い)
もっとも「ローテク」のお前には何のことだかわかるまい
<span class="hljs-number">112</span> :名無しさん@お腹いっぱい。:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">02</span>(水) <span class="hljs-number">19</span><span class="hljs-symbol">:</span><span class="hljs-number">38</span><span class="hljs-symbol">:</span><span class="hljs-number">32.16</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:X88cDqd0</span>
あいつ、<span class="hljs-constant">G</span>-<span class="hljs-constant">Sky</span>も知らん情弱とは思わなかったわw
<span class="hljs-number">48</span>のメンバーは去年の春頃から全員使ってるってのにww</code></pre>
<p>という書き込みが仲間より「不用意に」なされ、 <br>
以上のような犯行がばれたと気付くと、渡邉は、 <br>
<strong>犯罪「機器」の証拠隠滅行動を共犯者に指示します。</strong></p>
<pre class="prettyprint"><code class=" hljs lasso"><span class="hljs-number">243</span> :TON:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">05</span>(土) <span class="hljs-number">03</span>:<span class="hljs-number">24</span>:<span class="hljs-number">57.98</span>
KNKBフォーティエイト レギュラー各位
ども、緊急ミッションです。
既に通達もしましたが、最初に機器と共に手渡ししたDVD<span class="hljs-attribute">-ROM</span>を来週の水曜日までに
廃棄してください。ハサミを入れれば復元不可能です。
機器については、配布時と同様に、私が直接回収します。
こちらについては何もしなくても結構です。
私が責任をもって破壊・埋没します。
連絡についてもいつも通り、公衆電話からでお願いします。
※関東方面の方は別の者をアサインします。
誤ってDVD<span class="hljs-attribute">-ROM</span>からLinuxを起動せず投稿した人は、
「緊急時」と書かれた方のDVD<span class="hljs-attribute">-ROM</span>をセットして、
パソコンの電源を入れてください。
自動的にシステムが開始されます。
選択肢が出てきますが、(<span class="hljs-number">1</span>)Gutmann を選択してEnterを押してください。これでOKです。
遅くとも火曜日中には実施願います。これで<span class="hljs-number">120</span><span class="hljs-subst">%</span>大丈夫ですw
<span class="hljs-number">244</span> :TON:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">05</span>(土) <span class="hljs-number">03</span>:<span class="hljs-number">28</span>:<span class="hljs-number">47.05</span>
尚、奴が見ている例のスレには本件は展開しないでください。
<span class="hljs-number">245</span> :TON:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">05</span>(土) <span class="hljs-number">03</span>:<span class="hljs-number">35</span>:<span class="hljs-number">37.41</span>
ついでに、複数の方から頂いた質問がありますので、ついでに回答しておきます。
固定電話などについては、「かかってきた電話」については通話履歴というのは存在しません。
ご安心を。かける側は公衆電話、これを徹底してください。
<span class="hljs-number">246</span> :TON:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/<span class="hljs-number">05</span>(土) <span class="hljs-number">03</span>:<span class="hljs-number">37</span>:<span class="hljs-number">39.67</span>
訂正、 レギュラー各位 ではなく、正確には「フロント以外のレギュラー各位」です。
フロントは全員対処しました。以上。
</code></pre>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">564</span> :名無しさん@ゴーゴーゴーゴー!:<span class="hljs-number">2014</span>/<span class="hljs-number">04</span>/08(火) 08<span class="hljs-symbol">:</span><span class="hljs-number">32</span><span class="hljs-symbol">:</span><span class="hljs-number">04</span>.<span class="hljs-number">20</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:ym+FU4yh0</span>
他人のネットワークの<span class="hljs-constant">WEP</span>キーを解読して不正アクセス・<span class="hljs-constant">IP</span>偽装をして、
岡部氏を毛の壁と揶揄するスレに誹謗中傷の書き込みをするなど
電波法違反・不正アクセス禁止法違反に該当する重大な犯罪行為だ。</code></pre>
<pre class="prettyprint"><code class=" hljs cs">いかんせん、Qiita以降の奴しか知らないので、不慣れなところはレギュラーが極力、バックアップ願います。
<span class="hljs-number">8</span>賢枠 (暫定) <span class="hljs-number">2015</span>/<span class="hljs-number">10</span>/<span class="hljs-number">02</span>
・スキルハンターの鷹
・知の答弁人田中
・思考のゼロ除算ボレロ
・辣腕ギークのキャメル
・知のオーバーフロー加藤
・AIG(A-Jiro <span class="hljs-keyword">is</span> Guru)
・菅本・ザ・ストリートプログラマー
・(空席)
以上。
</code></pre>
<p>という「レギュラー」だの「バックアップ」だの人を中傷誹謗して貶めるために攻撃する行為をアホらしい幼稚なゲーム化してるのは、この文脈です。 <br>
【フロント(直接部隊)】 <br>
【フロント(遠距離狙撃)】 <br>
【後方支援】</p>
<p>それで、その「貢献」度合いによって、★勲章みたいなものが、リーダーから授与されるみたいです。 <br>
アホですね。 <br>
ちくわ @tikuwa_zero = @tikuwa_ore <br>
提督 <br>
とか書いてるのが首謀で、こいつに★がないのは、もちろんこいつが★を与える当事者、「提督」だかららしいです。 <br>
ちなみに、この、ちくわ @tikuwa_zero = @tikuwa_ore <br>
は、ペドフィリア(ロリコン)で、以下に示すように、 <br>
児童ポルノ画像をTwitterにUPしたり、他者をハッシュタグをもって執拗に攻撃していることを運営に咎められてアカウントを永久凍結されました。</p>
<p>自分のことは「セクマイ」セクシャルマイノリティだとか言ってます。</p>
<p><a href="http://twilog.org/tikuwa_ore/search?word=%E3%81%B5%E3%81%86%E3%80%82%E5%85%A8%E3%81%8F%E5%B0%8F%E5%AD%A6%E7%94%9F%E3%81%AF%E6%9C%80%E9%AB%98%E3%81%A0%E3%81%9C%EF%BC%81&ao=a">http://twilog.org/tikuwa_ore/search?word=%E3%81%B5%E3%81%86%E3%80%82%E5%85%A8%E3%81%8F%E5%B0%8F%E5%AD%A6%E7%94%9F%E3%81%AF%E6%9C%80%E9%AB%98%E3%81%A0%E3%81%9C%EF%BC%81&ao=a</a></p>
<blockquote>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
ふう。全く小学生は最高だぜ!</p>
</blockquote>
<p><a href="http://togetter.com/li/636375#c1401945">http://togetter.com/li/636375#c1401945</a></p>
<blockquote>
<p>ロリペドも合意の上であれば法的には問題だが、道義的には問題はない。</p>
</blockquote>
<p>などと、「道義」を意味不明なオレオレ定義をもって乱用してめちゃくちゃ俺理論をばらまいてるクズです。</p>
<p><a href="http://twilog.org/tikuwa_ore">http://twilog.org/tikuwa_ore</a> <br>
では、Hashtags統計をみたら、</p>
<pre class="prettyprint"><code class=" hljs vala">Hashtags
<span class="hljs-preprocessor">#rpg_logres983</span>
<span class="hljs-preprocessor">#日本翼778</span>
<span class="hljs-preprocessor">#ワーワー教647</span>
<span class="hljs-preprocessor">#放射脳558</span>
<span class="hljs-preprocessor">#毛の壁442</span>
<span class="hljs-preprocessor">#gokaiger216</span>
<span class="hljs-preprocessor">#tatoba183</span>
<span class="hljs-preprocessor">#活動家ゴッコ110</span>
<span class="hljs-preprocessor">#SG_anime106</span>
<span class="hljs-preprocessor">#リーガルハイ100</span>
<span class="hljs-preprocessor">#雛菊98</span>
<span class="hljs-preprocessor">#fourze88</span>
<span class="hljs-preprocessor">#prettyrhythm69</span>
<span class="hljs-preprocessor">#牛乳支障65</span>
<span class="hljs-preprocessor">#狼王</span>
</code></pre>
<p>だのくだらない個人攻撃専用のハッシュタグがずらりと並んでいます。 <br>
唯一例外は、<code>#rpg_logres983</code>というゲームのタグでしょうか。 <br>
ゲームしてるか、Twitterで誰かを集団でヘイトかまして袋叩きしている活動しか確認できない外道です。 <br>
もちろん、この「毛の壁」ってのが一部で有名な私を攻撃するためのハッシュタグですが、こいつも含めて刑事告訴してから「地下に潜った」とか言ってるみたいです。 <br>
当初は「エア告訴」だのなんだのさんざん言ってくれましたが、事実だとわかった途端に、ビビって最終的に起訴猶予処分になったお友達と一緒に所轄の警察署に自首したので、身元も判明し、最終的に時効かんかで処分されませんでしたが、神戸地検からの処分通知書で判明した実名は、芦田真一です。</p>
<p>現在は、 @tikuwa_zero として、Twitterのシリアルアカウントの鍵付き、また、 <br>
Togetgterで、闇のねりもの・ちくわ(@tikuwa_zero)のまとめ <br>
<a href="http://togetter.com/id/tikuwa_zero">http://togetter.com/id/tikuwa_zero</a> <br>
とか、箸にも棒にかからないくだらない「ネットの活動」をしています。</p>
<p><a href="http://twilog.org/tikuwa_ore/search?word=%E3%83%81%E3%83%A7%E3%83%B3&ao=a">http://twilog.org/tikuwa_ore/search?word=%E3%83%81%E3%83%A7%E3%83%B3&ao=a</a></p>
<blockquote>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
@fishmonger777 ネトウヨもネトサヨも、倭人も<strong>チョン</strong>も云えない世界なんてイヤじゃよ、オレは(笑)。 <br>
posted at 21:57:51</p>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
仮にも世界レベルの企業が、コンセプトアートとはいえパクリとかもうね。そんな事してるから<strong>チョンプギャーってバカにされんだっていい加減気付けよ</strong>、ホント。 <br>
posted at 22:53:09</p>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
どーでもいいけど、すべからくの使い方が間違ってる。このイルカアイコンの人の言を再現するなら、正しくは「外国人の開票参加に反対しない者はすべからく非国民であるがゆえに、チョン呼ばわりすべし」かな。 <a href="http://togetter.com/li/419348#c86392">http://togetter.com/li/419348#c86392</a>… <br>
posted at 11:38:17</p>
</blockquote>
<p>などと「チョン」を連呼したり、</p>
<blockquote>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
しかし先にも論じた通り、<strong>ヘイトスピーチ=即差別ではない。</strong>赤木氏の言は元中国籍の帰化人差別を公言した小野寺氏へのカウンターであり、因果応報を口にしたに過ぎない。 <br>
posted at 00:56:35</p>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
そもヘイトスピーチ云々ネット弁慶云々も、自分が気に食わない言論をヘイトスピーチと落とし込み、かつそれを使う対象をネット弁慶と定義する事で貶める、性質の悪い詭弁そのものですな。</p>
<p>ちくわ@だいぶヱロい@tikuwa_ore <br>
ヘイトスピーチというのは自らの意思で変えるのが極めて困難な個人の続柄や特徴をあげつらう事なので、難病患者を難病を理由にあげつらうのはヘイトだけど、バカにバカって云う単純な罵倒はヘイトじゃないぞ。そりゃただの侮辱だ。 <br>
posted at 11:59:41</p>
</blockquote>
<p>などと、ヘイトスピーカーが自己正当化するのによく見る、聞き飽きた俺様ロジックをばらまいていました。</p>
<p>最近はネット世界でも、ヘイトスピーチや、匿名の悪用性についての風当たりが強くなってきてるので、こういう生来のクズでもようやく道理も理解できるようになってしまい、ずいぶんと大人しくなって、どの口で言ってるのかわからないけど、そういう連中を批判するようなポーズを取りじめています。 <br>
<br>
それで長くなりましたが、要するに、</p>
<p>Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる</p>
<p>というのは、こういうクズを首謀とした、不正アクセス機器で発信元隠蔽して開示請求や、警察にバレないように、2ちゃんで犯罪書き込み続けている、いた、連中に、合流して恥ずべき真似をやらかしている、ってことなんですね。</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">490</span>:提督<span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) 08<span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">54.47</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:R/</span><span class="hljs-number">5</span>TOB1e.net [<span class="hljs-number">1</span>回目/全<span class="hljs-number">2</span>回]
ども、てーとくです。
今年もご支援ありがとう。
無職で有り余る時間のある彼ですが、年末のこの時期なので、まともに発言するはずもありません。
「忙しさアピール」にも余念がない事でしょう。
なので事実上、<span class="hljs-number">2015</span>年は逃亡のまま敗戦、という処理でかまわんでしよう。
気持ち良く年越し出きることを嬉しく思います。
来年も引き続き、レッツ毛いじり!!
<span class="hljs-number">496</span>: ◆<span class="hljs-constant">XiKWCqo0TU13</span> <span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">10</span><span class="hljs-symbol">:</span><span class="hljs-number">49.02</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:eE34tiRv</span>.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">2</span>回]
>><span class="hljs-number">490</span>
先日はどうもでした
良いお年を。来年は一人紹介しますので、これで晴れて<span class="hljs-number">8</span>人ですね!
<span class="hljs-number">501</span>:<span class="hljs-constant">BeastTadokoro</span><span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">14</span><span class="hljs-symbol">:</span><span class="hljs-number">31.20</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:/jEAfhOM</span>.net [<span class="hljs-number">1</span>回目/全<span class="hljs-number">2</span>回]
>><span class="hljs-number">490</span>
来年も力を合わせて頑張りましょう!レッツ毛イジリ!(笑い)
<span class="hljs-number">491</span>:提督<span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) 08<span class="hljs-symbol">:</span><span class="hljs-number">26</span><span class="hljs-symbol">:</span><span class="hljs-number">02</span>.<span class="hljs-number">25</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:R/</span><span class="hljs-number">5</span>TOB1e.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">2</span>回]
誰か新しいスレよろ
あっちの方ね。
<span class="hljs-number">498</span>:<span class="hljs-constant">Newbie</span>伊藤 ◆p02ZTYXhPKG5 <span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">25</span><span class="hljs-symbol">:</span><span class="hljs-number">26.41</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:vcolQJWW</span>.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">3</span>回]
>><span class="hljs-number">491</span>
すみません、こっちからは無理でした。
カマボコさん・<span class="hljs-constant">AIG</span>さんにお願いしときました。
そして、来年も宜しくお願いします!!!
</code></pre>
<p>というように、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">490</span>:提督<span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) 08<span class="hljs-symbol">:</span><span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">54.47</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:R/</span><span class="hljs-number">5</span>TOB1e.net [<span class="hljs-number">1</span>回目/全<span class="hljs-number">2</span>回]
ども、てーとくです。
今年もご支援ありがとう。
無職で有り余る時間のある彼ですが、年末のこの時期なので、まともに発言するはずもありません。
「忙しさアピール」にも余念がない事でしょう。
なので事実上、<span class="hljs-number">2015</span>年は逃亡のまま敗戦、という処理でかまわんでしよう。
気持ち良く年越し出きることを嬉しく思います。
来年も引き続き、レッツ毛いじり!!</code></pre>
<p>とか書いてるのが、チームを首謀するクズのちくわで間違いないが、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">496</span>: ◆<span class="hljs-constant">XiKWCqo0TU13</span> <span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">10</span><span class="hljs-symbol">:</span><span class="hljs-number">49.02</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:eE34tiRv</span>.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">2</span>回]
>><span class="hljs-number">490</span>
先日はどうもでした
良いお年を。来年は一人紹介しますので、これで晴れて<span class="hljs-number">8</span>人ですね!</code></pre>
<p>というのは、例の「ウィザード組」、「8賢者」のことだと推察できる。</p>
<blockquote>
<p>来年は一人紹介しますので、これで晴れて8人ですね!</p>
</blockquote>
<p>と8人に一人足りないらしいのは、流出した、</p>
<pre class="prettyprint"><code class=" hljs cs">
いかんせん、Qiita以降の奴しか知らないので、不慣れなところはレギュラーが極力、バックアップ願います。
<span class="hljs-number">8</span>賢枠 (暫定) <span class="hljs-number">2015</span>/<span class="hljs-number">10</span>/<span class="hljs-number">02</span>
・スキルハンターの鷹
・知の答弁人田中
・思考のゼロ除算ボレロ
・辣腕ギークのキャメル
・知のオーバーフロー加藤
・AIG(A-Jiro <span class="hljs-keyword">is</span> Guru)
・菅本・ザ・ストリートプログラマー
・(空席)
以上。 </code></pre>
<p>という情報と符号し、</p>
<p>このうちの、</p>
<p>・辣腕ギークのキャメル </p>
<p>っていうのは、さすがにすぐ、らくだの卯之助@camloebaのことだとわかる。 <br>
さすがにわかりやすすぎるので、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">166</span> :<span class="hljs-constant">Newbie</span>伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/08(火) <span class="hljs-number">18</span><span class="hljs-symbol">:</span><span class="hljs-number">14</span><span class="hljs-symbol">:</span><span class="hljs-number">35.11</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:TBndtfrq</span>
油断せず気を引き締めて参りましょう! </code></pre>
<p>とか下劣なAA貼り付けて喜んでる:Newbie伊藤 にしたもよう。</p>
<pre class="prettyprint"><code class=" hljs autohotkey"><span class="hljs-number">497</span>:Newbie伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span>:<span class="hljs-number">23</span>:<span class="hljs-number">39.50</span> ID:vcolQJWW.net
<span class="hljs-number">956</span> 仕様書無しさん <span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span>:<span class="hljs-number">05</span>:<span class="hljs-number">32.47</span>
田中がaskの仕様変更からものの数日で実用的なGUIアプリをHaskellで作成して公開していて草
<span class="hljs-label">http:</span>//tanakh.jp/posts/<span class="hljs-number">2015</span>-<span class="hljs-number">12</span>-<span class="hljs-number">20</span>-tomori-nao.html
<span class="hljs-number">499</span>:Newbie伊藤 ◆p02ZTYXhPKG5 :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span>:<span class="hljs-number">26</span>:<span class="hljs-number">12.92</span> ID:vcolQJWW.net
くらえ、素人!
<span class="hljs-label"> ,.-―: ̄`ー::::::::::</span>、
<span class="hljs-label"> /::::::::::::.::::::::::::::::::::::::::::`::</span>、、
<span class="hljs-label"> /::::::::::::::::::::::::::::::::::::::::::::::::::::::</span>`、
<span class="hljs-label"> l::::::::::::::::::::::::::::::::::::::::</span><span class="hljs-comment">;':l:::::::::::\::l </span>
<span class="hljs-label"> l:::::::::::::::::::::::::::::::::,,::::::::</span><span class="hljs-comment">;-,:,::::::::::::::::l </span>
<span class="hljs-label"> l::::::::::::::::,_,.::::</span>,'<span class="hljs-comment">;::::::;:::::: :: l ::::::::::::::l </span>
<span class="hljs-label"> l::::::::::/-/:::/-ニ,.::::/=,./::::::::::</span>l
<span class="hljs-label"> ヽ::::</span> ´、ひ> <span class="hljs-comment">;: l .<ひ>' 、::::::::/ </span>
<span class="hljs-label"> ヽ:::::  ̄ .)::</span><span class="hljs-comment">; l  ̄ l::::/ </span>
<span class="hljs-label"> 、:::::.. /:::</span><span class="hljs-comment">; .,-、 l:::/ </span>
<span class="hljs-label"> :::::: ゝヽ- ー' 、 l::</span>/
<span class="hljs-label"> ヽ:、::</span> / ,--、,-.、_ l /
<span class="hljs-label"> 、::</span>、 `ー ̄-' /
<span class="hljs-label"> ::</span>ヽ /
人 Y
( ヽ ノ
人 Y′
( ヽノ
人 Y′
( ヽノ
人 Y′
_( ヽノ、
,,.....イ.ヽく、人 Y ヽ--、
<span class="hljs-label"> :</span> | '<span class="hljs-comment">; \___ノ_ ノ| ヽ i </span>
| \/゙(__)\,| i |
> ヽ. ハ | ||
<span class="hljs-number">508</span>:島村卯月 ◆wK5afSYrKU :<span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">16</span>:<span class="hljs-number">06</span>:<span class="hljs-number">57.76</span> ID:<span class="hljs-number">5</span>+EuyxWv.net
>><span class="hljs-number">499</span>
メール致しました</code></pre>
<p>はて?:Newbie伊藤 ◆p02ZTYXhPKG5=らくだが嬉しそうに引用している</p>
<pre class="prettyprint"><code class=" hljs avrasm">田中がaskの仕様変更からものの数日で実用的なGUIアプリをHaskellで作成して公開していて草
<span class="hljs-label">http:</span>//tanakh<span class="hljs-preprocessor">.jp</span>/posts/<span class="hljs-number">2015</span>-<span class="hljs-number">12</span>-<span class="hljs-number">20</span>-tomori-nao<span class="hljs-preprocessor">.html</span></code></pre>
<p>ってなんだろう?とおもってリンクを開くと、</p>
<p>純粋関数空間: Home <br>
<a href="http://tanakh.jp/">http://tanakh.jp/</a> <br>
ここは田中英行(Hideyuki Tanaka, a.k.a tanakh)の個人ページです。 <br>
(@tanakh)</p>
<p>ってのがでてくる。誰これ?</p>
<p>ともかく犯罪者集団に合流した「ウィザード組」「8賢者」のひとり、</p>
<p>・知の答弁人田中 </p>
<p>っていうのは、この田中のことなのでしょう。あんまり覚えてないけど、 <br>
表で堂々と議論を展開することなく、2chで匿名でしょーもない「コードネーム」もらって喜んで書き込むとかかなりうっとうしいですねー。 <br>
というか、そのブログの写真</p>
<p><img src="http://tanakh.jp/img/me-ss.jpg" alt="enter image description here" title=""></p>
<p>いま見て思い出しましたが、やはりQiitaの記事になんかいちゃもんつけてきて、私が記事に引用して批判した覚えが有ります。それを根に持って、根に持っているだろうと粘着して観察していた犯罪者集団がリクルートしたのか。ほんとしょーもないですね。 <br>
知らんよ。こちらに批判されたって、さきに殴ってきたのはおまえだろ? <br>
犯罪者集団に「8賢者」とか持ち上げられて、影でこそこそ馴れ合って馬鹿か?恥をしれよ。</p>
<p>島村卯月 ◆wK5afSYrKUっていうのは、 <br>
フリーダム宇月 ◆wK5afSYrKU という、ハッシュタグも一致する「うづき」=佐々木俊尚のことなので、 <br>
佐々木氏は、Newbie伊藤=らくだの卯之助@camloebaへメールを送っていると。しょーもないですねー。</p>
<p>あとやたら、不用意に例のごとく</p>
<pre class="prettyprint"><code class=" hljs ">昨日より佐々木さんも参戦いただきました。
業務連絡 ちくわ殿、牟田殿、佐々木さんのレッドマインのアカウントの手配をお願いします</code></pre>
<p>とかベラベラとリクルートの「内部情報」を書きまくる、天然のダンディー山田 ◆6NdDvH3KR2 が、</p>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">980</span>:ダンディー山田 ◆<span class="hljs-number">6</span>NdDvH3KR2 <span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">29</span>(火) <span class="hljs-number">15</span><span class="hljs-symbol">:</span><span class="hljs-number">31</span><span class="hljs-symbol">:</span><span class="hljs-number">14.28</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:fdUZvWn6</span>.net [<span class="hljs-number">4</span>回目/全<span class="hljs-number">6</span>回]
スレ立て乙です!<span class="hljs-constant">AIG</span>さんか野田さんですか?
野田さん、なんで今年は来なかったんでっしゃろ?来年もよろしゅうに!!</code></pre>
<p>とか、「AIGさん」とかずっと書いてるんですね。 <br>
これ天然なんで、裏工作もなんもない事実です。 <br>
AIGという新参者が間違いなく、こういうしょーもない連中による2chの中傷誹謗スレを作成する作業に加担している。</p>
<p>他にもこういう書き込みがある。</p>
<pre class="prettyprint"><code class=" hljs ruby">
<span class="hljs-number">502</span>:<span class="hljs-constant">BeastTadokoro</span><span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">13</span><span class="hljs-symbol">:</span><span class="hljs-number">18</span><span class="hljs-symbol">:</span><span class="hljs-number">00</span>.<span class="hljs-number">76</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:/jEAfhOM</span>.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">2</span>回]
尚、<span class="hljs-constant">Qiita</span>は年末の特別フォーメーションで監視しますが、
基本、レギュラーは待機で結構です。
私と遠野・ランバダ・ゴサク・東雲・<span class="hljs-constant">AIG</span>だけでわまします。</code></pre>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-number">491</span>:提督<span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) 08<span class="hljs-symbol">:</span><span class="hljs-number">26</span><span class="hljs-symbol">:</span><span class="hljs-number">02</span>.<span class="hljs-number">25</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:R/</span><span class="hljs-number">5</span>TOB1e.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">2</span>回]
誰か新しいスレよろ
あっちの方ね。
<span class="hljs-number">498</span>:<span class="hljs-constant">Newbie</span>伊藤 ◆p02ZTYXhPKG5 <span class="hljs-symbol">:</span><span class="hljs-number">2015</span>/<span class="hljs-number">12</span>/<span class="hljs-number">26</span>(土) <span class="hljs-number">12</span><span class="hljs-symbol">:</span><span class="hljs-number">25</span><span class="hljs-symbol">:</span><span class="hljs-number">26.41</span> <span class="hljs-constant">ID</span><span class="hljs-symbol">:vcolQJWW</span>.net [<span class="hljs-number">2</span>回目/全<span class="hljs-number">3</span>回]
>><span class="hljs-number">491</span>
すみません、こっちからは無理でした。
カマボコさん・<span class="hljs-constant">AIG</span>さんにお願いしときました。
そして、来年も宜しくお願いします!!!</code></pre>
<p>クズのちくわ2tikuwa_zero=提督に、「そして、来年も宜しくお願いします!!!」とか言ってる、 <br>
Newbie伊藤 ◆p02ZTYXhPKG5==らくだの卯之助@camloebaも、 <br>
「AIGさんにお願いしときました。」とか符号する書き込みをしている。</p>
<p>さてここで、問題は、このQiiita経由らしい新参者のAIGとは誰か? <br>
ということになります。</p>
<p>もちろん、彼らは、もれなく私とどこかでやりとりしたことがあり、私と反目して、なんらかの怨恨をもっており、こういう愚かな行動をやらかすと犯罪者集団が自分等に合流してくれるだろうと値踏みをした人物です。</p>
<p>AIGは私が知ってる誰かなんですね。さっきの、 <br>
知の答弁人田中 = 田中英行 @tanakh みたいに。</p>
<p>それで、</p>
<p>・AIG(A-Jiro is Guru) </p>
<p>ってのは誰か?ああ、AIGっていうのは、 <br>
A-Jiro is Guruのことだったのかと、私にバレる。</p>
<p>おもいつくひと?一人しかいません。 <br>
東北大学の住井 英二郎@esumiiです。</p>
<p>Guruっていうのは、おれたち犯罪者集団のグルだってことと、 <br>
ソフトウェアのGURUってのをかけたつもりなんでしょう。 <br>
こういう言葉遊びがクズのちくわの唯一の取り柄です。</p>
<p>ああ、以上の私の推察、あるいは断定主観について、文句のある反論がある、 <br>
ここで名前出された当事者は、 <br>
kenokabe@gmail.com までどうぞ。 <br>
きちんとこの記事にそれを掲載して議論します。</p>
<p>今回はこういうしょうもない告発文ですみません。 <br>
あああと私はこいつらの妄想中傷設定では、 <br>
「FRPを理解していない」ということにされているようです(笑) <br>
まあ、事実なんてどうでもよくて、とにかく当方を蔑む評価をくだせれば、それで連中の目標達成なんで、そういう設定なんでしょう。毎度わかりやすい行動原則ですよね。。 <br>
最近、 <br>
自作FRPライブラリTimeEngineをブラッシュアップして <br>
<a href="http://timeengine.github.io/">http://timeengine.github.io/</a> <br>
を公開しました。 <br>
次回は、その日本語訳、 <br>
Reactの応用技術、あるいはReact再入門についての記事をUPしますのでお楽しみに!</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-3672152692905888002015-12-11T18:27:00.001+09:002015-12-11T18:44:29.583+09:002016年のnode、ES6、React、Babel、Atomエディタ界隈の方向性<p>この半年で、node、ES6、React、Babel、Atomエディタ界隈に結構な変化があり、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/08/javascriptes6react-jsxes5-atom-3-32015.html">JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン</a> <br>
で紹介したAtomエディタの環境構築の方法で、いま自身の環境をアップデートするにやると普通にコケてしまう、いろいろ不具合が出るので更新。</p>
<p>ES、JSXトランスパイラのデファクトスタンダードである<a href="https://discuss.babeljs.io">Babel公式サイトの掲示板</a>で、Babel開発者とやりとりした情報をベースに自分自身忘れないようにメモを兼ねて情報共有しておきます。</p>
<p><a href="https://discuss.babeljs.io/t/error-parsing-jsx-with-global-installation-babel-preset-react/59">https://discuss.babeljs.io/t/error-parsing-jsx-with-global-installation-babel-preset-react/59</a></p>
<h2 id="javascriptは本格的にecmascript-6es6へ移行した">JavaScriptは本格的にECMASCript 6(ES6)へ移行した</h2>
<p>実際使い込めば使い込むほどES6は強力。</p>
<p>2013年に、 <br>
<a href="http://www.infoq.com/jp/news/2013/04/Language-Expressiveness">調査: もっとも表現力に富んだ汎用プログラム言語は Clojure,CoffeeScript,Haskell</a>というのがあった。</p>
<blockquote>
<p>CoffeeScript (#6) は JavaScript (#51) よりもはるかに高い表現力を示している。事実上,すべての言語の中での最高値である。</p>
<p>一貫性においても CoffeeScript が変わらず No.1 であるが,4番目の Clojure と比較した IQR (interquartile range,,四分位範囲) の差異はわずか23LOC/コミットに過ぎない。</p>
</blockquote>
<p>というように、CoffeeScriptの表現力はプログラム言語の中でも際立っており、素のJavaScriptは比較すると随分と劣っていた。</p>
<p>しかしそのJavaScriptもまさにそのCoffeeScriptが獲得していた表現力を吸収するようにES6となり、標準化は正義ということで、CoffeeScriptの役割は終わったように思う。 <br>
JavaScriptはES6になり、もっとも表現力の高い言語に進化したと言っても過言でないと思うし、実際コーディングしていて関数型プログラミングの特性が発揮するように表現力が高まった実感がある。</p>
<p>以下、 <br>
Trending repositories <br>
<a href="https://github.com/trending?l=javascript&since=monthly">https://github.com/trending?l=javascript&since=monthly</a> <br>
のトレンドも踏まえる。</p>
<h2 id="nodejs">Node.js</h2>
<p> <br>
Node.jsの運営問題による開発の遅れから分裂していたio.jsはめでたく、Node.jsの体制を修正しながら本家に再統合。 <br>
Node v4.0.0となり、 <br>
矢継ぎ早に、Node v5.0.0のラインもリリースされた。</p>
<p><a href="https://osdn.jp/magazine/15/09/11/070600">io.jsをマージ、ES6サポートを実現した「Node.js 4.0」リリース</a></p>
<p><a href="https://nodejs.org/en/docs/es6/">https://nodejs.org/en/docs/es6/</a></p>
<p>ようやく、NodeでもECMASCript 6(ES6)が本格的にサポート開始。</p>
<p>つけくわえておくと、 <br>
<a href="https://github.com/Automattic/wp-calypso">https://github.com/Automattic/wp-calypso</a> <br>
というプロジェクトもトレンドにあるが、 <br>
Calypso is the new WordPress.com front-end <br>
ということで、WordPressのコンテンツエンジンもPHPからNodeベースになるのか、なったのか詳しいことはまったく調べていないので、あまり良く知らない。</p>
<h2 id="reactはdomと分離された">ReactはDOMと分離された</h2>
<p>ReactはあいかわらずクライアントサイドのUIで確固たる位置を占めており勢力を拡大しているように見える。</p>
<p>Reactは、もはやHTML専用のUIエンジンではない、ということで、 <br>
React DOMは本体Reactから分離された。</p>
<p><a href="http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html">http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html</a></p>
<p>React has nothing to do with browsers or the DOM. <br>
ReactはブラウザともDOMとも関係ない</p>
<blockquote>
<h3 id="major-changes">Major changes</h3>
<p>Two Packages: React and React DOM <br>
As we look at packages like react-native, react-art, react-canvas, and react-three, it has become clear that the beauty and essence of React has nothing to do with browsers or the DOM.</p>
<p>To make this more clear and to make it easier to build more environments that React can render to, we’re splitting the main react package into two: react and react-dom. This paves the way to writing components that can be shared between the web version of React and React Native. We don’t expect all the code in an app to be shared, but we want to be able to share the components that do behave the same across platforms.</p>
</blockquote>
<p>つまり、2014-2015年に、一部、日本国内で、Reactとは仮想DOMのことである、というような喧伝がなされていたが、実は仮想DOMは本質ではなく、DOMが仮想化されている大元となる理由、コンポーネント指向、至高、つまりUIがオブジェクト指向ではなく関数型プログラミングを体現していることがより明確になった。</p>
<p>Functional Stateless Components in React 0.14 <br>
<a href="https://medium.com/@joshblack/stateless-components-in-react-0-14-f9798f8b992d#.nsecgw6kw">https://medium.com/@joshblack/stateless-components-in-react-0-14-f9798f8b992d#.nsecgw6kw</a></p>
<h2 id="react-native">React Native</h2>
<p><a href="http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html">http://facebook.github.io/react/blog/2015/10/07/react-v0.14.html</a></p>
<blockquote>
<p>This paves the way to writing components that can be shared between the web version of React <br>
and React Native. </p>
</blockquote>
<p>とあるように、背景にはやはりReact Nativeの存在が大きい。</p>
<p><a href="https://github.com/facebook/react-native">https://github.com/facebook/react-native</a></p>
<p>ReactNativeは以前から存在していたが、iOSのみサポートしており、今や世界のスマホOSのマジョリティであるAndroidがサポートされていなかった。Reactバージョン0.14でDOMとの分離の方向性が打ち出されるとほぼ同時期に、Androidのサポートもリリースされて、今後スマホのUI開発でもReactのコンポーネント指向(関数型)も本格化すると思われる。 <br>
<br>
Reactで書かれたUIコードは、 <br>
Webブラウザでは、ReactDOM <br>
スマホでは、ReactNative <br>
に接続され、共用できる。</p>
<h2 id="babel">Babel</h2>
<p>Nodeが、ES6を本格的にサポート開始したことにより、ES6+→ES5トランスパイラであるBabelのJavaScript世界における重要性は薄まったが、</p>
<p>1 JavaScript世界のUIデファクトであるReactの言語JSXを広範なブラウザで稼働するES5へのトランスパイラするにために、FacebookはBabelプロジェクトに依存する方針を明確にしており(<a href="%28http://kenokabe-techwriting.blogspot.jp/2015/08/javascriptes6react-jsxes5-atom-3-32015.html%29">前回記事</a>参照)、Reactクライアントサイドをトランスパイルする為には、今後も末永くBabelは必須。</p>
<p>2 NodeのES6+対応はまだまだ発展途上。ES6で有用な仕様に開発途上オプションフラグを指定しなければいけないなど未熟。それに比べてBabelは現行、ES6+の対応度に勝る。 <br>
<a href="https://kangax.github.io/compat-table/es6/">https://kangax.github.io/compat-table/es6/</a></p>
<p>1,2より、Babelは今後もデファクトのトランスパイラとして活躍し、JSコミュニティ(Facebook/React含む)から幅広い支持がありそうな状況。 <br>
ボトムラインとして、事実、これまでNodeはio.jsと分裂したり、大元のV8エンジンのES6対応が遅々として進んでないようだったり大きな問題があった。それに比較してBabelプロジェクトはフットワークが軽く対応が早く、この2015年に、JavaScriptコミュニティがES6への移行することを強く後押した功績も大きいと思う。</p>
<h2 id="babelとnpmのプロジェクトローカル指向">Babelとnpmのプロジェクトローカル指向</h2>
<p>近頃、Nodeのパッケージマネージメントシステムであるnpmは3系に、Babelは6系にメジャーバージョンアップした。</p>
<p>npmも、Babelプロジェクトも、パッケージ依存は、Babelのようなツールも含めてプロジェクトローカルに分離独立させておくべきだ、という方針を強めている。</p>
<p>これはJavaScript、Node世界が、洗練された形で進化する過程で不可避に複雑化されて、必要なツールが増えてくると、各ツールとプロジェクトのバージョンの整合性が問題となってくる。</p>
<p>これまで多くの場合、ツールは、<code>npm install -g</code> などとし、ツールはグローバルにインストール、各プロジェクトから共用する、という発想だったのが、もうその方向性では行き詰まるので、各プロジェクトローカルにそれぞれ専用のバージョンでインストールしよう、という方向性になっている。</p>
<p>もちろん各パッケージにいちいち巨大なツールを含有していたら、複数のnpmパッケージに依存するプロジェクト全体がとんでもないことになるのだが、npmにはdevDependenciesという仕組みで、パッケージ配布時には自動ではインストールされることがない開発モードの依存パッケージという秀逸な仕組みがあるので、それでうまく整理できる。</p>
<p>しかしこれまでいまいち意味がよくわからなかったのが、 <br>
Babelの公式サイトのドキュメントで、</p>
<p><a href="http://babeljs.io/docs/setup/#babel_cli">http://babeljs.io/docs/setup/#babel_cli</a> <br>
<br>
Installation</p>
<pre class="prettyprint"><code class=" hljs lasso">$ npm install <span class="hljs-attribute">-g</span> babel<span class="hljs-attribute">-cli</span></code></pre>
<p>とあくまでグローバルインストールを公式に推奨しているように見えた。</p>
<p>しかし、Babel6系にアップデートした上で、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/08/javascriptes6react-jsxes5-atom-3-32015.html">JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン</a> <br>
のとおり、環境構築をしていくと、BabelのJSXのトランスパイルでエラーがでてコケる。</p>
<p>どうしようもないので、 <br>
<a href="https://discuss.babeljs.io">Babel公式サイトの掲示板</a>で質問してみたところ、 <br>
<a href="https://discuss.babeljs.io/t/error-parsing-jsx-with-global-installation-babel-preset-react/59">https://discuss.babeljs.io/t/error-parsing-jsx-with-global-installation-babel-preset-react/59</a></p>
<p>この理由は結局、そもそも公式ドキュメントのSetupにしたがってBabelをグローバルにインストールするのが間違いで、プロジェクトローカルに、</p>
<pre class="prettyprint"><code class=" hljs lasso">$ npm install <span class="hljs-subst">--</span>save<span class="hljs-attribute">-dev</span> babel<span class="hljs-attribute">-cli</span></code></pre>
<p>とdevDependenciesとしてインストールすべきである、Babelプロジェクト開発者はそういう方針である、ということがわかった。ドキュメントと方針に齟齬があるのは、今現在ドキュメントを大改定中であり、まだ追いついていないということ。</p>
<blockquote>
<p>thejameskyle</p>
<p>I’ve been wanting to update the documentation to say otherwise. I just haven’t gotten to it (I’m busy writing the babel handbook right now which does teach people to install locally).</p>
<p>Again, I want to, but I also want to rewrite most of the documentation, a lot of which is in progress.</p>
</blockquote>
<h2 id="結局よほどのことがない限り原則ツールも各プロジェクトローカルにdevdependenciesとしてインストールしてしまう">結局、よほどのことがない限り、原則、ツールも各プロジェクトローカルにdevDependenciesとしてインストールしてしまう</h2>
<pre class="prettyprint"><code class=" hljs lasso">$ npm install <span class="hljs-subst">--</span>save<span class="hljs-attribute">-dev</span> eslint babel<span class="hljs-attribute">-cli</span> babel<span class="hljs-attribute">-preset</span><span class="hljs-attribute">-es2015</span> babel<span class="hljs-attribute">-preset</span><span class="hljs-attribute">-react</span> webpack</code></pre>
<p>などとし、結果、たとえば公開している自作npmパッケージ<code>timeengine</code></p>
<p><a href="https://www.npmjs.com/package/timeengine">https://www.npmjs.com/package/timeengine</a> <br>
<a href="https://github.com/kenokabe/timeengine">https://github.com/kenokabe/timeengine</a></p>
<p>では、</p>
<p><a href="https://github.com/kenokabe/timeengine/blob/master/package.json">https://github.com/kenokabe/timeengine/blob/master/package.json</a></p>
<pre class="prettyprint"><code class=" hljs json">{
"<span class="hljs-attribute">name</span>": <span class="hljs-value"><span class="hljs-string">"timeengine"</span></span>,
"<span class="hljs-attribute">version</span>": <span class="hljs-value"><span class="hljs-string">"4.6.0"</span></span>,
"<span class="hljs-attribute">description</span>": <span class="hljs-value"><span class="hljs-string">"Time Engine is the True Functional Reactive Programming Library from the Point of View of Physics, our World and Time"</span></span>,
"<span class="hljs-attribute">main</span>": <span class="hljs-value"><span class="hljs-string">"timeengine.js"</span></span>,
"<span class="hljs-attribute">scripts</span>": <span class="hljs-value">{
"<span class="hljs-attribute">test</span>": <span class="hljs-value"><span class="hljs-string">"babel timeengine.es -o timeengine.js; babel-node test.js"</span>
</span>}</span>,
"<span class="hljs-attribute">devDependencies</span>": <span class="hljs-value">{
"<span class="hljs-attribute">babel-cli</span>": <span class="hljs-value"><span class="hljs-string">"^6.3.15"</span></span>,
"<span class="hljs-attribute">babel-preset-es2015</span>": <span class="hljs-value"><span class="hljs-string">"^6.3.13"</span></span>,
"<span class="hljs-attribute">babel-preset-react</span>": <span class="hljs-value"><span class="hljs-string">"^6.3.13"</span></span>,
"<span class="hljs-attribute">eslint</span>": <span class="hljs-value"><span class="hljs-string">"^1.10.3"</span></span>,
"<span class="hljs-attribute">immutable</span>": <span class="hljs-value"><span class="hljs-string">"*"</span>
</span>}</span>,
"<span class="hljs-attribute">repository</span>": <span class="hljs-value">{
"<span class="hljs-attribute">type</span>": <span class="hljs-value"><span class="hljs-string">"git"</span></span>,
"<span class="hljs-attribute">url</span>": <span class="hljs-value"><span class="hljs-string">"git+https://github.com/kenokabe/timeengine.git"</span>
</span>}</span>,
"<span class="hljs-attribute">keywords</span>": <span class="hljs-value">[
<span class="hljs-string">"FRP"</span>,
<span class="hljs-string">"functional"</span>,
<span class="hljs-string">"reactive"</span>,
<span class="hljs-string">"time"</span>,
<span class="hljs-string">"physics"</span>,
<span class="hljs-string">"mathematics"</span>,
<span class="hljs-string">"stream"</span>,
<span class="hljs-string">"sequence"</span>,
<span class="hljs-string">"event"</span>
]</span>,
"<span class="hljs-attribute">author</span>": <span class="hljs-value"><span class="hljs-string">"Ken Okabe"</span></span>,
"<span class="hljs-attribute">license</span>": <span class="hljs-value"><span class="hljs-string">"MIT"</span></span>,
"<span class="hljs-attribute">bugs</span>": <span class="hljs-value">{
"<span class="hljs-attribute">url</span>": <span class="hljs-value"><span class="hljs-string">"https://github.com/kenokabe/timeengine/issues"</span>
</span>}</span>,
"<span class="hljs-attribute">homepage</span>": <span class="hljs-value"><span class="hljs-string">"https://github.com/kenokabe/timeengine#readme"</span>
</span>}</code></pre>
<p>と、以下抜粋するように、<code>devDependencies</code>として開発ツールをプロジェクトローカルにインストールしてしまうのが最終的な方針と解決策である。</p>
<pre class="prettyprint"><code class=" hljs bash"> <span class="hljs-string">"devDependencies"</span>: {
<span class="hljs-string">"babel-cli"</span>: <span class="hljs-string">"^6.3.15"</span>,
<span class="hljs-string">"babel-preset-es2015"</span>: <span class="hljs-string">"^6.3.13"</span>,
<span class="hljs-string">"babel-preset-react"</span>: <span class="hljs-string">"^6.3.13"</span>,
<span class="hljs-string">"eslint"</span>: <span class="hljs-string">"^1.10.3"</span>,
<span class="hljs-string">"immutable"</span>: <span class="hljs-string">"*"</span>
},</code></pre>
<p>この際、</p>
<p><code>babel</code>コマンドは、プロジェクトローカルの <br>
<code>./node_modules/.bin</code> にインストールされる。</p>
<p>グローバルでインストールしていたときのように、コマンド単体のパスは通っておらず、以上の相対パスをいちいち叩くのは骨が折れ現実的ではにないので、シェルの初期設定に、</p>
<p>.zshrc</p>
<pre class="prettyprint"><code class=" hljs bash"><span class="hljs-keyword">export</span> PATH=<span class="hljs-variable">$PATH</span>:./node_modules/.bin</code></pre>
<p>などとしておけば良い。</p>
<h2 id="その他">その他</h2>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/08/javascriptes6react-jsxes5-atom-3-32015.html">JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン</a></p>
<p>で示した、</p>
<blockquote>
<p>.eslintrcというESLint設定ファイルに以下の内容をコピペし、ホームディレクトリ直下に新規作成します。</p>
</blockquote>
<pre class="prettyprint"><code class=" hljs json">{
"<span class="hljs-attribute">parser</span>": <span class="hljs-value"><span class="hljs-string">"babel-eslint"</span></span>,
"<span class="hljs-attribute">env</span>": <span class="hljs-value">{
"<span class="hljs-attribute">es6</span>": <span class="hljs-value"><span class="hljs-literal">true</span></span>,
"<span class="hljs-attribute">node</span>": <span class="hljs-value"><span class="hljs-literal">true</span></span>,
"<span class="hljs-attribute">browser</span>": <span class="hljs-value"><span class="hljs-literal">true</span>
</span>}</span>,
"<span class="hljs-attribute">rules</span>": <span class="hljs-value">{
"<span class="hljs-attribute">semi</span>": <span class="hljs-value">[<span class="hljs-number">2</span>, <span class="hljs-string">"always"</span>]</span>,
"<span class="hljs-attribute">strict</span>": <span class="hljs-value"><span class="hljs-number">1</span></span>,
"<span class="hljs-attribute">no-undef</span>" : <span class="hljs-value"><span class="hljs-number">2</span>
</span>}
</span>}</code></pre>
<p>というのは、グローバルでなくプロジェクトローカルにまとめる方針になるので以下のように更新。</p>
<p><a href="https://github.com/kenokabe/timeengine">https://github.com/kenokabe/timeengine</a> <br>
のとおり、</p>
<p>.babelrc <br>
.eslintrc <br>
ともに、プロジェクトローカルのファイル郡に含めてしまう。</p>
<p><a href="https://github.com/kenokabe/timeengine/blob/master/.babelrc">https://github.com/kenokabe/timeengine/blob/master/.babelrc</a></p>
<pre class="prettyprint"><code class=" hljs json">{
"<span class="hljs-attribute">presets</span>": <span class="hljs-value">[<span class="hljs-string">"es2015"</span>,<span class="hljs-string">"react"</span>]
</span>}</code></pre>
<p><a href="https://github.com/kenokabe/timeengine/blob/master/.eslintrc">https://github.com/kenokabe/timeengine/blob/master/.eslintrc</a></p>
<pre class="prettyprint"><code class=" hljs json">{
"<span class="hljs-attribute">env</span>": <span class="hljs-value">{
"<span class="hljs-attribute">es6</span>": <span class="hljs-value"><span class="hljs-literal">true</span></span>,
"<span class="hljs-attribute">node</span>": <span class="hljs-value"><span class="hljs-literal">true</span></span>,
"<span class="hljs-attribute">browser</span>": <span class="hljs-value"><span class="hljs-literal">true</span>
</span>}</span>,
"<span class="hljs-attribute">ecmaFeatures</span>": <span class="hljs-value">{
"<span class="hljs-attribute">jsx</span>": <span class="hljs-value"><span class="hljs-literal">true</span>
</span>}</span>,
"<span class="hljs-attribute">rules</span>": <span class="hljs-value">{
"<span class="hljs-attribute">semi</span>": <span class="hljs-value">[<span class="hljs-number">1</span>, <span class="hljs-string">"always"</span>]</span>,
"<span class="hljs-attribute">strict</span>": <span class="hljs-value">[<span class="hljs-number">2</span>, <span class="hljs-string">"function"</span>]</span>,
"<span class="hljs-attribute">no-undef</span>" : <span class="hljs-value"><span class="hljs-number">2</span>
</span>}
</span>}</code></pre>
<p>以上のような設定では、前回のように</p>
<p><a href="https://github.com/babel/babel-eslint">babel-eslint</a>をインストールすることは不要となった。</p>
<h2 id="atomエディタ">Atomエディタ</h2>
<p>Atomのプラグインは、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/08/javascriptes6react-jsxes5-atom-3-32015.html">JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン</a></p>
<p>と同じ。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-18691857178951327162015-08-21T03:37:00.001+09:002015-08-21T03:41:56.772+09:00加速するJavaScript開発界隈 今、注目を集めるGitHubレポ・ npm ライブラリ 5選<p>筆者も時折、npmライブラリを公開していますが、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/08/timeengine-frp.html">timeengine / Time Engine FRP ( Functional Reactive Programming / 関数型リアクティブ プログラミング) npmライブラリの公開</a></p>
<p><a href="https://www.npmjs.com/package/timeengine">https://www.npmjs.com/package/timeengine</a></p>
<h2 id="今npmnodejsの公開ライブラリ数が加速的に増加しており物凄いことになっています">今、npm(node.js)の公開ライブラリ数が加速的に増加しており、物凄いことになっています。</h2>
<p><img src="http://codezine.jp/static/images/article/8706/8706_001.gif" alt="" title=""></p>
<p><a href="http://codezine.jp/article/detail/8706">CodeZine Node.js/JavaScriptの情報収集手段 ~変化が激しいOSSは、直接GitHubをウォッチする</a>より引用</p>
<p>だいたいこのグラフで見ると、1年で2倍になっており、文字通り、指数関数的に増加している様相です。</p>
<p>また、ここ数年、GitHubでホストされているプロジェクトの言語でJavaScriptが1位です。</p>
<p><img src="https://cloud.githubusercontent.com/assets/2623954/9098640/f15e22b4-3b7f-11e5-9496-12b6d811f0ea.jpg" alt="" title=""></p>
<p>ここ最近、注目を集めているnpmライブラリ、GitHubに公開されているプロジェクトを示します。</p>
<h2 id="jaws-the-server-less-stack">JAWS: The Server-less Stack</h2>
<p><img src="https://camo.githubusercontent.com/0f9a88f0b1a2ff2b5344a7726cb60d1f55ec9cd2/68747470733a2f2f73657276616e742d6173736574732e73332e616d617a6f6e6177732e636f6d2f696d672f6a6177735f6c6f676f5f76312e706e67" alt="" title=""></p>
<p><a href="https://github.com/jaws-stack/JAWS">https://github.com/jaws-stack/JAWS</a></p>
<p>今GitHub@JavaScript界隈で一番注目されているプロジェクト。 <br>
著書でもちらっと触れた、関数型クラウドサービス、 Amazon Web Services Lambda Functionsを利用したアプリケーションスタック。</p>
<p><img src="https://github.com/servant-app/JAWS/raw/master/site/public/img/jaws_diagram_javascript_aws.png" alt="" title=""></p>
<p>JavaScriptで関数型プログラミングやるのがそもそも適していない、などなど一部国内の界隈で眠いことを言う方々を尻目に、Amazonクラウド環境でホストされるJavaScriptの関数のみをコールしてWebアプリケーションのバックエンドを構築するという次世代アプリケーションスタック。</p>
<h3 id="goals">Goals:</h3>
<ul>
<li><strong>Use No Servers:</strong> Never deal with scaling/deploying/maintaining/monitoring servers again.</li>
<li><strong>Isolated Components:</strong> The JAWS back-end is comprised entirely of AWS Lambda Functions. You can develop/update/configure each separately without affecting any other part of your application. Your app never goes down… only individual API routes can go down.</li>
<li><strong>Scale Infinitely:</strong> A back-end comprised of Lambda functions comes with a ton of concurrency and you can easily enable multi-region redundancy.</li>
<li><strong>Be Cheap As Possible:</strong> Lambda functions run only when they are called, and you only pay for when they are run.</li>
</ul>
<p>ということで、</p>
<p>とにかくクラウドでもなんでも自サーバーを保持しないので、いろんな面倒から解放される(はず)だ、</p>
<p>とにかく隔離されたコンポーネントだ、関数型のAWSラムダ関数だ、サーバーはないので落ちることはない、</p>
<p>無限にスケールする、マルチリージョンのコンカレントの関数だ、</p>
<p>関数コール分の従量制課金なので、コスパ最強のはずだ、</p>
<p>という、まさに次世代クラウドコンピューティング全開のWebアプリケーションの未来像が提示されています。</p>
<p>個人的には、まだ時期尚早、というか時間が加速しているので、そのうちすぐ検討しなければいけないのかな、という予感もありますが、今のところはAzureクラウドで快適なので、やはり人柱になるには現在の時間スケールで早熟すぎるという印象で、正直まだ面倒臭い感じがします。ただ時流に乗りまくってるビジョナリー、パイオニア達が一定数存在しており、やはり時間が加速している雰囲気をひしひしと感じています。</p>
<h2 id="dragula">dragula</h2>
<p><img src="https://github.com/bevacqua/dragula/raw/master/resources/logo.png" alt="" title=""></p>
<p><a href="http://bevacqua.github.io/dragula/">http://bevacqua.github.io/dragula/</a></p>
<p>GoogleKeepみたいな軽快なドラッグUIのライブラリ <br>
ドラッグとドラキュラでドラグラというネーミング。</p>
<p><img src="https://github.com/bevacqua/dragula/raw/master/resources/demo.png" alt="" title=""></p>
<p>オフィシャルのReactコンポーネントのブリッジもある。</p>
<p><a href="https://github.com/bevacqua/react-dragula">https://github.com/bevacqua/react-dragula</a></p>
<p>Reactはすでに業界標準。これは普通に使える。</p>
<h2 id="algebrajs">algebra.js</h2>
<p><a href="http://algebra.js.org/">http://algebra.js.org/</a> <br>
<a href="https://github.com/nicolewhite/algebra.js">https://github.com/nicolewhite/algebra.js</a></p>
<p>Build, display, and solve algebraic equations in JavaScript.</p>
<p>代数の方程式を書いたり、LaTeX表示にも対応して表示したり、解くライブラリ。</p>
<p>Mathematicaみたいな大掛かりなものでなく、こういう基本的で簡潔なライブラリは今後何気に重宝しそう、と個人的に思いました。</p>
<h2 id="professor-frisbys-mostly-adequate-guide-to-functional-programming">Professor Frisby’s Mostly Adequate Guide to Functional Programming</h2>
<p><img src="https://github.com/DrBoolean/mostly-adequate-guide/raw/master/images/cover.png" alt="" title=""></p>
<p><a href="https://github.com/DrBoolean/mostly-adequate-guide">https://github.com/DrBoolean/mostly-adequate-guide</a></p>
<p>JavaScriptの関数型プログラミング教本。</p>
<p>GitHubはもはやコードのプロジェクトだけではなく、書籍(Eブック)の発表の場としても活用されている。</p>
<h3 id="summary">Summary</h3>
<ul>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch1.md">Chapter 1: What ever are we doing?</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch1.md#introductions">Introductions</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch1.md#a-brief-encounter">A brief encounter</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch2.md">Chapter 2: First Class Functions</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch2.md#a-quick-review">A quick review</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch2.md#why-favor-first-class">Why favor first class?</a></li></ul></li>
<li><a href="ch3.md">Chapter 3: Pure Happiness with Pure Functions</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch3.md#oh-to-be-pure-again">Oh to be pure again</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch3.md#side-effects-may-include">Side effects may include…</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch3.md#8th-grade-math">8th grade math</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch3.md#the-case-for-purity">The case for purity</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch3.md#in-summary">In Summary</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch4.md">Chapter 4: Currying</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch4.md#cant-live-if-livin-is-without-you">Can’t live if livin’ is without you</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch4.md#more-than-a-pun--special-sauce">More than a pun / Special sauce</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch4.md#in-summary">In Summary</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch5.md">Chapter 5: Coding by Composing</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch5.md#functional-husbandry">Functional Husbandry</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch5.md#pointfree">Pointfree</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch5.md#debugging">Debugging</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch5.md#category-theory">Category Theory</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch5.md#in-summary">In Summary</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch6.md">Chapter 6: Example Application</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch6.md#declarative-coding">Declarative Coding</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch6.md#a-flickr-of-functional-programming">A flickr of functional programming</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch6.md#a-principled-refactor">A Principled Refactor</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch6.md#in-summary">In Summary</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch7.md">Chapter 7: Hindley-Milner and Me</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch7.md#whats-your-type">What’s your type?</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch7.md#tales-from-cryptic">Tales from the cryptic</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch7.md#narrowing-the-possibility">Narrowing the possibility</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch7.md#free-as-in-theorem">Free as in theorem</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch7.md#in-summary">In Summary</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md">Chapter 8: Tupperware</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#the-mighty-container">The Mighty Container</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#my-first-functor">My First Functor</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#schrodingers-maybe">Schrödinger’s Maybe</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#pure-error-handling">Pure Error Handling</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#old-mcdonald-had-effects">Old McDonald had Effects…</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#asynchronous-tasks">Asynchronous Tasks</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#a-spot-of-theory">A Spot of Theory</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch8.md#in-summary">In Summary</a></li></ul></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch9.md">Chapter 9: Monadic Onions</a> <br>
<ul><li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch9.md#pointy-functor-factory">Pointy Functor Factory</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch9.md#mixing-metaphors">Mixing Metaphors</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch9.md#my-chain-hits-my-chest">My chain hits my chest</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch9.md#theory">Theory</a></li>
<li><a href="https://github.com/DrBoolean/mostly-adequate-guide/blob/master/ch9.md#in-summary">In Summary</a></li></ul></li>
</ul>
<p>軽妙な語り口とイラストで内容も非常に濃密で品質が高く必読。</p>
<p>ライセンスは、CC BY-SA 4.0。こんなものがクリエイティブ・コモンズのライセンスででGitHubに無料でポンポンと(すべてのプロジェクトは開発者、筆者が心血を注いだ結晶(自分がそうだからわかる)だが、客観的事象としては加速しすぎていてそのようにしか見えない)UPされている時代になっている。</p>
<h2 id="you-dont-know-js-book-series">You Don’t Know JS (book series)</h2>
<p><img src="http://akamaicovers.oreilly.com/images/0636920026327/lrg.jpg" alt="" title=""></p>
<p><a href="https://github.com/getify/You-Dont-Know-JS">https://github.com/getify/You-Dont-Know-JS</a> <br>
<a href="https://www.kickstarter.com/projects/getify/you-dont-know-js-book-series">https://www.kickstarter.com/projects/getify/you-dont-know-js-book-series</a></p>
<p>同じく、GitHubにUPされているCC3-BY-NC-ND ライセンスの無料で読めるJavaScript本。</p>
<p><a href="http://www.amazon.co.jp/You-Dont-Know-JS-Going-ebook/dp/B00V20DQU8">http://www.amazon.co.jp/You-Dont-Know-JS-Going-ebook/dp/B00V20DQU8</a></p>
<p>AmazonKindle版でも無料。</p>
<p>先ほどの関数型本もそうだが、他のGitHubプロジェクト同様にIssueがあり、</p>
<p><a href="https://github.com/getify/You-Dont-Know-JS/issues">https://github.com/getify/You-Dont-Know-JS/issues</a></p>
<p>タイポはもちろん校正が集合知によって為されていくという、出版物とWikiの垣根も曖昧になってきたという趨勢。</p>
<h2 id="すでにここにある未来">すでにここにある未来</h2>
<p>とにかく、レイ・カーツワイルの収穫加速の法則でシンギュラリティに向けて邁進する塩梅がどんなものか、一番「身近で手軽に」感じられるのがGitHubのJavaScript関連のレポジトリーやnpmライブラリ界隈だと思います。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-87983707331964493022015-08-20T20:07:00.001+09:002015-10-06T13:21:21.109+09:00timeengine / Time Engine FRP ( Functional Reactive Programming / 関数型リアクティブ プログラミング) npmライブラリの公開timeengine / Time Engine FRP ( Functional Reactive Programming / 関数型リアクティブ プログラミング) npmライブラリの公開<br />
worldcomponent<br />
worldtimestream<br />
のコンセプトを継承したライブラリです。<br />
<a href="https://github.com/kenokabe/timeengine">https://github.com/kenokabe/timeengine</a> <br />
<a href="https://www.npmjs.com/package/timeengine">https://www.npmjs.com/package/timeengine</a><br />
<h1 id="timeengine">
timeengine</h1>
Time Engine is the True Functional Reactive Programming (FRP) Library from the Point of View of Physics, our World and Time<br />
<a href="https://npmjs.org/package/timeengine"><img alt="NPM version" src="http://img.shields.io/npm/v/timeengine.svg" title="" /></a> <a href="https://npmjs.org/package/timeengine"><img alt="Downloads" src="http://img.shields.io/npm/dm/timeengine.svg" title="" /></a><a href="https://david-dm.org/kenokabe/timeengine"><img alt="Dependency status" src="https://david-dm.org/kenokabe/timeengine.svg" title="" /></a><a href="https://david-dm.org/kenokabe/timeengine#info=devDependencies"><img alt="Dev Dependency status" src="https://david-dm.org/kenokabe/timeengine/dev-status.svg" title="" /></a><a href="https://www.blogger.com/blogger.g?blogID=1347856729769934602"><img alt="npm" src="https://img.shields.io/npm/l/express.svg" title="" /></a><br />
<a href="https://nodei.co/npm/timeengine/"><img alt="NPM" src="https://nodei.co/npm/timeengine.png?downloads=true" title="" /></a><br />
<h2 id="the-world-time-physics-mathematics-equations-and-functional-reactive-programming">
The World, Time, Physics, Mathematics, Equations, and Functional Reactive Programming</h2>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/07/javascriptfrp.html">JavaScriptで時間発展する物理系=私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証</a><br />
から再掲/<br />
<a href="https://ja.wikipedia.org/wiki/%E6%99%82%E9%96%93%E7%99%BA%E5%B1%95">時間発展</a>する物理系、つまり、私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証をJavaScript言語でしてみましょう。<br />
我々の馴染みの深い「放物線」を例に取ります。 <br />
「放物線を描く」と日常的によく使いますが、物理学(日本語)では正確には、「斜方投射」と言います。<br />
<blockquote>
<a href="https://ja.wikipedia.org/wiki/%E6%96%9C%E6%96%B9%E6%8A%95%E5%B0%84">斜方投射(しゃほうとうしゃ)</a>とは物体をある初速度をもって空中に投げ出す動作である。空気抵抗が十分小さく無視できる場合、斜方投射された物体の軌跡は放物線を描く</blockquote>
<img alt="enter image description here" src="https://lh3.googleusercontent.com/4W_WOyyW4pK6--X5WcJWHNOHmlPuj-3bSuW3g0snPM8=w340-h240-no" title="" /><br />
水平方向にx軸、 <br />
鉛直上向きにy軸をとります。<br />
初速 <script id="MathJax-Element-1" type="math/tex">v_0</script> <br />
偏角 <script id="MathJax-Element-2" type="math/tex">θ</script> <br />
のとき、 <br />
斜方投射してからの経過時間 <script id="MathJax-Element-3" type="math/tex">t</script> における <br />
物体の速度および座標 <script id="MathJax-Element-4" type="math/tex">(x,y)</script>は<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin6cbyjQ2wAnd_zZUIhB7JdR9GwHdwXZUDMPWg_R4iJmUiguP5z9OcAurUK00YSmssO4vRwhHurnm1_oeLxrVsv1EChy_2vCG8lg5jNpAAQWtUb-S_NwncD7DFdEMdKNRFUVo5T-8JU1E/s1600/formula.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="120" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin6cbyjQ2wAnd_zZUIhB7JdR9GwHdwXZUDMPWg_R4iJmUiguP5z9OcAurUK00YSmssO4vRwhHurnm1_oeLxrVsv1EChy_2vCG8lg5jNpAAQWtUb-S_NwncD7DFdEMdKNRFUVo5T-8JU1E/s320/formula.png" width="320" /></a></div>
<br />
という恒等式で表せます。(<script id="MathJax-Element-7" type="math/tex">g</script>は 重力加速度=9.8 m/ss)<br />
これがニュートン物理学の時間発展する恒等式です。<br />
<blockquote>
. タイガー・ウッズの平均ヘッドスピード57.5m/s ボール初速度85.0~86.5m/sと公表されています。</blockquote>
らしいですから、 <br />
初速を85.0m/s、偏角30度とし、空気抵抗を無視したゴルフのスーパーショットっぽい斜方投射を上記時間発展する恒等式をそのまま用いて、 <br />
<code>timeengine</code> <br />
<code>React</code>を利用して関数型リアクティブプログラミングのコードを書くと以下のようになります。<br />
<br />
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">//MKS system of units</span>
<span class="hljs-keyword">var</span> V0 = <span class="hljs-number">85.0</span>; <span class="hljs-comment">// m/s</span>
<span class="hljs-keyword">var</span> DEG = <span class="hljs-number">30</span>; <span class="hljs-comment">//degree</span>
<span class="hljs-keyword">var</span> THETA = DEG / <span class="hljs-number">180</span> * <span class="hljs-built_in">Math</span>.PI; <span class="hljs-comment">//radian</span>
<span class="hljs-keyword">var</span> G = <span class="hljs-number">9.8</span>; <span class="hljs-comment">//gravity const</span>
<span class="hljs-comment">//10msec time resolution</span>
<span class="hljs-comment">//t seconds elapsed since t0</span>
<span class="hljs-keyword">var</span> t = __.intervalSeq(<span class="hljs-number">10</span>).tMap((tt, t0) => (tt - t0) / <span class="hljs-number">1000</span>);
<span class="hljs-keyword">var</span> x = t.tMap((t) => V0 * <span class="hljs-built_in">Math</span>.cos(THETA) * t);
<span class="hljs-keyword">var</span> y = t.tMap((t) => V0 * <span class="hljs-built_in">Math</span>.sin(THETA) * t - 1/2 </code>* G * <span class="hljs-built_in">Math</span>.pow(t, <span class="hljs-number">2</span>));</pre>
The full code is represented at the bottom of this document.<br />
<h3 id="live-demo">
Live Demo</h3>
<a href="http://sakurafunctional.github.io/demo/react-physics/">http://sakurafunctional.github.io/demo/react-physics/</a><br />
<h1 id="basic">
Basic</h1>
The only API you get to know is <code>tMap</code>.<br />
<code>tMap</code> maps a time-sequence to another time-sequence.<br />
Time Engine is all about <code>tMap</code>.<br />
<h2 id="reactive-programming-in-javascript">
Reactive Programming in JavaScript</h2>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">var</span> x = __(); <span class="hljs-comment">// time sequence</span>
<span class="hljs-keyword">var</span> y = x.tMap((x) => x * <span class="hljs-number">2</span>); <span class="hljs-comment">// y = x * 2</span>
x.t = <span class="hljs-number">3</span>;
console.log(x.t); <span class="hljs-comment">//3</span>
console.log(y.t); <span class="hljs-comment">//6</span>
x.t = <span class="hljs-number">5</span>;
console.log(x.t); <span class="hljs-comment">//5</span>
console.log(y.t); <span class="hljs-comment">//10</span></code></pre>
<h2 id="declarative-code-like-math-equation-and-single-no-duplicate-update-by-automatic-dependency-resolution">
Declarative code like Math equation and Single (no duplicate) update by automatic dependency resolution</h2>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">var</span> a = __();
<span class="hljs-keyword">var</span> b = __([a]).tMap(([a]) => a * <span class="hljs-number">2</span>); <span class="hljs-comment">// b.t = 1 * 2 = 2</span>
<span class="hljs-keyword">var</span> c = __([a, b]).tMap(([a, b]) => a + b * <span class="hljs-number">3</span>); <span class="hljs-comment">// c.t = 1 + 2 * 3 = 7</span>
<span class="hljs-keyword">var</span> d = __([b]).tMap(([b]) => b * <span class="hljs-number">100</span>); <span class="hljs-comment">// d.t = 2 * 100 = 200</span>
<span class="hljs-keyword">var</span> e = __([a, b, c, d]).tMap(([a, b, c, d]) => a + b + c + d); <span class="hljs-comment">//210</span>
a.t = <span class="hljs-number">1</span>; <span class="hljs-comment">// a is updated, and the whole equations will be evaluated.</span></code></pre>
<h2 id="atomic-update-using-promise">
Atomic update using Promise</h2>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">var</span> atomic = __([a, b, c, d, e])
.tMap(([a, b, c, d, e]) => ({
a,
b,
c,
d,
e
}));
<span class="hljs-keyword">var</span> timeseq10 = atomic.tMap((val) => {
__.t = __.log(<span class="hljs-string">'atomic'</span>, val);
});</code></pre>
<h2 id="promise">
Promise</h2>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-keyword">var</span> m = __();
<span class="hljs-keyword">var</span> n = __();
<span class="hljs-keyword">var</span> o = __();
<span class="hljs-keyword">var</span> p = __([m, n, o]).tMap(() => <span class="hljs-string">'Promised'</span>);
<span class="hljs-keyword">var</span> timeseq15 = __.timeoutSeq(<span class="hljs-number">6000</span>)
.tMap(() => m.t = <span class="hljs-string">'some'</span>);
<span class="hljs-keyword">var</span> timeseq16 = __.timeoutSeq(<span class="hljs-number">7000</span>)
.tMap(() => n.t = <span class="hljs-string">'time'</span>);
<span class="hljs-keyword">var</span> timeseq17 = __.timeoutSeq(<span class="hljs-number">8000</span>)
.tMap(() => o.t = <span class="hljs-string">'other'</span>);
<span class="hljs-keyword">var</span> timeseq18 = __.timeoutSeq(<span class="hljs-number">10000</span>)
.tMap(() => m.t = <span class="hljs-string">'some'</span>);
<span class="hljs-keyword">var</span> timeseq19 = __.timeoutSeq(<span class="hljs-number">11000</span>)
.tMap(() => n.t = <span class="hljs-string">'time'</span>);
<span class="hljs-keyword">var</span> timeseq20 = __.timeoutSeq(<span class="hljs-number">12000</span>)
.tMap(() => o.t = <span class="hljs-string">'other'</span>);
<span class="hljs-keyword">var</span> timeseq21 = m.tMap((m) => {
__.t = __.log({
m
});
});
<span class="hljs-keyword">var</span> timeseq22 = n.tMap((n) => {
__.t = __.log({
n
});
});
<span class="hljs-keyword">var</span> timeseq23 = o.tMap((o) => {
__.t = __.log({
o
});
});
<span class="hljs-keyword">var</span> timeseq24 = p.tMap((p) => {
__.t = __.log({
p
});
});</code></pre>
<h2 id="install">
Install</h2>
<h3 id="node-iojs">
node / io.js</h3>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-variable">$ </span>npm install timeengine</code></pre>
<h3 id="webbrowser">
WebBrowser</h3>
<h4 id="es5-native">
ES5 native</h4>
include<br />
<code>https://github.com/kenokabe/timeengine/blob/master/timeengine.js</code><br />
then<br />
<pre class="prettyprint"><code class="language-html hljs "><span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text/javascript"</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"./timeengine.js"</span>></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span></code></pre>
<h4 id="es6-with-babel-transpiler">
ES6 with Babel transpiler</h4>
<a href="https://babeljs.io/">https://babeljs.io/</a><br />
include<br />
<code>https://github.com/kenokabe/timeengine/blob/master/babel-browser.js</code><br />
<code>https://github.com/kenokabe/timeengine/blob/master/timeengine.jsx</code><br />
then<br />
<pre class="prettyprint"><code class="language-html hljs "><span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"./babel-browser.js"</span>></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span>
<span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text/babel"</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"./timeengine.jsx"</span>></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span></code></pre>
<h2 id="test">
Test</h2>
<pre class="prettyprint"><code class=" hljs ruby"><span class="hljs-variable">$ </span>npm test</code></pre>
equivalent to<br />
<pre class="prettyprint"><code class=" hljs avrasm">$ babel timeengine<span class="hljs-preprocessor">.jsx</span> -o timeengine<span class="hljs-preprocessor">.js</span><span class="hljs-comment">; babel-node test.jsx</span></code></pre>
<h3 id="testjsx">
test.jsx</h3>
<pre class="prettyprint"><code class="language-js hljs ">(() => {
<span class="hljs-string">'use strict'</span>;
<span class="hljs-keyword">var</span> __ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./timeengine.js'</span>);
__.t = __.log(<span class="hljs-string">'test.jsx started...'</span>);
<span class="hljs-comment">//Reactive and Declarative code ===============</span>
<span class="hljs-keyword">var</span> x = __(); <span class="hljs-comment">// time sequence</span>
<span class="hljs-keyword">var</span> y = x.tMap((x) => x * <span class="hljs-number">2</span>); <span class="hljs-comment">// y = x * 2</span>
x.t = <span class="hljs-number">3</span>;
console.log(x.t); <span class="hljs-comment">//3</span>
console.log(y.t); <span class="hljs-comment">//6</span>
x.t = <span class="hljs-number">5</span>;
console.log(x.t); <span class="hljs-comment">//5</span>
console.log(y.t); <span class="hljs-comment">//10</span>
<span class="hljs-comment">/*
//comment out, dependency Error occures here
//since y depends on x, this is an illegal operation
y.t = 100;
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + x.t);
console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + y.t);
*/</span>
<span class="hljs-comment">//store values on timeStamps ==============</span>
<span class="hljs-keyword">var</span> i = __(<span class="hljs-literal">true</span>); <span class="hljs-comment">//store flag = true</span>
<span class="hljs-keyword">var</span> j = __([i], <span class="hljs-literal">true</span>).tMap(() => i.t * <span class="hljs-number">2</span>); <span class="hljs-comment">// j = i * 2</span>
i.t = <span class="hljs-number">3</span>;
console.log(j.t); <span class="hljs-comment">//6</span>
i.t = <span class="hljs-number">5</span>;
console.log(j.t); <span class="hljs-comment">//10</span>
<span class="hljs-comment">// seq can be operated just like vanilla JavaScript Array</span>
__.t = __.log(<span class="hljs-string">'i.length'</span>, i.length);
i.map((val) => {
__.t = __.log(<span class="hljs-string">'i.t'</span>, val); <span class="hljs-comment">// 3, 5</span>
});
j.map((val) => {
__.t = __.log(<span class="hljs-string">'j.t'</span>, val); <span class="hljs-comment">//6, 10</span>
});
<span class="hljs-keyword">var</span> timestamp_i0 = i.TimestampOnIndex(<span class="hljs-number">0</span>);
<span class="hljs-keyword">var</span> timestamp_i1 = i.TimestampOnIndex(<span class="hljs-number">1</span>);
<span class="hljs-keyword">var</span> timestamp_j0 = j.TimestampOnIndex(<span class="hljs-number">0</span>);
<span class="hljs-keyword">var</span> timestamp_j1 = j.TimestampOnIndex(<span class="hljs-number">1</span>);
__.t = __.log(i.T(timestamp_i0)); <span class="hljs-comment">//3</span>
__.t = __.log(i.T(timestamp_i1)); <span class="hljs-comment">//5</span>
__.t = __.log(j.T(timestamp_j0)); <span class="hljs-comment">//6</span>
__.t = __.log(j.T(timestamp_j1)); <span class="hljs-comment">//10</span>
<span class="hljs-comment">//==============================================</span>
<span class="hljs-comment">//------------------------</span>
<span class="hljs-keyword">var</span> timeseq0 = __
.timeoutSeq(<span class="hljs-number">500</span>, <span class="hljs-literal">true</span>) <span class="hljs-comment">// store === true</span>
.tMap((t) => {
__.t = __.log(<span class="hljs-string">'--------------------------------------------'</span>);
<span class="hljs-keyword">return</span> t;
});
<span class="hljs-keyword">var</span> timeseq1 = timeseq0.tMap((t) => {
__.t = __.log(<span class="hljs-string">'timeseq0.t'</span>, t);
__.t = __.log(<span class="hljs-string">'stored to arrray'</span>, timeseq0[<span class="hljs-number">0</span>]); <span class="hljs-comment">// same val</span>
<span class="hljs-comment">//stored to the seq array</span>
});
<span class="hljs-keyword">var</span> f = (tt, t0) => {
__.t = __.log(<span class="hljs-string">'t0'</span>, t0);
__.t = __.log(<span class="hljs-string">'tt'</span>, tt);
};
<span class="hljs-keyword">var</span> timeseq2 = __.timeoutSeq(<span class="hljs-number">1000</span>).tMap(f);
<span class="hljs-keyword">var</span> timeseq3 = __.timeoutSeq(<span class="hljs-number">2000</span>).tMap(f);
<span class="hljs-comment">//------------------------</span>
<span class="hljs-keyword">var</span> timeseq4 = __.timeoutSeq(<span class="hljs-number">2500</span>)
.tMap(__.log(<span class="hljs-string">'-------------------------------------------'</span>));
<span class="hljs-comment">// Single (no duplicate) update by dependency analysis</span>
<span class="hljs-keyword">var</span> a = __();
<span class="hljs-keyword">var</span> b = __([a]).tMap(([a]) => a * <span class="hljs-number">2</span>); <span class="hljs-comment">// b.t = 1 * 2 = 2</span>
<span class="hljs-keyword">var</span> c = __([a, b]).tMap(([a, b]) => a + b * <span class="hljs-number">3</span>); <span class="hljs-comment">// c.t = 1 + 2 * 3 = 7</span>
<span class="hljs-keyword">var</span> d = __([b]).tMap(([b]) => b * <span class="hljs-number">100</span>); <span class="hljs-comment">// d.t = 2 * 100 = 200</span>
<span class="hljs-keyword">var</span> e = __([a, b, c, d]).tMap(([a, b, c, d]) => a + b + c + d); <span class="hljs-comment">//210</span>
<span class="hljs-keyword">var</span> timeseq5 = a.tMap((a) => {
__.t = __.log({
a
});
});
<span class="hljs-keyword">var</span> timeseq6 = b.tMap((b) => {
__.t = __.log({
b
});
});
<span class="hljs-keyword">var</span> timeseq7 = c.tMap((c) => {
__.t = __.log({
c
});
});
<span class="hljs-keyword">var</span> timeseq8 = d.tMap((d) => {
__.t = __.log({
d
});
});
<span class="hljs-keyword">var</span> timeseq9 = e.tMap((e) => {
__.t = __.log({
e
});
});
<span class="hljs-comment">// Atomic update using build-in Promise mechanism</span>
<span class="hljs-keyword">var</span> atomic = __([a, b, c, d, e])
.tMap(([a, b, c, d, e]) => ({
a,
b,
c,
d,
e
}));
<span class="hljs-keyword">var</span> timeseq10 = atomic.tMap((val) => {
__.t = __.log(<span class="hljs-string">'atomic'</span>, val);
});
<span class="hljs-keyword">var</span> timeseq11 = __.timeoutSeq(<span class="hljs-number">3000</span>)
.tMap(() => a.t = <span class="hljs-number">1</span>);
<span class="hljs-keyword">var</span> timeseq12 = __.timeoutSeq(<span class="hljs-number">3500</span>)
.tMap(__.log(<span class="hljs-string">'--------------------------------------------'</span>));
<span class="hljs-keyword">var</span> timeseq13 = __.timeoutSeq(<span class="hljs-number">4500</span>)
.tMap(() => a.t = <span class="hljs-number">5</span>);
<span class="hljs-comment">//---------------------------------------------</span>
<span class="hljs-keyword">var</span> timeseq14 = __.timeoutSeq(<span class="hljs-number">5000</span>)
.tMap(__.log(<span class="hljs-string">'--------------------------------------------'</span>));
<span class="hljs-comment">//Promise---------------------------------------------</span>
<span class="hljs-keyword">var</span> m = __();
<span class="hljs-keyword">var</span> n = __();
<span class="hljs-keyword">var</span> o = __();
<span class="hljs-keyword">var</span> p = __([m, n, o]).tMap(() => <span class="hljs-string">'Promised'</span>);
<span class="hljs-keyword">var</span> timeseq15 = __.timeoutSeq(<span class="hljs-number">6000</span>)
.tMap(() => m.t = <span class="hljs-string">'some'</span>);
<span class="hljs-keyword">var</span> timeseq16 = __.timeoutSeq(<span class="hljs-number">7000</span>)
.tMap(() => n.t = <span class="hljs-string">'time'</span>);
<span class="hljs-keyword">var</span> timeseq17 = __.timeoutSeq(<span class="hljs-number">8000</span>)
.tMap(() => o.t = <span class="hljs-string">'other'</span>);
<span class="hljs-keyword">var</span> timeseq18 = __.timeoutSeq(<span class="hljs-number">10000</span>)
.tMap(() => m.t = <span class="hljs-string">'some'</span>);
<span class="hljs-keyword">var</span> timeseq19 = __.timeoutSeq(<span class="hljs-number">11000</span>)
.tMap(() => n.t = <span class="hljs-string">'time'</span>);
<span class="hljs-keyword">var</span> timeseq20 = __.timeoutSeq(<span class="hljs-number">12000</span>)
.tMap(() => o.t = <span class="hljs-string">'other'</span>);
<span class="hljs-keyword">var</span> timeseq21 = m.tMap((m) => {
__.t = __.log({
m
});
});
<span class="hljs-keyword">var</span> timeseq22 = n.tMap((n) => {
__.t = __.log({
n
});
});
<span class="hljs-keyword">var</span> timeseq23 = o.tMap((o) => {
__.t = __.log({
o
});
});
<span class="hljs-keyword">var</span> timeseq24 = p.tMap((p) => {
__.t = __.log({
p
});
});
<span class="hljs-keyword">var</span> timeseq25 = __.timeoutSeq(<span class="hljs-number">13000</span>)
.tMap(__.log(<span class="hljs-string">'--------------------------------------------'</span>));
<span class="hljs-keyword">var</span> f99 = () => {
__.t = __.log(<span class="hljs-string">'Any Event Function can be wrapped.'</span>);
};
__.t = __.wrap(setTimeout)(f99, <span class="hljs-number">14000</span>);
<span class="hljs-comment">//onMousemove or whatever instead of setTimeout</span>
<span class="hljs-comment">///-----------------------------------------------</span>
<span class="hljs-keyword">var</span> timeseq26 = __.timeoutSeq(<span class="hljs-number">15000</span>)
.tMap(() => {
__.t = __.log(<span class="hljs-string">'--------------------------------------------'</span>);
<span class="hljs-keyword">var</span> timeseq27 = __
.intervalSeq(<span class="hljs-number">1000</span>)
.tMap((tt, t0) => (tt - t0) / <span class="hljs-number">1000</span>)
.tMap((tt) => {
__.t = __.log(tt);
<span class="hljs-keyword">return</span> tt;
});
});
})();
</code></pre>
<h3 id="result">
result</h3>
<pre class="prettyprint"><code class=" hljs css">> <span class="hljs-tag">babel</span> <span class="hljs-tag">timeengine</span><span class="hljs-class">.jsx</span> <span class="hljs-tag">-o</span> <span class="hljs-tag">timeengine</span><span class="hljs-class">.js</span>; <span class="hljs-tag">babel-node</span> <span class="hljs-tag">test</span><span class="hljs-class">.jsx</span>
<span class="hljs-tag">test</span><span class="hljs-class">.jsx</span> <span class="hljs-tag">started</span>...
3
6
5
10
6
10
<span class="hljs-tag">i</span><span class="hljs-class">.length</span> 2
<span class="hljs-tag">i</span><span class="hljs-class">.t</span> 3
<span class="hljs-tag">i</span><span class="hljs-class">.t</span> 5
<span class="hljs-tag">j</span><span class="hljs-class">.t</span> 6
<span class="hljs-tag">j</span><span class="hljs-class">.t</span> 10
3
5
6
10
<span class="hljs-tag">--------------------------------------------</span>
<span class="hljs-tag">timeseq0</span><span class="hljs-class">.t</span> 1440134670777
<span class="hljs-tag">stored</span> <span class="hljs-tag">to</span> <span class="hljs-tag">arrray</span> 1440134670777
<span class="hljs-tag">t0</span> 1440134670277
<span class="hljs-tag">tt</span> 1440134671278
<span class="hljs-tag">t0</span> 1440134670277
<span class="hljs-tag">tt</span> 1440134672277
<span class="hljs-tag">-------------------------------------------</span>
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">c</span>:<span class="hljs-value"> <span class="hljs-number">7</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">e</span>:<span class="hljs-value"> <span class="hljs-number">210</span> </span></span></span>}
<span class="hljs-tag">atomic</span> <span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">a</span>:<span class="hljs-value"> <span class="hljs-number">1</span>, b: <span class="hljs-number">2</span>, c: <span class="hljs-number">7</span>, d: <span class="hljs-number">200</span>, e: <span class="hljs-number">210</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">d</span>:<span class="hljs-value"> <span class="hljs-number">200</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">b</span>:<span class="hljs-value"> <span class="hljs-number">2</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">a</span>:<span class="hljs-value"> <span class="hljs-number">1</span> </span></span></span>}
<span class="hljs-tag">--------------------------------------------</span>
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">c</span>:<span class="hljs-value"> <span class="hljs-number">35</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">e</span>:<span class="hljs-value"> <span class="hljs-number">1050</span> </span></span></span>}
<span class="hljs-tag">atomic</span> <span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">a</span>:<span class="hljs-value"> <span class="hljs-number">5</span>, b: <span class="hljs-number">10</span>, c: <span class="hljs-number">35</span>, d: <span class="hljs-number">1000</span>, e: <span class="hljs-number">1050</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">d</span>:<span class="hljs-value"> <span class="hljs-number">1000</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">b</span>:<span class="hljs-value"> <span class="hljs-number">10</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">a</span>:<span class="hljs-value"> <span class="hljs-number">5</span> </span></span></span>}
<span class="hljs-tag">--------------------------------------------</span>
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">m</span>:<span class="hljs-value"> <span class="hljs-string">'some'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">n</span>:<span class="hljs-value"> <span class="hljs-string">'time'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">p</span>:<span class="hljs-value"> <span class="hljs-string">'Promised'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">o</span>:<span class="hljs-value"> <span class="hljs-string">'other'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">m</span>:<span class="hljs-value"> <span class="hljs-string">'some'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">n</span>:<span class="hljs-value"> <span class="hljs-string">'time'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">p</span>:<span class="hljs-value"> <span class="hljs-string">'Promised'</span> </span></span></span>}
<span class="hljs-rules">{ <span class="hljs-rule"><span class="hljs-attribute">o</span>:<span class="hljs-value"> <span class="hljs-string">'other'</span> </span></span></span>}
<span class="hljs-tag">--------------------------------------------</span>
<span class="hljs-tag">Any</span> <span class="hljs-tag">Event</span> <span class="hljs-tag">Function</span> <span class="hljs-tag">can</span> <span class="hljs-tag">be</span> <span class="hljs-tag">wrapped</span>.
<span class="hljs-tag">--------------------------------------------</span>
1<span class="hljs-class">.002</span>
2<span class="hljs-class">.004</span>
3<span class="hljs-class">.006</span>
4<span class="hljs-class">.007</span>
5<span class="hljs-class">.008</span>
</code></pre>
<h2 id="react-physics-test">
React Physics Test</h2>
<img alt="enter image description here" src="https://lh3.googleusercontent.com/4W_WOyyW4pK6--X5WcJWHNOHmlPuj-3bSuW3g0snPM8=w340-h240-no" title="" /><br />
<script id="MathJax-Element-8" type="math/tex; mode=display">
x=(v_0\cosθ)t
</script><br />
<script id="MathJax-Element-9" type="math/tex; mode=display">
y = (v_0\sinθ)t - gt^2
</script><br />
<h3 id="indexjsx">
index.jsx</h3>
<pre class="prettyprint"><code class="language-js hljs "><span class="hljs-comment">/*global React __ */</span>
(() => {
<span class="hljs-string">'use strict'</span>;
<span class="hljs-comment">//MKS system of units</span>
<span class="hljs-keyword">var</span> V0 = <span class="hljs-number">85.0</span>; <span class="hljs-comment">// m/s</span>
<span class="hljs-keyword">var</span> DEG = <span class="hljs-number">30</span>; <span class="hljs-comment">//degree</span>
<span class="hljs-keyword">var</span> THETA = DEG / <span class="hljs-number">180</span> * <span class="hljs-built_in">Math</span>.PI; <span class="hljs-comment">//radian</span>
<span class="hljs-keyword">var</span> G = <span class="hljs-number">9.8</span>; <span class="hljs-comment">//gravity const</span>
<span class="hljs-comment">//10msec time resolution</span>
<span class="hljs-comment">//t seconds elapsed since t0</span>
<span class="hljs-keyword">var</span> t = __.intervalSeq(<span class="hljs-number">10</span>).tMap((tt, t0) => (tt - t0) / <span class="hljs-number">1000</span>);
<span class="hljs-keyword">var</span> x = t.tMap((t) => V0 * <span class="hljs-built_in">Math</span>.cos(THETA) * t);
<span class="hljs-keyword">var</span> y = t.tMap((t) => V0 * <span class="hljs-built_in">Math</span>.sin(THETA) * t - 1/2 * G * <span class="hljs-built_in">Math</span>.pow(t, <span class="hljs-number">2</span>));
<span class="hljs-comment">//==============================================================</span>
<span class="hljs-keyword">var</span> Drawscale = <span class="hljs-number">4</span>; <span class="hljs-comment">//4 dot = 1 meter</span>
<span class="hljs-keyword">class</span> ReactComponent extends React.Component {
constructor() {
super();
<span class="hljs-keyword">var</span> timeseq = __([x, y])
.tMap(([x, y]) => [<span class="hljs-number">50</span> + x * Drawscale, <span class="hljs-number">300</span> - y * Drawscale])
.tMap(([x, y]) => {
<span class="hljs-keyword">this</span>.rx = x;
<span class="hljs-keyword">this</span>.ry = y;
<span class="hljs-keyword">this</span>.forceUpdate();
});
}
render() {
<span class="hljs-keyword">var</span> el = (
<span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span>
<span class="hljs-tag"><<span class="hljs-title">h1</span>></span>For new shot, Just Reload the browser page<span class="hljs-tag"></<span class="hljs-title">h1</span>></span>
<span class="hljs-tag"><<span class="hljs-title">svg</span> <span class="hljs-attribute">height</span> = "<span class="hljs-attribute">100</span>%" <span class="hljs-attribute">width</span> = "<span class="hljs-attribute">100</span>%"></span>
<span class="hljs-tag"><<span class="hljs-title">circle</span> <span class="hljs-attribute">r</span>=<span class="hljs-value">"5"</span> <span class="hljs-attribute">fill</span>=<span class="hljs-value">"blue"</span>
<span class="hljs-attribute">cx</span> = {<span class="hljs-attribute">this.rx</span>}
<span class="hljs-attribute">cy</span> = {<span class="hljs-attribute">this.ry</span>}/></span>
<span class="hljs-tag"></<span class="hljs-title">svg</span>></span>
<span class="hljs-tag"></<span class="hljs-title">div</span>></span>
);
return el;
};
}
var mount = React.render(<span class="hljs-tag"><<span class="hljs-title">ReactComponent</span>/></span>, document.body);
})();
</span></code></pre>
<h3 id="live-demo-1">
Live Demo</h3>
<a href="http://sakurafunctional.github.io/demo/react-physics/">http://sakurafunctional.github.io/demo/react-physics/</a>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-19513280211094682812015-08-03T16:14:00.001+09:002015-08-14T00:02:47.310+09:00JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン<p>【注意】この記事は2015年夏に書かれましたが、事態は極めて流動的であり、この記事の内容はすぐに古くなる可能性があります。</p>
<h2 id="javascriptはes6からのトランスパイル形式が標準になりつつある">JavaScriptはES6+からのトランスパイル形式が標準になりつつある</h2>
<p>これまで、CoffeeScriptやTypeeScriptなどJavaScriptトランスパイル言語がありましたが、標準ではありませんでした。</p>
<p>しかし、FacebookのReactの独自言語JSXや次世代JavaSciptのECMA Sciptバージョン6(ES6/コードネームHarmony)が台頭してくるにつれ、すべてはES6+からレガシーのバニラJavaScript(ES5以下)へ、トランスパイルする形式に統合されつつあります。</p>
<h2 id="reactのビルドシステムはトランスパイラbabel旧6to5へ移行jstransformerなどは廃止の方向">Reactのビルドシステムは、トランスパイラ<code>Babel</code>(旧<code>6to5</code>)へ移行、JSTransformerなどは廃止の方向</h2>
<h3 id="deprecating-jstransform-and-react-tools-june-12-2015"><a href="http://facebook.github.io/react/blog/2015/06/12/deprecating-jstransform-and-react-tools.html">Deprecating JSTransform and react-tools (June 12, 2015)</a></h3>
<blockquote>
<p>Today we’re announcing the deprecation of react-tools and JSTransform.</p>
<p>As many people have noticed already, React and React Native have both switched their respective build systems to make use of <strong>Babel</strong>. This replaced JSTransform, the source transformation tool that we wrote at Facebook. JSTransform has been really good for us over the past several years, however as the JavaScript language continues to evolve, the architecture we used has begun to show its age. We’ve faced maintenance issues and lagged behind implementing new language features. Last year, Babel (previously 6to5) exploded onto the scene, implementing new features at an amazing pace. Since then it has evolved a solid plugin API, and implemented some of our non-standard language features (JSX and Flow type annotations).</p>
<p>react-tools has always been a very thin wrapper around JSTransform. It has served as a great tool for the community to get up and running, but at this point we’re ready to let it go. We won’t ship a new version for v0.14.</p>
</blockquote>
<h4 id="migrating-to-babel">Migrating to Babel</h4>
<blockquote>
<p>Many people in the React and broader JavaScript community have already adopted Babel. It has integrations with a number of tools. Depending on your tool, you’ll want to read up on the instructions.</p>
<p>We’ve been working with the Babel team as we started making use of it and we’re confident that it will be the right tool to use with React.</p>
</blockquote>
<p><img src="https://raw.githubusercontent.com/babel/logo/master/babel.png" alt="enter image description here" title=""></p>
<p><a href="https://app.codegrid.net/entry/babel-1">https://app.codegrid.net/entry/babel-1</a></p>
<h2 id="次世代デファクトfacebook-reactのjsxとes6トランスパイラbabelの親密な関係">次世代デファクト、Facebook-ReactのJSXとES6トランスパイラBabelの親密な関係</h2>
<p>上記Facebookのブログで発表されたBabelへビルドシステムを完全移行させる方針、そして、FacebookのReact開発チームがBabel開発チームと協働していることから明らかですが、ES6+トランスパイラであるBabelはJSXを完全にサポートしており、今後React-JSXの「標準」のコンパイラとなります。</p>
<p>ES6へ移行する最大の問題は、巷のブラウザ、そしてnode/io.jsに何時まで経ってもまともにサポートされておらず、実用的な観点から実入りがないというものがありましたが、BabelによってES5以下にトランスパイルされるため、互換性の問題は無くなり、今すぐすべてのES6仕様が利用できることになります。</p>
<p>そして、JSXは今後、ES6+の仕様に準拠し、依存する言語仕様に進化していく方針なので、Babelに適応することで、すべての問題が解決されます。今後JavaScriptのプログラマはBabelのトランスパイルシステムにコーディングを依存していくことになります。</p>
<h2 id="atomエディタではどうなのか">ATOMエディタではどうなのか?</h2>
<h3 id="built-in-6to5-support"><a href="http://blog.atom.io/2015/02/04/built-in-6to5.html">Built-in 6to5 support</a></h3>
<blockquote>
<p>Since this post was originally published the 6to5 library was renamed to babel so packages should now use the “use babel”; pragma in their JavaScript files.</p>
</blockquote>
<p>ATOMエディタでは、すでに<code>use babel</code>と指定することによりBabelがBuilt-inされておりES6でのパッケージ開発のサポートがされています。</p>
<p>念の為ですが、これはパッケージ開発のみのようです。つまり、ATOMにはBabelがビルトインされており、ES6+で開発したATOMライブラリは<code>use babel</code>フラグの指定により、Babel経由でトランスパイル実行されるということなのでしょう。</p>
<h2 id="atomエディタですべてのes6開発をシームレスに行うための最速環境構築">ATOMエディタですべてのES6開発をシームレスに行うための最速環境構築</h2>
<p>そこで、この記事では、ATOMエディタですべてのES6開発をシームレスに行うための最速環境構築を紹介します。</p>
<p>冒頭に書いたとおり事態は流動的なので、パッケージの組み合わせなどより良いものが近い将来登場する可能性は大いにありますが、現時点で筆者が認識しているベストプラクティスです。</p>
<p>再現性を確保したいので、開発環境をゼロからインストールをすることを想定しています。</p>
<p>ちなみに筆者の環境は、Debian8.1です。</p>
<h2 id="基盤">基盤</h2>
<h3 id="nvm-をインストール">nvm をインストール</h3>
<p><a href="https://github.com/creationix/nvm">https://github.com/creationix/nvm</a></p>
<h3 id="nvmからiojsをインストール">nvmからio.jsをインストール</h3>
<p>nvm install iojs</p>
<p>. ~/.nvm/nvm.sh <br>
nvm use iojs</p>
<p>確認 <br>
node -v </p>
<h3 id="atomをインストール">ATOMをインストール</h3>
<p><a href="https://atom.io/">https://atom.io/</a></p>
<h1 id="terminalの作業">Terminalの作業</h1>
<h2 id="babelをnpmインストール"><code>Babel</code>をnpmインストール</h2>
<p><a href="http://babeljs.io/">http://babeljs.io/</a></p>
<blockquote>
<p>Babel is a JavaScript compiler. <br>
Use next generation JavaScript, today.</p>
</blockquote>
<p>..</p>
<blockquote>
<p><strong>npm install -g babel</strong></p>
</blockquote>
<p>これで、<code>babel</code>コマンドが利用できるようになり、ターミナルで</p>
<blockquote>
<p>babel script.js</p>
</blockquote>
<p>などとすることにより、ES6やJSXコードをES5にトランスパイルします。</p>
<h2 id="eslint-with-babel-eslintをnpmインストール"><code>ESLint</code> with <code>babel-eslint</code>をnpmインストール</h2>
<p><a href="http://eslint.org/">http://eslint.org/</a></p>
<blockquote>
<p>The pluggable linting utility for JavaScript and JSX</p>
</blockquote>
<p><a href="https://github.com/babel/babel-eslint">https://github.com/babel/babel-eslint</a></p>
<blockquote>
<p>babel-eslint allows you to lint ALL valid Babel code with the fantastic ESLint.</p>
</blockquote>
<p>Babelプロジェクト公式のESLintプラグインです。ちなみに、JSHintやJSLint用プラグインはプロジェクトには存在しません。時代の流れを感じます。 <br>
<a href="http://qiita.com/inuscript/items/dcf48f56d8f484c0a1a8">時代はESLint。JSLintでもJSHintでもなくESLint。</a></p>
<p>babel-eslintのgithubレポページの説明に従って両方インストールします。</p>
<blockquote>
<p><strong>npm install -g eslint babel-eslint</strong></p>
</blockquote>
<p><strong><code>.eslintrc</code></strong>というESLint設定ファイルに以下の内容をコピペし、ホームディレクトリ直下に新規作成します。</p>
<pre class="prettyprint"><code class=" hljs json">{
"<span class="hljs-attribute">parser</span>": <span class="hljs-value"><span class="hljs-string">"babel-eslint"</span></span>,
"<span class="hljs-attribute">env</span>": <span class="hljs-value">{
"<span class="hljs-attribute">es6</span>": <span class="hljs-value"><span class="hljs-literal">true</span></span>,
"<span class="hljs-attribute">node</span>": <span class="hljs-value"><span class="hljs-literal">true</span></span>,
"<span class="hljs-attribute">browser</span>": <span class="hljs-value"><span class="hljs-literal">true</span>
</span>}</span>,
"<span class="hljs-attribute">rules</span>": <span class="hljs-value">{
"<span class="hljs-attribute">semi</span>": <span class="hljs-value">[<span class="hljs-number">2</span>, <span class="hljs-string">"always"</span>]</span>,
"<span class="hljs-attribute">strict</span>": <span class="hljs-value"><span class="hljs-number">1</span></span>,
"<span class="hljs-attribute">no-undef</span>" : <span class="hljs-value"><span class="hljs-number">2</span>
</span>}
</span>}
</code></pre>
<p>これでターミナルから</p>
<blockquote>
<p>eslint test.jsx</p>
</blockquote>
<p>など、ES6やJSXコードをLintできます。</p>
<p>この<code>.eslintrc</code>設定は<code>"rules":{}</code>がほぼ空の最低限の設定 <br>
(Strictモードの宣言がないとWarning【レベル1】される、セミコロン必須、定義なしエラー【レベル2】)で、 <br>
<a href="http://eslint.org/docs/rules/">http://eslint.org/docs/rules/</a></p>
<p>を参照しながら、ルールを追加し磨き上げていきます。</p>
<h2 id="zshrcなどに追加しておくと便利なエイリアス">.zshrcなどに追加しておくと便利なエイリアス</h2>
<pre class="prettyprint"><code class=" hljs livecodeserver"><span class="hljs-built_in">alias</span> <span class="hljs-operator">a</span>=<span class="hljs-string">"atom ./"</span></code></pre>
<p>など。 <br>
<code>a</code>でターミナルのカレントディレクトリをATOMで開く。 <br>
基本、もともとATOMはGUIのファイラー経由でなくターミナルでプロジェクトディレクトリを開くように設計されていると思う。</p>
<h1 id="atomを起動">ATOMを起動</h1>
<h2 id="lookfeel">★Look&Feel</h2>
<p>好みで設定。</p>
<p>筆者の場合 <br>
Settings > Themes</p>
<h4 id="ui-theme">UI Theme</h4>
<ul>
<li>Atom Dark <br>
(デフォルトのOne Darkはタブが見難すぎる)</li>
</ul>
<h4 id="syntax-theme">Syntax Theme</h4>
<ul>
<li>Solarized Dark <br>
<a href="http://ethanschoonover.com/solarized">http://ethanschoonover.com/solarized</a> <br>
(由緒正しい鉄板theme <br>
最初は違和感あるかもしれないが、徐々に良さがわかってくる) <br>
<a href="http://blog.remora.cx/2012/10/let-us-use-solarized.html">最強カラースキームと言えば SOLARIZED だよね!</a></li>
</ul>
<h3 id="file-iconsパッケージをatomにインストール"><code>file-icons</code>パッケージをATOMにインストール</h3>
<p><a href="https://github.com/DanBrooker/file-icons">https://github.com/DanBrooker/file-icons</a></p>
<p><img src="https://raw.githubusercontent.com/DanBrooker/file-icons/master/file-icons.png" alt="enter image description here" title=""></p>
<p>本体にマージすべき必須パッケージ。</p>
<h3 id="minimapパッケージをatomにインストール"><code>minimap</code>パッケージをATOMにインストール</h3>
<p><a href="https://atom.io/packages/minimap">https://atom.io/packages/minimap</a></p>
<p>本体にマージすべき必須パッケージ。</p>
<h3 id="language-babelパッケージをatomにインストール"><code>language-babel</code>パッケージをATOMにインストール</h3>
<p><a href="https://atom.io/packages/language-babel">https://atom.io/packages/language-babel</a></p>
<blockquote>
<p>Language grammar for ES2015 Javascript and Facebook React JSX syntax. The color of syntax is determined by the theme in use.</p>
</blockquote>
<p><code>.js</code>,.<code>babel</code>,<code>jsx</code> <code>es6</code>エクステンションのES6やJSXコードのシンタックスのハイライトをしてくれる。これ自体もLint機能が有るが弱い。</p>
<p>本体にマージすべき必須パッケージ。</p>
<p>ここまでで、表示は整いました。 <br>
<img src="https://lh3.googleusercontent.com/M30sUA9322_g1SW6_IZHGesjA8NcMniiZnlslfY7IUk=w1066-h1763-no" alt="enter image description here" title=""></p>
<h3 id="ここから上記terminalプログラムをatomで利用するためのパッケージをインストールします">ここから、上記TerminalプログラムをATOMで利用するためのパッケージをインストールします。</h3>
<h2 id="lint設定">★Lint設定</h2>
<h3 id="linter-linter-eslintパッケージをatomにインストール"><code>linter</code> & <code>linter-eslint</code>パッケージをATOMにインストール</h3>
<h4 id="linter-eslintの設定">linter-eslintの設定</h4>
<ul>
<li><p><code>Global Node Path</code>に、<code>npm config get prefix</code> で得られるNodeのグローバル・パスをコピペ。</p></li>
<li><p><code>Use Global Lint</code>をチェック。</p></li>
</ul>
<h2 id="コードformat-beautify">★コードFormat (Beautify)</h2>
<h3 id="esformatterパッケージをatomにインストール"><code>esformatter</code>パッケージをATOMにインストール</h3>
<p><code>Format On Save</code>にチェック。</p>
<p>JSXのコードで、 <br>
<code>class ReactComponent extends React . Component {</code> <br>
のところだけ、余分なスペースが入るのが気になるが、Lintと実行は問題ない。`</p>
<p><strong><code>~/.atom/packages/esformatter/.esformatter</code></strong></p>
<p><code>esformatter-collapse-objects</code>プラグイン参照を追加</p>
<pre class="prettyprint"><code class=" hljs json">{
"<span class="hljs-attribute">plugins</span>": <span class="hljs-value">[
<span class="hljs-string">"esformatter-jsx"</span>,
<span class="hljs-string">"esformatter-collapse-objects"</span>
]</span>,</code></pre>
<h2 id="確認">確認</h2>
<p>最終的に6パッケージがインストールされています。</p>
<p><img src="https://lh3.googleusercontent.com/Fo886eDmNo0733rvSccf3UEnNdYW5GibMsn-gsqtCvE=w875-h986-no" alt="enter image description here" title=""></p>
<h2 id="再起動">再起動</h2>
<p>ATOMのパッケージ、設定は再起動されないと反映されないものがあるので、再起動して挙動を確認します。</p>
<h2 id="オンタイムトランスパイルメインの設定">オンタイム・トランスパイルメインの設定</h2>
<p>一つのやり方として、ファイルエクステンションを<code>JSX</code>あるいは<code>ES6</code>に統一しておく、という方法があるでしょう。</p>
<h3 id="nodeiojs">node/io.js</h3>
<p>標準の<code>node</code>コマンドで、</p>
<p><code>node app.js</code></p>
<p>と実行する代わりに、Babelに付属している<code>babel-node</code>コマンドで、</p>
<p><code>babel-node app.jsx</code></p>
<p>と直接オンタイムで実行できます。 <br>
<a href="https://babeljs.io/docs/usage/cli/">https://babeljs.io/docs/usage/cli/</a></p>
<p>トランスパイルのオーバーヘッドがあるだけで、パフォーマンスのデメリットはありません。</p>
<h3 id="browser">Browser</h3>
<p>開発時には、オンタイムでトランスパイルしたほうが便利です。 <br>
React-JSXでは、JSX-Transfomerというオンタイムのトランスパイラーが利用できますが、これも廃止の方向に向かっており、同様に、Babelを利用します。</p>
<p><a href="https://babeljs.io/docs/usage/browser/">https://babeljs.io/docs/usage/browser/</a></p>
<p>ドキュメントにあるとおり、</p>
<pre class="prettyprint"><code class="language-js hljs "><body>
<span class="xml"><span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"node_modules/babel-core/browser.js"</span>></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span>
<span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"text/babel"</span>></span><span class="javascript">
<span class="hljs-comment">//your Babel ES6/JSX code</span>
</span><span class="hljs-tag"></<span class="hljs-title">script</span>></span>
<span class="hljs-tag"></<span class="hljs-title">body</span>></span></span></code></pre>
<p>とするのですが、一部ES7の機能を使いたい場合などのオプション指定のやり方はわからなかったので、同じページにあるAPIを利用して以下のようにも書けば、<code>{state: 0}</code>などのオプション設定が可能になります。</p>
<pre class="prettyprint"><code class=" hljs xml"><span class="hljs-tag"><<span class="hljs-title">body</span>></span>
<span class="hljs-tag"><<span class="hljs-title">script</span> <span class="hljs-attribute">src</span>=<span class="hljs-value">"./babel-browser.js"</span> ></span><span class="javascript"></span><span class="hljs-tag"></<span class="hljs-title">script</span>></span>
<span class="hljs-tag"><<span class="hljs-title">script</span>></span><span class="javascript">
<span class="hljs-keyword">var</span> urls = [<span class="hljs-string">"./index.jsx"</span>];
xhrDoc = <span class="hljs-keyword">new</span> XMLHttpRequest();
xhrDoc.open(<span class="hljs-string">'GET'</span>, urls[<span class="hljs-number">0</span>])
<span class="hljs-keyword">if</span> (xhrDoc.overrideMimeType)
xhrDoc.overrideMimeType(<span class="hljs-string">'text/plain; charset=x-user-defined'</span>)
xhrDoc.onreadystatechange = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.readyState == <span class="hljs-number">4</span>) {
<span class="hljs-keyword">if</span> (<span class="hljs-keyword">this</span>.status == <span class="hljs-number">200</span>) {
<span class="hljs-keyword">var</span> data = <span class="hljs-keyword">this</span>.response; <span class="hljs-comment">//Here is a string of the text data</span>
<span class="hljs-keyword">var</span> out = babel.run(data, { stage: <span class="hljs-number">0</span> });
}
}
}
xhrDoc.send() <span class="hljs-comment">//sending the request</span>
</span><span class="hljs-tag"></<span class="hljs-title">script</span>></span>
<span class="hljs-tag"></<span class="hljs-title">body</span>></span>
</code></pre>
<h2 id="プロダクション">プロダクション</h2>
<p>開発でないプロダクションでは、特にブラウザではES6+/JSXからES5以下へ、あらかじめオフライン環境でトランスパイルしておいたほうがパフォーマンス的に推奨されます。</p>
<p>この場合は、ターミナルで普通に<code>babel</code>コマンドでES6+/JSXファイルをトランスパイルする、ということになります。</p>
<p>前回、前々回の記事</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/07/nodefrpworldcomponentworldtimestream.html">nodeのFRP(関数型リアクティブ)ライブラリ<code>worldcomponent</code>の後継、<code>worldtimestream</code>の公開</a></p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/07/javascriptfrp.html">JavaScriptで時間発展する物理系=私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証</a></p>
<p>はこのBabelを用いたES6+/JSXのコードで開発しています。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-9831387209405791752015-07-31T11:18:00.001+09:002015-08-01T21:17:19.821+09:00JavaScriptで時間発展する物理系=私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証<p><a href="https://ja.wikipedia.org/wiki/%E6%99%82%E9%96%93%E7%99%BA%E5%B1%95">時間発展</a>する物理系、つまり、私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証をJavaScript言語でしてみましょう。</p>
<p>我々の馴染みの深い「放物線」を例に取ります。 <br>
「放物線を描く」と日常的によく使いますが、物理学(日本語)では正確には、「斜方投射」と言います。</p>
<blockquote>
<p><a href="https://ja.wikipedia.org/wiki/%E6%96%9C%E6%96%B9%E6%8A%95%E5%B0%84">斜方投射(しゃほうとうしゃ)</a>とは物体をある初速度をもって空中に投げ出す動作である。空気抵抗が十分小さく無視できる場合、斜方投射された物体の軌跡は放物線を描く</p>
</blockquote>
<p><img src="https://lh3.googleusercontent.com/4W_WOyyW4pK6--X5WcJWHNOHmlPuj-3bSuW3g0snPM8=w340-h240-no" alt="enter image description here" title=""></p>
<p>水平方向にx軸、 <br>
鉛直上向きにy軸をとります。</p>
<p>初速 <script type="math/tex" id="MathJax-Element-1">v_0</script> <br>
偏角 <script type="math/tex" id="MathJax-Element-2">θ</script> <br>
のとき、 <br>
斜方投射してからの経過時間 <script type="math/tex" id="MathJax-Element-3">t</script> における <br>
物体の速度および座標 <script type="math/tex" id="MathJax-Element-4">(x,y)</script>は</p>
<p><script type="math/tex; mode=display" id="MathJax-Element-5">
x=(v_0\cosθ)t
</script></p>
<p><script type="math/tex; mode=display" id="MathJax-Element-6">
y = (v_0\sinθ)t - gt^2
</script></p>
<p>という恒等式で表せます。(<script type="math/tex" id="MathJax-Element-7">g</script>は 重力加速度=9.8 m/ss)</p>
<p>これがニュートン物理学の時間発展する恒等式です。</p>
<blockquote>
<p>. タイガー・ウッズの平均ヘッドスピード57.5m/s ボール初速度85.0~86.5m/sと公表されています。</p>
</blockquote>
<p>らしいですから、 <br>
初速を85.0m/s、偏角30度とし、空気抵抗を無視したゴルフのスーパーショットっぽい斜方投射を上記時間発展する恒等式をそのまま用いて、 <br>
<code>worldtimestream</code> <br>
<code>React</code>を利用して関数型リアクティブプログラミングのコードを書くと以下のようになります。</p>
<h2 id="code">code</h2>
<h4 id="恒等式の宣言">恒等式の宣言</h4>
<p><code>worldtimestream</code>で、物理系の時間<code>t</code>をコードに恒常的にマップするworldengineとして宣言しておきます。</p>
<pre class="prettyprint"><code class=" hljs php">___.world = ___((t) => { <span class="hljs-comment">// world engine</span>
<span class="hljs-comment">//===========================================================================</span>
});
</code></pre>
<p>その中で、恒等式の初期設定が宣言され、</p>
<pre class="prettyprint"><code class="language-js hljs "> <span class="hljs-keyword">var</span> V0 = <span class="hljs-number">85.0</span>; <span class="hljs-comment">// m/s</span>
<span class="hljs-keyword">var</span> deg = <span class="hljs-number">30</span>; <span class="hljs-comment">//degree</span>
<span class="hljs-keyword">var</span> THETA = deg / <span class="hljs-number">180</span> * <span class="hljs-built_in">Math</span>.PI; <span class="hljs-comment">//radian</span>
<span class="hljs-keyword">var</span> G = <span class="hljs-number">9.8</span>; <span class="hljs-comment">//gravity const</span></code></pre>
<p>恒等式そのものが<code>t</code>の時間関数<code>coordinateEquation</code>で宣言されています。</p>
<pre class="prettyprint"><code class=" hljs javascript"> <span class="hljs-keyword">var</span> coordinateEquation = (t) => {
<span class="hljs-keyword">var</span> x = V0 * <span class="hljs-built_in">Math</span>.cos(THETA) * t;
<span class="hljs-keyword">var</span> y = V0 * <span class="hljs-built_in">Math</span>.sin(THETA) * t - G * <span class="hljs-built_in">Math</span>.pow(t, <span class="hljs-number">2</span>);
<span class="hljs-keyword">return</span> {
x: x,
y: y
};
};</code></pre>
<p>これで、すべての関係性は記述されていますが、この時間発展する時間関数の恒等式を実際の画面表示をするための「計算」は一切なされていません。</p>
<p>つまり、ここまでは、物理系と物理量コードのストリームとの関係性が100%抽象世界として宣言されただけで、コンピュータのハードウェアでその関係性の具現化、つまりふたたび、そのストリームが具体的な物理系としての画面に反映する「計算」タイミングなどの指示は行われていません。</p>
<h4 id="計算からの画面描写画面描写も関係式の計算に他ならない">計算からの画面描写(画面描写も関係式の計算に他ならない)</h4>
<p>この「計算」部分を一手に司るのが、Reactコンポーネント<code>ReactComponent</code>です。</p>
<p><code>componentWillMount()</code>において、</p>
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-reserved">var</span> <span class="hljs-function"><span class="hljs-title">init</span> = <span class="hljs-params">()</span> =></span> {
<span class="hljs-reserved">var</span> T0 = t();
<span class="hljs-reserved">var</span> <span class="hljs-function"><span class="hljs-title">f</span> = <span class="hljs-params">()</span> =></span> {
___.world = ___coordinate.appear(coordinateEquation((t() - T0) / <span class="hljs-number">1000</span>));
};
___.world = t.computeInterval(f, <span class="hljs-number">10</span>); <span class="hljs-regexp">//</span>calculate <span class="hljs-number">10</span>milsec resolution
};
___.world = t.computeTimeout(init, <span class="hljs-number">0</span>);</code></pre>
<p>で、<code>___coordinate</code>というストリームを、10ミリセカンドの解像度をもって<code>t</code>の時間関数<code>coordinateEquation</code>で「計算」することを宣言します。</p>
<p><code>___x={___()} ___y={___()}</code>というReactが描写するコンポーネントのXY座標に相当する、<code>worldtimestream</code>のストリームとして定義されたプロパティは、<code>___coordinate</code>が「計算」されると、適切な画面座標に投影しながら</p>
<pre class="prettyprint"><code class="language-js hljs "> <span class="hljs-keyword">var</span> com = <span class="hljs-keyword">this</span>;
___.world = ___coordinate.compute((coordinate) => {
___.world = com.props.___x.appear(<span class="hljs-number">50</span> + coordinate.x * Drawscale);
___.world = com.props.___y.appear(<span class="hljs-number">300</span> - coordinate.y * Drawscale);
com.forceUpdate();
});</code></pre>
<p>コンポーネントを再描画します。</p>
<p>このように、FRPライブラリ<code>worldtimestream</code>とReactを利用することで、簡潔に、 <br>
<a href="https://ja.wikipedia.org/wiki/%E6%99%82%E9%96%93%E7%99%BA%E5%B1%95">時間発展</a>する物理系、つまり、私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)を実現可能です。</p>
<pre class="prettyprint"><code class="language-js hljs ">___.world = ___((t) => { <span class="hljs-comment">// world engine </span>
<span class="hljs-comment">//=========================================================================== </span>
<span class="hljs-comment">//MKS system of units </span>
<span class="hljs-keyword">var</span> ___coordinate = ___();
<span class="hljs-keyword">var</span> V0 = <span class="hljs-number">85.0</span>; <span class="hljs-comment">// m/s </span>
<span class="hljs-keyword">var</span> deg = <span class="hljs-number">30</span>; <span class="hljs-comment">//degree </span>
<span class="hljs-keyword">var</span> THETA = deg / <span class="hljs-number">180</span> * <span class="hljs-built_in">Math</span>.PI; <span class="hljs-comment">//radian </span>
<span class="hljs-keyword">var</span> G = <span class="hljs-number">9.8</span>; <span class="hljs-comment">//gravity const </span>
<span class="hljs-keyword">var</span> coordinateEquation = (t) => {
<span class="hljs-keyword">var</span> x = V0 * <span class="hljs-built_in">Math</span>.cos(THETA) * t;
<span class="hljs-keyword">var</span> y = V0 * <span class="hljs-built_in">Math</span>.sin(THETA) * t - G * <span class="hljs-built_in">Math</span>.pow(t, <span class="hljs-number">2</span>);
<span class="hljs-keyword">return</span> {
x: x,
y: y
};
};
<span class="hljs-comment">//============================================================== </span>
<span class="hljs-keyword">var</span> Drawscale = <span class="hljs-number">4</span>; <span class="hljs-comment">//4 dot = 1 meter </span>
<span class="hljs-keyword">var</span> ReactComponent = React.createClass(
{
componentWillMount() {
<span class="hljs-keyword">var</span> com = <span class="hljs-keyword">this</span>;
___.world = ___coordinate.compute((coordinate) => {
___.world = com.props.___x.appear(<span class="hljs-number">50</span> + coordinate.x * Drawscale);
___.world = com.props.___y.appear(<span class="hljs-number">300</span> - coordinate.y * Drawscale);
com.forceUpdate();
});
<span class="hljs-keyword">var</span> init = () => {
<span class="hljs-keyword">var</span> T0 = t();
<span class="hljs-keyword">var</span> f = () => {
___.world = ___coordinate.appear(coordinateEquation((t() - T0) / <span class="hljs-number">1000</span>));
};
___.world = t.computeInterval(f, <span class="hljs-number">10</span>); <span class="hljs-comment">//calculate 10milsec resolution </span>
};
___.world = t.computeTimeout(init, <span class="hljs-number">0</span>);
},
render() {
<span class="hljs-keyword">var</span> com = <span class="hljs-keyword">this</span>;
<span class="hljs-keyword">var</span> el = (
<span class="xml"><span class="hljs-tag"><<span class="hljs-title">div</span>></span>
<span class="hljs-tag"><<span class="hljs-title">h1</span>></span>For new shot, Just Reload the browser page<span class="hljs-tag"></<span class="hljs-title">h1</span>></span>
<span class="hljs-tag"><<span class="hljs-title">svg</span> <span class="hljs-attribute">height</span> = "<span class="hljs-attribute">100</span>%" <span class="hljs-attribute">width</span> = "<span class="hljs-attribute">100</span>%"></span>
<span class="hljs-tag"><<span class="hljs-title">circle</span> <span class="hljs-attribute">r</span>=<span class="hljs-value">"5"</span> <span class="hljs-attribute">fill</span>=<span class="hljs-value">"blue"</span>
<span class="hljs-attribute">cx</span> = {<span class="hljs-attribute">this.props.___x.t</span>()}
<span class="hljs-attribute">cy</span> = {<span class="hljs-attribute">this.props.___y.t</span>()}/></span>
<span class="hljs-tag"></<span class="hljs-title">svg</span>></span>
<span class="hljs-tag"></<span class="hljs-title">div</span>></span>
);
return el;
}
});
var mount = React.render(<span class="hljs-tag"><<span class="hljs-title">ReactComponent</span> <span class="hljs-attribute">___x</span>=<span class="hljs-value">{___()}</span> <span class="hljs-attribute">___y</span>=<span class="hljs-value">{___()}</span> /></span>, document.body);
//==============================================================
//===========================================================================
});
</span></code></pre>
<h3 id="live-demo">Live Demo</h3>
<p><a href="http://sakurafunctional.github.io/demo/react-physics/">http://sakurafunctional.github.io/demo/react-physics/</a></p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-69263221954628661362015-07-30T14:42:00.001+09:002015-08-05T07:43:39.812+09:00nodeのFRP(関数型リアクティブ)ライブラリ`worldcomponent`の後継、`worldtimestream`の公開<p>nodeのFRP(関数型リアクティブ)ライブラリ<code>worldcomponent</code>の後継、<code>worldtimestream</code>をnpmで公開をしました。</p>
<p><a href="https://www.npmjs.com/package/worldtimestream">https://www.npmjs.com/package/worldtimestream</a> <br>
<a href="https://github.com/kenokabe/worldtimestream">https://github.com/kenokabe/worldtimestream</a></p>
<p>FacebookのJSXで開発テストしており、ライブラリもテストも最終的にバニラJavaScriptへコンパイルしています。</p>
<h2 id="install">Install</h2>
<h3 id="node-iojs">node / io.js</h3>
<blockquote>
<p>npm install worldtimestream</p>
</blockquote>
<h3 id="webbrowser">WebBrowser</h3>
<p><a href="https://raw.githubusercontent.com/kenokabe/worldtimestream/master/js/worldtimestream.js">https://raw.githubusercontent.com/kenokabe/worldtimestream/master/js/worldtimestream.js</a></p>
<p>をコピーペースト</p>
<h2 id="rationale">Rationale</h2>
<p>アイデアは、前回の記事です。</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/07/title.html">関数型プログラミングと古典物理学の密接な関係</a></p>
<p>Date.now() はストリームへ透過に参照する時間関数ですが「ユーザの現在時間」が暗黙に引数として渡されているため理解しにくいです。</p>
<p>より物理系と時間という物理量の概念を関数型のコードで明示できるように、FRPライブラリをハックしました。</p>
<p><code>worldtimestream</code>は命名したとおり、時間軸上のストリームです。 <br>
時間要素に依存しているので、<code>worldtimestream</code>のストリームは物理量です。</p>
<pre class="prettyprint"><code class=" hljs coffeescript">___.world = ___<span class="hljs-function"><span class="hljs-params">((t) => {
<span class="hljs-regexp">//</span>...........
})</span>;</span></code></pre>
<p>という時間発展の恒等式を宣言することにより、 <br>
古典物理学の物理量である時間変数<code>t</code>が得られます。</p>
<p>別に時間変数<code>now</code>と宣言しても構いませんが、現在時間というのは、なかなか哲学的素養がないと理解しにくい概念であるので、恒等的な値<code>t</code>として宣言します。</p>
<h4 id="以下すべて基礎となる上記のスコープ内で記述します">以下、すべて基礎となる上記のスコープ内で記述します。</h4>
<p>上記コードにより、</p>
<h4 id="時間発展しているworldtimestreamのストリームの物理系の物理量t">時間発展している<code>worldtimestream</code>のストリームの物理系の物理量<code>t</code></h4>
<p>が、↓</p>
<h4 id="時間発展しているユーザが現在実行しているコード">時間発展しているユーザが現在実行しているコード</h4>
<p>へ恒等的に<code>map</code>されているので、 <br>
<code>t()</code>とすることにより、それぞれの瞬間のユーザは透過にその値を参照できます。</p>
<p>つまりそれが、時間発展している世界のそれぞれの瞬間のユーザにとっての「現在時刻」であるということになります。</p>
<p>たとえば、</p>
<pre class="prettyprint"><code class=" hljs avrasm"> ___<span class="hljs-preprocessor">.world</span> = ___<span class="hljs-preprocessor">.log</span>(t())<span class="hljs-comment">;</span></code></pre>
<p>という恒等式を宣言しておくと、 <br>
このコードを意識的に計算するアクションを起こした、すべてのユーザのそれぞれの現在時刻がコンソールへ表示されます。</p>
<p>また、ストリーム<code>___a</code>を宣言しておき、</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute"> var ___a </span>=<span class="hljs-string"> ___();</span></code></pre>
<pre class="prettyprint"><code class=" hljs coffeescript"> ___.world = ___a.compute<span class="hljs-function"><span class="hljs-params">(() => {
___.world = ___.log(t(), <span class="hljs-string">'a'</span>, ___a.t());
})</span>;</span></code></pre>
<p>と恒等式を宣言しておくと、</p>
<p>時間発展するストリーム<code>___a</code>に <br>
「過去」から「未来」方向 <br>
あるいは <br>
「未来」から「過去」方向 <br>
で変化が生じた瞬間に、ユーザの関与なしに任意のコードを自動計算させることが可能です。</p>
<pre class="prettyprint"><code class=" hljs coffeescript"> <span class="hljs-reserved">var</span> <span class="hljs-function"><span class="hljs-title">f0</span> = <span class="hljs-params">()</span> =></span> {
___.world = ___.log(<span class="hljs-string">'test start'</span>);
___.world = ___a.appear(<span class="hljs-number">0</span>);
};
___.world = t.computeTimeout(f0, <span class="hljs-number">0</span>);</code></pre>
<p>というのは、このコード全体が任意のユーザによって最初に実行された瞬間<code>t</code>における、ストリーム<code>___a</code>の値を宣言しています。</p>
<pre class="prettyprint"><code class=" hljs avrasm"> var f = () => {
___<span class="hljs-preprocessor">.world</span> = ___a<span class="hljs-preprocessor">.appear</span>(___a<span class="hljs-preprocessor">.t</span>() + <span class="hljs-number">1</span>)<span class="hljs-comment">;</span>
}<span class="hljs-comment">;</span>
___<span class="hljs-preprocessor">.world</span> = t<span class="hljs-preprocessor">.computeInterval</span>(f, <span class="hljs-number">1000</span>)<span class="hljs-comment">;</span></code></pre>
<p>とすることで、そこ瞬間を起点として、ストリームの時間軸上で「未来」方向に1秒間のインターバルの値を宣言しています。</p>
<p>この場合は、ストリーム<code>___a</code>のそのインターバル地点のある時間<code>t</code>における値が参照されており、その値に1を加えた値をストリーム<code>___a</code>の未来方向の次の瞬間に現れているという「関係性」を宣言しています。</p>
<p>念の為ですが、ストリーム<code>___a</code>は過去から未来まで時間軸上でイミュータブルで変化しません。ストリーム上に離散する値の関係性が上記コードによって宣言されているだけです。</p>
<p>たとえばこのストリーム<code>___a</code>をオブジェクト参照などで、コピーあるいは「バックアップ」すれば、過去から未来までまったく同じストリームがコピーされます。 <br>
つまり、未来方向の任意の時間で、 <br>
<code>___a</code>の値が<code>appear</code>されるという宣言があるのならば、まったく同じイミュータブルなストリームである<code>___b</code>もその同時の瞬間に値に「変化」が起こるストリームとして宣言されます。</p>
<p>過去未来の時間軸上で別の運命をもつ別のストリームを作成するには、同様に</p>
<pre class="prettyprint"><code class=" hljs fix"><span class="hljs-attribute">var ___b </span>=<span class="hljs-string"> ___();</span></code></pre>
<p>というような別個の独立したストリームを宣言します。</p>
<p>もし、この独立したストリーム<code>___b</code>が、 <br>
ストリーム<code>___a</code>と関係がある場合は、その都度その関係式を宣言します。</p>
<p>たとえば、 <br>
<code>___a</code>のストリーム上のある瞬間の値が、 <br>
<code>___b</code>のストリーム上の同一瞬間の値と等しくなり、「未来方向」へはずっとその値のままである、という我々が日常レベルで使う用語としての「値のバックアップ」という関係を宣言したいのであれば、</p>
<pre class="prettyprint"><code class=" hljs avrasm"> ___<span class="hljs-preprocessor">.world</span> = ___b<span class="hljs-preprocessor">.appear</span>(a<span class="hljs-preprocessor">.t</span>())<span class="hljs-comment">;</span></code></pre>
<p>とすれば簡単に出来ます。</p>
<p>あるいは、</p>
<p><code>___a</code>と<code>___b</code>は、物理量<code>t</code>に依存しない形で、恒等的な関係が存在するとき、</p>
<p>たとえば</p>
<p><code>___b = ___a x 5</code> <br>
の関係を宣言したい場合は、</p>
<pre class="prettyprint"><code class=" hljs avrasm"> ___<span class="hljs-preprocessor">.world</span> = ___a<span class="hljs-preprocessor">.compute</span>((<span class="hljs-built_in">x</span>) => {
___<span class="hljs-preprocessor">.world</span> = ___b<span class="hljs-preprocessor">.appear</span>(<span class="hljs-built_in">x</span> * <span class="hljs-number">5</span>)<span class="hljs-comment">;</span>
})<span class="hljs-comment">;</span></code></pre>
<p>とすれば簡単に宣言できます。</p>
<h2 id="test">Test</h2>
<p><strong>test.jsx</strong></p>
<pre class="prettyprint"><code class=" hljs coffeescript"><span class="hljs-string">'use strict'</span>;
<span class="hljs-reserved">var</span> ___ = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./worldtimestream.js'</span>);
___.world = ___<span class="hljs-function"><span class="hljs-params">((t) => {
<span class="hljs-reserved">var</span> ___a = ___();
<span class="hljs-reserved">var</span> ___b = ___();
___.world = ___a.compute(() => {
___.world = ___.log(t(), <span class="hljs-string">'a'</span>, ___a.t());
});
___.world = ___b.compute(() => {
___.world = ___.log(t(), <span class="hljs-string">'b'</span>, ___b.t());
});
___.world = ___a.compute((x) => {
___.world = ___b.appear(x * <span class="hljs-number">5</span>);
});
<span class="hljs-reserved">var</span> f0 = () => {
___.world = ___.log(<span class="hljs-string">'test start'</span>);
___.world = ___a.appear(<span class="hljs-number">0</span>);
};
<span class="hljs-reserved">var</span> f = () => {
___.world = ___a.appear(___a.t() + <span class="hljs-number">1</span>);
};
___.world = t.computeTimeout(f0, <span class="hljs-number">0</span>);
___.world = t.computeInterval(f, <span class="hljs-number">1000</span>);
})</span>;
</span></code></pre>
<p>実際に、<strong>test.jsx</strong>を実行した結果は以下のようになります。</p>
<blockquote>
<p>1438234695190 ‘a’ 0 <br>
1438234695200 ‘b’ 0 <br>
1438234696204 ‘a’ 1 <br>
1438234696204 ‘b’ 5 <br>
1438234697206 ‘a’ 2 <br>
1438234697206 ‘b’ 10 <br>
1438234698208 ‘a’ 3 <br>
1438234698208 ‘b’ 15 <br>
1438234699209 ‘a’ 4 <br>
1438234699209 ‘b’ 20 <br>
1438234700211 ‘a’ 5 <br>
1438234700211 ‘b’ 25 <br>
1438234701213 ‘a’ 6 <br>
1438234701213 ‘b’ 30 <br>
1438234702214 ‘a’ 7 <br>
1438234702214 ‘b’ 35 <br>
1438234703215 ‘a’ 8 <br>
1438234703215 ‘b’ 40</p>
</blockquote>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-31594803878320748682015-07-30T07:57:00.001+09:002015-07-30T14:58:34.178+09:00関数型プログラミングと古典物理学の密接な関係<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a>のコメント欄で計算機科学の基礎としての、プログラミングの「時間」要素、そして「時間」を考えるとは即ち、物理学を考えることである、という重要な論点が確認されています。</p>
<p>JavaScriptの<code>Date.now()</code>をimmutableなストリームと、透過な参照をする関数として考えるとき、誤解されやすいのが、</p>
<blockquote>
<p><a href="https://ja.wikipedia.org/wiki/%E5%8F%82%E7%85%A7%E9%80%8F%E9%81%8E%E6%80%A7">参照透過性(さんしょうとうかせい、英: Referential transparency)</a>は、計算機言語の概念の一種で、文脈によらず式の値はその構成要素(例えば変数や関数)によってのみ定まるということを言う。 具体的には変数の値は最初に定義した値と常に同じであり、関数は同じ変数を引数として与えられれば同じ値を返すということになる。 当然変数に値を割り当てなおす演算である代入 (Assignment) を行う式は存在しない。 このように参照透過性が成り立っている場合、ある式の値、例えば関数値、変数値についてどこに記憶されている値を参照しているかということは考慮する必要がない、即ち参照について透過的であるといえる。</p>
</blockquote>
<p>のうち「文脈によらず」「関数は同じ変数を引数として与えられれば同じ値を返す」という要素だと思います。 <br>
@nonstarter氏が感じる「謎」</p>
<blockquote>
<p><code>t1 = Date.now(); (0〜9まで足してコンソールに表示); t2 = Date.now(); console.log(t1 == t2);</code> <br>
と <br>
<code>t1 = Date.now(); (0〜9まで足してコンソールに表示); t2 = t1; console.log(t1 == t2);</code> <br>
とで結果が異なる、というDate.now()の単純明瞭この上ない「参照不透明性」をどうするつもりなのかはまったく謎のママなわけです。</p>
</blockquote>
<p>はまさにこの要素の疑念だと読み解けます。</p>
<p>まず、コメント欄で誰も注意していないので、厳しく注意しておきますと、この@nonstarter氏によるコードは関数型プログラミング、あるいは宣言型プログラミングのコードでもなんでもありません。</p>
<p>関数型・宣言型でない理由は単純で、</p>
<pre class="prettyprint"><code class=" hljs javascript">t1 = <span class="hljs-built_in">Date</span>.now(); <span class="hljs-comment">// ① </span>
<<span class="hljs-number">0</span>〜<span class="hljs-number">9</span>まで足してコンソールに表示するための処理コード> ; <span class="hljs-comment">// ②</span>
t2 = <span class="hljs-built_in">Date</span>.now(); <span class="hljs-comment">// ③</span></code></pre>
<p>はコードが <br>
ステップ ① <br>
ステップ ② <br>
ステップ ③ <br>
というように、上から下へ時間遷移とともに流れ、値はコードの上下関係、時間の前後に依存する、という命令型の発想を前提として書かれている命令型のコードなので、そもそもが「参照不透明性」だとか関数型のコードとしては議論するのは間違いです。 <br>
ステップ ① <br>
と <br>
ステップ ③ <br>
では「時間」が違うので、Dateというストリームに参照透明にアクセスする時間関数now()の返り値は異なって当然です。</p>
<p>正しい関数型・宣言型のコードを書くと、</p>
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> f = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
console.log(<span class="hljs-built_in">Date</span>.now());
};
<span class="hljs-keyword">var</span> dummy1 = setTimeout(f, <span class="hljs-number">0</span>); <span class="hljs-comment">//ユーザがコードを実行した瞬間に即時実行</span>
<span class="hljs-keyword">var</span> dummy2 = setTimeout(f, <span class="hljs-number">1000</span>); <span class="hljs-comment">//ユーザがコードを実行した1秒後に実行</span></code></pre>
<p>こうなります。コードのロジックがコードの上下関係や、時間の前後関係にまったく依存していないことに注意してください。この「非同期」で宣言型のコードでは、ステップ①②③などありません。</p>
<p><code><0〜9まで足してコンソールに表示するための処理コード> ;</code> <br>
を関数型で書くならば、その処理の終了のコールバック関数で書きます。@nonstarter氏が書いたような命令の終了の「同期」を待つような命令型のコードで書いてはいけません。</p>
<p>now()の実引数が空だから、「関数は同じ変数を引数として与えられれば同じ値を返す」事を考えるとおかしい!と思うのも、すでにコメント欄で反論されているとおり、間違った考えです。 <br>
now()というのは、その特性を表す字面でも明確ですが、時間関数であって、 <strong>値はユーザの現在時間に依存する</strong>のです。 <br>
数学的には、概念的には、<strong>コードに表記されずとも暗黙に、ユーザの現在時間が実引数として渡される関数</strong>です。</p>
<p>now()という時間関数が返す<strong>値はユーザの現在時間に依存する</strong>というのは、</p>
<p>@chimetorch氏が引用したコード <br>
<a href="http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove_dom">http://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_onmousemove_dom</a></p>
<pre class="prettyprint"><code class=" hljs javascript">document.getElementById(<span class="hljs-string">"myDIV"</span>).onmousemove = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>myFunction(event)};
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">myFunction</span><span class="hljs-params">(e)</span> {</span>
<span class="hljs-keyword">var</span> x = e.clientX;
<span class="hljs-keyword">var</span> y = e.clientY;
<span class="hljs-keyword">var</span> coor = <span class="hljs-string">"Coordinates: ("</span> + x + <span class="hljs-string">","</span> + y + <span class="hljs-string">")"</span>;
document.getElementById(<span class="hljs-string">"demo"</span>).innerHTML = coor;
}</code></pre>
<p>の<code>event</code>の<strong>値はユーザの現在時間に依存する</strong>というのと等価ですし、</p>
<p>elmのコード</p>
<pre class="prettyprint"><code class=" hljs vhdl">import Graphics.Element exposing (..)
import Mouse
main : <span class="hljs-keyword">Signal</span> Element
main = <span class="hljs-keyword">Signal</span>.<span class="hljs-keyword">map</span> show countClick
countClick : <span class="hljs-keyword">Signal</span> Int
countClick = <span class="hljs-keyword">Signal</span>.foldp (\clk count -> count + <span class="hljs-number">1</span>) <span class="hljs-number">0</span> Mouse.clicks</code></pre>
<p>の「シグナル」の<strong>インデックス値はユーザの現在時間に依存する</strong>のと等価です。</p>
<p>もちろん、上記elmの「シグナル」同様に、JavaScriptのDateストリームをFRP的に拡張して、</p>
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> f = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(now)</span>{</span>console.log(now);};
<span class="hljs-keyword">var</span> dummy = <span class="hljs-built_in">Date</span>
.interval(<span class="hljs-number">1000</span>) <span class="hljs-comment">// specifies a 1sec interval between each element</span>
.map(f);</code></pre>
<p>と書けるようにするのは、大変意義あるハックですが、標準で、</p>
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> f = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>{</span>console.log(<span class="hljs-built_in">Date</span>.now());};
<span class="hljs-keyword">var</span> dummy = setInterval(f, <span class="hljs-number">1000</span>);</code></pre>
<p>書くほうが楽です。</p>
<p>私が書いた、<code>worldcomponent</code>も、実用的な観点から、 <br>
Date.now()と同様に、now()関数で直接値が参照できるように設計しています。これまで触った数々のFRPライブラリの経験から、この仕様のほうが取り回ししやすいという結論です。</p>
<p>もしくは、</p>
<pre class="prettyprint"><code class=" hljs lasso"><span class="hljs-built_in">var</span> main <span class="hljs-subst">=</span> <span class="hljs-built_in">Date</span><span class="hljs-built_in">.</span><span class="hljs-built_in">map</span>((now) <span class="hljs-subst">=></span> {
<span class="hljs-comment">//now はユーザの現在時刻</span>
<span class="hljs-comment">//ここにすべてのコードを記述していく</span>
});</code></pre>
<p>と暗黙でなく明示的な表記にすれば、関数型のコードとしてより美しいかもしれません。 <br>
しかし、これはただ <br>
明示的な構造の中にnowと書くか、 <br>
暗黙的な実引数でDate.now()と書くかの違いにすぎません。</p>
<p>いずれにせよ、@nonstarter氏による命令型のコード以外、私が書いたものも含め上記すべての関数型・宣言型のコードは、</p>
<ul>
<li><strong>コードのロジックがコードの上下関係や、時間の前後関係にまったく依存していない</strong></li>
</ul>
<p>のですが、</p>
<ul>
<li><strong>コードの中の値はユーザの現在時間に依存する</strong></li>
</ul>
<p>ことに注意してください。</p>
<p>前者と後者の区別がつくプログラマは、関数型プログラミング、計算機科学のほんとうの基礎の素養がきちんとありますが、<em>前者と後者の区別がつかず、関数型でなく命令型のコードを書きながら『単純明瞭この上ない「参照不透明性」』などと発言してしまう人</em>は勉強しなおしたほうがよろしいでしょう。</p>
<p>前者については、命令型でない関数型の基礎なので、特にいまさら説明を加える必要はないと思います。 </p>
<p>後者については、関数型プログラミングで、時間変化する領域に踏み込むことになるので、多少の説明が必要だと思います。</p>
<p>念の為、もう何度も繰り返しているのですが、この部分を説明していのが、 <br>
私の著書 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/04/iq145.html">関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間</a> <br>
やSICP <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/05/99iq145jkiq145jkmitsicp.html">99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう</a> <br>
であるということです。</p>
<h2 id="後者-コードの中の値はユーザの現在時間に依存するつまり関数型プログラミングと古典物理学の密接な関係について解説します">(後者) <strong>コードの中の値はユーザの現在時間に依存する</strong>、つまり、関数型プログラミングと古典物理学の密接な関係について解説します。</h2>
<p>まず、根本の根本の部分ですが、このように時間の値そのものを取り扱うコードにしても、イベント(シグナル)を使うマウスポインタ、クリックのコードにしても、値は時間変化します。</p>
<ul>
<li><strong>コードの中の値はユーザの現在時間に依存する</strong></li>
</ul>
<p>時間変化するから、「文脈によって変わる」、だから「参照不透明」なミュータブルと考えるのは間違いです。</p>
<ul>
<li><strong>コードのロジックがコードの上下関係や、時間の前後関係にまったく依存していない</strong></li>
</ul>
<p>というのが、「文脈によって変わらない」という意味で、「参照透明」であるということです。</p>
<p>私、そしてSICPの著者が関数型プログラミング、計算機科学の基礎と不可分として使う物理学の用語では、<a href="https://ja.wikipedia.org/wiki/%E6%99%82%E9%96%93%E7%99%BA%E5%B1%95">時間発展</a>と言うのですが、</p>
<blockquote>
<p>時間発展(じかんはってん)とは、時間が進むことで物理系が変化することである。 <br>
古典物理学における時間発展とは、物理量の値が時間によって変化することである。</p>
</blockquote>
<p><strong>変化しているのは、時間が進むことで変化する我々の世界の「物理系」「物理量」であること</strong>を理解してください。</p>
<p>古典物理学にせよ、関数型プログラミングのコードにせよ、それは数学なので、「参照不透明」に値が変化することなどはありえません。</p>
<p>古典物理学で絶対時間<code>t</code>が時間が進む(様に見えている)ことで物理系が変化し、物理量の値が時間発展するからといって、絶対時間<code>t</code>が破壊的代入されている、わけではありませんし、関数型プログラミングにしても全く同様です。</p>
<p>正しい関数型・宣言型のコード</p>
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> f = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
console.log(<span class="hljs-built_in">Date</span>.now());
};
<span class="hljs-keyword">var</span> dummy1 = setTimeout(f, <span class="hljs-number">0</span>); <span class="hljs-comment">//ユーザがコードを実行した瞬間に即時実行</span>
<span class="hljs-keyword">var</span> dummy2 = setTimeout(f, <span class="hljs-number">1000</span>); <span class="hljs-comment">//ユーザがコードを実行した1秒後に実行</span></code></pre>
<p>は、時間が進むことで変化する我々の世界という「物理系」において不変(immutable)で、参照透過です。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-12428230824354353672015-07-25T21:18:00.001+09:002015-07-25T23:42:42.843+09:00worldcomponent関数リアクティブプログラミング(FRP)ライブラリの破壊的代入について<p>拙書の延長で、<a href="http://kenokabe-techwriting.blogspot.jp/2015/04/worldcomponent-tiny-frp.html">当ブログにて公開している、関数リアクティブプログラミング(FRP)ライブラリ</a> <br>
<code>worldcomponent</code>について、拙書をレビューすると称する悪意あるQiita記事、<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a>のコメントで、激しい論争が繰り広げれられており、<strong>強い関心</strong>を持って読み通しました。</p>
<p>この記事では著者/開発者としての見解を提示します。</p>
<p><code>worldcomponent</code>がオブジェクトの値の破壊的代入による実装がある、との批判ですが、その通りです。</p>
<p><a href="https://github.com/sakurafunctional/worldcomponent/blob/master/worldcomponent.js">https://github.com/sakurafunctional/worldcomponent/blob/master/worldcomponent.js</a></p>
<p>これは、JavaScriptのオブジェクトの値が破壊的代入されたときに、イベントが発生する<code>Object.defineProperties</code>の<code>set</code>の特性を利用して実装されているライブラリです。 <br>
(<strong>このような言語仕様の低層のハックが原理的に関数型であるわけがない</strong>)</p>
<pre class="prettyprint"><code class=" hljs actionscript">Object.defineProperties(value,
{
val: <span class="hljs-comment">//value.val</span>
{
<span class="hljs-keyword">get</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span>
{</span>
<span class="hljs-keyword">return</span> state;
},
<span class="hljs-keyword">set</span>: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(x)</span>
{</span>
state = x;
computingF.map(
<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(f)</span>
{</span>
f(x);
});
<span class="hljs-keyword">return</span>;
}
}
});</code></pre>
<p>この特性により、オブジェクトの変更をWATCHするためのポーリング実装などは不要で、かなり効率的で無駄のない実用に耐えるFRP機構を実現しています。</p>
<p>すでに当該コメント欄でも複数名の有志により見解が示されていますが、拙書では「ハードウェアモード」の操作として表現もしているとおり、根本的に関数型プログラミングのパラダイムを実現するために、低層のライブラリまで関数型で書く必要性も合理性も一切ありませんし、実際にほとんどのJavaScriptやnode.jsで利用可能な公開されている関数ライブラリはそのライブラリの実装自体(ライブラリのソースコード)は関数型で書かれておらず命令型(もちろん破壊的代入も)で書かれています。<code>worldcomponent</code>もその一つの関数ライブラリで、利用することで関数型のコードが書けます。</p>
<p><code>Object.defineProperties</code>の<code>set</code>というオブジェクトの値への破壊的代入を「感知」する手法を利用しているので、オブジェクトの参照への破壊的代入をもって実装すると、この機構が機能することはありません。</p>
<p>たとえば、</p>
<pre class="prettyprint"><code class=" hljs javascript"> appear: <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(a)</span> {</span>
<span class="hljs-keyword">var</span> f1 = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {</span>
<span class="hljs-comment">// value.val = a; </span>
<span class="hljs-comment">//`Object.defineProperties`の`set`機構に不可欠な「値」の破壊的代入をコメントアウト</span>
<span class="hljs-keyword">var</span> o = {val: a}; <span class="hljs-comment">//新規オブジェクトの作成</span>
value = o; <span class="hljs-comment">//オブジェクト参照への破壊的代入</span>
};
<span class="hljs-keyword">return</span> f1;
},</code></pre>
<p>とコードを変更すると、<code>Object.defineProperties</code>の<code>set</code>はトリガーされません。つまり、原理的にオブジェクト参照への破壊的代入ではこのライブラリは機能しない設計になっています。</p>
<h2 id="javascriptの関数型プログラミングのbestpractice">JavaScriptの関数型プログラミングのBestPractice</h2>
<p>JavaScriptは基本的に参照の値渡し(参考 <a href="http://qiita.com/mozisan/items/1b9d4bf5a1bb341dd354">JavaScriptはオブジェクトについて参照渡しだなんて、信じない</a>)なので、通常 <br>
<strong><code>=</code> (イコール)</strong> <br>
で参照であれ、値であれ、オブジェクトを<em>バックアップ</em>をしたと見做すのは危険なので、行うべきではありません。</p>
<p>コメント欄に親切に紹介もされていましたが、このような場合のBestPracticeとしては、これも公開されている<a href="http://underscorejs.org/">undersocre</a>や<a href="https://lodash.com/">lodash</a>、<a href="https://facebook.github.io/immutable-js/">Immutable</a>(全部摂書でも紹介しました)の関数ライブラリのオブジェクトのコピー関数を活用して、言語仕様の詳細をライブラリ実装以下に隠蔽してしまい、非関数型的なパラダイムの議論を回避します。</p>
<p><code>worldcomponent</code>の利用も関数型のパラダイムにおいて、その実装レベルが問題となることはまったくありません。</p>
<p>また、<code>worldcomponent</code>の実装について、@Lambada氏により、<em>無駄に複雑なスパゲッティ・プログラム</em>などと繰り返し<strong>激しい誹謗中傷</strong>が繰り広げられております。</p>
<p>私としましては、<code>Object.defineProperties</code>の<code>set</code>を使ってFRPを効率的に実現するために、無駄がないように極限まで洗練させてコードを公開したつもりですが、すでに@Lambada氏は現段階で<code>worldcomponent</code>の仕様も含めて十二分に精査されたことでしょうから、もちろん<code>Object.defineProperties</code>の<code>set</code>を使わない別の方法でも構わないですし、氏が無駄のない複雑でないコードを提示していただければ助かります。氏のより洗練されたコードで代替した上で<code>npm</code>のバージョンを上げて公開するつもりなのでよろしくお願いします。</p>
<h2 id="なぜ関数型プログラミングのコードについてオブジェクト参照だとか状態オブジェクトの再利用の話を熱弁しているのか">なぜ、関数型プログラミングのコードについて「オブジェクト参照」だとか「状態オブジェクトの再利用」の話を熱弁しているのか??</h2>
<p>@Lambada氏による珍妙な主張、オブジェクト参照による<em>バックアップ</em>であるなら、</p>
<blockquote>
<p>過去の状態への巻き戻しや状態オブジェクトの再利用等が容易</p>
</blockquote>
<p>ということですが、このような事象は<strong>ありえない</strong>こともコメントで指摘されているとおりです。</p>
<p>これまでの議論でも明らかですが、JavaScriptでは、<code>worldcomponent</code>、<code>React</code>のオブジェクト如何に関わらず、対象が何であれ対象の内部実装がわからない限り、自分が何をやったのか知ることはできないので、<strong><code>=</code> (イコール)</strong>で何かを<em>バックアップ</em>したとするのは危険で問題が生じるので行うべきではなく、BestPracticeとして、何らかの適切な関数ライブラリを利用するオブジェクトのコピーを明示的に行います。</p>
<p>だいたい、何故この人は、オブジェクト指向の「オブジェクト参照」だとか「状態オブジェクトの再利用」の話を関数型プログラミングのコードで熱弁されているのでしょうか?? <br>
パラダイムの違いに無頓着であるからですし、一義的に私のコードのあら探し、誹謗中傷に熱心なだけで、まったく全体の景色が見えていないからですね。</p>
<p>たとえば、ポジションをニュートラルにして冷静にさせるためにLisp言語にでも置き換えてみると、Lispにはコピーする関数もありますが、「オブジェクト参照の破壊的代入が・・・コピーが・・・」などという議論にはならず、単に新たな値に対して、コピーでも<code>map</code>でも関数を用いてイミュータブルに新規に値を明示的に作成するはずです。</p>
<p>この明示的な操作において、容易も困難も何もありません。 <br>
意図をもって明示的にやるか、やらないかの違いしかありません。</p>
<h2 id="最後に-frpにおけるオブジェクトのバックアップというナンセンスについて-1">最後に FRPにおけるオブジェクトの<em>バックアップ</em>というナンセンスについて</h2>
<p>表層的な観点からは、</p>
<p><code>oldvalue</code>(バックアップされたとする古い値)</p>
<p><code>newvalue</code>(新規に出現する値)</p>
<p>などで、</p>
<blockquote>
<p>過去の状態への巻き戻しや状態オブジェクトの再利用</p>
</blockquote>
<p>するということを示唆しているのでしょうが、 <br>
この<code>newvalue</code>は <br>
「値の破壊的代入」がされているとする、 <br>
<code>___totalClicks.now()</code> <br>
と何ら違いはないことは自明です。</p>
<p>また、真に関数型パラダイムの観点からは、 <br>
(SICPでも解説されているレベルという意味です <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/05/99iq145jkiq145jkmitsicp.html">99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう</a>) <br>
<code>___totalClicks</code>というのは、イミュータブルなオブジェクトであり、ミュータブルに耐えず変化しているのは、現実世界の我々が意識している「時間」のほうであり、 <br>
<strong>この我々が常に意識している「現在時間」には、どの瞬間においても常に<code>now()</code>で参照透過にイミュータブルな時間軸上の現在時刻のストリームデータにアクセスできる、という設計です。</strong></p>
<p><strong>FRP的設計思想として、現在時間の<code>now()</code>が、<code>___totalClicks</code>というイミュータブルなオブジェクトの唯一の読み取りインターフェイス</strong>であり、「オブジェクト」の<em>バックアップ</em>などすべきではありません。</p>
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword">var</span> ___ = worldcomponent;
<span class="hljs-keyword">var</span> ___totalClicks = ___(<span class="hljs-number">0</span>);
___.world = ___totalClicks.appear(<span class="hljs-number">42</span>); <span class="hljs-comment">// ___totalClicksの値を42に設定</span>
<span class="hljs-keyword">var</span> ___totalClicksBak = ___totalClicks; <span class="hljs-comment">// ___totalClicksの「バックアップ」を保存</span></code></pre>
<p>のようなコードはFRPのコードではないので、書いてはなりません。</p>
<p><strong>真のFRP</strong>ライブラリとしての<code>worldcomponent</code>の設計理念としては、もちろん独立したストリームを別個に宣言しておきます。</p>
<pre class="prettyprint"><code class=" hljs cs"><span class="hljs-keyword">var</span> ___ = worldcomponent;
<span class="hljs-keyword">var</span> ___totalClicks = ___(<span class="hljs-number">0</span>);
<span class="hljs-keyword">var</span> ___totalClicksBak = ___(___totalClicks.now()); <span class="hljs-comment">// ___totalClicksの「バックアップ」を保存</span>
___.world = ___totalClicks.appear(<span class="hljs-number">42</span>); <span class="hljs-comment">// ___totalClicksの値を42に設定</span>
<span class="hljs-comment">//...................</span>
</code></pre>
<p>このコードは<code>___totalClicksBak</code>という命名や、「バックアップ」を保存というコメントの言葉遣いが<strong>真のFRP</strong>的に徹底的に間違っていますが、対比するためにやむを得ずそのように書いています。</p>
<p>もちろん、FRPの個々に定義されたストリームは勝手に相互に干渉しあうことなどありませんから、@Lambada氏による</p>
<blockquote>
<p>このように、___totalClicksのほうしか更新していないのに、___totalClicksBakの値まで変わっています。</p>
</blockquote>
<p>というGlitchは起こりようがありませんし、そもそもFRPにおいて、ストリームをオブジェクト参照による<em>バックアップ</em>するのが間違いです。</p>
<p>たとえばReactにしても、オブジェクト参照コピーによる<em>バックアップ</em>が、設計上、API上全く想定されていないのと同じことです。宣言型のコードに取り組むとき<em>バックアップ</em>などという概念はナンセンスです。このブログでイミュータブルな真に関数型のDBを紹介しました。 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/05/10frp99iq145jk3.html">10年先を行く斬新な関数型(FRP)データベースについて説明する 99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その3】</a> <br>
そこでは、</p>
<blockquote>
<p>すべてのタイムスタンプにデータを保持するのではなくて、 <br>
「差分」が発生した瞬間のデータのみを保持する。 <br>
というアイデアは、結構使えるんですね。 <br>
というか、とっくに広く使われています。 <br>
GitHubです。 <br>
Gitのようなバージョン管理システムは、データの差分のみを記録していきます。</p>
</blockquote>
<p>という<strong>真のFRP</strong>の実現の具体例の片鱗を紐解きましたが、GitHubが瞬間瞬間の<em>バックアップ</em>でなく、すべてのタイムスタンプですべての事象をイミュータブルにパイルアップして記録していくシステムであるのはよく知られていることです。</p>
<p>FRP的設計思想として、現在時間の<code>now()</code>以外に、任意の計算可能な、つまり現在時刻より過去という意味ですが、任意の時刻にアクセスできる読み取り可能なインターフェイスを実装しているのが、拙書の最終章Day5で掲載している<code>timecomponent</code>というFRPライブラリであるということになります。</p>
<p>以上のような議論に比較して、</p>
<p><code>oldvalue</code>(バックアップされたとする古い値)</p>
<p><code>newvalue</code>(新規に出現する値)</p>
<p>という<strong><em>バックアップ</em>というのは、いかに非関数型的発想で命令型パラダイムであるか!という事実に気がつけるか気がつけないか</strong>がFRPあるいは関数型パラダイムを真に理解できているか否かの違いです。</p>
<p>FRPの議論をするとき、ある論者が、<em>バックアップ</em>というナンセンスで批評を始めた時点で、その論者はFRPのことは何も理解していないと断定して構いません。</p>
<p>もちろん拙書を手間暇かけて読解していただいた読者諸氏におかれましては、上記私の意図するところは哲学的根本レベルで伝わっているものと信じます。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-57749867442610703472015-07-11T12:30:00.001+09:002015-07-11T17:44:01.348+09:00「お絵かきアプリ」と「クリックカウンター」を簡単に実装できると見せかける誤魔化しと嘘 原理的に可能かどうか?と実用的であるかどうか?は違うが、それを「銀の弾」ではない、という言葉をもって自らの嘘、誤魔化しの言い訳として悪用するな<h2 id="お絵かきアプリとクリックカウンターを簡単に実装できると見せかける誤魔化しと嘘-原理的に可能かどうかと実用的であるかどうかは違うがそれを銀の弾ではないという言葉をもって自らの嘘誤魔化しの言い訳として悪用するな">「お絵かきアプリ」と「クリックカウンター」を簡単に実装できると見せかける誤魔化しと嘘 原理的に可能かどうか?と実用的であるかどうか?は違うが、それを「銀の弾」ではない、という言葉をもって自らの嘘、誤魔化しの言い訳として悪用するな </h2>
<p>「レビュー」と称する欺瞞に満ちた、批判のための批判記事 <br>
<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a>には、こんな追記がありました。</p>
<blockquote>
<h1 id="追記20150530デスクトップアプリケーション">追記(2015/05/30):デスクトップアプリケーション??</h1>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">著者はブログで@camloebaさんや@esumiiさんにデスクトップアプリケーションをOCamlで作成するように求めているようです</a>。著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません(<strong>当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります</strong>)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。</p>
</blockquote>
<p>が、さらに「追記」の「追記」がなされたようです。</p>
<blockquote>
<p>(追記:コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にするとOCamlでは困難であろうという指摘を頂いています。利点はともかくHaskellと同じようにモナドを利用したライブラリを作成するなら純粋な関数型でのプログラミングも可能になる(けれどもOCamlプログラミングとしてはわざわざそのようなことをしても嬉しくはない)ということになります。とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)</p>
</blockquote>
<p>この</p>
<blockquote>
<p>コメント欄にてyataketa9056さんに、既存のGUIライブラリを前提にするとOCamlでは困難であろうという指摘を頂いています。</p>
</blockquote>
<p>とは、</p>
<blockquote>
<p><em>yataketa9056 Jul 11, 2015 04:27</em> <br>
<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b#comment-d9a8cdf2efc67044c158">幾つか補足と、間違いがありますので指摘します。 <br>
末尾呼出最適化は ECMAScript6 で導入されていますが、これをサポートする JS 実装は現在ほとんどないはずです。 <br>
js_of_ocaml 系のコードが末尾再帰でもスタックがあふれないのは、js_of_ocaml のコンパイラが末尾再帰呼出(全ての末尾呼出しではない)を goto やトランポリンで置き換えているからです。Scala の末尾再帰呼出が JVM 上でやはり同じようにコンパイルされているはずです。 <br>
<strong>OCamlでは「破壊的代入の類の副作用」を使用せずに一般の GUI アプリケーションを書くのはほとんど無理でしょう。なぜなら OCaml の全ての GUI ライブラリは状態は副作用を使うことを前提にメインループが設計されているからです。これを乗り越えるとすると @Lambada さんのようにメインループ自体を自分で書く事になり、一般的にはスケールしません。</strong> <br>
Haskell の GUI ライブラリでは普通は状態は State なり IO を含む GUI モナドを使って書く事になりますが、そのような GUI ライブラリを OCaml 上で作れば同じような事が出来るはずです。<strong>OCaml でそこまで純粋関数型のコードを書く事に実用的意味があるとは思えませんが。</strong></a></p>
</blockquote>
<p>というものです。(太字は岡部によるもの)</p>
<p>この @nonstarterらの強弁に欺瞞を感じる良識のある指摘です。</p>
<p>まず、@nonstarterによる「言い分」</p>
<blockquote>
<p>著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません</p>
</blockquote>
<p>ですが、私の趣旨は明らかで、実用的なアプリを書けるのか?ということに尽きます。 <br>
前回、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/07/day-1.html">『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと</a> <br>
において、趣旨を大前提として再確認しました。</p>
<blockquote>
<p>著者が挙げている「クリックカウンター」や「お絵かき」の類</p>
</blockquote>
<p>とは、FacebookのGUIコンポーネント指向、FRPライブラリである、Reactを活用した簡単なサンプルであり、同様yに、著書のDay5に示した、マウスドラッグのサンプルWebアプリです。</p>
<p>これらは、あくまで「実用性意味」を大前提とした投げかけでした。</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<h2 id="素朴な疑問なんですが貴方がた延々と私の関数型プログラミングの無理解やらスキルに偉そうなことを言い続けているけど実際のところ貴方たちは関数型プログラミングで実用に耐えうるデスクトップアプリとか書いたことあるんでしょうかというか書けるんですか">素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??</h2>
<p>ということです。</p>
<p>「<strong>実用に耐えうる</strong>」こういう極めてシンプルなテーゼに徹頭徹尾誤魔化しを続けているのが、<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a> <br>
であり、それは、最終的に、プラグマティックで真摯な読者への裏切りとして決着します。</p>
<h2 id="nonstarterらが回答した副作用を使用せずに書くのもなんら困難ではありませんとするクリックカウンターやお絵かきはスケールしません-机上の空論である">@nonstarterらが「回答」した、「副作用を使用せずに書くのもなんら困難ではありません」とする、「クリックカウンター」や「お絵かき」は「スケールしません。」 「机上の空論」である</h2>
<blockquote>
<p><strong>OCamlでは「破壊的代入の類の副作用」を使用せずに一般の GUI アプリケーションを書くのはほとんど無理でしょう。なぜなら OCaml の全ての GUI ライブラリは状態は副作用を使うことを前提にメインループが設計されているからです。これを乗り越えるとすると @Lambada さんのようにメインループ自体を自分で書く事になり、一般的にはスケールしません。</strong></p>
</blockquote>
<p>と良心的な指摘、欺瞞の看破のコメントもあるように、連中が、岡部の言うようなFRPを使わなくても、「なんら困難ではありません。」かんたんに書けるという趣旨で放言しているコードは、「スケールしません。」 <br>
つまり、問題を極めて単純化して簡単な解放で事足りるものに限定したら、それは「なんら困難ではありません。」「かんたんに書ける」わけですが、ちょっと複雑になってきたら、もう破綻する、複雑な、つまり実用的なアプリなんて書けっこない、ということです。</p>
<p>「机上の空論」です。</p>
<h2 id="実用に耐えない机上の空論のコードを自ら実装した当然の結果への言い訳銀の弾ではない">実用に耐えない「机上の空論」のコードを自ら実装した当然の結果への言い訳、「銀の弾ではない」???</h2>
<p>「机上の空論」を自分が勝手に放言するのは、良識ある人間に看破されるだけだが、それを勝手に一般化して、言い訳するマジックワードが、「<strong>銀の弾ではない</strong>」です。</p>
<blockquote>
<h1 id="追記20150530デスクトップアプリケーション-1">追記(2015/05/30):デスクトップアプリケーション??</h1>
</blockquote>
<p>の最後には、こういうデタラメが書かれています。</p>
<blockquote>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<p>間違い、デタラメです。</p>
<p>まず、私は、</p>
<blockquote>
<p>素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、<strong>実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??</strong></p>
</blockquote>
<p>「実用に耐えうる」複雑なケースを想定したコードを示せ、と要求した。</p>
<p><strong>私が示したコードは、GUIの関数合成を具現化したコンポーネント指向のReactをベースとし、同時にイベントを合成可能なFRPのコードです。</strong></p>
<p>コンポーネント指向は、関数合成であり、</p>
<blockquote>
<p>綺麗な関数合成では上手くいかないようなものになることが多い</p>
</blockquote>
<p>というものを最初から、根本的に解決するアプローチであり、私はそのサンプルコードを首尾一貫して、著書でも、先の「問いかけ」のブログ記事でも示しているわけです。</p>
<p>当然、いくらでもスケール可能なことは、FacebookやInstagramのサイトで実証されている現在進行形でアクティブに開発され多くの技術者が参入している次世代Webのデファクトである技術です。</p>
<p>スケールしない、複雑になったら破綻する、「クリックカウンター」や「お絵かき」のコードではありません。</p>
<p>一方で、@nonstarterらは、「副作用を使用せずに書くのもなんら困難ではありません」などと、読者を勘違いさせて当たり前の、極めて単純な実装でしか使えないコードしか示せませんでした。</p>
<p>「机上の空論」です。</p>
<p>極めて限定された、単純な問題でしか使えない、「机上の空論」の実用に耐えないコードを、「副作用を使用せずに書くのもなんら困難ではありません」と、あたかも簡単に書ける、その先に実用性があると読者を勘違いさせて、思い込ませて、騙してまるで平気な感じです。こういう看過できない欺瞞を暴くために、私は、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<blockquote>
<p>素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??</p>
</blockquote>
<p>と、先にコンポーネント指向、FRPでサンプルコード示して問いかけたわけですが、もうその「回答」のダメさっぷりは明らかでしょう。</p>
<p><strong>この自らの「回答」のダメさぷりを、まるで一般的な関数型プログラミングの限界のように、また読者を欺いて、正当化するのが、この連中の常套手段です。</strong></p>
<p>どういうことか?</p>
<h2 id="銀の弾丸にはならないと言わなければなりません">銀の弾丸にはならないと言わなければなりません ???</h2>
<p>こういう言い草です。</p>
<p>@nonstarterが強弁するとおり、</p>
<blockquote>
<p>状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません</p>
</blockquote>
<p>のであれば、 <br>
そもそも、私がサンプルとして示した、コンポーネント指向のReactで、UIを関数合成して見せているコードでは、「綺麗な関数合成で上手くいっている」(それがReactの関数ライブラリとしての真価)わけなので、「本質的に銀の弾丸」である、ということになります。</p>
<p>それを自分たちが、コンポーネント、FRPでなくても「なんら困難ではありません」などと、極めて限定的な単純化された例題にしか適用できないスケールしない実用に耐えないコードを勝手に示しておいて、だから、関数合成では上手く行かない、銀の弾ではない、などと説明されても、こちらとしては、ほらね?だからあんたらダメなんだよ、わかったかい?と再確認する意味しかありません。</p>
<p>関数型プログラミング、コンポーネント指向、FRPは、机上の空論でない、真に実用に耐えるアプケーションを構築するために必須な「銀の弾丸」である、この見解を改めて確認し、異論があるのであれば、こちらは、すでにスケールするコンポーネント指向のFRPのReactで構築したアプリを提示しているのだから、再度、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<blockquote>
<p>素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??</p>
</blockquote>
<p>と広い読者にむけて、自らの主張を立証していただきたいと考えています。<strong>絶対無理でしょうが。</strong></p>
<p>なんども繰り返し確認しますが、関数型プログラミングのGUI実用化、世界的潮流としては、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/07/javascript.html">プログラミングの世界的潮流と机上の空論としての関数型プログラミング②「素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。」(苦笑)</a></p>
<p>で示したような状況があり、これは「銀の弾」として重宝されながら圧倒的な普及を見せているわけです。</p>
<p>あさっての方向をみて、あたかも実用的だと見せかけながら「机上の空論」に執着しながら、「机上の空論」で実用に耐えないから「銀の弾ではない」というような自己の規定した論理の中で無限ループするトートロジーのようなことを言ってる連中には、<strong>絶対無理でしょう。</strong></p>
<p>コンポーネント指向、FRPでなければ、実用的なプログラミングはできないとする私の主張をわざわざ否定したいえばかりに、わざわざまた「机上の空論」を開陳して、結果「銀の弾ではない」、と結論づけて、あんたら何がしたいのか?読者の足を引っ張って楽しいのか? <br>
自ら、実用的局面でなんら価値を生み出すことはなく、ありもしない限界的を設定して、こちらの言うことが間違いだと見せかけるために、批判のための批判がしたいだけだろう?ということです。</p>
<h2 id="末尾再帰ループの最適化">末尾再帰ループの最適化</h2>
<blockquote>
<p>気づきにくいといけませんので、上にあるLambadaさんのコメントの追記部分を転記させていただきます:</p>
<blockquote>
<p>追記:岡部氏が最近のブログエントリで、上述のプログラムは再帰を使っているので「即効で」スタックオーバーフローすると主張していますが、関数型プログラミングの基本の一つである末尾再帰なので、スタックオーバーフローしません。もし仮に末尾再帰がスタックオーバーフローするJavaScript処理系があったとしたら、JavaScriptか、少なくともその処理系が、関数型プログラミングに不適切です。 <br>
岡部氏は上述のプログラムを無限ループに書き換えて「Chromeタグ(原文ママ)の反応がなくな」ったと主張していますが、無限ループにしたら反応がなくなって当然です。なお、少なくとも私の手元のChromeやFirefoxでは、無限ループする末尾再帰ですら(当然ながらブラウザの反応は重くなりますが)スタックオーバーフローは再現しません(メモリ消費量も特に増えません)。岡部氏がスタックオーバーフローと主張している画面には「Either Chrome ran out of memory or the process for the webpage was terminated for some other reason」(Chromeのメモリがなくなったか、もしくは何らかの他の理由でWebページのプロセスが終了されました)とあるので、スタックオーバーフローではなく、無限ループしているプロセスを強制終了した等かもしれません。 <br>
なお、他の方々から、Graphics.loop_at_exitではなく、ネイティブなOCaml処理系であればGraphics.wait_next_eventを、js_of_ocamlであればGraphics_js.loopを用いるべきとのご指摘をいただきました。そのとおりなのですが、元の文で述べたとおり、最も手っ取り早く試していただけるTry OCamlで動くよう、Graphics.loop_at_exitを用いました。また、そもそもTry OCamlのGraphics.loop_at_exitやjs_of_ocamlのGraphics_js.loopはループでも再帰でもなく、イベントハンドラの登録を行なって戻ってくるだけなのでスタックオーバーフローなど起こるわけがない、とのご指摘もいただきました。ありがとうございます。</p>
</blockquote>
<p>なお、私も単なる素人ですし不適切なことを書いているだろうとは思いますが、今回のkenokabeさんの一連の主張を見ると流石に私ですら真面目に取り合う必要を感じません。しかしkenokabeさんがどのような理解の水準で関数プログラミングに関する書籍を執筆し(てしまっ)たのかが著者ご本人のお蔭で完全に明らかになったように思います。</p>
</blockquote>
<p>まず、この人をはじめ、私が「末尾再帰最適化を理解していない、知らなかった」ということにしたいようです。</p>
<p>岡部はXXを知らない、理解していない、という勝手な決めつけ、中傷をもって、本のレビューとするという悪質な手口はこの@nonstarterによる常套手段ですが、もちろん知っています。</p>
<p>まず、念の為に、解説すると、 <br>
再帰ループの末尾最適化とは、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/07/day-1frpgui.html">【学習者要注意!】『関数型プログラミングに目覚めた!』のレビュー(Day-1)の「状態遷移関数」を使った非FRPのGUIコードがメモリリークする実用に耐えない不良品でしかなかったことについて 読者騙せて楽しいですか?</a> <br>
で、発生するような問題をコンパイラレベルで回避するための言語の仕組みです。</p>
<blockquote>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b#comment-d9a8cdf2efc67044c158">末尾呼出最適化は ECMAScript6 で導入されていますが、これをサポートする JS 実装は現在ほとんどないはずです。js_of_ocaml 系のコードが末尾再帰でもスタックがあふれないのは、js_of_ocaml のコンパイラが末尾再帰呼出(全ての末尾呼出しではない)を goto やトランポリンで置き換えているからです。Scala の末尾再帰呼出が JVM 上でやはり同じようにコンパイルされているはずです。</a></p>
</blockquote>
<p>とあるように、単に、スタックオーバーフローする再帰関数の無限ループを、内部で関数呼び出しでない無限ループのコードに書き換えることで実装されています。</p>
<p>上記のように、同じJavaScriptであってもバージョンによって、末尾再帰最適化の実装があったりなかったり、Javaも同様です。C#では、末尾再帰最適化はありませんが、F#ではあったりします。</p>
<p>趨勢として、JavaScript,C#,Javaなどのメインストリーム言語では、末尾再帰最適化はない、と考えていた方が良いでしょう。 <br>
OCamlは、末尾再帰最適化はあるのでしょう、よく知りませんが、しかしいずれにせよ、コンパイラがメモリリークしないように書き換えてくれる言語であったとしても、<strong>イベントハンドリングするために、コード上で無限ループを回して、1ループごとに、イベントハンドラー追加するような設計はアホな設計です。こんなことをすべきではありません。</strong></p>
<p>こういうアホな設計を正当化したいのが、 <br>
なにがなんでもFRPを使わなくても書けるという机上の空論のやり方であり、延々と説明してきたとおり、スケールしません。イベント、UIを関数合成するような私が提示しているやり方ではないので、実用に耐えるコードではありません。</p>
<p>実用に耐えない、ということを自己正当化するために、彼らがなんて言うのか?というと、</p>
<blockquote>
<p>本質的には銀の弾丸にはならないと言わなければなりません</p>
</blockquote>
<p>とか、</p>
<blockquote>
<p>素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。</p>
</blockquote>
<p>とかです。</p>
<p>そもそも、関数型プログラミングのメリットとは、簡潔な構造であり、生産性であり、実用的であるからです。</p>
<p>純粋関数型プログラミングだ!と、結果、無残な無限ループごとにイベントハンドリング追加するような無理な設計であったり、末尾再帰最適化してくれるからOCamlだ、JavaScriptは使えない、という話では、ありません。</p>
<h2 id="関数型プログラミングとは汎用的な概念であり特定の関数型プログラミング言語に縛られたり依存するものではない">関数型プログラミングとは汎用的な概念であり、特定の関数型プログラミング言語に縛られたり依存するものではない</h2>
<h2 id="javascriptが関数型プログラミング言語としてもっとも実用的である">JavaScriptが関数型プログラミング言語としてもっとも実用的である</h2>
<h2 id="reactをはじめとするコンポーネント指向frpは強固な汎用性と実用性が実証されている">Reactをはじめとする、コンポーネント指向、FRPは強固な汎用性と実用性が実証されている</h2>
<p>ということです。</p>
<blockquote>
<p>とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。またこの主張自体はHaskellでのコードによっても充分に示されています。)</p>
</blockquote>
<p>繰り返しますが、私がデスクトップアプリだのFRPだのコンポーネント指向だの書いているのは実用に耐えうるアプリについてであり、</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<blockquote>
<p>素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??</p>
</blockquote>
<p>実用に耐えない、関数合成もできない、極めて限定的で単純な「机上の空論」の誤魔化しコードを提示しろ、と言ったのではありません。</p>
<p>すでにReactを中心に実用化がバリバリとなされ活発に開発が進んでいる現状の2015年において、</p>
<blockquote>
<p>とはいえ原理的に不可能でないのなら(そして不可能でないので)、純粋な関数プログラミングでGUIアプリケーションを作成するのにFRPがなんら必要でない、という趣旨には充分です。</p>
</blockquote>
<p>みたいな、「原理的に不可能でない」と強弁するので、その原理的に不可能でない「FRPがなんら必要でない、という趣旨には充分」なやり方を採用したら、複雑なアプリは書けない、と来る。</p>
<p>だったら、「机上の空論」として、原理的に不可能でなくても、「机上の空論」ではない現実的なプログラミングにおいては、実用に耐えない、「充分」でないですよね?</p>
<p>挙句の果てに、そのダメさを自己正当化するために、「銀の弾丸ではない」とわけのわからない一般化をして、可能性の限定を正当化する、とめちゃくちゃな言い分をして、読者を愚弄しているのがこういう連中である、ということです。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-1390192118267498052015-07-11T10:30:00.001+09:002015-07-11T12:58:39.574+09:00『関数型プログラミングに目覚めた!』のレビュー(Day-1)の嘘と誤魔化し ー 自分たちが非実用的な「机上の空論」を語っている事をけして読者に語らないこと<p>非実用的な「机上の空論」を語っている事を最後の最後まで読者に教えないこと、あたかもその延長線上で、最終的には簡単に実用的なアプリケーションが書けると「見せかける」こと、これをやられて結局割を食うのは、そういう解説を読んで学び実務に活用しようと期待する真摯な読者、学習者です。</p>
<p>これが、世に広く普及して業務レベルのGUIアプリケーションを構築するプログラミング言語であると見做すことはできないプログラミング言語で解説されている、巷の多くの関数型プログラミングの解説において、私が観察する欺瞞です。</p>
<p>その欺瞞のアンチテーゼとして、対極に位置する私の根本的スタンスは、現状を誠実に観察して、このような世界的潮流で、これまでとは違った考え方が必要な関数型プログラミングなるものを、あくまで最後の最後まで実用に耐えるアプリを読者が書ける水準に到達するように、正しい道標(みちしるべ)を示すことです。 <br>
本当に世の中に役立つことを発信することです。</p>
<h2 id="それって結局最終的に使えるようになるの">それって結局、最終的に使えるようになるの?</h2>
<p>YES</p>
<p>か</p>
<p>NO</p>
<p>か。我々はつまるところ技術者でプラグマティストであるので、そこを気にします。</p>
<p>関数型プログラミングが、これまで広く一般のプログラマにとってメインストリームとして受け入れ難かったのは、主に2つ理由があるでしょう。</p>
<p>1.「考え方」の転換が必要だとは喧伝されるが、巷の解説はその部分をけして掘り下げることはなく、すぐに専門用語や数学的・形式的説明に終始してしまい、パラダイムシフトが体感できない。</p>
<p>2.先行事例が実質皆無であった。メインストリームになって当然の道具立てが存在しなかった。</p>
<p>この状況を踏まえると、関数型プログラミングは、結局最終的に使えるようになるのか?の答えは</p>
<p>NO</p>
<p>と審判が下され続けていたという過去の現実はなんら不思議ではありません。</p>
<p>私が著書<a href="http://kenokabe-techwriting.blogspot.jp/2015/04/iq145.html">『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』</a> を執筆したとき、最終的な目的は、2014年にプログラミング世界を圧巻したFacebookのGUIコンポーネント指向FRPライブラリであるReactを真に実用的な関数型プログラミングのスキルのひとつの出口として提示することでした。</p>
<p>これって、最終的には使えるようになる、 <br>
関数型プログラミングに入門して、真剣に取り組んで、 <br>
満額回答 YES が得られる、という<strong>最終的な担保をつけた</strong>わけです。</p>
<p>その最終的な担保をつけた上で、もっとも根本的なレベルまでプログラミングを掘り下げて解説しました。</p>
<p><a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう</a></p>
<p>で詳説したとおり、基本的にはSICPが書いていること、世に高く評価されているかなり踏み込んだ要素まで書きました。</p>
<p>関数型プログラミングの「考え方」の根本には以上に示したような哲学的要素があり、そこはSICP以外にきっちりと解説している文献は見当たらなかったので、全力で書きました。</p>
<p>SICP自体も、この辺の真価を理解できる人ばかりではなく、まったく評価できない人が多く、賛否両論で有名な本でもあります。しかし、真価を理解できる人は高く評価し、関数型プログラミングの聖典とまで言われたりします。</p>
<p>結局のところ、私の試みとは、まず、Before、ほとんどのプログラマが拠り所にしているポジションからスタートして、徐々にSICPレベル以上の哲学まで踏み込み、パラダイムシフトしながら、最終的に本当に実用的なFacebookーReactまで、一本の筋を通しながら解説することでした。</p>
<h2 id="机上の空論に執着し実用レベルを強く期待する読者を騙すことを厭わない解説">「机上の空論」に執着し、実用レベルを強く期待する読者を騙すことを厭わない解説</h2>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/07/javascript.html">プログラミングの世界的潮流と机上の空論としての関数型プログラミング②「素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。」(苦笑)</a> <br>
で、「机上の空論」ではない関数型プログラミング言語としてのJavaScriptの圧倒的優位性を立証しました。</p>
<p>今どき、</p>
<p>「そもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。」</p>
<p>などと、平気で発言するような論者の解説など読んでも最終的には裏切られることはあらかじめ見極めていたほうが良いと思います。</p>
<p>既出の2点、</p>
<p>1.「考え方」の転換が必要だとは喧伝されるが、巷の解説はその部分をけして掘り下げることはなく、すぐに専門用語や数学的・形式的説明に終始してしまい、パラダイムシフトが体感できない。</p>
<p>2.先行事例が実質皆無であった。メインストリームになって当然の道具立てが存在しなかった。</p>
<p>という論点にまるで無頓着で、他人の解説のあら探し批判のための批判は精一杯試みるが、自分自身なにも生み出さない、生み出すつもりも鼻からない、という感じです。</p>
<p>2015年の多くの関数型プログラミング解説の読者は、その延長線上に、満額回答「YES」を期待している、実用レベルを強く期待しているわけですが、かなりそういう世界的潮流には無頓着です。</p>
<p>「そもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。」</p>
<p>とのうのうと発言できるということは、この辺なんら勉強していない、というか、自身、関数型プログラミングの実用化にそれほど関心がなく、そういう現状において極めて偏った、倦厭されるべきスタンスで解説を展開しようとしているわけです。</p>
<p>その歪として、「机上の空論」になります。 <br>
「関数型プログラミングの考え方の違い」 <br>
や <br>
「実用的なGUIライブラリを書く方法」 <br>
などは、何も教えてもらえない、最終的には読者は裏切られます。 <br>
「できない」ことを「あたかもできるように見せかける」ここがこの手の解説の典型的な欺瞞です。</p>
<h2 id="本当はあさっての方向を向いており読者をそちらへ誘導しようとしているのにまるでその先に汎用的実用性があるように見せかける大嘘誤魔化し">本当はあさっての方向を向いており、読者をそちらへ誘導しようとしているのに、まるでその先に汎用的、実用性があるように見せかける大嘘、誤魔化し</h2>
<p>それをやっているのが、 <br>
『関数型プログラミングに目覚めた!』のレビュー(Day-1)であり、嘘と誤魔化しですが、それにひとつ悪用されている「マジックワード」があります。</p>
<h2 id="銀の弾ではないという言葉を自らの嘘誤魔化しの言い訳として悪用するな">「銀の弾」ではない、という言葉を自らの嘘、誤魔化しの言い訳として悪用するな</h2>
<p>ということですね。</p>
<p>この辺り、具体的に次回のエントリに続きます。</p>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/07/blog-post.html">「お絵かきアプリ」と「クリックカウンター」を簡単に実装できると見せかける誤魔化しと嘘 原理的に可能かどうか?と実用的であるかどうか?は違うが、それを「銀の弾」ではない、という言葉をもって自らの嘘、誤魔化しの言い訳として悪用するな</a></p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0tag:blogger.com,1999:blog-1347856729769934602.post-75943092394088873362015-07-06T20:11:00.001+09:002015-07-06T20:53:29.793+09:00【学習者要注意!】『関数型プログラミングに目覚めた!』のレビュー(Day-1)の「状態遷移関数」を使った非FRPのGUIコードがメモリリークする実用に耐えない不良品でしかなかったことについて 読者騙せて楽しいですか?<p>まず、 <br>
<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a>というのは、</p>
<p>@nonstarter <br>
<a href="http://qiita.com/nonstarter">http://qiita.com/nonstarter</a> <br>
という素人かつ大学関係者を自称しながら、 <br>
言論人として文責をまったく負わずに済む、 <br>
素性のしれない匿名のQiita捨てアカウントによる、 <br>
書捨て記事であり、 <br>
「批判のための批判記事」です。</p>
<p><strong>「レビュー」などと称していますが、対象となる書籍の良い部分は一切書いておらず、とにかく徹頭徹尾、揚げ足取り、歪曲捏造しているので、「批判のための批判記事」であることが露骨にあらわれてしまっていますが、本人はそのことに露ほども自覚がないのでしょう。</strong></p>
<p>この【レビュー】読んでる人が、私のところへ送ってくださる感想は、</p>
<blockquote>
<p>相手の方、(自称ではありますが)どっかの大学の教育者らしいのですよね。 <br>
そのような立場の人間が急いで私のコメントに返した内容は悲惨なものです。 <br>
終始、私がプログラミングの初歩も弁えない愚物であるかのように見せかけるための理屈をこねくり回しておよそ立場ある教育者としては恥ずべき、うっすら侮蔑をにじませた記述に終始しています。 <br>
ネットスラング的には「効いてる、効いてるw」様子で、泡くって焦ってる姿が見えます。</p>
<p>確認が取れましたら、おちょくる感じで反論コメントを書いてみようかとも思うのですが、 <br>
しかし、コメントを読んで口をついて出た言葉は <br>
「度し難ぇ・・・」 <br>
やっぱりゾンビじゃないか!面倒くせぇーーー(笑)(失礼しました) <br>
ちょっと心配なのが、こうした事を続けるとコメントを削除されないかという点です。 <br>
せっかくのリンクが無くなってしまいますからね・・・</p>
</blockquote>
<p>といった感じです。</p>
<p>これから、記事をわけて、<a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a>への「回答」の精査と、この <br>
<a href="http://qiita.com/nonstarter/items/2763f5d85f2b8df3b18b">『関数型プログラミングに目覚めた!』のレビュー(Day-1)</a> <br>
シリーズによる本書への批判のための批判を精査していきます。</p>
<h2 id="学習者要注意関数型プログラミングに目覚めたのレビューday-1の状態遷移関数を使った非frpのguiコードがメモリリークする実用に耐えない不良品でしかなかったことについて-読者騙せて楽しいですか">【学習者要注意!】『関数型プログラミングに目覚めた!』のレビュー(Day-1)の「状態遷移関数」を使った非FRPのGUIコードがメモリリークする実用に耐えない不良品でしかなかったことについて 読者騙せて楽しいですか? </h2>
<p>さて、私が、 <br>
<a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p>と示した「挑戦」、というか、</p>
<p>「あんたらどうせ最終的には実用に耐える関数型プログラミングのコードなんて提供できないんでしょ?(笑)」</p>
<p>という「確認」記事を出したところ、</p>
<p><strong>案の定、メモリリークする実用に耐えない不良品しか提示されませんでした。</strong></p>
<p><strong>こういう連中の言うことを鵜呑みにしがちな【学習者要注意!】です。</strong></p>
<h2 id="問題のコメントとコード">問題のコメントとコード</h2>
<blockquote>
<p><em>Lambada 0 contribution May 30, 2015 11:03</em> <br>
<br>
本書の数々の重大な誤りに対し正当な技術的批判を加えても <br>
著者から激しい誹謗中傷行為を受けるようですので匿名で失礼します。 <br>
OCamlで変数への破壊的代入を行わないでごく簡単に書くと以下のようになります。 <br>
(通常のOCaml環境ではwait_next_eventを用いるべきですが、 <br>
<a href="http://try.ocamlpro.com">http://try.ocamlpro.com</a> で動くようにloop_at_exitを用いています。 <br>
後者ではChromeもしくはFirefox推奨です。)</p>
</blockquote>
<p><strong>clickcounter.ml</strong></p>
<pre class="prettyprint"><code class=" hljs fsharp"><span class="hljs-comment">(* クリックカウンター *)</span>
<span class="hljs-keyword">open</span> Graphics
<span class="hljs-keyword">let</span> () = open_graph <span class="hljs-string">" 900x600"</span>
<span class="hljs-keyword">let</span> <span class="hljs-keyword">rec</span> k c =
clear_graph ();
moveto <span class="hljs-number">450</span> <span class="hljs-number">300</span>;
draw_string (string_of_int c);
loop_at_exit [Button_down] (<span class="hljs-keyword">fun</span> event -> k (c + <span class="hljs-number">1</span>))
<span class="hljs-keyword">let</span> () = k <span class="hljs-number">0</span> ;;</code></pre>
<p><strong>mousedrag.ml</strong></p>
<pre class="prettyprint"><code class=" hljs vbnet">(* マウスドラッグ *)
open Graphics
<span class="hljs-keyword">let</span> () = open_graph <span class="hljs-string">" 900x600"</span>
<span class="hljs-keyword">let</span> rec k = <span class="hljs-keyword">function</span>
| `Up ->
loop_at_exit [Button_down] (fun <span class="hljs-keyword">event</span> ->
k (`Down(<span class="hljs-keyword">event</span>.mouse_x, <span class="hljs-keyword">event</span>.mouse_y)))
| `Down(x, y) ->
loop_at_exit [Button_up] (fun <span class="hljs-keyword">event</span> ->
moveto x y;
lineto <span class="hljs-keyword">event</span>.mouse_x <span class="hljs-keyword">event</span>.mouse_y;
k `Up)
<span class="hljs-keyword">let</span> () = k `Up ;;</code></pre>
<blockquote>
<p>いずれも岡部氏の主張とは正反対に、ストリームなどまったく用いず <br>
状態渡しで実現されています。 <br>
逆に、岡部氏のコードはよく見ると state = x; という部分で <br>
カウンタ変数への破壊的代入を行っており、何ら関数的ではありません。 <br>
(無駄に複雑なスパゲッティ・プログラムですが、よく読むと要するに <br>
state = state + 1; と同じ破壊的代入です。) <br>
ご参考になれば幸いです。</p>
</blockquote>
<h2 id="超おもしろいですね既定路線すぎてこんなことして技術者として恥ずかしくないんでしょうか笑">↑ 超おもしろいですね。既定路線すぎて。こんなことして技術者として恥ずかしくないんでしょうか?(笑)</h2>
<p>いかにも「<strong>関数型プログラミングで実用的なGUIアプリ書いたことない、普段から書いておらず無頓着な低スキルコーダー</strong>」丸出しのコードが提示されました。</p>
<p>OCamlに詳しくない読者の方々にかいつまんで説明すると、これは要するに、再帰関数の無限ループを使ったコードです。</p>
<p>拙書にも書きましたが、再帰関数とは、自分自身を呼び出す関数のことで、無限ループになります。</p>
<p>それでですね、<strong>こういう再帰関数の無限ループをもって、GUIアプリを書いてはいけません。絶対に。</strong></p>
<p>なんでか?<strong>メモリリークするから</strong>ですよ。</p>
<p>関数を呼び出すと、その関数がが何やったかきちんとメモリに記憶しています。</p>
<p><a href="https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%AB%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF">コールスタック</a>と言って、ちょっと気の利いたプログラマなら誰でも知っている基礎知識です。</p>
<blockquote>
<p>コールスタック (Call Stack)は、プログラムの実行中にサブルーチンに関する情報を格納するスタックである。実行中のサブルーチンとは、呼び出されたが処理を完了していないサブルーチンを意味する。実行スタック (Execution Stack)、制御スタック (Control Stack)、関数スタック (Function Stack)などとも呼ばれる。また、単に「スタック」と言ったときにコールスタックを指していることが多い。コールスタックを正しく保つことは多くのソフトウェアが正常動作するのに重要であるが、その詳細は高水準言語からは透過的である。</p>
</blockquote>
<p>再帰関数も当然、例外なくスタックを保持してメモリを消費します。 <br>
つまり、再帰関数を1回すごとに、ちょっとずつメモリを消費します。</p>
<p>しかもGUIのイベント拾うという、ただ単なる繰り返しをしたいためだけに、無意味にメモリを消費していく、つまり、メモリリークするんですね。</p>
<p>ひじょーにアホらしい設計であるのは、すぐ解ると思いますし、実際に、マウスポインタの動きを拾うイベントを無限再帰ループで拾ったりすると、スタックがオーバーフローします。いわゆる<strong>StackOverflow(スタックオーバーフロー)</strong>ですね。今どき耳慣れた言葉でしょうし、それほど超基本的でありがちな設計ミスというか、結構スキルレベル低めのバグです。</p>
<h2 id="不良品コードの証拠として超頻繁なイベントをシミュレートしてスタックオーバーフローさせてやりました">不良品コードの証拠として超頻繁なイベントをシミュレートしてスタックオーバーフローさせてやりました・・・</h2>
<blockquote>
<p><a href="http://try.ocamlpro.com">http://try.ocamlpro.com</a> で動くようにloop_at_exitを用いています。 <br>
後者ではChromeもしくはFirefox推奨です</p>
</blockquote>
<p>と、なんか偉そうに書いておられるので、実際に、その推奨されているChromeブラウザで</p>
<p><a href="http://try.ocamlpro.com">http://try.ocamlpro.com</a> <br>
にアクセスして、</p>
<p>動作確認のために、超頻繁なイベントをシミュレート、つまり、マウスイベントを待たずに、即時、再帰関数を呼び出すようにコードを改変して、</p>
<pre class="prettyprint"><code class=" hljs fsharp"><span class="hljs-keyword">open</span> Graphics
<span class="hljs-keyword">let</span> () = open_graph <span class="hljs-string">" 900x600"</span>
<span class="hljs-keyword">let</span> <span class="hljs-keyword">rec</span> k c =
clear_graph ();
moveto <span class="hljs-number">450</span> <span class="hljs-number">300</span>;
draw_string (string_of_int c);
k (c + <span class="hljs-number">1</span>)
<span class="hljs-keyword">let</span> () = k <span class="hljs-number">0</span> ;;</code></pre>
<p>をペーストして、走らせてみると、即効でChromeタグの反応がなくなり、こうなりました。</p>
<p><img src="https://lh3.googleusercontent.com/9rDNUZFlJK6AOkhIxXufHlnrNw_y4HMtt2lr5U4FW2M=w1073-h571-no" alt="enter image description here" title=""></p>
<p>「He’s dead, Jim!」 <br>
ChromeがRan out of memoryしたそうです。</p>
<h3 id="別にコード改変せずともじっくり待てば通常数万ループ程度でどんなコードでもスタックオーバーフローするしこの提示された不良コードも最終的に必ずこうなります">別にコード改変せずとも、じっくり待てば、通常数万ループ程度で、どんなコードでもスタックオーバーフローするし、この提示された不良コードも最終的に必ずこうなります。</h3>
<p>念のためですが、イベント待たずに即時呼び出ししたのは、メモリリーク、スタックオーバーフローの確認テストの「時間節約」のためです。</p>
<h2 id="こんな超基本的な過ちを犯しているお粗末なコードをありがたがるqiitaの記事主">こんな超基本的な過ちを犯している、お粗末なコードをありがたがるQiitaの記事主</h2>
<blockquote>
<p><em>nonstarter 135 contribution May 30, 2015 11:18</em></p>
<p>Lambadaさん <br>
<strong>著者の主張に対する反例となるOCamlコードをお示しいただきどうもありがとうございます。私の手元でも問題なく動作しました。</strong></p>
<p>デスクトップ云々の件もそうですが、ブログを含む著者の一連の主張は明らかに誤ったものであることが多く、いったい何がしたいのかを忖度することがおよそ困難であるように思います。やはり、いちいち誤りに反応せず、放っておくのが正しいのでしょうか。初心者の方が早期に問題に気がつけばいいのですが。</p>
</blockquote>
<p>はい、笑止千万。なんでしょうか、この茶番は。 <br>
確かに、メモリリークする不良品のコードであろうが、なんであろうが、たかだかクリック数十回程度では、それは「手元でも問題なく動作しました!」となるように見えるでしょうね。</p>
<p>いうまでもなく<strong>スタックオーバーフローするまで、っていう時限爆弾抱えてますが。</strong></p>
<p>そういう、使い込まないと判明しないスタックオーバーフロー、メモリリークのバグが一番たちが悪くて、あなたたち、そういうのを流布しているわけです。</p>
<blockquote>
<p><strong>やはり、いちいち誤りに反応せず、放っておくのが正しいのでしょうか。初心者の方が早期に問題に気がつけばいいのですが。</strong></p>
</blockquote>
<p>とか、偉そうに書いていますが、どの口で言ってるんでしょうか?</p>
<p>この人たちはそんなレベルにはいませんし、というか結構多くの技術者が、「ああこれはまずいコードだな」って気がついていると思うんですよ。気が付かずに、こういう連中の戯言を鵜呑みにして「ああやっぱり著者=岡部のいうことは間違いだったんだ」とか結果的に多くの初心者を騙している自覚を持ってください。かなり有害。</p>
<p>念の為に、JavaScriptで、イベントつきの無限再帰ループまわすコードは以下のようになります。 <br>
原理は一緒で面倒なのでコンソールでも動くように、ユーザ入力なしの<code>setTimeout</code>イベントを使って1秒毎のタイマーにしてます。</p>
<pre class="prettyprint"><code class=" hljs matlab">var f = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(c)</span> {</span>
<span class="hljs-transposed_variable">console.</span><span class="hljs-built_in">log</span>(c);
setTimeout(<span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> {<span class="hljs-title">f</span><span class="hljs-params">(c+1)</span>;}, 1000);</span>
};
f(<span class="hljs-number">0</span>);</code></pre>
<p>これでも、確かに「<strong>著者の主張に対する反例となるOCamlコードをお示しいただきどうもありがとうございます。私の手元でも問題なく動作しました。</strong>」と、錯覚することは可能です。</p>
<p>きちんと1秒ごとに数字がカウントアップされていくのがJavaScriptのコンソールで確認できるでしょう。 <br>
しかし、同様に、超頻繁なイベントをシミュレートするために、<code>setTimeout</code>を外して、即時、再帰関数呼び出しするようにコードを変えてみます。</p>
<pre class="prettyprint"><code class=" hljs javascript"><span class="hljs-keyword">var</span> f = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(c)</span> {</span>
console.log(c);
f(c+<span class="hljs-number">1</span>);
};
f(<span class="hljs-number">0</span>);</code></pre>
<p>結果、</p>
<blockquote>
<p>17930 <br>
17931 <br>
17932 <br>
17933 <br>
17934 <br>
17935 <br>
17936 <br>
17937 <br>
17938 <br>
17939</p>
<p>17734 <br>
:0</p>
<p>RangeError: Maximum call stack size exceeded</p>
</blockquote>
<p>はい、予想通り、というかこんなの既定路線なんですが、スタックオーバーフローになりました。</p>
<p>再帰関数で、イベント拾うようなコードを書いてはいけません。常識レベルですが、その程度の常識もないスキルの技術者の分際で、常識的な発言をしている論者に対して、偉そうに不当に糾弾しているのか、もしくは、 <br>
ちょっとマズイかな?でも、まあ岡部の言うことが間違っていると読者に思わせて騙せればそれでいいや、みたいなことでしょうか?</p>
<p>可能性は2つしかないですが、どっちにしてもかなりろくでもない連中です。</p>
<blockquote>
<p>逆に、岡部氏のコードはよく見ると state = x; という部分で <br>
カウンタ変数への破壊的代入を行っており、何ら関数的ではありません。 <br>
(無駄に複雑なスパゲッティ・プログラムですが、よく読むと要するに <br>
state = state + 1; と同じ破壊的代入です。) <br>
ご参考になれば幸いです。</p>
</blockquote>
<p>あのねえ。なにが、ご参考になれば幸いだと。</p>
<p>自分のコーディング能力で理解しにくいコードを、 <br>
「無駄に複雑なスパゲッティ・プログラム」 <br>
とか、てきとーなデタラメ言うなと。 <br>
ヤ●ザの因縁つけ、当たり屋となんら変わらないやり方ですね。</p>
<blockquote>
<p>カウンタ変数への破壊的代入を行っており、何ら関数的ではありません。</p>
<p>読むと要するに <br>
state = state + 1; と同じ破壊的代入です。</p>
</blockquote>
<p><strong>違います。</strong></p>
<p>拙書にも何度も書いていますが、関数ライブラリ自体は「ハードウェアモード」の命令型であったり、破壊的代入もします。 <br>
そうやって用意した、関数ライブラリを利用するコードが関数型であるということです。</p>
<p>こんな因縁が通るのであれば、FacebookのReactだって、FRPのコードは破壊的代入してますから、</p>
<blockquote>
<p>なんら関数的ではありません。</p>
</blockquote>
<p>と因縁つけられるわけですね。</p>
<p><strong>まあ、Facebookの技術者は優秀なので、間違ってもこんなアホな無限再帰ループをもって、Reactライブラリ実装していないことだけは100%確かです。実際メモリリークなんてしていないから。</strong></p>
<blockquote>
<h1 id="追記20150530デスクトップアプリケーション">追記(2015/05/30):デスクトップアプリケーション??</h1>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">著者はブログで@camloebaさんや@esumiiさんにデスクトップアプリケーションをOCamlで作成するように求めているようです</a>。著者が挙げている「クリックカウンター」や「お絵かき」の類を作成するのに特別なexpertiseは不要で、単に使用するGUIライブラリ・グラフィックスライブラリのドキュメントが読めれば充分なので、その趣旨は私にはまったく判然としません(<strong>当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります</strong>)。もちろん、OCamlであれHaskellであれ破壊的代入の類の副作用を使用せずに書くのもなんら困難ではありません。 <br>
クリックカウンターはHaskellでOpenGLに対するラッパーであるGlossライブラリを使うならばこうなります(手元の環境でインストールしやすかったのでこれを使いました): <br>
<img src="https://qiita-image-store.s3.amazonaws.com/0/77993/a5e2752a-0049-7561-bcc6-909a9cc6e269.png" alt="ClickCounter.png" title=""></p>
</blockquote>
<pre class="prettyprint"><code class="language-hs:ClickCounter.hs hljs mathematica">import <span class="hljs-keyword">Graphics</span>.Gloss.Interface.Pure.Game
main = play disp colour freq ini draw eTrans tTrans
where
disp = (InWindow <span class="hljs-string">"Click Counter"</span> (<span class="hljs-number">225</span>, <span class="hljs-number">150</span>) (<span class="hljs-number">40</span>, <span class="hljs-number">40</span>))
colour = white
freq = <span class="hljs-number">100</span>
ini = <span class="hljs-number">0</span>
draw = <span class="hljs-keyword">Translate</span> (-<span class="hljs-number">75</span>) (-<span class="hljs-number">50</span>) . <span class="hljs-keyword">Text</span> . show
tTrans _ n = n
eTrans (EventKey (MouseButton LeftButton) <span class="hljs-keyword">Up</span> _ _ ) n = n + <span class="hljs-number">1</span>
eTrans _ n = n</code></pre>
<blockquote>
<p>お絵かきアプリも難しいところはなにもなく、ドラッグ中かどうかのフラグをマウスボタンの上下で切り替えて管理し、フラグを状態遷移関数(状態とイベントをとって状態を返す純粋な関数)の引数として渡していくだけです。 <br>
<img src="https://qiita-image-store.s3.amazonaws.com/0/77993/90617001-5623-9810-180f-46651c11cfaa.png" alt="DrawingCanvas.png" title=""></p>
</blockquote>
<pre class="prettyprint"><code class="language-hs:DrawingCanvas.hs hljs mathematica">import <span class="hljs-keyword">Graphics</span>.Gloss.Interface.Pure.Game
import Data.Monoid(mconcat)
main = play disp colour freq ini draw eTrans tTrans
where
disp = (InWindow <span class="hljs-string">"Drawing Canvas"</span> (<span class="hljs-number">400</span>, <span class="hljs-number">400</span>) (<span class="hljs-number">40</span>, <span class="hljs-number">40</span>))
colour = white
freq = <span class="hljs-number">100</span>
ini = (<span class="hljs-keyword">False</span>, [], [])
draw (_, path, paths) = mconcat $ map line $ path:paths
tTrans _ w = w
eTrans (EventKey (MouseButton LeftButton) <span class="hljs-keyword">Down</span> _ _ ) (_, path, paths) = (<span class="hljs-keyword">True</span>, path, paths)
eTrans (EventKey (MouseButton LeftButton) <span class="hljs-keyword">Up</span> _ _ ) (_, path, paths) = (<span class="hljs-keyword">False</span>, [], path:paths)
eTrans (EventMotion pos) (<span class="hljs-keyword">True</span>, path, paths) = (<span class="hljs-keyword">True</span>, pos:path, paths)
eTrans _ w = w</code></pre>
<blockquote>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)、結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。</p>
</blockquote>
<p>同じです、Haskellで書こうと何しようと、一緒。</p>
<blockquote>
<p>いずれにせよ、状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)</p>
</blockquote>
<p>みたいなことを、GUIアプリケーションのイベントを拾うために実装してはいけません。 <br>
マウスポインタの移動みたいな超頻繁なイベントが発生するこういう「お絵かきアプリ」なんて、即死確定ですが、普段関数型プログラミングでGUIアプリなんて書く経験が未熟なので、そんな基本的なことすら気にならないのでしょう。</p>
<h2 id="要するにこういう連中は関数型プログラミングの理論のことしか考えておらず状態機械という言葉が使いまわせてもそれが実用的にはメモリリークしてスタックオーバフローすることすら知らない">要するにこういう連中は、関数型プログラミングの「理論」のことしか考えておらず、状態機械という言葉が使いまわせても、それが実用的にはメモリリークしてスタックオーバフローすることすら知らない</h2>
<p>ということです。</p>
<p>あとね、</p>
<blockquote>
<p>(<strong>当該の記事で著者がOCamlで「お絵かきロジック」を実装してみせよと要求する一方で自身ではJavaScriptによるそれを公表していない点も気になります</strong>)</p>
</blockquote>
<p>こういう「気になります」程度の「揚げ足取り」部分をわざわざ太字にするとかしょうもないことしているから、各所で、レビューを装った単なるネガキャンにすぎない、だと見透かされているのだから留意したほうが良いです。</p>
<p>こちらは、自前で、FRPのライブラリを実装しているのだから、「お絵かきロジック」でもなんでも時間変化するアプリは書けるし、本書を読んではみたが、巧妙に論評を避けている(内容を理解できていない)Day5に「お絵かきロジック」と等価のReactサンプルアプリ書いているのですが、理解できなかったから無視したわけですね。</p>
<h2 id="結論">結論</h2>
<p><a href="http://kenokabe-techwriting.blogspot.jp/2015/05/esumiicamloebaocaml.html">住井 英二郎@esumiiさんとか、らくだの卯之助@camloebaさんに聞きたいのだけど、そもそも貴方たちはOCamlでデスクトップアプリ書けるんですか?</a></p>
<p>あんたらどうせ最終的には実用に耐える関数型プログラミングのコードなんて提供できないんでしょ?(笑)</p>
<p>という「確認」記事を出したところ、</p>
<p><strong>案の定、メモリリークする実用に耐えない不良品しか提示されませんでした。</strong></p>
<h2 id="frpを利用しない自称関数型guiアプリはメモリリークする不良品しか書けなかった">FRPを利用しない自称関数型GUIアプリは、メモリリークする不良品しか書けなかった</h2>
<p><strong>こういう連中の言うことを鵜呑みにしがちな【学習者要注意!】です。</strong></p>
<p>というか、こういうのは序の口です。 <br>
この記事主はまだまだ、やらかしているので、それ全部反論していきます。</p>
<p>こんないい加減な知識とコードを書きなぐった記事で、人の主張を不当に否定して、学習者騙せて楽しいですか?いい加減にしたらどうか?</p>
<blockquote>
<p><em>nonstarter 135 contribution May 31, 2015 11:27</em> <br>
hiyakashi_さん <br>
マウスポインタの現在位置を表示するというような、先行するイベントに依存しない処理のみの場合には状態を渡して云々は特にありませんが、先行するイベントに依存するようなある程度複雑な処理をしようとすれば、どうしても状態とイベントから状態への純粋な関数を使って、シグナル(特にイベントのストリーム)を畳み込んで状態のストリームを得ていくことになりますよね(FRPを支援する代表的な関数型プログラミング言語Elmのfoldp : (a -> state -> state) -> state -> Signal a -> Signal stateがまさにそれです)。 <br>
ElmClickCounter.elm <br>
clickCount : Signal Int <br>
clickCount = foldp (\click total -> total + 1) 0 Mouse.clicks <br>
一定以上に複雑なものを関数型スタイルで書こうとする場合には、状態遷移を純粋な関数として表現するという手法をFRPそれ自体によって免れることはできません(私が理解する限りでは)。 <br>
私の結論は、著者であるkenokabeさんの言葉を額面通り受け取れば、彼はFRPを理解していないのだろう(或いは少なくともfoldpのような畳込みが必要になるような一定以上に複雑なFRPを経験したことがないのだろう)、というものです。 <br>
GUIアプリケーションの構築に際して、IOモナドによるプログラミングがうまくいく/うまくいかないその程度に、現状のFRP(念頭においているのはElmですが)もうまくいく/うまくいかないだろう、と私は考えています。</p>
</blockquote>
<p>また、</p>
<blockquote>
<p>私の結論は、著者であるkenokabeさんの言葉を額面通り受け取れば、彼はFRPを理解していないのだろう(或いは少なくともfoldpのような畳込みが必要になるような一定以上に複雑なFRPを経験したことがないのだろう)、というものです。</p>
</blockquote>
<p>とか、メモリリークする不良品コードをありがたがる人が、FRP理解していないとか因縁づけ。</p>
<blockquote>
<p>Lambada 0 contribution May 31, 2015 15:37 <br>
岡部氏は <br>
『関数型プログラミングのパラダイム内で、そういうマウスボタンが押されているのか、押されていないのか?入力の状態が時間遷移していく場合、上記ブログエントリでも論じたSICPでも、拙書でも解説しているとおり、FRPの実装が必ず必要となります。 <br>
「時間」が本質的だから、時間をを集合、SICPの言葉でいえば「遅延ストリーム」とした実装が必要です。』 <br>
と断言しているにも関わらず、現に私やnonstarter氏のコードのように <br>
「時間」も「ストリーム」も出てこない関数的状態渡しによる実装が <br>
容易である以上、岡部氏の誤りは明らかだと思います。ご参考まで。</p>
</blockquote>
<p>念の為ですが、</p>
<blockquote>
<p>拙書でも解説しているとおり、FRPの実装が必ず必要となります。 <br>
「時間」が本質的だから、時間をを集合、SICPの言葉でいえば「遅延ストリーム」とした実装が必要です。</p>
</blockquote>
<p>っていう主張は普通に維持します。</p>
<blockquote>
<p>断言しているにも関わらず、現に私やnonstarter氏のコードのように <br>
「時間」も「ストリーム」も出てこない関数的状態渡しによる実装が容易である以上、岡部氏の誤りは明らかだと思います。ご参考まで。</p>
</blockquote>
<p>はい確かに、メモリリークしてスタックオーバーフローするような「関数的状態渡し」=再帰関数の無限ループみたいなアホな実装は容易ですね。 <br>
もちろん、気の利いた技術者は普通にアホなやり方だと知っているのでやらないだけですが。 <br>
「理論」のことだけ考えて、実用的なGUIアプリケーションを書くことが念頭にないから、こういう低レベルなことを言って、間違っていない人を誤りが明らかだ、とかいう愚を犯す。</p>
<p>まだまだ続きます。</p>Ken OKabehttp://www.blogger.com/profile/13759444559259994373noreply@blogger.com0