Topics

・関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い

ガラパゴス・ネットスラング=「関数型ポエム」という呪詛、先入観的読書と、フェアなレビューの登場

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

JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン

2016年のnode、ES6、React、Babel、Atomエディタ界隈の方向性

Dockerじゃないsystemd-nspawn+machinectlが非常に良い

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その2】関数型プログラミングのイミュータブルな世界観とイミュータブルな実世界を完全に統合

10年先を行く斬新な関数型(FRP)データベースについて説明する 99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その3】

[React (.js Facebook)解説 関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 サポート記事【静的HTML編】React 解説【動的HTML-FRP編】

量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説01量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説02

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

LISPデータ構造の問題点の指摘と抜本的解法としての新プログラミング言語の策定/純粋関数型言語「SPINOZA」

著書『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』 [Day1]たち読み記事 無料公開中

『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』を大変多くの方々にお買い求めいただき、感謝します。本書の全目次を公開し、質問を受け付けます。

2015年5月27日水曜日

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



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

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

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

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

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

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

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

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


のうち、これは最初のエントリとなります。



前回のエントリ

関数型プログラミングと私の著書の正確性についてきちんと議論(論争)します。

を書いたところ、
【自称】関数型コミュニティの「メンバー」よりお返事がある、とのお知らせを親愛なる読者の方からご一報いただきました。
らくだの卯之助‏@camloeba
疑似科学者と論争はしませんよ。議論にならないし最後は勝手に勝利宣言するだけですから。
5:22 AM - 26 May 2015
なるほど、今度は「疑似科学者」ですか。随分な言われようですね。
私も貴方がたは、いろいろ上から目線で偉そうには言うが、ほんとうに肝心な部分では逃げまわるばかりなので、議論になりにくいな、と思っています。

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

科学的方法(かがくてきほうほう、英語:scientific method)とは、物事を調査し、結果を整理し、新たな知見を導き出し、知見の正しさを立証するまでの手続きであり、かつそれがある一定の基準を満たしているもののことである 。科学的手法、科学的検証ともいわれる。
科学者は実験を重視します。
科学は証拠となる事実(生データ/証拠物件)を要求する。
それが示されない限り、その仮説は最終的には「机上の空論」に終わる。
「机上の空論」なんと適切なワーディングなのでしょうか。
机上 = Desktop デスクトップ
らくだの卯之助‏@camloebaさん、あなたは、そのアカウント名のとおり、OCaml愛好者でおられて、私の関数型プログラミングの主張や、「理解」について、いろいろ言っておられますよね?延々と。まあ、よほど当方の主張が気になるんでしょう。現代人として恥ずべき焚書みたいな真似が大失敗してしまったし。
『関数型プログラミングに目覚めた!』のレビュー(Day-1)
でも、どこでも、貴方のTweetが結構利用されてるので、いやでも目につきます。
らくだの卯之助‏@camloeba
0 から 9 まで列挙した配列、この本の問題として本質的ではないという意見。しかし、この例を選んでしまっているところにリスト、配列、空間コスト、評価戦略などの関数型プログラミングの大切な概念に対する無理解が見て取れるため極めて象徴的であるのです
5:43 PM - 8 May 2015
これみたらわかるけれども、例の東北大学の住井 英二郎@esumiiさんもリツイートされていますね?
素朴な疑問なんですが、貴方がた、延々と私の関数型プログラミングの「無理解」やらスキルに偉そうなことを言い続けているけど、実際のところ、貴方たちは、関数型プログラミングで、実用に耐えうるデスクトップアプリとか書いたことあるんでしょうか?というか、書けるんですか??
机上 = Desktop デスクトップのアプリをOCamlで書いて見せてくださいよ。議論はしなくて良いから。
「疑似科学者」なんて罵倒するなら、自分で証明しろ、って思いますね。
さあどうぞ。
個人的に、OCamlを振り回して、国内で関数型プログラミングで、なんかこういう、私の主張にたいしても上から目線で偉そうにごちゃごちゃ文句いってくる連中が、GUIアプリ書いてる事象を目撃したことがこれまで一度もない。
なんで?
まあ、技術者ならば、科学的精神をリスペクトするならば、
らくだの卯之助‏@camloebaさん、あなたが自身の関数型プログラミングのスキルが「机上の空論」でないことを示してください。

私はすでに拙書でも、当ブログでも、関数型プログラミングで実用に耐えうるGUIアプリが書けるポテンシャルを証明している

React (.js Facebook)解説 関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 サポート記事【静的HTML編】
React 解説【動的HTML-FRP編】
という、技術記事をUPしています。
特に後者は、拙書の延長で、FRPの適用をしています。

Click Counter

Click Counterなる、
「ああこれが出来るなら、多分どんなWebアプリも書けるだろうな!」
というシンプルかつ要点をおさえているWebアプリを
React+worldcomponentで構築してみます。

各グレーの「カード」をクリックすると、

Localのクリック数、Totalしたクリック数がカウントアップされます。
そして、前回の
【静的HTML編】の一番最後のコードが、ベースになっています。
ChildrenComponentなど、よく見比べてみてください。
コード

var ___ = worldcomponent;
___.world = ___.log('start!'); //debug log

var CARDS = 4;
var ___totalClicks = ___(0);

var TopComponent = React.createClass(
{
  render: function()
  {
    var divStyle = {background:"#aaaaaa"};
    var el = (
      <div style={divStyle}>
        <h1>Click Counter</h1>
        <ChildrenComponent/>
      </div>
    );
    return el;
  }
});

var ChildrenComponent = React.createClass(
{
  render: function()
  {
    var createChild = function(n)
    {
      return (<ChildComponent id={n} ___clicks={___(0)}/>);
    };

    var array = Immutable.Range(0, CARDS).toArray();
    var elArray = array.map(createChild);

    var el = (<div>{elArray}</div>);
    return el;
  }
});

var ChildComponent = React.createClass(
{
  componentDidMount: function()
  {
    var com = this;

    ___.world = com.props.___clicks
                .compute(function(x){com.forceUpdate();});
    ___.world = ___totalClicks
                .compute(function(x){com.forceUpdate();});
  },
  handleClick: function()
  {
    var com = this;

    ___.world = com.props.___clicks
                  .appear(com.props.___clicks.now() + 1);
    ___.world = ___totalClicks
                  .appear(___totalClicks.now() + 1);
  },
  render: function()
  {
    var com = this;

    var divStyle = {background:"#dddddd",
                    width:"210px",height:"210px",
                    margin:"5px",float:"left",
                    "user-select": "none",
                    "-moz-user-select": "none",
                    "-webkit-user-select": "none",
                    "-ms-user-select": "none"};

    var el = (<div style={divStyle} onClick={com.handleClick}>
                <h2>id : {com.props.id}</h2>
                <h4>Local Clicks : {com.props.___clicks.now()}</h4>
                <h4>Total Clicks : {___totalClicks.now()}</h4>
              </div>);
    return el;
  }
});

var mount = React.render(<TopComponent/>, document.getElementById("mountpoint"));

ちなみに

もちろん、OCaml FRPで検索したら、なんかあるようですが、
https://www.google.co.jp/search?q=OCaml+FRP&oq=OCaml+FRP&aqs=chrome..69i57j69i59l2&client=ubuntu&sourceid=chrome&es_sm=0&ie=UTF-8#q=OCaml+FRP&lr=lang_ja
OCamlで実用的なWeb・デスクトップアプリを書く情報って、日本語ではほぼ皆無に等しいし、
住井 英二郎@esumiiさんが、Qiitaで直接、私にむかって「読め」とおっしゃられた、ご自身のWeb記事
数理科学的バグ撲滅方法論のすすめ—目次
連載目次
第1回 OCamlを試してみる
第2回 「単一代入」と「末尾再帰」
第3回 計算量の工夫でプログラムは劇的に速くなる
第4回 関数型言語とオブジェクト指向,およびOCamlの”O”について
第5回 LablGLで3Dグラフィックス ~OCamlの「多相バリアント」と「ラベル付き引数」~
第6回 OCamlの「モジュール・システム」
第7回 「代数データ型」でいろいろなデータを表してみる
第8回 独自のプログラミング言語を開発してみよう(その1)
第9回 独自のプログラミング言語を開発してみよう(その2) プログラムを実行できるようにする
第10回 静的スコープと関数クロージャ
~関数型言語のインタプリタを書いてみる~
第11回 クロージャによる超軽量並行プロセスの簡単実装法
第12回 「型推論」の実装法
第13回 「表明」と「契約」による命令型プログラムの形式的検証 
第14回 型=命題,プログラム=証明 
第15回 型からプログラムを当てる 
第16回 すべてのものは関数である 
をざっと拝読したわけですよ。
もちろん、ここで、
関数型プログラミングたるものが「机上の空論」ではない、と示すべき、なのが
第5回 LablGLで3Dグラフィックス ~OCamlの「多相バリアント」と「ラベル付き引数」~
であるわけです。

ティーポットの描画と回転

これだけでも描画はできるのだが,せっかくの3Dグラフィックスなので,少しくらいは動きを入れたい。そこで,キーボードから入力があったら回転する,という関数も定義・登録しよう。
# let keyboard ~key:k ~x:x ~y:y = (* 入力されたキーkとマウスの座標x,yを引数とする *)
    if k = int_of_char 'q' then exit 0; (* 入力された文字がqだったら終了 *)
    GlMat.rotate ~angle:2.0 ~x:0.25 ~y:0.5 ~z:1.0 (); (* そうでなければ回転 *)
    display () (* 描画関数displayを呼び出して,全画面を再描画 *) ;;
val keyboard : key:int -> x:'a -> y:'b -> unit = <fun>
# Glut.keyboardFunc keyboard (* キーボード処理関数keyboardを登録 *) ;;
- : unit = ()
なるほど、
99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう
で、こんなものは関数型プログラミングのコードではない、と批判した、「お絵かきロジック」のミュータブルな破壊的代入はなされていないようです。
でも、これ見て私が率直に何を思ったか?
「うまく逃げているな」と思いました。
この「ティーポットの描画と回転」のGUIアプリのコードは、たしかに、関数型プログラミングの要件を満たしていますが、それが可能になっているのは、とりもなおさず、このサンプルが簡単、もっというとGUIアプリとしてはかなり例外的で特殊だからです。
じゃあ、この調子で、「お絵かきロジック」を書けるのか?というと、書けないですよね?
ならば、あなたのすべての解説は、最終的には、「机上の空論」に帰着する。
関数型プログラミングたるものが「机上の空論」でない、という必要な情報がまったく提供されていない。
いったい、なんでこんなことになっているんでしょうか??

背景考察

関数型プログラミングのパラダイム内で、そういうマウスボタンが押されているのか、押されていないのか?入力の状態が時間遷移していく場合、上記ブログエントリでも論じたSICPでも、拙書でも解説しているとおり、FRPの実装が必ず必要となります。
「時間」が本質的だから、時間をを集合、SICPの言葉でいえば「遅延ストリーム」とした実装が必要です。
少なくとも、これまで私が見た、すべてのOCaml解説で、このFRPの解説を体系的になしている文献は皆無です。もちろん、この住井氏によるWeb記事も含めてそうですよね。非常に巧妙にそこを避けて、あたかもGUIでもなんでも出来るようには見せては、いるが、実際FRPを導入しないと、「お絵かきロジック」のように、状態変数の破壊的代入は避けられないので、破綻します。
私が一貫して、批判している、住井氏による、
「関数型言語」に関するFAQ形式の一般的説明
という、Qiita記事ですが、
それだと入出力や状態(state)すら表せないのでは?
いいえ、純粋な関数型プログラミングでも、入力を引数、出力を戻り値とする関数を考えることにより、入出力も表現できます。非常に簡単に言うと、例えばhello(x) = “Hello, ” + x + “!”みたいな関数で(これも文法は適当です)、文字列hogehogeを入力するとHello, hogehoge!と出力する、みたいなプログラムを書くことができます。
同様に、状態(の変化)についても、古い状態を引数として受け取り、新しい状態を戻り値として返す関数により表すことができます。
という、状態(の変化)の解説、(太字にした)最後部分の「一般的解説」を拝見して、「ああこの人はFRP理解していないんだ」と思いました。
同様に、状態(の変化)についても、古い状態を引数として受け取り、新しい状態を戻り値として返す関数により表すことができます。
という作法で「お絵かきロジック」のアプリを書けるんでしょうか?書けるわけがありません。時間が本質的なのに、時間の処理を関数型プログラミングのパラダイムで一切考慮されていないからですね。
まったく、時間軸上のデータの集合化、FRPについてはかすってもいません。
要するにこの理解は間違いです。
いろいろあれ読め、これ読めという方なので、
念の為ですが「権威ある」SICPでは、オブジェクト指向と、遅延評価のストリーム(FRP)が対比的に論じられています。
Both the object-based approach and the stream-processing approach raise significant linguistic issues in programming. With objects, we must be concerned with how a computational object can change and yet maintain its identity. This will force us to abandon our old substitution model of computation (section 1.1.5) in favor of a more mechanistic but less theoretically tractable environment model of computation. The difficulties of dealing with objects, change, and identity are a fundamental consequence of the need to grapple with time in our computational models. These difficulties become even greater when we allow the possibility of concurrent execution of programs. The stream approach can be most fully exploited when we decouple simulated time in our model from the order of the events that take place in the computer during evaluation. We will accomplish this using a technique known as delayed evaluation.
オブジェクト準拠の解決法とストリーム処理の解決法は, どちらもプログラミングの重要な言語学的論点を持ち込む. オブジェクト間には, 計算オブジェクトが, どう変化出来, しかも同一性を保持出来るかという点に注意しなければならない. そのため, より機械的だが理論的には制御し難い, 計算の 環境モデル(environment model)の方がよく, 古い置換えモデル(1.1.5 節)を捨てることになる. オブジェクト, 変化, 同一性を扱うことの難しさは, 計算モデルに時を取り込む必要性の根本的な結果である. これらの難しさは, プログラムの並列実行の可能性を許すと大幅に増大する. ストリームの解決法は, 評価中に計算機の中で発生する事象の順序から, モデルでのシミュレートされた時を分離すると, 十分な利用が可能になる. われわれはこれを 遅延評価(delayed evaluation)という技法を使って達成しよう.
一方で、
「関数型言語」に関するFAQ形式の一般的説明では、
オブジェクト指向と関数型は対立していますか?
いいえ
(略)
上の記述はあくまで理論の話です。紹介記事の冒頭に書いたとおり、「単純な関数型言語に、複雑なオブジェクト指向はいらない」という考え方もあります(私個人の好みもそれに近く、OCamlのOはほとんど使っていません。参考リンク:オブジェクトは OCaml の鬼子)。
えーっと、最初は、いいえ→同じ研究者(含む自分)が研究して、キーノートが、っていう説明だけだったものが、なんか、どんどんと「トーンダウン」して、
上の記述はあくまで理論の話です
という珍妙なエクスキューズが最近、追加されました。
「オブジェクト指向」って、そもそも「理論」じゃないですよね?
「指向」、パラダイムであって、理論ではない。
こんなものは、どこでも書かれている初歩的な知識です。
拙書では、アラン・ケイのことを延々と書いて紹介しましたが。
あなたの理解と「初心者」への説明の仕方は最初から決定的に間違っている。
直交・独立な概念だ、って言うのが流行しているようですが、オブジェクト指向って、一般的に命令形でしょ?状態変数を隠蔽するカプセル化するんだから、イミュータブルな関数型プログラミングと、排他的です。
さらに、なんか編集追加されていて、参考リンク:オブジェクトは OCaml の鬼子っていうのは、当初から私が展開している論説とまったく一緒なんですが、いったい何をやってるんですか??
「鬼子」っていうのは、
直交・独立な概念だ、じゃなくって、
排他的な意味あいなのではないですか?日本語としてね。
どっちなんですか?こういうどっちつかずの説明しかできないのでしょうか?実際に、
数理科学的バグ撲滅方法論のすすめ—目次
第4回 関数型言語とオブジェクト指向,およびOCamlの”O”について
では、まるでそんな「オブジェクトは OCaml の鬼子」という明確な主張はなされておらず、ぼやーっと、どっちにでも取れるような記述になっています。
この辺が、いわゆる学者にありがちな保身的知的欺瞞であり、読者は二の次である、保身的解説なんですね。
オブジェクト指向と関数型は対立していますか?
いいえ

上の記述はあくまで理論の話です ←OOは理論じゃないので間違い

(私個人の好みもそれに近く、OCamlのOはほとんど使っていません。参考リンク:オブジェクトは OCaml の鬼子)。
こんなものは一般的解説としては成立していない、と考えます。一番割り食うのは、読者なんですね。意味不明。あなたのどっちつかずの「見解」だけが、巧妙に保身される。
関数プログラミング実践入門 ──簡潔で、正しいコードを書くために
という書籍でも、
そして,「関数プログラミングにおける思考方法」は,よく知られた構造化プログラミングやオブジェクト指向プログラミングのそれとはかなり違います。他の関数プログラミング関連書籍を読んだことのある方でも,ともすれば「どう考えて書いていったらよいか」設計方法/思考方法がピンとこない方がいるかもしれません。書き方がわかっても,考え方が伴わなければ,プログラムとはそうそう書けるものではありません。そのため本書では,関数型言語で関数プログラミングを行う際,どのように考えを進めていけば関数型言語らしい簡潔なコードになるかを説明しています。
あとはもう、まるまる、
関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い
で、さんざん、オブジェクト指向と、関数型プログラミングが「パラダイム」として「違う」と列挙したとおりですね。
オブジェクト指向は、「理論」でもなんでもないので。
曖昧にしてマルチパラダイムだ、と延々強弁する、意義もメリットもまったくわかりません。だって、考え方が「かなり」違うんでしょ?
じゃあ、その「かなり」違う考え方を説明してよ、って読者は思ってるのに、「いいえ」対立していません、直交・独立な概念だ、でも鬼子です、って何をやりたいんでしょうか??

遅延評価とイベント駆動とFRPのおはなし

以下、この議論で、超重要な(そして、OCaml愛好者を中心とする【自称】関数型プログラミングコミュニティの連中が、まったく無頓着、理解していない)内容です。
超重要なので、
99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう
からまるまる再掲します。

ストリーム (SICP)

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html
http://sicp.iijlab.net/fulltext/x350.html
3.5 Streams
We’ve gained a good understanding of assignment as a tool in modeling, as well as an appreciation of the complex problems that assignment raises. It is time to ask whether we could have gone about things in a different way, so as to avoid some of these problems. In this section, we explore an alternative approach to modeling state, based on data structures called streams. As we shall see, streams can mitigate some of the complexity of modeling state.
3.5 ストリーム
モデル化の道具としての代入について十分理解し, 代入が惹き起す複雑な問題も認識した. これらの問題の幾分かを回避するため, 別の方向へいった方がよかったか考えてみよう. 本節では, 状態をモデル化する, ストリーム (streams)というデータ構造に基づいた, もう一つの解決法を調べてみる. すぐ分るように, ストリームは状態のモデル化の複雑さの幾分かを軽減する.
いよいよ、SICPで、関数型プログラミングのパラダイムにおいて、
「時間」の問題をいかに鮮やかに解決するか?その具体的な解法が示されます。
Let’s step back and review where this complexity comes from. In an attempt to model real-world phenomena, we made some apparently reasonable decisions: We modeled real-world objects with local state by computational objects with local variables. We identified time variation in the real world with time variation in the computer. We implemented the time variation of the states of the model objects in the computer with assignments to the local variables of the model objects.
少し後戻りして, この複雑さがどこから来たか反省しよう. 実世界の現象をモデル化しようとして, 明らかに合理的な決定をいくつかした: 局所状態を持つ実世界のオブジェクトを, 局所変数を持つ計算オブジェクトでモデル化した. 実世界の時間変化を計算機内の時間変化と同一視した. モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.
オブジェクト指向の「複雑さ」の「レビュー」=「反省点」が考察されます。
実世界の時間変化を計算機内の時間変化と同一視した
これがまずいんですね。
そして、その大前提として、
「実世界の時間変化」っていう論点化がちゃんと出来ているかどうかです。
ほとんどの論者、解説文では、こんなこという水準に達していませんから、そもそもこういう発想、考察自体が無理です。
モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.
秀逸な知見です。
状態変数への破壊的代入を繰り返すことで、そのモデルの時間変化に対応させている。
破壊的代入、っていうのはモデルの時間変化のためにやっていた、
こういう「自覚」をもってるプログラマって今、日本に何人くらいいるんでしょうか?
拙書の読者には随分いるでしょうから、少しは増えたかもしれません。
Is there another approach? Can we avoid identifying time in the computer with time in the modeled world? Must we make the model change with time in order to model phenomena in a changing world? Think about the issue in terms of mathematical functions. We can describe the time-varying behavior of a quantity x as a function of time x(t). If we concentrate on x instant by instant, we think of it as a changing quantity. Yet if we concentrate on the entire time history of values, we do not emphasize change – the function itself does not change.52
(52 Physicists sometimes adopt this view by introducing the “world lines” of particles as a device for reasoning about motion. We’ve also already mentioned (section 2.2.3) that this is the natural way to think about signal-processing systems. We will explore applications of streams to signal processing in section 3.5.3.)
これ以外の解決法があるだろうか. 計算機内の時をモデル世界の時と同一視するのを避けることは出来るだろうか. 変化する世界の現象をモデル化するのに, モデルを時と共に変化させなければならないか. これらの論点を数学関数を使って考えてみよう. 量xの時間変化する振舞いを, 時の関数x(t)と書くことが出来る. xを時刻時刻に注目すれば, それを変化する量だと思う. しかし値の全時間の歴史に注目すれば, 変化を強調しない—関数それ自身は変らない.52
(52 物理学者は運動に関する推論の道具として, 粒子の 「世界線」を導入することでこの視点を採用する時がある. われわれは(2.2.3 節で)これは信号処理システムを考える自然な方法であると述べた. 3.5.3節でストリームの信号処理への応用を述べる.)
SICPの著者は、
物理学者は運動に関する推論の道具として, 粒子の 「世界線」を導入することでこの視点を採用する時がある.
この言及以外に何度も物理学の知見を披露しており、物理学の素養があります。
ここが非常に重要な論者の素養による洞察であり、
「計算機科学」を数学理論ではなく、我々が棲息する物質世界の一部の事象として捉えています。
これが重要。
ほとんどの「計算機科学」の研究者、あるいは技術者にはこの視点が徹底的に欠落しており、
だから、結構ろくでもない状況になっています。話してもまったく通じない。
ちゃんと勉強してるの?って私などは思ってしまうんですが。
知識としてあるだけで、異なる分野の関連を結び付けられないのであれば、それは知性のセンスのなさです。
私はだからこそ、拙書のDay1の関数型プログラミングのフックが終わった後の
Day2の最初部分で、もういきなり、物質世界のことを書き始めました。
コンピュータとは、ハードウェアとソフトウェアで成り立っている不思議な存在であり、
計算という事象も、物質世界で起こっているのである、論理世界の中で完結するものではない、
とさんざん強調しましたが、これを上記の書評のように「わかりやすい」充実した内容だ、
と素直に理解できる知性もあれば、何を言っても伝わらない愚鈍があったのは、
まさに拙書で予想したとおりとなりました。
この「計算機科学」が「物質世界」の挙動を考慮する必要があり、
物理学の知見と関係があると示すのは、最終的にはもちろん、このように最終部分のFRPのことまで一本の線をつなぐためには絶対に必要な地ならしでした。
そして、この物理学者が、物理で記述するのが、
これらの論点を数学関数を使って考えてみよう.
xの時間変化する振舞いを,
時の関数x(t)と書くことが出来る.
xを時刻時刻に注目すれば, それを変化する量だと思う.
しかし値の全時間の歴史に注目すれば, 変化を強調しない—関数それ自身は変らない.52
という結構、中学でも高校でも習うごくごく物理の基礎的な数式展開です。
関数それ自身は変らない.
これは要するに、時間変化であろうがなんであろうが、
時間変数=時刻にたいして、
物質世界はイミュータブルな関数として記述される、ということです。
そして、この時間変数の関数をプログラミングで実現する技術こそが、
何度も話しているFRPであり、拙書のDay4で具体的な技術として解説している、Facebook-Reactです。
もちろん、Facebook-Reactでは概念実証としては、極めて不十分ですから、
より時間の関数であることを完全に概念実証した自前の
timecomponent
を提示しました。計算可能な任意の時刻の値にイミュータブルにアクセスして
値を返す関数です。
そして、このFRP技術を可能にするのが、
まさに時間軸を無限の並びとして扱う、遅延評価なんですね。
SICPでは続いて、以下のように論じられています。
If time is measured in discrete steps, then we can model a time function as a (possibly infinite) sequence. In this section, we will see how to model change in terms of sequences that represent the time histories of the systems being modeled. To accomplish this, we introduce new data structures called streams. From an abstract point of view, a stream is simply a sequence. However, we will find that the straightforward implementation of streams as lists (as in section 2.2.1) doesn’t fully reveal the power of stream processing. As an alternative, we introduce the technique of delayed evaluation, which enables us to represent very large (even infinite) sequences as streams.
時を離散ステップで測るなら, 時間関数を(無限かも知れぬ)並びとしてモデル化出来る. 本節ではモデル化しようとするシステムの時間史を表現する並びを使い, 変化をモデル化する方法を見よう. そのためにストリーム (streams)という新しいデータ構造を取り入れる. 抽象の視点からはストリームは単なる並びである. しかしストリームを(2.2.1節のように)リストとして簡明直截に実装しても, ストリーム処理の力を十分に発現出来ない. その代り 遅延評価(delayed evaluation)の技法を取り入れよう. それを使えば非常に長い(無限でさえある)並びでもストリームとして表現出来る.

ストリームは遅延リスト

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.1
http://sicp.iijlab.net/fulltext/x351.html
3.5.1 Streams Are Delayed Lists
3.5.1 ストリームは遅延リスト
In general, we can think of delayed evaluation as demand-driven'' programming, whereby each stage in the stream process is activated only enough to satisfy the next stage. What we have done is to decouple the actual order of events in the computation from the apparent structure of our procedures. We write procedures as if the streams existedall at once” when, in reality, the computation is performed incrementally, as in traditional programming styles.
一般に遅延評価は 「要求駆動」プログラミングと考えることが出来る. ストリーム処理の各段階は次の段階を満足させるのに十分なだけ起動される. これまでやったのは計算における事象の実際の順を, 手続きの見かけの構造と 切り離すことである. われわれは伝統的なプログラミングスタイルでのように, ストリームがあたかも「みんな一緒に」存在したかのように手続きを書くが, 実際は計算が漸進的に実行される.
ここにも、SICPの著者のたいへん秀逸な知見があります。
遅延評価とは、一般化すると、「要求駆動」=イベント駆動(ドリブン)のプログラミングである、ということです。
これは、もちろん拙書でも、同じであるからこそ、
「必要なときに必要な分だけ計算する方法」とわざと書いていて、
それは、「イベント駆動」と同じである、
論理と計算が分離されたやり方である、そして宣言型である、と何度も説明しています。
そして、しつこいようですが、何度も言いたいのですが、
こういう解説は、拙書とSICP以外には見たことがありません。

——

JavaScriptを関数型プログラミング言語として使う是非について

を論点として明示的に切り出し、対立論者を批判する、という予告をしていました。
というより、対立論者、反論、といっても正直ここは、

「非常にレベルが低い」論点だと思っています。

Amazonのレビュー
なぜ関数型プログラミング本でHaskell, Erlang, Clojureなどの関数型言語を採用しなかったのか。
本書を手にする人達は、少なからず関数型言語に興味があり、まさかJavaScriptで関数型プログラミングやろうとなんて考えていないかと思います。
というトンデモ見解については、ここまであからさまなもの、よりオブラートに包んでいるが根本的に同様の勘違いをしているもの、
例えば
Qiitaに、また素性の知れない文責を伴わない無責任な(恥の)書き捨て中傷記事
『関数型プログラミングに目覚めた!』のレビュー(Day-1)について
素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。)
とりあえず
「素人としては深入りを避けたい」
と言い訳しながら、
(著者の)「関数型プログラミングの無理解を象徴的に示すもの」
だとか、あからさまに中傷するあたり、お里がしれます。

なんにも知らないで、また「書評・レビューのフリ」をして「中傷」しているんだな・・・

と呆れるばかりです。非常に低レベルです。
こういう連中は、「技術の正確性」を喧伝し、
私にたいして「理解していない」「嘘を言うな」と文句を言いますが、自分の無理解やデマの拡散にはまるで無自覚です。

【害悪】なのは、JavaScriptは、関数型プログラミングに適していない、という事実に反するデマを拡散し、学習者に誤解させることです

上記、FRPのデモでも明らかであるが、現在、JavaScriptが一番FRPの実装が、Facebook-Reactを中心に進んでおり、実用化されている。

関数型プログラミングと言語の結びつきの思い込み

何度も持ちだして申し訳ないですが、
「お絵かきロジック」はOCamlという関数型言語で書かれていましたが、関数型のコードではありませんでした。
基本、どの関数型言語でやろうと、時間が本質的であることに無頓着で、考慮せず、なんらかの破壊的代入をやっている限り、それは関数型プログラミングではありません。

2015年5月26日火曜日

関数型プログラミングと私の著書の正確性についてきちんと議論(論争)します。

関数型プログラミングと私の著書の正確性についてきちんと議論(論争)します。

私の著書である、

関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間

著書『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』 [Day1]たち読み記事 無料公開中

enter image description here

について、一部巷では、その
「技術的正確性」について、

  • 良い部類では、フェアな疑義
  • 程度の低い部類では、本気で勘違いしながら個人攻撃と混ぜものにしながら論者の自己都合、保身による感情的なネガティブキャンペーン
  • 最悪な部類では、自身が間違っていることを本当は理解しながら、あるいは内容をまるで理解する位置にいないのに、とにかく当方の足を引っ張ることだけが目的であるのに、フェアであることを装いながら展開するネガティブキャンペーン

が存在します。

Why? なぜ今、議論(論争)を開始するのか?

大前提 私のスタンス

大前提として、私は、一言論人として、ひとりの物書きとして、ひとりの技術者として、正確な情報を世に広めたい、特に次世代にむけて、教育者の端くれとして、正しい情報を発信、伝達しておきたいと考えています。

現状を観察して是としない

しかしながら現状、私の主張に反対する、ごくごく一部のフェアな論者、そして大多数はアンフェアな連中が一定数存在しており、この情報伝達を不当に妨げています。
一言論人として、ひとりの物書きとして、ひとりの技術者として、現状を是とはしません。

「批判」は上等なのですが、何故か「批判」を「装う」そのほとんどが、文責をまったく伴わない捨てアカウントによる書き込み、というより無様な「書き捨て」によって行われており、そのほとんどの内容は事実の歪曲、中傷が核となっている。

私は、著書を「批判」あるいは「中傷」されており、社会的実体としてまずまずいろんな影響を受けるわけですが、著書を「批判」あるいは「中傷」する、その発信元の大多数が「書き捨て」であることに留意してください。

わけのわからない文責を伴わない烏合の衆による「書き捨て」が、私への反論主体として形成されている。なんでこんなことになっているのでしょうね?

基本、現代のネットは言いたい放題で、いかに自分のリスクがなく、いかに相手にダメージを与えるか?みたいな極めて卑劣な力学をもって行動している連中が多いです。
で、これは、書籍の話であり、技術の話なんですよね。
そもそも論なんですが、なんで、技術者が技術論を語るのに、なんで匿名じゃないと語れないのか?
非常に胡散臭い状況であるのは、ちょっと気が利いた人ならば誰でもすぐに感じ取れることでしょう。

この辺の欺瞞、異常さに多くの人は気づくべきでしょう。

単純に、あっちこっちでワーワー言われているので、一周させるまでゆっくりと様子見をしていたから

で、なんでそんなことになっているのか?っていうと、基本、総体としてネガティブキャンペーンなんだからなんですね。ネガキャンじゃなければ、普通にフェアに文責を明らかにして、ひとりの技術者として立論すれば良い。で、いったいどこにそんなものがあるのですか?
ごくごく一部の例外は存在しますが、基本「ワーワー言いたいだけ」で、それが「印象操作」の助けになって、自分の気持ちをスッキリさせたいだけなので、反論の体をなしていません。

そういうのにいちいち反応するのは、私は体もひとつしかないし、本件にコミットできる手間時間も原理的に限られているので、物理的に不可能なんですね。そもそも連中は「技術的正確性」とやらを謳うが、そういう物理的不可能性の要素も見越していろいろ圧倒して単にゴリ押ししたいだけなので、最後はわけのわからない個人攻撃、あるいは「この著者は理解していない!」と言いたいだけなのが丸見えで、中傷の域を出ません。

だから、しばらくどんなもんなのか、連中の「手口」が全部明らかになるまで様子見をしていました。

「手口」っていうのは、ただ単に「揚げ足取り」だからです。
あらゆる人、物事の「悪い部分」をあげつらって「揚げ足取り」をするのは、どんな愚か者にも簡単にできます。

「レビュー」と称した、単なる誤解に基づく中傷、勘違い、理解不足、悪口の列挙なんてどんな愚か者でも簡単にできます。

そういう「パターン」が一通り出尽くすまで、逐一こちらがまっとうな「反論」あるいは是正行為をする価値は認められませんでした。

もう現段階で満足ですかね?もう出尽くしましたか?ご苦労様です。

論争の需要が大きい

本書の読者から、様々な、本書への反論あるいは「あからさまな」ネガティブレビューについてのご質問のメールが絶えません。

本書を出版した当初から、もちろんコントラバーシャルなトピックを扱うことはそれまでの経緯から、またパラダイムシフトをテーマとする本書の性格から、論争は想定していました。
ただし、それはあくまでフェアなスタンスで、展開されるものであったのですが、一部懸念していたとおり、著者としての私への個人攻撃とごちゃまぜにされながら、「論争」とは到底呼べない、極めて低レベルの、結構な暴力的行為を伴う、ネガティブキャンペーン、ゴリ押しに留まります。

「技術的正確性」という点で、まるで無頓着であり、本書、あるいは私の主張の否定があからさまな目的化しています。
たとえば、Amazonレビューのクロージャの反論説明ですが、これは大嘘です。

Amazonで、102 人中、93人の方が、「このレビューが参考になった」と投票されている、著書の「クロージャ」の説明が誤っているとの指摘が、誤っていることについて

正確な知識を求める読者、あるいは潜在的読者にとって、このような状況は間違いなく害悪なのですが、本書の正確性を云々いう連中は、この状況を批判することはまずありません。

広い初心者の正しい理解、よりも本書の毀損、「自分が属する陣営」の正しさ、という構図が透けて見えます。

関数型プログラミングの理解の推進となる

事実関係の検証、異なる見解の対比は、対象の理解を深めます。
特に、誰々がXXと言ってるのがソースで、だから正しい、これが関数型プログラミングである!というような、説明者の権威的保身に満ちた、たいして役に立たない説明を延々と読まされるよりは、それをも相対化して俯瞰して検討することにより、概念の理解が深まるでしょう。

誰を相手に議論すべきなのか?

まず、議論(論争)というからには、相手を特定しておく必要があります。

とりあえず、いろいろ面倒ですが分類をしていく下準備をします。

論外

当ブログでもすでに説明しましたが、私は個人として数年前から、ネット上の露骨なヘイト行為、誹謗中傷の対象となっています。その中心的グループは、昨今のネット事情をご覧になれば容易に感じは掴めるとは思いますが極めて執拗で病的な、法に抵触するレベルの集団であり、本来この連中はこのような技術的な議論に関与できる存在ではありません。
彼らが当方に「粘着する理由」「怒っている理由」とは、とりもなおさず、私が連中の卑劣さと異常さを堂々と指摘したからに過ぎません。
この件については、
著書のAmazonレビューによる露骨な名誉毀損、業務妨害行為についてでも、説明していますが、「ターゲット」とされている被害者は私ひとりではありません。連中を相手に批判した複数人が同じような被害に遭っています。この誹謗中傷集団には、Twitterでは誹謗中傷犯とグルになっている悪名高い弁護士もいるし、大阪大学の教授もいるし、著名なITライターもいます。
こちらを「叩く」ことで、こういう異常な連中が「自己正当化」される道理などありえるはずもないのですが、こういう連中は頭がおかしいので、私を誹謗中傷することで、「私の間違いを証明」できて、「自分たちは正しい」ということにしたいようです。要するにそういう動機で延々と粘着しています。連中は異常な自身のアイデンティティ(2ちゃんの誹謗中傷常習犯によくいるアレ)を正当化したいという、ただ一つの目的で利害が一致して集まる烏合の衆であり、道義的にも論理的にも倫理的にもなんの正当性もありません。単に損得勘定だけで振る舞う集団です。
要するに「逆恨み」ですね。PC遠隔操作事件の片山裕介が、自分の極めて異常で幼稚な犯罪行為を手段を選ばず「自己正当化」しようとしたのとまったく同じ異常なメンタリティです。この連中はもちろん、片山裕介被告を最後の最後まで「同類」としてシンパシーを露骨に表明しながら擁護していたのが非常にわかりやすかったです。
彼らは2ちゃんねるのスレッドに巣食って、数年に渡り当方へ嫌がらせ、誹謗中傷を延々と繰り返しています。自分らの振る舞いがそんなに正しいのであれば、匿名の2ちゃんねるの書き込みではなくて、実名で堂々と書けば良いのですが、できるわけもありません。法に抵触するレベルのことやらかしているからですね。「意図」としては単に当方の足を手段を選ばず(実際、2ちゃんねるに書き込むときにも集団的に、中国製の違法Wifi機器を悪用したりVPNで身元を隠蔽する工作を行っている)引っ張りたいだけであり、「ことさらおもしろおかしく」することで、当方を怒らせたいだけであり、なんの正当性も存在しません。以上は誰が見てもブラックである「違法」な集団です。技術的議論の「スペック」的にはその水準に達しておらない連中がほとんどすべてであり、「技術的正確性」の是非の議論から、この連中は厳密に排除しておくべきです。

論外+

次に、このような「技術的正確性」の是非の議論から厳密に排除しておくべき連中を咎めるどころか、その流れを歓迎し、「合流」して、技術的議論を展開するように見せかけて、当方への個人攻撃を悪用、援用することで、あたかも自分の断片的な技術の主張の短文書き捨てのほうが信頼できると見せかける、自分の主張が正しいと理屈もへったくれも存在しないゴリ押しをして平気な連中がいます。すでに何名かは、かなりはっきりと上述の誹謗中傷グループに合流していることでしょうし、2ちゃん的メンタリティに片足以上踏み込んでいる連中です。「毛の壁」なんちゃら、と、とにかく「毎度」書きたい連中がこれに該当します。

例の『数学ガール』の著者が一蓮托生となってなんか言っていた件については、

qtamaki キーボートを叩く狂犬。 #毛の壁注意

SICPと絡めて論じた記事については、

qtamaki 長いだけの怪文書です。費やした時間分あなたの人生を損ないます。#毛の壁注意

とかですね。私がこういう記事上げるや否や、ほぼ毎回Hatenaブックマークでこういうコメント投下する常習犯です。
この、アプリカティブ株式会社代表の人はいい加減にしておいたほうが良いと思う。こういうの法にも抵触すると思うので。程度問題でもありますが、あなたかなり執拗に延々とやってるんで、いい加減警告しておきます。
ネット上の露骨なヘイト行為に合流しているこの層の輩は根本的に「技術的正確性」の議論なんてのには関心なんてありません。雰囲気だけでわーっと便乗しながら、いかにゴリ押しを手段を選ばず完遂したいか?それだけが目的であり、それ以上の意図なんてありません。この連中は、2015年5月の段階で「もう岡部の技術的主張は間違いと証明された」と既成事実化を図っているのでわかりやすいです。それだけが目的であり、本当の技術的正確性なんて気にもしていません。例のクロージャの話でもなんでもそうです。とにかく歪曲して、私が間違っており、自分らのネガキャン目的の「訂正」のほうがまさに正しかったとか延々とゴネています。なんら整合性のないゴネぶりですが、とにかくそういう「印象操作」だけは余念がありません。ほんとは技術的に不正確でデタラメでもデマでも私の説明のほうががデマで、それを咎めている(つもりの勘違いした)Amazonレビューの「正しさ」が「証明」できればそれでいいみたいなんですね。

上記この層も、なんら具体的な技術の議論はしない(するように見せかけるが嘘を前提にしている)ので、「技術的正確性」の議論から厳密に排除しておくべきです。

中立あるいは味方と勘違いさせる形で、論外層と、対立論者と一緒になっている層

「技術的正確性」を論じる水準にないと本人が明言しているにも関わらず、なんとなく私の著書が「技術的正確性」に欠くという印象を後押しするだけで、「技術的正確性」については論じるつもりはなさそうな層。

『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間 』の著者として、『数学ガール』の著者である結城 浩氏に申し上げます。本書のたいせつな潜在的読者の読書機会を奪わないでください。

という極めて属人的なエントリ記事が、また当ブログの他の非属人的エントリを押しのけて注目されましたが、勝手に注目した連中が「炎上マーケティング」だのまた中傷しているのはともかくとして、氏もそうですし、それ以外にも、なんとなく日和見だけれども、正確性はない、間違っているに違いないと、印象論で判断している層は結構多いようです。

この層も、自身「技術的正確性」を論じるではなく、無条件に信じる信じないのレベルに留まっているので、議論の相手からは除外します。

対立論者

基本的に、文責を伴う、氏名や社会的属性がある程度確認できる個人。
ある程度まとまった情報を発信しているのであれば、匿名であっても構いません。

ただし社会通念上、可能な限り、それなりに文責を取る形で論じるのがまっとうな作法であるのは言うまでもありません。

どこで議論すべきなのか?

私はこのブログで一貫して情報を発信します。

反論があるのであれば、同じ土俵でフェアにやってください。

そもそも論ですが、TwitterやらHatenaブックマークのコメント、2ちゃんスレッドの書捨てで、なんかワーワー言われても、情報として統合なんてされないし、こちらは知ったことではないのですよね。

ランダムでネット上のアイデンティティでさえ定かでない、一時的な書捨ての情報、たとえばTwitterのタイムラインやHanteのコメントでは、まとまった情報をトレースするのは極めて困難であるので、そういう断片的な情報は除外します。

あと、Amazonレビューをもって、議論を仕掛けらたら全面的に反論しますが、後述するとおり、間違っているとこちらが説明しても、やったらやりっぱなしであることはすでに証明されていることでしょう。これまでの状況の’推移より、上記に説明した単にネガキャンの一環と見做すのが妥当でしょう。それが「テロ行為」であり暴力とみなす読者も多いことはすでに説明しました。

当たり前のことで、念の為ですが、2ちゃんねるスレッドは論外です。最初から「そういう場所で、そういうことしかできない連中」による「そういうレス」なので、情報としてカウントしません。
くだらない、価値がない、いかなる「内輪の合意」がそこでなされようとも、そういう歪な合意は世論としてカウントすべきではありません。
どーせ頭数に任して、最後にレスしたものの印象操作で勝ち!みたいなことで、まともな人間であればあるほど、そういう場所から遠ざかるでしょうから、そういう場所の力学を心底理解しながら、そういう場所の力学をもって「勝った」と思っている愚者の行動は、あくまで愚者による結論であるので、論理的にカウントしません。
また、そういう歪な合意や風潮に左右されかねない良識もある一般の方々におかれましては、謹んでご注意申し上げておきます。

ボトムラインとしては、まとまった情報で、こちらに「わかるように」おねがいします。できたら、メールでお知らせいただければありがたいです。読者の方々もそういうまとまった情報があったらお知らせ願えれば、こちらから議論の対象としてカウントもできるのでよろしくお願いします。

何を議論するのか?技術論である

何を議論するのか?
もちろん技術論です。

技術論とは無関係な個人攻撃は厳密に排除します。

これは「権威主義」にも関わることですが、論者が誰であるか?
そういうのが心配で心配でたまらない人はこういう技術論には向いていません。
昨今、大阪で、長期的な地方統治と、ごく短期間の利害のみで判断した特定の層の有権者の影響が大きい残念な民主的な決定がなされましたが、政治家個人への感情論も、完全ではないが一番マシな民主主義の結果ではあるのでしょう。

しかし、これは技術論です。「感情論」「属人議論」「多数決」で決まる、民主主義の議論ではありません。

また、2ちゃんねるのレスや、Hanteブックマークのコメントは、民主主義ですらありません。ただの暴力です。

本書への「批判の仕方」は検証され、議論の対象となる

後述する項目も含め、「論者のスタンス」あるいは「論者の先入観」というのは議論の対象となります。

技術論とは無関係な個人攻撃は厳密に排除します。

と矛盾すると勘違いした人へ。

「批判の仕方」「論者のスタンス」あるいは「論者の先入観」を検証するというのは、あくまで議論のフェアネスを担保するために必要な作業であり、議論のフェアネスを最初から損なうのが第一の目的である不当な個人攻撃ではありません。

ちゃんと読んでるの?それってただの中傷でしょ?というのを批判的にフィルターアウトするのに必要な作業です。

その時彼と喫茶店にいたのですが、その30分くらいで大体内容は把握しました。
「内容を把握した」だけで、理解、共感は到底出来ません。
パラパラっと全体の構成を見ても、ラノベ→JavaScriptコード→ラノベ→宗教哲学→React→ラノベと、読み手としては何の本を読んでいるのかわからなくなり、表紙を見ると関数型プログラミングと書いてあり、更に「??????」となります。

という物言いなどは、検証します。

また、XXでXXなので、故にこの著者=岡部は、関数型プログラミングを理解していない、という物言いについても検証します。
このパターンは技術的議論を装った書評、レビューの中で巧妙に展開されているケースが多いです。結局それがやりたかったのだな・・・と馬脚を表すパターンです。

本書のラノベ、「ものがたり」自体の運びについての論評は技術論でないので厳密に排除するが、本書、技術の説明の構成、「読みやすさ」については解説書としての性格上重要なので、議論の対象とする

上記と関連します。
根本的なことですが「30分くらいで大体内容は把握しました。」という読み方を想定して400ページの本を書いたわけもありません。

本書で出現する、用語や言葉遣いは議論の対象となる

特に「論理」「論理の物質化」という言葉遣いなど。

Day1に出てくる「問題の論理」「論理操作」「論理構造」といったキーターム(らしきもの)の内実はさっぱりわかりません。特にどれも「論理」という語を含んでいる辺りが問題で、いったいこの3つに何か共通する要素としての「論理」なる何事かがあるのでしょうか?
そのような「論理」なるものの説明が与えられないままに、「問題の論理」「論理操作」「論理構造」といった表現を並べられても、関数プログラミングを関数プログラミングよりも不明瞭な何事かで説明しようという無益な試みになるしかない、というのがDay1についての率直な感想です。
また著者の主張をそのまま信ずるならば、現実に行われている関数プログラミングの多くが「ダサい」ものだという事になりますが、翻って、著者が「クールなコード」と認めるようなものでどれほどの関数プログラミングができるかは極めて疑わしいということになるでしょう。

これは、上記の、【本書への「批判の仕方」は検証され、議論の対象となる】や、【本書、技術の説明の構成、「読みやすさ」】と関連します。基本事実に基づかない中傷行為です。

以上のような中傷は結構頻繁になされており、まとめて明示的にリンクしながら、論証します。

技術における属人的な趣向は議論の対象となります。

技術にも、特にプログラミングの世界では「より好み」というのが存在し、特にプログラミング言語やパラダイム選択には、ある種の宗教的選択に似たものがあります。

プログラミングとは知的コミットメントであり、その世界を掘り下げるにはそれなりのリソースが必要です。これまで投入したリソースや構築したスキル、そしてキャリアに関わる、極めて「個人的に親密」な行為でもあります。

技術論には、技術にまつわる背景思想、設計思想、技術的パラダイムの世界観、哲学を含む

論点

議論がとめどなく発散しないように、本書が論じている範囲に限定しながら、論点をいくつか上げます。随時追加します。

JavaScriptを関数型プログラミング言語として使う是非について

なぜ関数型プログラミング本でHaskell, Erlang, Clojureなどの関数型言語を採用しなかったのか。
本書を手にする人達は、少なからず関数型言語に興味があり、まさかJavaScriptで関数型プログラミングやろうとなんて考えていないかと思います。

というトンデモ見解については、ここまであからさまなもの、よりオブラートに包んでいるが根本的に同様の勘違いをしているもの、
例えば

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

とりあえず
「素人としては深入りを避けたい」
と言い訳しながら、
(著者の)「無理解を象徴的に示すもの」
と中傷するあたり、お里がしれます。

この類のそれこそ「関数型プログラミングへの無理解」による中傷が、非常に多いので反論というか、きちんと批判していきます。

関数型プログラミングとオブジェクト指向の関係性、マルチパラダイムなど

関数型プログラミングは、「理論」さえ語れば十分なのか?「世界観」「設計哲学」は不要なのか?

プログラミングと計算機理論、「実世界」と「時間」こそが本質的であることの哲学的考察

関数型プログラミングと、宣言型プログラミング、遅延評価、イベント駆動の関係 先行評価との対比

関数型プログラミングとGUIプログラミング、関数型リアクティブプログラミング(FRP)についての考察

クロージャとレキシカルスコープと関数型言語の関係性

以上の論点について、今後、本書への批判的記述についての反論記事を集中的にUPしていきます。

2015年5月22日金曜日

10年先を行く斬新な関数型(FRP)データベースについて説明する 99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その3】

前回、
99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その2】関数型プログラミングのイミュータブルな世界観とイミュータブルな実世界を完全に統合

の最後で、

で、実際この、

すべてのタイムスタンプにデータを保持するのではなくて、
「差分」が発生した瞬間のデータのみを保持する。

というアイデアは、結構使えるんですね。
というか、とっくに広く使われています。
GitHubです。

Gitのようなバージョン管理システムは、データの差分のみを記録していきます。

さて、これはどういう意味か?

  • 物質世界とは、「時間」変数をもって表現できるイミュータブルな関数の返り値である。

関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界を完全に統合

時間 tにおける世界を、時間関数 fをもって、

の返り値を実装する方針において、
データベースを、関数型プログラミングでイミュータブルに実装する手段をすでに我々は持っている、ということです。

あらゆる、膨大なデータベースを、差分バージョン管理システムを適用することによって、
任意の時間tにおけるデータベースを、イミュータブルに、参照透過に参照できる、ってことです。

そもそも、Gitのようなバージョン管理システムという仕組み自体が、
時間を実世界のデータのバージョンインデックスとして取り回すパラダイムなんですが、
もういろいろこのように、道具立ては揃っているわけです。

道具立てだけは揃っていて、そのパラダイム、世界観、設計思想、考え方に追随できていないのが世のプログラマです。

関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界を完全に統合
するにあたって、このパラダイムが、

実世界の時間変化を計算機内の時間変化と同一視した
モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.

@SICP
という、オブジェクト指向のパラダイムと対立するのは、当たり前のことであって、
「時間」と世界観と、当然の哲学の話を語れば、宗教の勧誘、人智を超えた形而上学的な幻想世界、オカルト扱いされる現状は、ダサい、劣ってるなあ、と思うわけです。

と総括したところ、拙書の読者の方々より、いろいろ質問のメールをいただきました。

今回、そのことについてさらに具体的事例をもって説明したいと思います。

普段からいろいろ新しい技術について勉強している人、探しまわっている人は少し前にこんな興味深い記事を目にしたことがあるかもしれません。

以下部分的に引用させていただきます。

Clojureの作者が作ったデータベースDatomicが凄い

プログラミング言語Clojureの作者Rich Hickey氏率いるClojure HackerのチームがDatomic(デートミックと発音するらしい)というデータベースをリリースしました。これが何やらとてつもないです。10年先を行ってる技術じゃないでしょうか。 まだ本番サービスは始まっていませんが開発環境用のライブラリが配布されています。 Datomicは斬新なアーキテクチャなので一言で説明するのはとても難しいです。 私が理解できたことを簡単に説明します。

変更不可なAppend-onlyデータベース

従来のデータベースで、あるレコードを変更するというのはそのレコードに対応した場所があり、そこのデータを書き換えるということを意味していました。
Datomicでは書き換え可能な場所はなく、過去の事実時刻と共に全て記録します。 例えば、大統領がブッシュからオバマに変わっても、過去にブッシュが大統領だったという事実は消えません。 ある時刻で大統領がブッシュだったという事実とは別に、単にある時刻で大統領がオバマになったという事実が記録されるのです。 現時点で誰が大統領なのかは時刻が新しい方を見れば分かります。
全ての新たな事実の追加(ライト)は後述するTransactorによって完全に順序付けされています。 つまり、任意の時点のデータベースとは、その時点までの事実の単なる集合に過ぎないのです。 過去の任意の時点が完全な状態で記録されているため、任意の時点に対してクエリーを投げることができます。
ここまで聞くと同じように append-only なデータベースReThinkDBなどを思い浮かべるかもしれません。 Datomicは変更不可性の強みを更にレバレッジするユニークな特徴を持っています。

事実の Atomic な最小単位 Datom

Datomic は事実を RDB のレコードや Mongodb のドキュメントのような形で保持していません。 代わりにDatomという事実のAtomicな最小単位に分解して保持しています。
Datomはエンティティ、属性、値、時刻から構成されています。
こうすることによりどんなDatomのセットも決まったデータ構造に埋め込むことなくクエリーから発見できていいそうです。
よく理解できてませんが、RDBやMongodbだとレコード(ドキュメント)の中身はどんなクエリーでも毎回同じ組み合わせだけど、それがクエリー次第で色んな組み合わせになるってことかな。

感想

Hacker Newsでもかなりの人が一体なんなんだこれはと戸惑ってる感じでした。 The Joy of Clojure の著者 fogus さんは「Datomicはエイリアンの高度なテクノロジーで満たされたUFOだ」と言っていましたが、全く同じように感じました。 Richが作らなければ、何年待ってもこんなのできなかったんじゃないかと思います。
私は気に入ったなんてレベルじゃないので、これからどんどん使っていきたいです。

これが、前回、私が説明した可能性に溢れた、そうあるべき未来的DBの実装の一例です。
もちろん、それを読んでその世界観を理解していただいた賢明な読者は、

変更不可なAppend-onlyデータベース
Datomicでは書き換え可能な場所はなく、過去の事実時刻と共に全て記録します。

という記述で、「ああイミュータブルな関数型プログラミングの世界観だ」「FRPだ!」とすべてを理解されることでしょう。

Datomic
The fully transactional, cloud-ready, distributed database.
http://www.datomic.com/

Why Datomic?  なぜDatmoicなのか?

Immutable data means strong consistency combined with horizontal read scalability, plus built-in caching.
イミュータブルなデータは、強い整合性・・・ (あと略、書いている通り)

大事なのは、このDatomの細かい仕様ではありません。
それがWhat「何」であるかよりも、
大事なのは、このClojureの作者Rich Hickey氏率いるClojure Hackerのチームが、いったいどういう設計思想、思想的背景、世界観をもってこういうDBを開発実装したのか?というその根っこの部分です。
そこさえしっかり踏まえておればあとは枝葉にすぎないし、場合によってはこういう実装のほうがより良いのではないか?と自分でより良いイノベーションを思いつくことも可能です。

開発者自身によるYoutube動画
What is Datomic?

には、

A sound model of information of time

と、SICPでも拙書でも嫌というほど強調している(同時に、巷の関数型プログラミング解説ではまったくと言って触れられることがない)、計算機科学においては、「時間が本質的」である知見が具現化されています。

背景にある世界観をまるで理解しないまま、10年進んでいる!という評価で追いつこうとしてドキュメントをさらっても、なんだかわかったようなわからなかったようなモヤモヤ感とともに、わかったつもりになる、という事になります。

ここまで聞くと同じように append-only なデータベースReThinkDBなどを思い浮かべるかもしれません。

というのも、もちろん同じ関数型、FRPのリーグに属する次世代DBです。

そして、よくよく理解していないと、これがイミュータブルな関数型、FRPのパラダイムに属する斬新なアーキテクチャーによって構成される次世代DBであることは、気づきにくいですね。

関数型プログラミングは、オブジェクト指向技術と「直行」するとか、パラダイムも世界観も何も考えることもない、関数型プログラミングとは何?ということばかり語っても、教えられてもどうしようもないです。

もちろんOCamlの「多相ヴァリアント」なんて瑣末な知識が役立つわけもないでしょう。そんな知識があったところで、世界観の転換、パラダイムシフトには「歯が立たない」わけです。

実際、上記のDBには、明示的に関数型パラダイムである、ミュータブルな物質世界観ではない、時間軸をイミュータブルな集合として扱う世界観である、というのは、あんまり丁寧に説明もされていません。

じゃあ、どこで説明されているのか?

ひとつは、このシリーズの#1で上げたSICPです。しかし、実際SICPは一般に読み解くのは難解ですから、手軽なのは、このブログ記事の概略であり、さらに、基本まったく同じことを掘り下げて書いた、私の本です

関数型プログラミングの「パラダイム」「世界観」「時間が本質」であることを、一貫して解説しました。そのことを理解できたオープンマインドで柔軟な知性を有する次世代プログラマ、はむしろ少数派であったようですが。

この「世界観」の部分に自身の考え方が追随できて、さらなるイノベーションを起こせるか起せないか?が今後のプログラマに求められるシビアなスキルなのだと私は考えています。

「今後」のプログラマです。現世代の我が国のプログラマはいろいろいろ問題が多い、残念な現状であるのは、このブログ記事で論じている通りです。ぜひ反面教師にして乗り越えていってください。

私は次世代プログラマの方々に期待してこのブログ記事を書いています。応援しています。

2015年5月17日日曜日

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その2】関数型プログラミングのイミュータブルな世界観とイミュータブルな実世界を完全に統合

関数型プログラミングで、キーワードとなるのは、

  • イミュータブル(変更不能)
  • 状態変数

です。

これらは字面でも明らかですが、
「変わる」というのが概念の根本にあります。

プログラミングを実用化するにあたって、
たとえば、SICPの例では、銀行口座のアカウント、
それからこういうブログ・コンテンツマネージメント・システム(CMS)、
TwitterやFacebookなどのSNS、それからゲームなどいろいろありますが、
時間遷移するアプリケーションを設計する際には、
まさに「変わる」のは、実世界の「時間」に呼応して「変わる」ということです。

計算機科学において、以上のような実世界の事象を計算機の中でモデル化するわけですが、
実世界と、一言でさらっと言うが、実世界とは一体何か?
あんまり深く考える人はいない、
少なくともプログラミングではそんなことまで考える必要はない、と考える人がほとんどです。

実世界とは何か?この根本には我々が普通にあると「錯覚」している「時間」がその根本にあります。
実世界を語るとき、観察者の意識と「時間」というのは避けて通れません。
観察者の意識、というのは、コンピューティングにおいては、ユーザの意識です。
SICPでも、プログラミングとは、根源的には認識論の問題となると語られているとおり、
きちんと我々は一体何をやっているのか?丁寧に、一切の誤魔化しなく考えを詰めていくと、
計算機科学は必ずここに到達せざるをえません。
計算機科学とは、数学のみで完結しているわけはなく、
コンピュータというハードウェアで、実世界というものをモデル化するのであるから、
これは当然のことです。

「時間」こそがプログラミングにおいて根源的な概念です。

実世界をモデル化する際、
「時間」の概念を軽視することによって、明らかになるいくつかの強固な思い込みがあります。
明らかになる、というよりかは、ほとんどの場合まったく考慮されていないので、
その思い込みについては無自覚です。

思い込みは、掘り下げるといくらでも出てくるのですが、
如何せん哲学の話なので、本稿では理解のハードルが低い「現実的」なものに絞って論じます。

  • 物質世界とは、「時間」変化するミュータブルな存在である。

基本的にはこの素朴な世界観があります。
基本的にはこの素朴な世界観が、プログラミングするときに無自覚に援用されます。
ほとんどの場合、この素朴な世界観に疑義を挟むことなくプログラミングは設計されていきます。

関数型プログラミングは、イミュータブルな世界観なので、
この「思い込み」によって徹底的な齟齬が生じます。
そしてこれは「思い込み」であり、間違いです。

この「思い込み」は、当然我々が生まれ育った環境からの経験で醸成される、
素朴な世界観なのですが、物理学で数学をもって、世界を俯瞰すると、
ごくごく単純に、我々の世界はニュートン物理学の宇宙観で近似できて、

時間 tにおける世界は、時間関数 fをもって、

と単純に描写できます。

  • 物質世界とは、「時間」変数をもって表現できるイミュータブルな関数の返り値である。

と、こうなります。
思い込みによる素朴な世界観ではなく、より理知的なこちらの世界観を採用することによって、
関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界は完全に統合され、
関数型プログラミングの真のポテンシャルを実用的なアプリケーション開発に利用することが可能になります。

以上が、大前提となる基本方針なのですが、
以上をほんとうに実装するには、多少の知恵が必要です。

イミュータブルな物質的な実世界とは、
スピノザの汎神論で語られるとおり論理の一つのモードにすぎないわけですが、
根本的な原理としてそれは「無限」です。

ところが、ここでその「無限」の実世界の中のごくごく一部の矮小な存在でしかない、
「有限」なリソースしか有しないコンピュータ(計算機)で、モデル化するのだから、
結構、いろいろ無理です。

結構、いろいろ無理だから、この、
関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界は完全に統合
というアイデアは水泡に帰す、というのが繰り返されます。

だいたい考えてみればわかりますが、
有限に無限を押し込めることは土台不可能です。

無限はトリッキーで、アンタッチャブルです。触ってはいけないし、触ることはできない。
もちろんこれは、無限まるごと、という意味で、
無限の一部ならば、原理的に有限になり、有限ならば触れるようになる。
円周率の桁は無限に続くが、我々が計算するときは、
円周率の近似値をもって、計算します。
自然数も無限数列だが、自然数のひとつひとつは普通に触れる。

「論理」と「計算」は別である、ということです。
無限という「論理」はけっして「計算」しきれない。
しかし、
「必要な時に必要な分だけ計算する」のは可能です。
これは、プログラミングでは、イベント駆動であり、遅延評価です。
この双方は根本的には、同一の概念です。

これは、つまり前回でもSICPから引用した、

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.1
http://sicp.iijlab.net/fulltext/x351.html

3.5.1 Streams Are Delayed Lists
3.5.1 ストリームは遅延リスト

In general, we can think of delayed evaluation as demand-driven” programming, whereby each stage in the stream process is activated only enough to satisfy the next stage. What we have done is to decouple the actual order of events in the computation from the apparent structure of our procedures. We write procedures as if the streams existedall at once” when, in reality, the computation is performed incrementally, as in traditional programming styles.
一般に遅延評価は 「要求駆動」プログラミングと考えることが出来る. ストリーム処理の各段階は次の段階を満足させるのに十分なだけ起動される. これまでやったのは計算における事象の実際の順を, 手続きの見かけの構造と 切り離すことである. われわれは伝統的なプログラミングスタイルでのように, ストリームがあたかも「みんな一緒に」存在したかのように手続きを書くが, 実際は計算が漸進的に実行される.

ということになります。

遅延評価とイベント駆動は、
「必要な時に必要な分だけ計算する方法」
と、拙書であえて表現しているとおり、根源的に同一概念であり、
「無限」の実世界の中のごくごく一部の矮小な存在でしかない、
「有限」なリソースしか有しないコンピュータ(計算機)で、モデル化するための唯一の賢い方法です。
その果実として、
関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界を完全に統合
することが、はじめて可能になるわけですね。

また、パラダイムとして、関数型プログラミングは宣言型ですが、
宣言型ということは、ソースコードの「論理」の記述は、
即座に「計算」されない、ということです。
「論理」が「計算機」によって読み込まれた「時間」に
「計算」されるのが、命令型プログラミングです。念の為。
拙書では、この評価戦略を「手当たりしだいの計算方法」とか書きました。

宣言型のコードは、「論理」が読み込まれた「時間」に「計算」されないので、
これは、遅延評価であり、同じ概念として、イベント駆動である、ということです。

だから、評価戦略でいろいろ、理解不能なより好みを強弁する連中もいますが、
関数型プログラミングと遅延評価は絶対に切り離せません。
ここは基本中の基本です。よろしいですね?

「必要な時に必要な分だけ計算する方法」
このスマートな絶対方針は、
関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界を完全に統合
するとき、あらゆる局面で、超強力な唯一の解決策になります。

時間 tにおける世界を、時間関数 fをもって、

と単純に描写するとき、
まず普通は、

たしかにイミュータブルだよね、しかしまあ、
こんなとんでもない時間関数を有限なリソースしかないコンピュータで実装するのは不可能である

そう思うわけです。
これは要するに、前述のとおり、「無限」と「有限」のことをよくよく検討しないで、
不用意に考察するから、そういうことになるわけで、
いかに必要ないと思い込んでいる哲学的考察でも、ちゃんと掘り下げておいたほうが良い、という教訓です。

もちろん実際は、「必要な時に必要な分だけ計算する方法」で解決可能な問題にすぎません。

  • 物質世界とは、「時間」変数をもって表現できるイミュータブルな関数の返り値である。

を実装するということは、すなわち、
時間 tにおける世界を、過去、現在、未来のすべての時間にわたって、もれなくすべてのデータを保持するということです。

たとえば、前回、こんなものは関数型プログラミングのコードではない、「ダサい」と批判した題材の、
「お絵かきロジック」ですが、

  • 物質世界とは、「時間」変数をもって表現できるイミュータブルな関数の返り値である。

この世界観を、そのまま関数型プログラミングの世界観でコーディングする、ということは、
時刻 t における、マウスポインタの座標を返す時間関数を実装する、という事になります。

アプリケーションが起動させてから終了させるまでの「すべてのあらゆる時刻」
t における、マウスポインタの座標
をもれなく保持する、ということになります。

時刻 t における、マウスポインタの座標

これは物質世界を俯瞰した理性的な世界観のイミュータブルなデータです。

そして復習ですが、非理性的な素朴な世界観では、「ダサい」コードでは、前回書いた通り、

Let’s step back and review where this complexity comes from. In an attempt to model real-world phenomena, we made some apparently reasonable decisions: We modeled real-world objects with local state by computational objects with local variables. We identified time variation in the real world with time variation in the computer. We implemented the time variation of the states of the model objects in the computer with assignments to the local variables of the model objects.
少し後戻りして, この複雑さがどこから来たか反省しよう. 実世界の現象をモデル化しようとして, 明らかに合理的な決定をいくつかした: 局所状態を持つ実世界のオブジェクトを, 局所変数を持つ計算オブジェクトでモデル化した. 実世界の時間変化を計算機内の時間変化と同一視した. モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.

..

実世界の時間変化を計算機内の時間変化と同一視した

モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.

秀逸な知見です。
状態変数への破壊的代入を繰り返すことで、そのモデルの時間変化に対応させている。
破壊的代入、っていうのはモデルの時間変化のためにやっていた、
こういう「自覚」をもってるプログラマって今、日本に何人くらいいるんでしょうか?

という感じになっていました。

時刻 t における、マウスポインタの座標、というのは実際に、

pointer[t]みたいに逐一残らず記録していっても構いません。

今どき大したデータ量にもならないでしょうから。

でもこのお絵かきケースもそうですが、多くのケースで、ほんとうに必要なのは、
直近の時刻tにおける、マウスポインタの座標、だけですよね?

直近以前の時刻のデータについては必要ない。保持する必要はありません。
だから、過去のデータについてはどんどん破棄していけば良い。

時間 tにおける世界を、時間関数 fをもって、

の返り値を実装する、
時刻 t における、マウスポインタの座標を返す時間関数を実装する、
にしても、関数の設計としては、関数内部で状態変数を保持して、破壊的代入して、
常に最新のマウス座標を返せば、それで事足りる、ということです。

実際こうやって設計されているのが、Facebook-Reactです。
Reactは真に宣言的なコンポーネント指向の関数ライブラリであり、
すべてのコンポーネントはイミュータブルであるわけですが、
Reactのコンポーネントにはstateという、わかりにくい「状態変数」ぽい概念があります。

ぶっちゃけこれは、直近の時刻t限定の時間関数です。

また、このブログのReact 解説【動的HTML-FRP編】
で、利用している、私が作った、worldcomponent The tiny FRP
も、以上の設計思想で構築されています。
これは、Reactコンポーネントのstateのように、埋め込みFRPでない、
単体のFRP機構なので、いくらでもポテンシャルが見込めます。

ただ、それはそれ、として、

時間 tにおける世界を、時間関数 fをもって、

の返り値を実装する、

というのは、興味深いアイデアであり、
実際に、任意の時刻tで、その瞬間の値を返す時間関数を実装するのは可能なのか?
概念実証もしました。

いろいろ検討しなければならない要素はあって、
まず、任意の時刻tというものの「解像度」ですね。
時間っていうのは物理学でも、プランク時間の解像度しかなくて、デジタルで離散的だということですが、
コンピュータでは、マイクロセカンドの「解像度」が妥当でしょう。

じゃあ、マイクロセカンドの解像度で、たとえばマウスポインタの座標を全部保持するのか?
もちろんそういう設計も可能でしょうが、「必要な時に必要な分だけ計算する方法」でやればよい。

マウスポインタが移動したイベントの、そのタイムスタンプで、配列にデータを格納する。
マイクロセカンドの解像度で、すべてのタイムスタンプにデータを保持するのではなくて、
「差分」が発生した瞬間のデータのみを保持する。

だって、マウスポインタが移動していない、差分が発生していないのに、
マイクロセカンドの解像度で、すべてのタイムスタンプで座標データ保持とかやるのは明らかにスマートな方法ではない、「必要な時に必要な分だけ計算する方法」でやればよい。

逆に任意の時刻tで、時間関数にアクセスしたときは、
その、任意の時刻tから、「過去」の方向、タイムスタンプの値が小さい方向に、だーっとスキャンしていって、保持されているデータにヒットすれば、それが、任意の時刻tに紐付けられるデータです。
なぜならば、差分がそのタイムスパンは発生していないのだから。

これが拙書で、
timecomponent タイムコンポーネントで時間軸上の全部のバージョンを扱う
と紹介している、

https://www.npmjs.com/package/timecomponent

であり、

timecomponent タイムコンポーネントで過去にアクセスし、1秒前の過去をリアルタイム再生する

と、実際に概念実証のDEMOを示しています。

http://sakurafunctional.github.io/demo/frp-redball-delay/index.html

上記URLクリックして開いて、マウスポインタ動かすと、1秒前の過去に「リアルタイムアクセス」することができます。

で、実際この、

すべてのタイムスタンプにデータを保持するのではなくて、
「差分」が発生した瞬間のデータのみを保持する。

というアイデアは、結構使えるんですね。
というか、とっくに広く使われています。
GitHubです。

Gitのようなバージョン管理システムは、データの差分のみを記録していきます。

さて、これはどういう意味か?

  • 物質世界とは、「時間」変数をもって表現できるイミュータブルな関数の返り値である。

関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界を完全に統合

時間 tにおける世界を、時間関数 fをもって、

の返り値を実装する方針において、
データベースを、関数型プログラミングでイミュータブルに実装する手段をすでに我々は持っている、ということです。

あらゆる、膨大なデータベースを、差分バージョン管理システムを適用することによって、
任意の時間tにおけるデータベースを、イミュータブルに、参照透過に参照できる、ってことです。

そもそも、Gitのようなバージョン管理システムという仕組み自体が、
時間を実世界のデータのバージョンインデックスとして取り回すパラダイムなんですが、
もういろいろこのように、道具立ては揃っているわけです。

道具立てだけは揃っていて、そのパラダイム、世界観、設計思想、考え方に追随できていないのが世のプログラマです。

関数型プログラミングのイミュータブルな世界観と、イミュータブルな実世界を完全に統合
するにあたって、このパラダイムが、

実世界の時間変化を計算機内の時間変化と同一視した
モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.

@SICP
という、オブジェクト指向のパラダイムと対立するのは、当たり前のことであって、
「時間」と世界観と、当然の哲学の話を語れば、宗教の勧誘、人智を超えた形而上学的な幻想世界、オカルト扱いされる現状は、ダサい、劣ってるなあ、と思うわけです。

2015年5月16日土曜日

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう

関数型プログラミングそのものが「何」であるか?そんなことはとりあえず<まったく>重要ではない。

関数型プログラミングが「銀の弾」であるのは「何故」なのか?関数型プログラミングは、あなたのコーディングで「何を可能」とするのか?その根本的な「理由」を知ることがもっとも重要である。

関数型プログラミングを「銀の弾」にするために要求されるスキルとは実は「考え方」であり哲学であり、世界の「捉え方」であり世界観である。関数型プログラミングそのものが構成される理論、関数型プログラミング言語の仕様書をいくら眺めていても、何故それが「銀の弾」になり得るのか?何を可能とするのか知るには、まるで役に立たないだろう。

「考え方」哲学、世界の「捉え方」世界観とは?物質世界の「時間」は計算機科学の根源に関わる。ここを理解せよ。この水準に達していないすべての解説、書籍は、最終的に役には立たない。

ここに一冊の本があります。拙書ではありません。

浅井 健一 (著)『プログラミングの基礎 (Computer Science Library) [単行本]』です。

『数学ガール』の著者の結城浩 ‏@hyuki氏と対話する
東北大学の住井 英二郎‏@esumii 氏によれば、

私がよく知っている中で最も良い

関数型プログラミングの本である、らしいです。

以下は、もちろん私の名前と著書と対比的に「オススメ」されたということですから、
私は本当に今回、著書を出版した意味があったと思います。
このように、我が国でそれなりに名も通るだろう知性に、
たとえ拙書への「disり」文脈のあてつけであったとしても、
それを起点として、本稿のように我が国の憂うべき現状を論じることができるのですから。
どうもありがとうございます。

https://twitter.com/esumii/status/593754761507123200

結城浩 ‏@hyuki 4月30日
ほんとうに詳しい方が、正確でわかりやすい関数型プログラミング(言語)の本を書くのが、最も大きな反論です。また、業界全体にとっても入門者にとっても意味のあることだと思います。私は「あなた」にお願いしているのです。よろしくお願いいたします。

Eijiro Sumii ‏@esumii 4月30日
@hyuki (私も含め皆さんが何度も言っていてすみませんが)http://www.amazon.co.jp/dp/4781911609 じゃだめですか?

enter image description here

Eijiro Sumii ‏@esumii 4月30日
@hyuki http://pllab.is.ocha.ac.jp/~asai/book-mov/ に解説ビデオやスライド等もあります(お茶大学部2年生の授業用ですが他の人が見ても有用だと思います)

結城浩 ‏@hyuki 4月30日
@esumii いや、私にそう言われましても…この本は、岡部さんをdisる人たちが、IQなんとかの本の代わりに推薦なさる本なのかしら。それならばそれで、まったく(私は)異論ありません。私は単に「本のdisり」より「本のオススメ」のツイートやブログ記事を見たいだけなんです…

結城浩 ‏@hyuki 4月30日
@esumii 素晴らしい。

Eijiro Sumii ‏@esumii 4月30日
@hyuki disるのが目的の人たちはわかりませんが、最近も(少なくとも私の観測範囲では)しばしばお勧めされていると思います。どうも失礼しました

結城浩 ‏@hyuki 4月30日
@esumii こちらこそ、オススメありがとうございます。いま買いました。2-3週間後に届くらしいですが…

Eijiro Sumii ‏@esumii 4月30日
@esumii (他の本をおすすめしないわけではなく、私がよく知っている中で最も良いと思う次第。他にも良い本はあると思います。これも何度もすみませんが http://d.hatena.ne.jp/akuraru/20150410/p1 … などをば)

らしいですから、その、オススメ本の概要を読者の皆さんと共有するために、
出版元のサイエンス社のサイトより、目次を確認してみます。

http://www.saiensu.co.jp/?page=book_details&ISBN=ISBN978-4-7819-1160-1

<内容詳細>
デザインレシピを用いてプログラミングに必要な思考法を学び,メトロネットワーク最短路問題を解きながらデータ構造とアルゴリズムを身につける,関数型言語OCamlによる入門者のための教科・参考書.
<目次>
第1章 はじめに
  1.1 デザインレシピ
  1.2 使用する言語
  1.3 準備
  1.4 参考となる資料

第2章 基本的なデータ
  2.1 整数
  2.2 実数
  2.3 文字列
  2.4 真偽値
  2.5 そのほかのデータ

第3章 変数の定義
  3.1 変数の必要性
  3.2 変数定義の構文
  3.3 変数の実行方法
  3.4 ほかの言語の変数との違い

第4章 関数の定義
  4.1 関数定義の必要性
  4.2 関数定義の構文
  4.3 関数の型
  4.4 型推論と型チェック
  4.5 関数の実行方法
  4.6 関数定義に対するデザインレシピ

第5章 条件分岐
  5.1 条件分岐の必要性
  5.2 条件分岐の構文
  5.3 kyuyoの例
  5.4 式としてのif文
  5.5 条件分岐に対するデザインレシピ
  5.6 真偽値を返す関数
  5.7 条件分岐の実行方法

第6章 さまざまなエラー
  6.1 構文エラー
  6.2 未定義の変数
  6.3 型エラー
  6.4 実行時のエラー
  6.5 論理的なエラー

第7章 組とパターンマッチ
  7.1 組の構文
  7.2 パターンマッチ
  7.3 構造データに対するデザインレシピ
  7.4 パターンマッチの実行方法

第8章 レコード
  8.1 レコードの必要性
  8.2 レコードの構文
  8.3 レコードとパターンマッチ
  8.4 そのほかの記法
  8.5 ユーザによる型定義
  8.6 データ定義に対するデザインレシピ
  8.7 駅名と駅間の情報の定義

第9章 リスト
  9.1 リストの構造
  9.2 リストの構文と型
  9.3 リストとパターンマッチ
  9.4 再帰関数
  9.5 再帰関数に対するデザインレシピ
  9.6 テンプレートの複合
  9.7 駅名リストと駅間リストの整備

第10章 再帰関数を使ったプログラミング
  10.1 関数のネスト
  10.2 リストの中の最小値を求める関数
  10.3 局所変数定義
  10.4 パターンマッチつき局所変数定義
  10.5 ふたつのリストを結合する関数
  10.6 ふたつの昇順に並んだリストをマージする関数
  10.7 駅名・駅間リストからの情報の取得

第11章 自然数と再帰
  11.1 自然数の構造
  11.2 自然数に基づいた再帰関数
  11.3 ベキ乗を求める関数
  11.4 リスト上の再帰との違い

第12章 ダイクストラのアルゴリズム
  12.1 グラフ上の最短路問題
  12.2 ダイクストラのアルゴリズム
  12.3 アルゴリズムの正当性
  12.4 プログラムにおける頂点と辺の定義
  12.5 駅名の重複の除去

第13章 一般化と高階関数
  13.1 データの一般化
  13.2 関数の一般化とmap
  13.3 多相型と多相関数
  13.4 値としての関数
  13.5 関数を返す関数
  13.6 確定点に隣接する点の最短距離の更新

第14章 高階関数を使ったリスト処理
  14.1 条件を満たす要素を取り出す関数
  14.2 各要素をまとめあげる関数
  14.3 局所関数定義
  14.4 名前のない関数
  14.5 infix関数とprefix関数
  14.6 完全数を求める関数

第15章 新しい形の再帰
  15.1 再帰関数の構造
  15.2 部分問題の生成
  15.3 補助関数の作成
  15.4 停止性の判定
  15.5 一般の再帰に対するデザインレシピ
  15.6 最短距離最小の点の分離
  15.7 例の作成とデバッグについて

第16章 情報の蓄積
  16.1 情報の欠落
  16.2 アキュムレータ
  16.3 アキュムレータの活用
  16.4 最初の完動プログラム
  16.5 プログラム作成のプロセス

第17章 再帰的なデータ構造
  17.1 バリアント型
  17.2 木
  17.3 再帰的なデータ構造に対するデザインレシピ
  17.4 2分探索木
  17.5 多相型の宣言
  17.6 停止性
  17.7 get_ekikan_kyoriの高速化
  17.8 全通りを尽くしていない場合の対処

第18章 例外と例外処理
  18.1 オプション型
  18.2 オプション型を使った例外処理
  18.3 オプション型を使った例外処理の問題点
  18.4 例外処理専用の構文
  18.5 例外処理の実際
  18.6 例外処理を使ったプログラミング
  18.7 最短路問題における例外処理

第19章 モジュール
  19.1 モジュールの構文
  19.2 2分探索木のモジュール
  19.3 モジュールインタフェース:シグネチャ
  19.4 抽象データ型
  19.5 そのほかのシグネチャの宣言法
  19.6 ファイルの分割と分割コンパイル
  19.7 2分探索木モジュールの使用

第20章 モジュールの開発
  20.1 赤黒木
  20.2 赤黒木への挿入
  20.3 赤黒木の再構成
  20.4 「または」のパターン
  20.5 赤黒木のモジュール化
  20.6 open文

第21章 逐次実行
  21.1 副作用を持つ関数
  21.2 unit型
  21.3 逐次実行の構文
  21.4 実行中の変数の表示
  21.5 実行の順序
  21.6 スタンドアローンのプログラム
  21.7 引数の渡し方

第22章 値の書き換えと参照透過性
  22.1 参照透過性
  22.2 呼び出し回数のカウント
  22.3 参照型と値の書き換え
  22.4 参照透過性の喪失
  22.5 変更可能なレコード
  22.6 配列
  22.7 配列の変更

第23章 副作用命令を使ったプログラミング
  23.1 ダイクストラ法におけるデータアクセス
  23.2 ヒープ
  23.3 ヒープへの挿入
  23.4 そのほかの操作
  23.5 ヒープのインタフェース
  23.6 副作用命令の影響について
  23.7 ヒープ実装の概要

第24章 まとめ―プログラミングとは―
  24.1 OCamlを習得して
  24.2 この先の道

索引

この種の解説本の一番大きな問題点とは、
「プログラミングの概念」と「特定のプログラミング言語の仕様」がごっちゃ混ぜになっていることです。
つまり、例えば私などはOCamlという言語について、まったく心を揺り動かされない、というか、
好きではない言語ですから、

第3章 変数の定義
3.4 ほかの言語の変数との違い

であるとか、

第6章 さまざまなエラー

であるとか、言語特有の「仕様」について章をわけて解説されても、
そんなことには全く意味を見いだせない、ということがあります。

第2章 基本的なデータ

についてもそうです。
この本はOCamlですが、Haskellをもって「関数型プログラミング」を解説している本などは、
「型」についての章があり、いかに「型」が重要なのか?ということが延々と論じられていたりします。
データの型というのは、根本的に「関数型プログラミング」のパラダイムとは何の関係もありません。

もちろん、この「オススメ」書籍のタイトルとは、
『プログラミングの基礎』であって、
『関数型プログラミングの基礎』ではありません。そうエクスキューズしたい人もいることでしょう。
でも現に、こうやって関数型プログラミングの文脈でオススメする人が多かったり、
実際、

関数型言語OCamlによる入門者のための教科・参考書

と出版元のサイエンス社より紹介もされていたり、

Eijiro Sumii ‏@esumii 4月30日
@hyuki http://pllab.is.ocha.ac.jp/~asai/book-mov/ に解説ビデオやスライド等もあります(お茶大学部2年生の授業用ですが他の人が見ても有用だと思います)

と引用される著者サイトによると、

「プログラミングの基礎」を使った授業紹介
浅井 健一
このページでは、お茶の水女子大学、理学部、情報科学科の2年生を 対象とした授業「関数型言語」のビデオほかを公開しています。 この授業は反転授業 (flipped class) を行っており、 受講生は授業前に以下の予習を求められます。

「関数型言語」の授業として、まさに本書の内容が踏襲されてレクチャーされているようです。

だから、この本は『プログラミングの基礎』であって『関数型プログラミングの基礎』ではない、というのはまず通らないエクスキューズでしょう。

「関数型プログラミング」を知りたい読者が喜び勇んでこの本に取り組むと、その期待が裏切られるのは目に見えています。
また、私は他人の授業に口を出す権利もありませんが、この著者のレクチャーを受けて、関数型プログラミングを習得できるとは思いません。

何が起こっているのか?
「関数型プログラミング」そのものの根本的な概念、「考え方」がまったく整理されて提示されていないのです。

データ型などの、特定のプログラミング言語の「仕様」を述べるのならば、それはきちんと、「関数型プログラミング」の概念と明示的にわけて説明すべきです。

さらに、この本では、評価戦略についてはまったく触れられていません。
実はこの辺は、関数型プログラミングのパラダイムにとって、「考え方」にとって非常に重要な要素です。

遅延評価(リスト)(SICPでは「ストリーム」拙書では「まとまり」として集合的に取り扱う)
は、関数型プログラミングのパラダイムの根幹であり、
(識者であると一般に見做されている人でもこの辺を理解できていない人は多いが)
遅延評価(リスト)なくしては、数学の無限の概念は扱えないし、
遅延評価(リスト)をそのまま時間軸に展開することによって、
はじめて、時間変化する状態変数をイミュータブルに関数型プログラミングのパラダイムで扱えるようになり、実用的なアプリケーションを構築することが可能となります。
コードの全体としても、遅延評価でなければ、真に宣言的に書くことはできません。

逆に言うと、浅井 健一 (著)『プログラミングの基礎 (Computer Science Library) [単行本]』は、
時間変化する状態変数をイミュータブルに関数型プログラミングのパラダイムで扱えるようになることなど、まったく解説されていないわけで、読んだところで、実用的なアプリケーションを構築できるようにはなりません。

我々が暮らす物質世界に紐づく「時間」とは、
まさにプログラミングと密接に関わる概念であり、
特に関数型プログラミングの世界観の根幹でもあります。
ここを綺麗にすっとばすと、まさに我々が暮らす物質世界に紐づく「時間」に関わるプログラミング、
つまり、GUI、入出力を伴う、時間変化する状態を扱うアプリケーションを書くことは不可能のままです。

ここにもう一冊の本があります。拙書ではありません。

このことが更に明白になる事例が以下です。

住井 英二郎‏@esumii 氏の最後のツイートには、
http://d.hatena.ne.jp/akuraru/20150410/p1
があり、そのリストでは、
関数型プログラミング入門本のオススメ書籍ツートップとして、
五十嵐 淳 (著)『プログラミング in OCaml ~関数型プログラミングの基礎からGUI構築まで~

enter image description here

関数型プログラミングの基礎からGUI構築まで、ということなので、
今度こそ、読んだならば、関数型言語で、関数型のパラダイムで、
きちんと実用アプリが書けるようになる!と一瞬期待が持てます。
というより、ほとんどの読者はまさにそこを期待しているわけです。

別に学者、研究者の趣向で、解説が理論にたいして網羅的である、
とかそういうのを重視するのは勝手なのですが、
最終的にはきちんと、実用に耐えうるアプリケーションがその延長で書けないと、
それはまさに文字通り「机上の空論」に終わるわけです。

関数型プログラミングがこれまでけっしてメインストリームにならなかったのは、
関数型プログラミングが非常に残念ながらずっと「机上の空論」で在り続けたからです。

でも、昨今の事情を見ると、どうも違うようだ、という潮流になってきた。
業務に役に立つのか?趣味のアプリケーション構築に使えるのか?
プロ・アマ問わずそういう情報こそが求められている。

これまでと異なる考え方が必要であるならば、それを教えて欲しい、
言語の仕様やらアルゴリズムのことはもう結構。必要ならば自分でいくらでもできる、
でも考え方とやらをきちんと語っている解説などどこにもないじゃないか?
私は少なくとも、関数型プログラミングを独学しはじめたとき、この辺非常に不満だったわけですね。
最終的に自分で本を書くことになってしまいましたが。

それで、ここでもっとも特筆すべきこととは、
関数型プログラミングの「考え方」「哲学」「パラダイム」「世界観」をしっかりと理解しているのであれば、実用的な、GUIを伴うアプリケーションって、きちんと関数型プログラミングのパラダイムで書けるのです。それは非常に洗練されて見通しの良い、バグが介入しないメンテナンス性の極めて高い、美しいコードになります。関数型プログラミングの宣言型のコードです。

拙書では、かなり綿密に設計して、一貫してそこまで軸を通して解説しましたが、果たしてこの
五十嵐 淳 (著)『プログラミング in OCaml ~関数型プログラミングの基礎からGUI構築まで~
はどうなのか?検証してみましょう。

https://gihyo.jp/dp/ebook/2012/978-4-7741-5314-8
によれば、

1章 はじめに

1.1 この本の読み方
1.2 準備
1.3 OCamlに関する情報源
1.4 OCamlの特徴
1.5 OCamlの歴史
第2章 いろいろな式を評価してみよう

2.1 対話式コンパイラ
2.2 基本データ型とその演算
2.3 変数束縛による定義
第3章 関数型言語の醍醐味:関数

3.1 簡単な関数の定義
3.2 条件分岐と真偽値型bool
3.3 局所的変数束縛とlet3.4 構造のためのデータ型:組
3.5 再帰関数
3.6 高階関数
第4章 少ない手間で型付けをする:多相性と型推論

4.1 多相的関数とパラメトリック多相
4.2 型推論とlet多相
4.3 Case Study:コンビネータ
4.4 練習問題
第5章 再帰的多相的データ構造:リスト

5.1 リストの構成法
5.2 リストの要素へのアクセス:match 式とリストパターン
5.3 リストを操作するさまざまな関数
5.4 Case Study:整列アルゴリズム
5.5 練習問題
第6章 データ構造をデザインする:レコードとヴァリアント

6.1 レコード
6.2 ヴァリアント
6.3 ヴァリアントの応用
6.4 Case Study:二分木
6.5 Case Study:無限列
6.6 練習問題
第7章 例外処理

7.1 オプション型による例外処理
7.2 raise式とtry式による例外処理
7.3 exception宣言とexn型
7.4 練習問題
第8章 書き換え可能なデータ構造と入出力を使った命令型プログラム

8.1 unit型
8.2 書き換え可能なデータ構造
8.3 制御構造
8.4 Case Study:参照を使ったデータ構造ーーキュー
8.5 チャネルを使った入出力
8.6 練習問題
第9章 モジュールによるプログラムの構造化

9.1 ライブラリ・モジュールの使い方
9.2 モジュール定義
9.3 シグネチャを使った情報隠蔽と抽象データ型
9.4 練習問題
第10章 バッチコンパイラと分割コンパイル

10.1 バッチコンパイラによる実行可能ファイルの作成
10.2 モジュール単位の分割コンパイル
10.3 システム周りの関数・モジュール
10.4 その他
10.5 練習問題
第11章 モジュール関数:ファンクター

11.1 ライブラリモジュールのファンクターとファンクター適用
11.2 ファンクター定義
11.3 ファンクターと情報隠蔽
11.4 複数の引数をとるファンクター
11.5 練習問題
第12章 OCamlの“O”:オブジェクト

12.1 単純なクラス
12.2 自分自身のメソッドを呼び出す
12.3 継承によるクラスの拡張
12.4 オブジェクトのための型付け
12.5 より高度なクラス機能・型
12.6 練習問題
第13章 ラベル付き引数とオプション引数

13.1 ラベル付き関数を使う
13.2 ラベル付き引数詳説
13.3 オプション引数
13.4 まとめ
第14章 多相ヴァリアント

14.1 多相ヴァリアントの基本
14.2 関数定義の拡張
14.3 再帰的関数と多相ヴァリアント
14.4 その他
14.5 練習問題
第15章 GUI ライブラリ:LablTk

15.1 「銀行窓口」を作ってみる
15.2 ウィジェットの紹介
15.3 ウィジェットの配置:Tk.pack関数とPackモジュール
15.4 イベント処理の割り当て:bind
15.5 その他
15.6 練習問題
第16章 Case Study:お絵かきロジック

16.1 お絵かきロジックとは?
16.2 プログラム解説
16.3 まとめ
あとがき

まず、パッと見て、
前段の書籍のように、

第3章 変数の定義
3.4 ほかの言語の変数との違い
第6章 さまざまなエラー

など、OCaml特有の言語仕様についてはこの本では章立てされていないことがわかります。
同じOCamlを利用した「関数型言語」の本でも、章立てされたりされなかったり、
ということは、そんなことは全く重要ではない証左です。

逆に、この本では、

第6章 データ構造をデザインする:レコードとヴァリアント
第14章 多相ヴァリアント

などと、「ヴァリアント」なるプログラミング世界では一般的ではない用語が散見されます。
これも、OCamlの言語特有の仕様にすぎず、実際、前段の書籍の目次では

17.1 バリアント型

と1節だけ出現していた用語です。
つまり、「関数型言語」の解説として、まったく重要でない、ということを意味します。

いかに、「関数型言語」「関数型プログラミング」を解説する本が、
特定のプログラミング言語の特有の仕様について、章の多くを割いて、
読者に本当に必要とされていない情報が無駄に解説されているのか?
同時に、
読者が本当に必要としている情報が綺麗にすっとばされているのか?うかがい知れることでしょう。

次に、

第8章 書き換え可能なデータ構造と入出力を使った命令型プログラム

「関数型プログラミングの基礎からGUI構築まで」解説すると銘打っているのに、
入出力に関して、「命令型」プログラムで解説されています。

「命令型」と「宣言型・関数型」は対立するパラダイムなので、
このように入出力を「命令型」をもって解説するということは、
その対比として、パラダイムシフトを読者に体験させながら、
入出力を「関数型」をもって解説されているのでしょうか?

もちろん、なされていません。

この本も、「時間」とプログラミングの関係、
遅延評価のこと、遅延評価リストを時間軸にマッピングするFRPのことなど
まったく書かれていないので、そんなことは出来るはずもないわけです。

入出力が関数型と対立する命令型で解説されているのと同様に、
関数型と対立するオブジェクト指向についても、
まさに「マルチパラダイム」的にごっちゃに論じられています。

第12章 OCamlの“O”:オブジェクト
12.1 単純なクラス
12.2 自分自身のメソッドを呼び出す
12.3 継承によるクラスの拡張
12.4 オブジェクトのための型付け
12.5 より高度なクラス機能・型
12.6 練習問題

プログラミング in OCaml ~関数型プログラミングの基礎からGUI構築まで~
なのですから、関数型プログラミングの中で、
命令型による入出力やら、
オブジェクト指向に解説を、
関数型プログラミングとのパラダイム対比としてでなく連続的に解説するのは、間違いだと考えます。
それが極めて象徴的に具現化してしまったのが、この
「関数型プログラミングの基礎からGUI構築まで」の集大成となる最終2章であり、

第15章 GUI ライブラリ:LablTk
15.1 「銀行窓口」を作ってみる
15.2 ウィジェットの紹介
15.3 ウィジェットの配置:Tk.pack関数とPackモジュール
15.4 イベント処理の割り当て:bind
15.5 その他
15.6 練習問題
第16章 Case Study:お絵かきロジック
16.1 お絵かきロジックとは?
16.2 プログラム解説
16.3 まとめ

以上は非常に問題があると観察します。

これは、もはや関数型プログラミングの解説でもなんでもありません。
もちろん、これは容易に予想できたことであり、
関数型プログラミングの本当の世界観の部分に深く踏み込むことなく、
つまり、それは「遅延評価」や「時間」の話であるわけですが、
そういうのを綺麗にすっとばして、
関数型プログラミングでGUIアプリなんて書いてみせることができるはずもないのです。

GUIライブラリ:LablTk

というのがあります。
関数型プログラミングの理路からいくと、
これは拙書が最後部分で総括した、Reactのような宣言型のFRPライブラリでなければいけません、
が、これまでの観察から、おそらくこれは、単なる命令型かつオブジェクト指向のGUIライブラリ、
なのでしょう。

念の為に、OCamlのGUIライブラリ:LablTkとはいかなるものか?
ロゼッタコードで調べてみると、
http://rosettacode.org/wiki/Window_creation#OCaml

Library: LablTk

open GMain

let window = GWindow.window ~border_width:2 ()
let button = GButton.button ~label:"Hello World" ~packing:window#add ()

let () =
  window#event#connect#delete  ~callback:(fun _ -> true);
  window#connect#destroy ~callback:Main.quit;
  button#connect#clicked ~callback:window#destroy;
  window#show ();
  Main.main ()
let () =
  let app = SFRenderWindow.make (640, 480) "OCaml-SFML Windowing" in

  let rec loop() =
    let continue =
      match SFRenderWindow.getEvent app with
      | Some SFEvent.Closed -> false
      | _ -> true
    in
    SFRenderWindow.clear app SFColor.black;
    SFRenderWindow.display app;
    if continue then loop()
  in
  loop()
open Xlib

let () =
  let d = xOpenDisplay "" in
  let s = xDefaultScreen d in
  let w = xCreateSimpleWindow d (xRootWindow d s) 10 10 100 100 1
                                (xBlackPixel d s) (xWhitePixel d s) in
  xSelectInput d w [KeyPressMask];
  xMapWindow d w;
  let _ = xNextEventFun d in  (* waits any key-press event *)
  xCloseDisplay d;
;;

ああこれは、ありがちな普通のオブジェクト指向のGUIライブラリであって、
関数型プログラミングのコンポーネント指向のGUIライブラリではないな、というのがすぐわかります。

GUIの時間経過にともなう、状態の変化はFRPでイミュータブルに実装されているのか?
さらなる検証が必要なのですが、
https://gihyo.jp/dp/ebook/2012/978-4-7741-5314-8
によれば、非常に幸いなことに、

著者の五十嵐淳さんのサイトにおいて,本書のサポートページが開設されています。

ということです。

http://www.fos.kuis.kyoto-u.ac.jp/~igarashi/OCaml/

第16章のプログラム

ということで、

第16章 Case Study:お絵かきロジック
の詳細が確認できます。

GUI とメインプログラム: gui.ml
http://www.fos.kuis.kyoto-u.ac.jp/~igarashi/OCaml/gui.ml

をから、この関数型プログラミング本の最終章である、
Case Study:お絵かきロジック
の核となるロジック部分を抜粋すると、

(** 各種ウィジェット操作 **)

(* マス目にマウスポインタが来た時の動作 *)
let focus label _ = Label.configure label ~background:selcol

(* マス目からマウスポインタが離れた時の動作 *)
let unfocus label st _ = 
  Label.configure label ~background:(color_of_state !st)

(* マス目の上でマウスボタンが押された時の動作 *)
let pressed label st _ = 
  st := toggle !st;
  Label.configure label
    ~relief:(relief_of_state !st) ~background:(color_of_state !st) 

(* マス目をクリア *)
let clear label st _ =
  st := NotPressed;
  Label.configure label
    ~relief:(relief_of_state !st)
    ~background:(color_of_state NotPressed) 

(* 全マス目をクリア *)
let clear_all cells states =
  List.iter2 
    (fun (_::c_row) st_row -> 
      List.iter2 (fun c_row st_row -> clear c_row st_row ()) 
        c_row st_row) 
    cells states 

となっています。

st := toggle !st;
st := NotPressed;

というように、stというミュータブルな状態変数に、破壊的代入を繰り返していることが容易に確認できます。

これは、関数型プログラミングのパラダイムのイミュータブルな参照透過な宣言型コードではありません。

関数型プログラミングのパラダイムで書きたいのであれば、
ReactのStateや、または私が開発した
拙書の中のDemoとして利用している、
timecomponentや、
当ブログ記事で利用している、
worldcomponentのように、
集合としてイミュータブルなストリームに参照透過にアクセスするFRP機構を実装しなければなりません。

そして、上記書籍は、その時間の集合に、
イミュータブルなストリームに参照透過にアクセスするFRP機構についてなんら論じていないのは明白です。

関数型プログラミングとは、状態をもたない、
破壊的代入をして参照透過でないことは避けるべきなのに、
なんでこんな結末になってしまっているのでしょうか?

非常におそまつな結果であると言わざるをえません。

『ずいぶんとダサいコードを書いているのね』

enter image description here

これが、2015年春に執筆し出版した、拙書、『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』の帯のメインキャッチフレーズであり、本書の冒頭で唐突にはじまるセリフです。

計算機科学のほんとうの基礎と、ほんとうの関数型プログラミングへのパラダイムシフト

関数型プログラミングで、このようなお絵かきロジックのGUIアプリケーションを
宣言的に記述するには、時間を抽象化した、SICPの用語でいうとストリームを用意して、
FRPのコードを書きます。

多くの論者は、結局のところ、
関数型プログラミングのパラダイム、考え方を十分に検討せず、
その中核となる物理世界と人間の認識との関係における「時間」の哲学的側面、
時間をストリームとして抽象化する、ということをやらないままに、ゴリ押ししていくので、
時間変化を伴うGUIアプリを書くフェイズになると、
このように、関数型プログラングの手法はあっけなく破綻してしまいます。

以上の2冊の本は「関数型プログラミング」の解説として、
少なくとも、国内では上記の高く評価されているらしい、トップノッチの扱いのようですが、
後述するSICPが到達している知見には遠く及びません。その水準には達していない。
だから、実際にGUIの段になって破綻する。

そこで、GUIなどは、関数型プログラミングでやるには向いてない、
そこは「臨機応変」にオブジェクト指向でやれば良い、
何事にも一長一短がある、関数型プログラミングは「銀の弾」でない、
「適材適所」でやればいいのであってマルチパラダイムだ、
などと、かなり適当なごまかしでお茶を濁す、
いうよりも、ほとんどすべての論者は本気でそう考えています。

実際には関数型プログラミングの「銀の弾」のポテンシャルとしては限界があるわけでもなんでもなく、
ただ単純に、彼らが何も理解していないから、「時間」とプログラミングの関係について考えたこともなく、
「遅延評価」じゃなくてもいいっていうことは、当然、
時間遷移にともなう状態変数をイミュータブルに取り扱えるFRPも理解できていない、
もっと言えば、その理解に必要である、世界観、
「計算機科学のほんとうの基礎」を理解していないので、
ほんとうの関数型プログラミングへとパラダイムシフトできていない、からです。

彼らが、関数型プログラミングのポテンシャルを引き出せないのは、
彼らの知見が一定の水準に達していないからに過ぎません。

関数型プログラミングで、時間遷移するGUI実用プログラミングができなくて当然であり、
「銀の弾」ではないと勘違いしたことを堂々と言ってしまうわけです。

関数型プログラミングの基礎からGUI構築まで、きちんと解説しているのであれば、
SICPにおいては、

  • human mind (ひとの心)
  • collections of computer programs (計算機プログラムの集積)
  • the computer (計算機)

拙書では、

  • 精神
  • 論理
  • 物質

と表現して論じている要素というか、

three foci of phenomena
三つの現象

について結びつけて、
状態、時間変化、時間が本質であることがしっかりと論述されていなければなりません。
これが「計算機科学のほんとうの基礎」です。

はい、こう書かれて???となる人は、
「計算機科学のほんとうの基礎」がない、ということです。
だから「ダサい」コードが書かれている本をオススメとしてもちあげて平気なのですね。

「計算機科学のほんとうの基礎」は、オープンマインドで好奇心旺盛な知性にとっては習得は容易です。

しかし、
「計算機科学のほんとうの基礎」は、「訳知り顔」の連中の知性にとっては習得は極めて困難です。
彼らは固定観念に縛られていますから、それは、マインド・コントロールを解くような作業なのです。

あらかじめ断っておくと、私は彼らは「何を言っても通じない」とあきらめているので、
結構最初っから相手にしていません。
私がこうやって本を執筆したり、こうやって解説しているのは、オープンマインドで好奇心旺盛な知性に向けてであり、それは主に「次世代」です。

世界観を伴わない理論のみで関数型プログラミングを一生懸命学んでも、関数型プログラミングの実用アプリを書けるようにはならない

上記の2冊の本は「関数型プログラミング」の解説として、
少なくとも、国内では上記の高く評価されているらしい本ですが、
「計算機科学のほんとうの基礎」については何一つ触れられていません。

その結果、関数型プログラミングのパラダイムで、
実用アプリを書けるようにはならない、ことは説明しました。

関数型プログラミングの理論的側面のみを追求すれば良いという固定観念は捨てなければならない。それは一面にすぎず、重要なのは世界の見方のほうである。

関数型プログラミングは、これまで理論的側面のみが重視されてきました。
関数型プログラミングは、これまで研究者のものであり、エンドユーザのものではありませんでした。

では、エンドユーザは何を習得すべきか?
研究者のより好みを鵜呑みにして、理論的側面を学習しても何もなりません。
それは今まで関数型プログラミングがメインストリームにならなかったトラックの周回に自分自身がまた参加するようなものです。
もちろん、理論的側面まで追求したければやれば良いわけですが、それはひとつの側面にすぎず必須の作業でもなんでもない、それだけやってもどこにも到達することはない、と自覚しておくのは非常に重要です。

エンドユーザが真に習得すべきなのは、
「計算機科学のほんとうの基礎」です。
実際これを習得するのは、いろいろ固定観念を捨てる必要があります。
なぜなら、それは何度も繰り返しているとおり、「時間」の概念に触れることだからです。

コンピューティングとは、所詮、我々が生活するこの物質世界で展開される事象であり、
数学理論の中だけで完結しているものではありません。

ここがほとんどの研究者が徹底的に見落とし、何か重大な勘違いをしている点であり、
私はその辺を本に徹底的に書いて解説したつもりですが、まったく伝わらなかったようで、
ああこれはダメだな、と正直あきらめました。
その一方で、目測どおり、オープンマインドで好奇心旺盛な知性は「ドキドキワクワク」しながら楽しみながら読んでいただけたようです。

なぜ「ダサい」という穏当でない否定的文句が全面に押し出されているのか?

そして、多くの人が、きっとこう思うことでしょう。
「やれやれ、また、一体なぜ、【ダサい】だの、そんな否定的文句を言わねばならないのか?
どうも穏当なやり方じゃあないね・・・」

実際、この副読記事のタイトルにしてもそうです。

いくつかの理由が考えられるでしょう。

  • その1 この本の主人公である「サクラ」あるいは、この本を書いた著者、この記事の筆者=私が穏当ではない個性をもつ人物だから。(私は自分では別に普通だと思っていますが、周囲の騒ぎようを客観的にみると、おそらく穏当な人物であるとは見做されてはいないのでしょう。それは客観的事実として認めざるを得ません。)

  • その2 穏当ではない人物は、「穏当ではない考え方」をし、平均的多数の考え方を平気で否定してしまうから。(というか、物事の考え方であるとか、真偽って、「多数決」や「権威」や「通説=世間に広く通用している説のこと」で決まるものじゃないですよね?これも私はごくごく普通のあるべき作法であるとは思ってますが、)

  • その3 イノベーション(英: innovation)

    物事の「新結合」「新機軸」「新しい切り口」「新しい捉え方」「新しい活用法」(を創造する行為)のこと。一般には新しい技術の発明を指すと誤解されているが、それだけでなく新しいアイデアから社会的意義のある新たな価値を創造し、社会的に大きな変化をもたらす自発的な人・組織・社会の幅広い変革を意味する。つまり、それまでのモノ・仕組みなどに対して全く新しい技術や考え方を取り入れて新たな価値を生み出して社会的に大きな変化を起こすことを指す。(Wikipedia)

    とは、変革による新しい価値の創造であり、
    変革とは、必ず、既存の枠組み、既存の考え方の否定であり、
    変革とは、必ず、(既存の枠組みにとっては)穏当ではない事象のことである。
    新しい価値の創造ができるのであれば、変革は歓迎されるし、これまでわれわれ人類はその繰り返しでここまで進歩を遂げてきた。既存の考え方の否定は原理的に必ずしなければならない必須の作業である。
    既存の考え方にとらわれるな。既存の考え方を捨てよ。

  • その4 関数型プログラミングとは、パラダイムシフト(英: paradigm shift)

    その時代や分野において当然のことと考えられていた認識や思想、社会全体の価値観などが革命的にもしくは劇的に変化することを言う。パラダイムチェンジとも言う。(Wikipedia)

    であるが、Lisp、Haskellはじめ、これまで理論先行であり、肝心の言語ユーザ(プログラマ)の考え方がそのポテンシャルに追随、適応できていない。だから、関数型プログラミングはこれまでメインストリームで普及することもなく、イノベーションも起こっていないのである。
    技術者とあろうものが、目の前にある程度以上に完成されたイノベーティブな道具が用意されているのにもかかわらず、それを使いこなしてイノベーションを起こせていない状況は、「ダサい」と批判されて然るべきものであると私は信じる。
    関数型プログラミングがイノベーションを起こせる「銀の弾」であると理解できていない99%のプログラマは、要するに、肝心の言語ユーザ(プログラマ)の考え方がそのポテンシャルに追随、適応できていないだけである。
    関数型プログラミングを語るとき、物質世界とプログラミングの「時間」性について言及できない、理解できていないプログラマは、そのポテンシャルに追随、適応できていないと見なして良い。そして99%の技術者が「時間」とプログラミングの深淵な関係性が理解できないのは、99%の技術者が哲学的素養に欠けるからである。

  • その5 他ならぬ、イノベーションを先導、良い意味で煽動すべき立場にある、関数型プログラミングの教育者、解説者、書籍の著述者陣こそが、肝心の言語ユーザ(プログラマ)として、関数型プログラミングの考え方、ポテンシャルに追随、適応できていない。彼らが一番ダサく、その社会的責任は重い。
    関数型プログラミングとはパラダイムシフトであり、イノベーティブであるポテンシャルを有するが、既存の考え方を否定することをためらい、適材適所だのマルチパラダイムだの、適当かつ穏当な解説に終始するばかりに、パラダイムシフトは理解されることはなく、イノベーションは起こらない。穏当な解説に終始するのは、著述者が革新たる「既存の考え方の否定」という当然必要な行為を怠り、嫌がっているからである。その根底は、自身穏当でない言論を展開することによる批判を恐れる保身がある。
    もしくは、たた単純に自身の知性の限界から既存の考え方の否定であることを理解できていない。
    関数型言語の数学的な基礎理論を延々いくらこねくりまわして開陳したところで、それはイノベーションではない。
    イノベーションとは、前述の通り、「新しい捉え方」「新しい活用法」のことである。いくら、そのものを数学的に「描写」しても、「考え方」を伴わない限り、パラダイムシフトは絶対に起こらない。
    そしてよりによって、拙書の発売を受けて、「アンチテーゼ」の本を出せとか出すなとか、非常にくだらない話を振るものまで居る。拙書こそが既存の、一定の水準に達していない諸々の関数型プログラミングの書籍への「アンチテーゼ」であったことになるだけ早く気がついて欲しいし、これ以上、一定の水準に到達していない関数型プログラミングの書籍は出るのは望ましくないと私は考える。それは「ダサい」本である、と予め批判しながら、大きな釘を刺しておきたい。
    一定の水準、というのは、もちろん、時間とプログラミングと関係性について論述するということであり、さらに踏み込んで、マシンで具象化される物質世界、コードそのものの論理世界、ユーザの精神世界の3要素について、きちんと論述するということである。この水準に達していない関数型プログラミングのすべての本はダサい。

  • その6 このダサく膠着した状況に、一石投じるべく、私は以前からネット上に記事を投稿していた、というか、このようにくだらない状況をずっと見ていると、石を1個でも2個でも投げ込んで、バランスをくずしてみたくなるのだが私である。それはイノベーションという意味で良いことであると信じている。イノベーションとは、まず否定からはじまるわけであり、否定的要素を全面に押し出した「脱アルゴリズム」シリーズの記事をUPしたが、案の定その心理的反発は凄まじい物であった。それはもちろんくだらない平穏な均衡が保たれていたところに、変なやつに石を投げ込まれて、その平穏な均衡がかき乱されてしまったからである。彼らの「現状維持」への復元欲求は大きかった。
    そのような折、非常に時流に敏感な秀和システム者の、ある編集者が、私を発見した。この方はプロなので、そのような不協和音の原因は私ではなく、時流に適応できていない彼らのほうであると見抜いており、一連の状況を「痛快」であると私と認識を共有した。数回ほどのやりとりの末、出版の機会の打診をいただいた。
    それまでの経験を元に「フローは不要」と言葉尻を変えて天才JKに語らせるラノベというようにパッケージングを変更した。これは著書の素案として公開したが、読者の反応は悪くなかった。しかし真に関数型プログラミングのパラダイムシフトの要素が露見するFRPにまで話を進めると、他ならぬ、イノベーションを先導、煽動すべき立場にある、関数型プログラミングの教育者、解説者、書籍の著述者陣の一部からも激しい反発が表明された。彼らを中心に私の言説は有害であり、Google検索結果を「汚染」しているとまで言われ、総体としてみて私の言説を封じ込めるべく「焚書」のような恥ずべき行為が堂々と展開された。現代日本は中世ヨーロッパではないので、この現象は言論の世界において「ダサい」と糾弾される以上の愚行であると信じる。

  • その7 出版に向けて私の執筆は粛々と進み、出版社の方々の多大なるご理解とご協力により、ほぼ私の思惑どおりの理想的な書籍が無事出版された。これに「怒り狂った」のが上記の彼らである。彼らの極めて愚かな「焚書」の試みは、ものの見事に失敗し、彼らの矛先は、私の言説を世に出した当の出版社へ向けられた。同時にそれはAmazonレビューの低評価をゴリ押しするという、非常にわかりやすい言論世界のテロ行為としてネガティブキャンペーンが露骨に行われた。この現象は言論の世界において「ダサい」と糾弾される以上の愚行であると信じる。

  • その8 彼がここぞとばかりに大騒ぎし、ネガティブキャンペーンを展開した影響として、短期的には本書の売上に影響があった。一部著者や出版社への露骨な業務妨害行為や名誉毀損行為が行われた案件については法的な対応を取るが、中長期的には、単にその事象がネットで広く検証される証拠として大きく露出しただけであった。不正なネガティブキャンペーンが行われた事実は明白に追認される状況となっているし、このブログの記事のGoogle検索結果の露出度は飛躍的に上昇した。Google検索結果を「汚染」しているから記事を抹消できた、彼らが喜んでいた以前よりも私の主張はネット上に露出することになり、彼らの邪な思惑はまた失敗した。
    現代日本において、誰かの考えを不当に封印しようとするような愚かな試みが成功するはずがないのであって、そんな試みをしても無駄である。
    以上の不正、愚行はすべて今後中長期の検証のために記録に残っている。
    騒げば騒ぐほど私の考えはより多くの人の眼に触れ、今後検討されることになるだろう。彼らは「ダサい」。

  • その9 所詮技術の話である。所詮哲学の話である。人の生命財産に関与する政治的トピックではない。真に自由な議論である「はず」で、「ダサい」とDisろうが何しようが上等である。
    せいぜい、本の著者・この記事の筆者=私が「穏当ではない個性をもつ人物だな!」と社会的評価を下げるだけで終わる話である。

  • その10 最後はもっともプラグマティック(現実的)な理由からである。つまりそれはマーケティングである。パラダイムシフトを起こすにせよ、イノベーションを後押しするにせよ、こういう私の主張が読まれなければ話ははじまらない。特に情報が過多な昨今、主張、言説は読まれてナンボである。平均的な読者が欲しているものをしっかりと見極めた上で、提供する必要がある。そして、こういう記事は、なにより、貴方が求めている、欲している。今、貴方はいったいどういう経緯で、このブログ記事を読むことになったのだろうか?よく自問自答して欲しい。非常にくだらないことであるが、ネット利用者=大衆は、炎上、諍い、揉め事、そういう事象が大好きである。「ダサい」「まるで理解できない」こういう他者への否定的言及をする記事を読むのが大好きである。
    もちろんこの記事にしてもタイトルとして「SICPの解説」とだけ銘打っても良かっただろう。それで読まれるのであれば、私はわざわざ上記のように自己正当化しながら「工夫」もする必要はない。しかし、非常に残念な現実として、このような「読者への訴求力が弱いタイトルの記事」はまったく読まれることはない。いかに重要な主張をしていたとしても、想定する平均的読者はまったく興味がないので読もうとはしないのである。僭越な物言いとなるが、本書のタイトルは平均的な「貴方」にレベルを合わせて決めている。それがマーケティングというものであり、貴方は興味をそそられ、いくばくかの知見を無償で得ることができ、少なくとも考えるキッカケは得ることになるだろう。しかも「また、岡部が穏当ではない長い記事を書いているのだな」といういつもの優越感と共に。
    「穏当ではない」と思うのならば読まなければ良いのであるが、こぞって読む。それが平均的な様態であるのだろう。貴方は何も損をしない。「岡部は穏当ではない」と口々に言い合ういつもの光景が繰り返されるだけのことで、損をするのは私一人である。しかしそれはあくまで短期的な雰囲気に過ぎす、私としては中長期的な「穏当ではない」影響を与えられればそれで目的は達成されている。それはすなわちイノベーションである。

99%の「ダサい」プログラマ、の99%という数字について

実際は99.9%とかそういう感じ、だと思います。そもそも本書はまだ国内プログラミング人口に比較すると売れているわけでもないですし、本書発売後の反応をみても、理解している読者はむしろかなり少数派であると思います。

もちろん、私は真摯に先入観もなくオープンマインドで著書を読了していただいた読者まで「ダサい」と見下すつもりはありません。

誰でも最初は入門者であるのです。サクラも私も含めて。
セキヤ君は、サクラ先輩に「ダサい」とDisられましたが、それは本書のプロットどおり「愛の鞭」であったわけです。私がいったい誰に向かって「ダサい」と言っているのか、それは本書を読んでくれた人には十分伝わっていることだろうと思います。

未だ道半ば、通過点に過ぎない。社会実験はまだまだ続く。

「社会実験」といえば、ビジネスとしてやっておられるプロフェッショナルな担当編集者はじめ、出版社には失礼かもしれませんが、おそらくこの私の意図は信頼するパートナーである本書の担当編集者は理解されることでしょう。
ビジネスの側面としても、本書はネガティブキャンペーン下にありながらも予約段階からベストセラーになり、その後も一定以上の水準の売上は維持しているようです。また今後もこのように本書の著者として然るべき情報を発信していくことで、本書の存在価値、売上の面で、出版社に恩返しすることは可能であると信じます。

それを踏まえ、これは社会実験です。個人的に大きな意義があると考えているから、こうやって出版に一生懸命になったり、こういう長い記事を何本も書けるわけです。個人的に知的にとても興味のある取り組みです。

なぜ拙書を読むと「疲れる」人と「ドキドキワクワク」する人に別れるのか?彼ら双方の何が違うのか?それは固定観念に縛られないオープンマインドな知性を有するか?権威主義であるかないかである。勝利宣言

Persistence 続けることに意味がある。
『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』を読んだ

パラダイムシフト
本書の前半半分は、命令形プログラミングと関数型プログラミングのパラダイムの違いを非常に分かりやすく説明されています。自分が今まで書いていた命令形プログラミングはフローを作成して機能毎に分割して作っていましたが、関数型プログラミングはフローや状態を排除し論理毎に機能を作成し、必要になった時に必要な分だけ計算する(イベント駆動)という方法を取ります。「論理」と「計算」を分けて考えるという説明はわかりやすかったです。

NyaoPress
関数型プログラミングに目覚めつつある!

これはひょっとして次にくる古くて新しいパラダイムなのではないかと思ってワクワクした。そこで目に入ったのがこの本。
お姉さんにプログラミングの手ほどきを受けるという素敵な場面に出くわしたことのない僕は年甲斐もなくワクワクしながら読んだ。使われているのはJavaScriptだ。思ったとおり。まともな関数型言語だった。

お姉さんはパラダイムの変化を哲学の視点からも説明してくれる。関数型の足元がしっかり固まるようで心強い。よし、ここしばらくこれにハマってみようということで、JavaScriptの関連本を買い、彼女が使っているAtomというエディタをUbuntuに入れようとしているのがまさに今。

仕事で受け入れられるようになるにはひょっとすると10年かかるかもしれない。そのころには定年だ。だけどこのワクワク感。逃す手はない。

少々煙たがられてもLispの時のように挫折せずにモノにしたい。そう思うのである。

表紙に騙されてもいいから、プログラマーなら読んでおくべき本だ。

Simple Blog
関数型プログラミングに目覚めた?

以前からぼんやりと関数型プログラムが出来るようになりたいと思ってましたが、ネットでちょっと調べる程度で出来るものではなかったです(自分にとっては)。
でたまたま平積みされていた本書を立ち読みすると、ストーリー仕立てで面白そうだったのと、1300円と安価だったので即購入。GW一杯かけて読むことにしました。本書は丁度5月1日に発売されていたのでそういう読み方も想定していたと思う。ちょうど5日間だし。

内容としては「0から9までの数をすべて足すコード」を、関数型プログラムで書くまでが前半の100ページ以上かけて説明されています。関数を一個一個定義していって最後に関数型のコードで「0から9までの数をすべて足すコード」ができるところ、フィボナッチ数列を関数型プログラムで求めるところでかなり感動してしまった

この前半はかなり充実した内容だと思う。関数型プログラムがどうしてもよく分からない、そもそもなんでオブジェクト指向ではダメなのか、何から始めればいいのかとか、最初の取っ掛かりが掴めずにいた自分にはピッタリ嵌ってしまった。また読み物として前から後ろに読んでいっても復習の章があったりして自然と考え方が定着します。普通技術書は重要なことが書いてあるページは読者が覚えておいて何度も開き直すような読み方になると思いますが、読み物として読んでいってる人にも理解させようという気概がある書き方みたい。
なんというか、ストーリー仕立てということもあるしとても情熱的な書き方になっている。一度オブジェクト脳になってしまった頭をパラダイムシフトさせるにはこのくらいの熱意が感じられないと難しいのかも。今まで関数型プログラムの壁に当たって引き返していたのが、女子高生にダサいコードと罵られたことで何としてでも超えてやろうと思えたわけだ。

読み終わってアマゾンを見ると本書に関して内容が薄いとかそもそも誤解に基づいた主張とか、レビューの点数があまりに低いのでビビった。
 まぁ本の内容が正しい、ということより、内容がどうであれその本に影響を受けて関数型プログラムの習得に強い動機付けがなされた人、あるいは最初の壁を突破した人が一人いる、ということの方が重要なので、個人的には超おすすめ。

関数型プログラムをやりたいけどよく分からない、って状態で(女子高生に罵られるのがそんなに嫌いじゃない人が)読むと絶対面白いと思う。
というか普通に考えて発売から1週間足らずでこれだけのレビューを集めてる、そんでほとんどが低評価ってのがなんていうか、、本の内容がどうというより余程嫌われてるんですねこの作者w。
Amazonのレビュー見てると、どうもこの作者の人となりによって不当に評価されている気がする。この本のターゲット層は関数型プログラムなんか出来ないって人で取っ掛かりを求めてる人なんじゃないの?
言語として、関数型プログラムなんか出来ない人にも馴染みの深い、関数型プログラムが書けるものって、JavaScriptがぴったりだと思う。
で関数型をこれから始める取っ掛かりって意味で関数型の考え方とか作り方とかをここまでページ数使って簡単に解説してるものは他にないと思うけど。

変な先入観を持ってこの本読まずに、難しい本を最初に手に取って「やっぱ関数型って意味わかんね」ってなるくらいなら、この本を最初に読めばいいと思う。
まぁ、表紙が良いのと値段も安いので買う人多いと思うけど。。

NODE/JQUERY/JS, オブジェクト指向・システム開発, 書籍・雑誌, 本おすすめ
書評: 関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間Add Star

まじめな話、いろいろある関数型言語の入門書の中で一番理解しやすく一番神髄的なところを説明している本ではないでしょうか。文体や表紙にだまされることなく、関数型言語の考え方の核になる部分がわかりやすく書かれています。下手に圏論やモナドなどを持ち出さないところも重要です。Amazon等でいろいろ批判されていますが、それらの用語を多用する小難しい事オレがんばっておぼえた的なところがにじみ出すぎている、良くある関数型入門的なWebサイトより256倍マシです。小難しく書かれたHaskell本を読んで挫折した人は、この本でセキヤくんと一緒にJavaScriptでやり直してみるのが良いのではないかと思います。しかも1300円です。ほかの関数型言語の書籍がいったいいくらすると。

個人的には、良くある「フロント技術者」の人たちが書いているFacebookのReactの記事を読んでもその重要性や目的がさっぱりわからなかったのですが、この本を読んですとんと落ちました。もうそれだけで1300円分の価値が十分ありましたよ。

あと本書で大事なのは、哲学と計算機科学との関係についてちゃんと触れられている点で、こんな事まで理解している高二怖いと思いましたが、そこはすごく大事な点です。どちらかというと本書はオブジェクト指向にたいして否定的なので、そちら文脈での哲学や仏教思想については触れられていませんが、オブジェクト指向と仏教の因果律との関係なども面白いテーマでしょう。結局対象をどう捉えるかというパースペクティブはどの様なパラダイムであれ重要で、そのパースペクティブを与えるのが哲学だからです。

ということで、内容の濃い、でも読みやすい1300円でした。

ということで、普通に検索したら、拙書について、ネガティブキャンペーンにまったく影響されない、超ポジティブレビューの絶賛があったので、引用させていただきました。
全文ではないので、リンク先で読んでください。

著者として、特に、ああ伝わったんだ、と感慨深かった部分を勝手に太字にさせていただいております。

固定観念に縛られないオープンマインドな知性は、この宇宙で何者にも影響されない。
ネガキャンなら、それはネガキャンだと見抜けるんですね。だから連中が何をやろうと無駄です。
彼らのきらめく知性に、その薄汚れた手はけっして触ることはできない。
ここを今回の中心人物である私が断言しておきたいと思います。
以上のレビューは私の勝利宣言です。

残念ながら全部ではないが、そして全部というのはきっと無理な作業なのだろうが、
私が書いた解説は、ものがたりは、一定数の読者の知性を、ワクワクドキドキさせ、
感動させ、パラダイムシフトを体験させることに成功した。
この事実は紛れもないのですね。それこそが重要です。どうもありがとうございます。

2015年の春、私はやることはすべてやりきった。

だから、そう思っています。

99%の「ダサい」プログラマの「マインドコントロール」を解くに等しい、緻密さと困難を伴う作業である

では、以上のようなキラメク知性をもっていない、
固定観念に縛られないオープンマインドな知性を有する、のではない、
「計算機科学のほんとうの基礎」を今後も理解することは絶対にないであろう、
愚鈍な連中はどうすればよいのか?

連中は当然見捨てて、放置しておくべきです。
しかし、ひとつ大きな問題がある。
無教育なまま、勘違いしたまま延々と間違った考え方を流布させたままにするのは、
世の中のためにはならない。

しかし、そういう連中にむかって「教育」するのは並大抵の作業ではありません。
現実に、拙書を読んでも理解できない、とすでに大失敗しているわけで。
2015年の春、私は自分にできることは、すべてやりきった、と思いますし、
これ以上どうすればよいのか?検討もつきませんでした。

固定観念に縛られないオープンマインドな知性を有する、のではない連中について、
固定観念に縛られない新たな世界観を提示するというのは、
まさに「マインドコントロール」を解くに等しい、緻密さと困難を伴う作業なのです。

2015年の初夏、私はまたちょっと違うやり方で試みようと思う それは知的な暴力である

本書では、プログラミングと「時間」との関係について事細かに説明しました。

SICPにおいては、

  • human mind (ひとの心)
  • collections of computer programs (計算機プログラムの集積)
  • the computer (計算機)

拙書では、

  • 精神
  • 論理
  • 物質

と表現して論じている要素、SICPで言う

three foci of phenomena
三つの現象

について解説しました。

私は、平均的な知性しか想定しなかったのですが、
キラメク知性をもっていない、
固定観念に縛られないオープンマインドな知性を有する、のではない、
「計算機科学のほんとうの基礎」を今後も理解することは絶対にないであろう、
愚鈍な連中はどうすればよいのか?

よりレベルを下げるしか方法はありません。
それは恥ずべきレベルです。
それは知的な暴力です。

権威主義には権威主義をもって対抗する

「新しい考え方」を提示する際に、「既存の考え方」に縛られる固定観念に縛られ、
こちらの話を傾聴する気など最初からなく、理解するつもりもなく、
大騒ぎして反発する聴衆に、黙って席に座って傾聴させるにはどうすれば良いでしょうか?

権威主義で、そんなに権威をありがたがるのであれば、彼らが望む通り、権威を利用してやれば良いでしょう。

権威主義のレベルにまでレベルを下げることにします。

権威主義とは一種の暴力行為です。
本来リスペクトされるべき知性を有する相手にたいして、こんな手段を取るべきではありません。

そもそも権威に左右されない知性と感性を持っている聴衆には、そんな真似をする必要はまったくありませんし、断じてすべきではありません。だから拙書では、いかなる形式においても、プログラミングの権威を借りるような真似は一切しませんでした。読者の知性を信頼していたからです。
もちろん哲学史のビジョナリーの思索は描写させていただきましたが。権威にけしてとらわれることがなかった、彼らの自由な知性を権威と捉えないでください。

権威に囚われ左右される知性と感性しか持っていない愚鈍な聴衆にむけては、逆にそこを利用することにします。

「ほらよくご覧なさい。こんなに偉い人がこう言ってるんだから、正しいに決まっているでしょう?」

そういう理路のまったくない無条件の信頼を要求し、信仰の強制をします。
これは信仰の強制にすぎないのですが、そういう連中にとっては「安心と信頼」になってしまうようです。
非常に愚かなことですが、連中が欲しているのであれば、試しにそれを与えてみましょう。

懇切丁寧に話をしても、こちらが何を試みようと話が通じない相手にだけ、
それは知的な「強制力」としてやむを得ず発動します。
権威による説明とは知的に最低の作法であり、相手の知性を愚弄する暴力的行為です。

同時に、私自身も「虎の威を借りる狐」に成り下がるわけで、私自身のレベルも同時に下げることとなります。

今回、このようにレベルを下げざるを得ない顛末になったことを非常に残念に思います。

さて、どういう権威が有用でしょうね?

SICPという権威を利用させてもらって、連中を黙らせる。黙って座って傾聴させる。

以前、Qiitaで私に対して、匿名捨てアカウントをもって、「有害な記事」だとか、上から目線で、あれ読めこれ読め、と言ってきた慇懃無礼な、どっかの大学の情報系の教師によるコメントが参考になるでしょう。

私はあなたの指導教官ではないし、教える義務もありませんので、これ以上の努力はいたしません。最低限の指摘はすでに終了しています。
幸いなことに世の中には、すぐれた書籍があふれております。いい世の中です。ぜひ、一読することをおすすめしたします。
この分野に関わりたいのであれば、避けては通れないコンピュータサイエンスの基本ばかりです。
[1] “Structure and Interpretation of Computer Programs” http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-1.html#titlepage
[2] “Introduction to the Theory of Computation” http://www.amazon.co.jp/Introduction-Theory-Computation-Michael-Sipser/dp/113318779X
[3] “Types and Programming Languages” http://www.amazon.co.jp/Types-Programming-Languages-Benjamin-Pierce/dp/0262162091
以上を参考文献として上げる理由を以下に述べておきます。
[1] - Kenokabe さんは、評価(eval) と 関数呼び出し(apply) の基本的区別がついていないようです。私がこれまで出会ってきた学生ならば、これらの区別は100人中100人が学習によりできるようになります。Kenokabe さんの中における「評価」と、100人中100人が共通の語彙として相互理解している「評価」がどのように異なるか、ぜひ、SICP を読むことをおすすめします。
[2] - Kenokabe さんは、コンピュータプログラミングにおいて「計算」するということがどういうことかその原理を理解していないようです。この本は、「計算」するとはどういうことか?時間と空間との関係についてもきちんと数学的な証明をもって述べています。ぜひ一読を。
[3] - λ計算についての深い知識はここでの議論ではそれほど必要ないかと思われますがやはり身につけておいたほうが今後は他人とのコミュニケーションがスムーズになると思われます。

なるほど。

この分野に関わりたいのであれば、避けては通れないコンピュータサイエンスの基本ばかりです。
[1] “Structure and Interpretation of Computer Programs” http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-1.html#titlepage

「この分野に関わりたいのであれば」とかいったい何様のつもりか知らないですが、それはともかくとして、この人物が「権威的書籍」であると考えているのは、

Structure and Interpretation of Computer Programs” http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-1.html#titlepage

『計算機プログラムの構造と解釈』
(Structure and Interpretation of Computer Programs。原題の略称SICPがよく使われる)

enter image description here

であることが観察されます。

http://sicp.iijlab.net/

魔術師本: (名詞) MITの入門コースで使う計算機科学の優れた教科書 ハル・エイブルソン, ジェリー・サスマン, ジュリー・サスマン共著(和田英一訳)「計算機プログラムの構造と解釈 第二版」(ピアソン・エデュケーション 2000年). 表紙の魔術師ゆえにそういわれる. LISP/Scheme世界の聖典のひとつ. まれに紫本としても知られている.
ハッカー英語辞典 第2版(MITプレス 1993)より

http://d.hatena.ne.jp/minghai/20140402/p1
には、日本語訳をされた方による紹介があるので参考になります。

SICPとは何か?
SICPとはMITが作成した何も知らない新入生向けのプログラミングの教科書です。
プログラミングと強調したことには理由があります。この本は良くあるプログラミング言語の教科書ではなく、あくまでもプログラミングを勉強するための教科書だからです。このことはこの本の中でも、最初の前書き、序文にて何度でも繰り返し強調されています。筆者達がこの本をそれまでの教科書から著しく際立たせる特徴として誇る理由です。
米国の新聞、ボストングローブ紙のMITの創立150周年記念企画にて作成されたMITでの最も重要な発明リストにもこのSICPは選ばれています。

127番 もっとも重要な本
Harold Abelson and Gerald Jay Sussman, a pair of MIT computer science professors, wrote “Structure and Interpretation of Computer Programs,” which remains a classic for encouraging the teaching of not one specific programming language, but big-picture themes students could apply across a range of programming scenarios.
MITの計算機科学の二人の教授、Harold AbelsonとGerald Jay Sussmanは”SICP”を出版しました。
これは1つの特定のプログラミング言語を教えるのではなく、学生が一連のプログラミングの
シナリオに渡って適用できる大局的なテーマを教えることを促す古典としてあり続けています。

SICPは、MITという世界有数の権威ある理系大学の授業の教科書であり、
実際、関数型プログラミングの世界において「古典」であり「聖典」であり、
名のしれた「権威」であるのは間違いないので、申し分ないでしょう。

SICPについては、私は関数型プログラミングの独自研究の過程でひととおり目は通していました。

そもそも、私は、SICPが採用しているLisp/Schemeに不満で、
自分自身の関数型言語を開発していたくらいなので、
LISPデータ構造の問題点の指摘と抜本的解法としての新プログラミング言語の策定/純粋関数型言語「SPINOZA」
あまり楽しめなかった、ハマれなかったのですが、
SICPの著者の知見と、一部哲学的内容については、かなり高く評価しています。

そしてこれは最初に説明しておかなければなりませんが、
私は自分の考えを確立させる上で、SICPの哲学的知見に頼ったわけではありません。
私は自分自身の考えが確立していたので、「ああ同じ知見が書かれているな」と確認できたのです。

おそらくほとんどの読者は、SICPを読んでみても、その哲学的知見はなんのことか理解できないでしょう。
それは上記の慇懃無礼で上から目線のどこかの大学の教師が
「この分野に関わりたいのであれば、避けては通れないコンピュータサイエンスの基本ばかりです。」
などと言いながら、「権威的書籍」として振り回し、読んだことを自慢したいだけで、その結果、
自身なんら理解できていないことからも明白です。
SICPに書かれている哲学的側面をきちんと理解していたならば、全くおんなじことを主張している私の言説を「有害だ」なんて言えるわけがないからです。

ということで、本稿では、SICPを「権威」として悪用させていただくことにします。

また、悪用であり、知的暴力で申し訳ないですが、権威主義ではない、固定観念に縛られないオープンマインドな知性をもつ読者にとっても、それは再確認ということで有用だと考えます。

SICPは、関数型言語の数学的な基礎理論を超えた「穏当ではない考え方」を堂々と示している拙書に先行する唯一の型破りな書籍である(多分ね、例外があったら教えて)

拙書が物珍しい、類書がない、と評価されるっていうことは、私以外にはそういう考え方を、型破りに、全面的に提示した書き手が存在しない、というだけのことです。

実際そうなのですが、フェアに、かなり厳密に言うと、これは少しだけ議論の余地が存在します。

本書に書いてあることは、基本すべて私自身の思索の結果ではありますが、
前述の通り、研究過程において、SICPの著者が提示している考えとの一致は確認していました。

SICPは、現在、正当なる哲学的行為を愚弄する「呪いのことば」として国内IT世界で流行している「ポエム」から「穏当ではない考え方」を含む序文が始まりますし、各章の冒頭には、それこそ文字通り、文学的「ポエム」が掲載されています。

こんなふうに。

4  超言語的抽象
… 魔法は言葉にある. —アブラカダブラ, 開け胡麻, など— しかしある物語の呪文は, 次の物語では呪文ではない. 真の魔法はどの呪文がいつ, 何のために働くかを理解することである. トリックはトリックを学ぶことである.
… そしてこれらの言葉は, アルファベットの文字で出来ている; ペンで書ける二十字余りの記号である. これが鍵だ. そこに手が届きさえすれば宝でもある. それは宝への鍵が宝であるようなものだ.
John Barth キメラ

国内の非常に愚かな状況において、投げつけられる呪いのことば「ポエム」と愚弄されている、哲学的言及がこのようにある、という事実は、すなわち、このSICPとは、著者自身の思索の結晶であり、誰か他の人の言葉を模倣したのではない、オンリーワンであり、完全なるオリジナルである、ということを示唆します。

私が重視しているプログラミングの思想、世界観について、
関数型言語の数学的な基礎理論を超えた「穏当ではない考え方」について、
冒頭から一貫して、もうかなり大胆に踏み込んで書いてあります。

SICPはなぜ聖典と言われているのか?

SICPという本は、ほとんどの場合、二次的に言及された途端に、その「原典の真髄」「聖典の輝き」は失われてしまいます。二次的に言及する解説はほんとうにつまらないものばかりです。まさに聖典ぽいですよね。

SICPはほとんどの場合、そのLisp/Schemeの数学的基礎理論の要素ばかりが読解されて、二次的に言及されますが、その魅力は、それがオンリーワンであり、オリジナルであることに起因していると私は観察しますし、JavaScriptを設計し開発実装した、ブレンダン・アイクをはじめ熱烈な信者が存在するのは、その哲学的要素による関数型プログラミングの真髄がしっかりと語られているからであると思います。

この辺の価値がわかる読者は少数派でしょう。
しかしこの辺の価値がわかる読者は、パラダイムシフトが体感させてもらえるので、まさに信者となります。
これが関数型プログラミングの聖典と言われる所以だと私は同意しています。

「関数型プログラミングの聖典だ」「MITの教科書だ」という、他人の評価、あるいは権威につられて読んだ人たちは、SICPが語る「穏当ではない考え方」、哲学的要素「ポエム」の部分は、理解できないので、そのたいせつな部分を綺麗にそぎ落として、言及するので、その二次的言及を読んだところで、たいした意味などありません。
「原典」でしか価値がないといわれるのが「聖典」なわけなので、そういうことです。

そして、そのそういう一般に理解されない「原典の真髄」「聖典の輝き」の部分ばかりを、拙書は書いている、ということになります。SICPが「聖典」であるのは、前述の通り、その世界観の解説、哲学的要素が強いからであって、哲学的要素には実際のところ、SICPの表紙にもある魔法なんてものはないわけですから、私でも誰でも書こうと思えば書けるわけです。その内容さえ理解しておれば、ですが。

本稿でのSICPの引用

本稿ではすべて、英語版は、
MIT PressのSICPページ
http://mitpress.mit.edu/sicp/
http://mitpress.mit.edu/sicp/full-text/book/book.html
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-4.html#%_toc_start
Structure and Interpretation of Computer Programs

日本語翻訳版は、
http://sicp.iijlab.net/
http://sicp.iijlab.net/fulltext/
http://sicp.iijlab.net/fulltext/xcont.html
計算機プログラムの構造と解釈 第二版 和田 映一 訳

より引用します。

上記サイトをメンテナンス、翻訳され、広く無償で公開されている方々にお礼申し上げます。

SICPは「ポエム(プログラミング分野の哲学的言及を愚弄する呪いの言葉)」から始まる

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-5.html#%_chap_Temp_2

Foreword

Educators, generals, dieticians, psychologists, and parents program. Armies, students, and some societies are programmed. An assault on large problems employs a succession of programs, most of which spring into existence en route. These programs are rife with issues that appear to be particular to the problem at hand. To appreciate programming as an intellectual activity in its own right you must turn to computer programming; you must read and write computer programs – many of them. It doesn’t matter much what the programs are about or what applications they serve. What does matter is how well they perform and how smoothly they fit with other programs in the creation of still greater programs. The programmer must seek both perfection of part and adequacy of collection. In this book the use of “program” is focused on the creation, execution, and study of programs written in a dialect of Lisp for execution on a digital computer. Using Lisp we restrict or limit not what we may program, but only the notation for our program descriptions.

Our traffic with the subject matter of this book involves us with three foci of phenomena: the human mind, collections of computer programs, and the computer. Every computer program is a model, hatched in the mind, of a real or mental process. These processes, arising from human experience and thought, are huge in number, intricate in detail, and at any time only partially understood. They are modeled to our permanent satisfaction rarely by our computer programs. Thus even though our programs are carefully handcrafted discrete collections of symbols, mosaics of interlocking functions, they continually evolve: we change them as our perception of the model deepens, enlarges, generalizes until the model ultimately attains a metastable place within still another model with which we struggle. The source of the exhilaration associated with computer programming is the continual unfolding within the mind and on the computer of mechanisms expressed as programs and the explosion of perception they generate. If art interprets our dreams, the computer executes them in the guise of programs!

http://sicp.iijlab.net/fulltext/xfore.html

序文

教育者, 将軍, 栄養士, 心理学者, 親はプログラムする. 軍隊, 学生, 一部の社会はプログラムされる. 大規模な問題への攻撃はプログラムを次々と利用するが, その殆んどは途中で現れる. プログラムには手元の問題に特有と思われる議論が多い. プログラミングをそれ自身で知的活動と評価するには計算機プログラミングに向わなければならない. 計算機プログラム—その多くを読み, 書きしなければならない. そのプログラムが何に関するものか, どの応用のためかということには関係しない. 関係するのはいかにうまく動作するか, 更に大きいプログラムを作るために他のプログラムといかにうまく適合するかということである. プログラマは部品の完成度と集積の妥当性の両方を求めなければならない. 本書では「プログラム」の利用は, 電子計算機の実行に使うLispの一方言で書いたプログラムの創作, 実行と研究を対象とする. Lispの使用はわれわれが何をプログラムするかではなく, プログラム記述の記法だけに限定し制限する.

本書の主題との関係でわれわれは三つの現象: ひとの心, 計算機プログラムの集積と計算機に関る. 計算機プログラムは心に生れた物理的, 心理的プロセスのモデルである. ひとの経験と思考から生じたこれらのプロセスは数において巨大であり, 細部において複雑であり, 一時には部分的にしか理解されない. それらは計算機プログラムによって永遠に満足出来るようにモデル化されることは殆んどない. 従ってプログラムが注意深く細工した離散的な記号の集積, 相互作用する関数の組合せであっても, 絶えず進化する. われわれはモデルの認知が深まり, 広まり, 一般化するにつれ, まだ苦闘中の他のモデルの間で, モデルが究極的に準安定な場所を得るまで変化を続ける. 計算機プログラミング対応した陽気な気分の源泉は, プログラムとして表現した機構の心の中と計算機の上での絶えまなき解明と, それらが生成する認知の拡大である. 技術が夢を解釈するなら, 計算機はプログラムを装って夢を実行するであろう.
https://github.com/minghai/sicp-pdf による翻訳)
この本の主題は 3 つの事象に焦点を当てます。人の心、コンピュータプロ
グラムの集合、そしてコンピュータです。全てのコンピュータプログラムは人
の心の中で生まれる現実の、または精神的な過程のモデルです。これらの過程
は人の経験と思考から浮かび上がり、数はとても多く、詳細は入り組んで、い
つでも部分的にしか理解されません。それらはコンピュータプログラムにより
稀にしか永遠の充足としてモデル化されることはありません。従って、例え私
達のプログラムが注意深く手作りされた別個の記号の集合だとしても、連動す
る機能の寄せ集めだとしても、それらは絶えず発展します。私達のモデルの知
覚がより深まるにつれ、増えるにつれ、一般化されるにつれ、モデルが究極的
に準安定な位置に逹っするまで変更を行い、その中には依然として私達が格闘
xivするモデルが存在します。コンピュータプログラミングに関連する歓喜の源は
プログラムとして表現された仕組みの心の中とコンピュータ上で絶え間無く続
く発展であり、それにより生まれる知力の爆発です。もし技巧が私達の夢を解
釈するならば、コンピュータはプログラムとして現わされるそれらを実行する
のです!

さて、SICPの序文からいきなり読者へ投げつけられる、この壮大な「ポエム」の意味が理解できる人はいったいどの程度存在するでしょうか?
特に、

Our traffic with the subject matter of this book involves us with three foci of phenomenaOur traffic with the subject matter of this book involves us with three foci of phenomena: the human mind, collections of computer programs, and the computer. Every computer program is a model, hatched in the mind, of a real or mental process.
本書の主題との関係でわれわれは三つの現象: ひとの心, 計算機プログラムの集積と計算機に関る. 計算機プログラムは心に生れた物理的, 心理的プロセスのモデルである.

以下、

If art interprets our dreams, the computer executes them in the guise of programs!
技術が夢を解釈するなら, 計算機はプログラムを装って夢を実行するであろう.

までの部分です。

上記、SICP冒頭の哲学的言及は、この本が、極めて優れた哲学的洞察による知見を有し、真に計算機科学を理解している個人、あるいはそのようなごく限られた少数の精鋭によって執筆されていることを意味します。
そして、このレベルの知見まで到達しながら関数型プログラミングを解説している本はSICPの他にはひとつも存在しません。もちろん今このように指摘している私自身の著書を除いて、といういことになってしまいますが(笑)

もしも貴方が、

「ああなるほどなぁ、さすがすごいことが書いてある!」

と理解して、感銘を受けることが出来るのであれば、貴方はプログラミングの「考え方」を真に理解できている、それがパラダイムシフトであると理解し、イノベーションを起こせるだけの、極めて高い知見、計算機科学においての真の知見を有する、ごく少数の技術者である、ということを意味しています。

もしも貴方が、

「なんだこのポエム?(笑)まあいいや学者のちょっとしたおふざけの戯言だろう、本論とは関係ないのだろうし、とりあえずまっとうに取り合う価値はなさそうだ、無視無視」

としか感じられないのであれば、貴方がいくら、ラムダ式やらなんちゃら、関数型プログラミングの数学的基礎をこねくりまわして開陳することが得意でも、プログラミング、ソフトウェ開発分野の書籍の著者でも、研究者であっても、伝道師であっても、大学の情報系の教授であっても、所詮その程度の技術者・研究者である、ということを意味しています。拙書の文脈で申し上げると「ダサい」大多数のプログラマのひとりである、ということです、念の為。

ちなみに、本稿では今後この「ポエム」という、プログラミング分野の哲学的言及を愚弄する、珍妙で愚かな集団による呪いの言葉を使うことはしません。もう十分と意味と皮肉は伝わったと思うので。
今後はただまっとうに「哲学的言及」と表現することにします。

拙書をちゃんと読んでくれた人ならば、先入観のない気の利いた賢明な読者であれば、ここで
「あれ?」
とひっかかってくれるはずです。

三つの現象

three foci of phenomena: the human mind, collections of computer programs, and the computer.
三つの現象: ひとの心, 計算機プログラムの集積と計算機

  • human mind (ひとの心)
  • collections of computer programs (計算機プログラムの集積)
  • the computer (計算機)

の3つです。

拙書では、

  • 精神
  • 論理
  • 物質

と表現している要素にそのまま相当します。

three foci of phenomena
三つの現象

という表現であることに注意してください。
the computer (計算機)=物質
でさえも、 phenomena、現象である、と表現されているのです。
この表現もそうですが、

If art interprets our dreams, the computer executes them in the guise of programs!
技術が夢を解釈するなら, 計算機はプログラムを装って夢を実行するであろう.

なんていう言及は、まさに拙書で書いたスピノザの汎神論についての言及であると言え、
この物質世界が、human mind (ひとの心)=精神による、夢である、というようなことでこの壮大な世界観をもってSICPの主題を示唆するパラグラフは締めくくられています。

いや、別に自分の著書に無理やりこじつけた我田引水ではありませんよ?
私は、別に著書を執筆するにあたり、SICPを真似したわけでもありませんが、
今回改めて冒頭文を読んで、ああ同じテーマが主題として書かれているな、と思いましたし、
上記SICPの冒頭部分の哲学的言及が理解できる人であれば、拙書でも、ちゃんと読了した上で、同じ説明をしていることが簡単に理解できていることでしょうし、
上記SICPの冒頭部分の哲学的言及が理解できない人であれば、その水準に達していないので、どうでも知的不誠実で無責任な難癖もつけられるだろう、ということにすぎません。

SICPの構成

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-7.html#%_chap_Temp_4
Preface to the First Edition

Our design of this introductory computer-science subject reflects two major concerns. First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute. Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems.

http://sicp.iijlab.net/fulltext/xpre1.html
第一版への前文

この計算機科学の入門科目の設計には二つの主要な関心事があった. 第一に計算機言語は単に計算機に演算を実行させる方法だけでなく, 方法に関する考えを表現する新しい形式的媒体であるという考えを樹立したかった. そこでプログラムは人びとが読むように, そして計算機はたまたま実行するように書くべきである. 第二にこの科目が扱う実質的な材料は, このレベルが特定のプログラム言語の構成の構文でも, 特定の関数を効率よく計算するアルゴリズムでも, アルゴリズムの解釈や計算の基礎でもなく, 巨大なソフトウェアシステムの知的複雑性の制御に使う技法であった.


以下の部分、

First, we want to establish the idea that a computer language is not just a way of getting a computer to perform operations but rather that it is a novel formal medium for expressing ideas about methodology. Thus, programs must be written for people to read, and only incidentally for machines to execute.
第一に計算機言語は単に計算機に演算を実行させる方法だけでなく, 方法に関する考えを表現する新しい形式的媒体であるという考えを樹立したかった. そこでプログラムは人びとが読むように, そして計算機はたまたま実行するように書くべきである.

これはもちろん、
「単に計算機に演算を実行させる方法」 = 命令(手続き)型

「方法に関する考えを表現する新しい形式的媒体であるという考え」=宣言型
のパラダイムの対比をするのが第一の目的である、
そのようにこのコースを設計していることが明示されています。

「そして計算機はたまたま実行するように書くべきである. 」
というのは、イベント駆動、遅延評価のことです。
両者は根本的には同一の概念なので、こうやってまとめて書かれています。
さすがです。バラバラに解説してなんとも思わない巷の本とは格が違います。
著者の高い知見がこういう細かい部分からでも読み取れます。
拙書では「必要なときに必要な分だけ計算する方法」と書いているソレのことですね、もちろん。

Second, we believe that the essential material to be addressed by a subject at this level is not the syntax of particular programming-language constructs, nor clever algorithms for computing particular functions efficiently, nor even the mathematical analysis of algorithms and the foundations of computing, but rather the techniques used to control the intellectual complexity of large software systems.
第二にこの科目が扱う実質的な材料は, このレベルが特定のプログラム言語の構成の構文でも, 特定の関数を効率よく計算するアルゴリズムでも, アルゴリズムの解釈や計算の基礎でもなく, 巨大なソフトウェアシステムの知的複雑性の制御に使う技法であった.

本稿の前半で批判した、2つの書籍が、OCamlという「関数型言語」特有の仕様について多くの章を割いている、ようなことはしたくない、また同様に「効率の良いアルゴリズム」や「計算の基礎」なんていう理論的側面を掘り下げるようなことは、したくない意思表明がなされています。

さすがですね。

SICPを俯瞰して、まず素晴らしいのは、きちんと、関数型プログラミングの
パラダイムシフト前、
パラダイムシフト後、
と章を大きく分けて論じており、
パラダイムシフト前後の対比する作業が丁寧に、綺麗になされていることです。
構成からして、そんじょそこらの訳知り顔の本とは格が違います。

パラダイムシフト後では、パラダイムシフト前の枠組みを土台にして、
逐一比較して論証が進められています。

http://sicp.iijlab.net/fulltext/x100.html
1  手続きによる抽象の構築

は実際に、パラダイムシフト前の説明なので、まったくおもしろくありません。
故に、ここからは本稿で引用すべき秀逸な知見は存在しません。

http://sicp.iijlab.net/fulltext/x200.html
2  データによる抽象の構築
では、
Lispの「言語仕様」、データ構造の基板について説明がされています。

リスト構造と型

Haskellを使って関数型プログラミングを解説している本は、
ほぼ例外なく「型」こそが重要である、と強調しながら始まります。

しかし、このSICPでは、「型」についての言及はありません。
なぜなら、SICPが使うLisp/Schemeは、根本でリストを構築するPair構造があるだけで、型なんてものが存在しないからです。

その代わりに「リスト構造」について長々と書かれています。
逆にHaskell本では、このSICPのように「リスト構造」について長々と書かれることはありません。

以上のような事実は、型であってもリストであっても、別段関数型プログラミングにとっては
本質的でも重要でもない、ってことです。
それは個々の言語の性格に縛られているものであって、関数型プログラミングのパラダイムシフトを理解するのには役立ちません。

実際、Lispのリスト構造については、私は大いなる異論があって、
決定的に間違っていると考えるので、自分でそのリスト構造を真逆にしたデータ構造を基板として、
独自の関数型言語を構築しました。

SICPは前述のとおり、極めて卓越した知見を有する著者によって書かれた書籍ですが、
私個人としてあんまりハマれないのは、素材としてのLisp/Schemeが基板とするデータ構造、
リスト構造がまったく気に入らないからです。

故に、SICPのリスト構造、S式、
データに解説している部分はまるまるすっとばすことにします。

そんな部分は本質でもなんでもないので。

おもしろいのは、もちろんパラダイムシフト後の、

http://sicp.iijlab.net/fulltext/x300.html
3  標準部品化力, オブジェクトおよび状態

以降である、ということです。

『変化している時にも静止している. 』「時間」の概念の理解こそが関数型プログラミングの真の理解への鍵である。

Chapter 3
Modularity, Objects, and State
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-19.html#%_chap_3

3  標準部品化力, オブジェクトおよび状態
http://sicp.iijlab.net/fulltext/x300.html

の冒頭の哲学的言及が、
このパラダイムシフトを象徴的に言い表しています。

(Even while it changes, it stands still.)
(変化している時にも静止している.)

「変化」と「時」、「静止」というキーワードです。

これは、拙書を精読していただいたら、後半、バンバンでてくるキーワードですね。
嫌ほど出てきて、固定観念に縛られ、理解を拒む愚鈍な連中にとっては、苦痛で仕方がない、

アラン・ケイやスティーブ・ジョブズを引き合いに出すくらいはまだ良かったのですが、プラトンのイデアとか汎神論、精神世界と物質世界、大日如来の真言(マントラ)、果てはスピノザの神とか言い始めたときには、ほんとマジ超ヤバいと思いました。
ここまで来ると完璧に宗教の勧誘です。(検閲削除)や(検閲削除)などのように、実際には母親が指導しているのかもしれません。このままではセキヤ君が(検閲削除)になってしまいそうで、読んでいて気が気ではありません。

だとか、

岡部イズム満載で素晴らしい。
読者は…、上級者向けかもしれません。この世界観を楽しめる人には良書でしょう。
むむっ!と唸らせる表現もチラホラ。時間はバージョン番号だ!とか、慧眼で(゚д゚)!
価格も安い!この内容で1,300円は安い。使える言い回しも多数!
値段以上にエンターテイメントの要素は散りばめられています… と思う。
なんといっても、「物質」だの「精神」だの、読者の理解を超越していて頭が下がります。

だとか、

著者本人ですら、自らの書こうとしている内容を理解していないのでしょう。
蒙昧主義的で曖昧な言葉で不理解を誤魔化そうとするため、結果としてとても他人が読める文章にはなっていません。
このため、間違いを指摘しようにもこの駄文を理解するのが面倒で、まともな人なら黙殺するということになります。
何も知らない初心者や、自分に理解できないものを有り難がる愚かな人が、煙に巻かれて本書の内容を信じないことを祈ります。
こんなオカルトが出版まで至ってしまったとは、編集者や出版社の罪は深いなと思います。

だとか、

何というか、フィネガンズ・ウェイクを彷彿とさせるような人智を超えた形而上学的な幻想世界が本書の中では展開されています。
本書のカテゴリは「技術書+ラノベ」ではなく「宗教」や「奇書」と謳ったほうがより正確かもしれません。

と連中がけして理解できない、哲学的要素、あるいは
「計算機科学のほんとうの基礎」の部分です。

これがSICPのキモであり、拙書のキモであり、
本稿のキモです。

「時間」

みなさん、「時間」についてちゃんと考えたことありますか?

SICPの序文にあった、

Our traffic with the subject matter of this book involves us with three foci of phenomena
本書の主題との関係でわれわれは三つの現象

three foci of phenomena: the human mind, collections of computer programs, and the computer.
三つの現象: ひとの心, 計算機プログラムの集積と計算機

  • human mind (ひとの心)
  • collections of computer programs (計算機プログラムの集積)
  • the computer (計算機)

の3つと不可分の概念ですよね。

拙書では、

  • 精神
  • 論理
  • 物質

と表現している要素

の関係を解き明かす鍵が「時間」です。

繰り返しますが、
関数型プログラミングの解説本で、
こういう3つの「現象」と「時間」の関係にきちんと言及しているのは、
SICPと拙書くらいです。

他の本の著者はその水準にまで到達していないので、そんな「時間」という哲学的要素なんて、
プログラミングに、関数型プログラミングの解説に言及する必要なんてまったくない、と思っているのですね。

オブジェクト指向と関数型プログラミングの2つの「世界観」の対比 「時間」の言及

SICPでは、オブジェクト指向と関数型プログラミングの2つの「世界観」の対比が、極めて明確に、丁寧になされています。それは対立するバラダイム「世界観」なんですね。

同じページです。Chapter 3の最初にそれは明示されています。
Chapter 3
Modularity, Objects, and State
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-19.html#%_chap_3

3  標準部品化力, オブジェクトおよび状態
http://sicp.iijlab.net/fulltext/x300.html

To a large extent, then, the way we organize a large program is dictated by our perception of the system to be modeled. In this chapter we will investigate two prominent organizational strategies arising from two rather different “world views” of the structure of systems. The first organizational strategy concentrates on objects, viewing a large system as a collection of distinct objects whose behaviors may change over time. An alternative organizational strategy concentrates on the streams of information that flow in the system, much as an electrical engineer views a signal-processing system.
大きいプログラムを組織化する方法は, われわれがモデル化するシステムをどう認識するかにかなりなところまで左右される. 本章では, いくらか異ったシステム構造の二つの「世界観」から生じる顕著な組織化戦略を研究する. 第一の組織化戦略は オブジェクト(objects)に注目するもので, 巨大システムを, 時間とともに変化するいろいろなオブジェクトの集りと見るものである. もう一つの組織化戦略は,電気技術者が信号処理システムを見るように, システム内を流れる情報の ストリーム(streams)に注目するものである.


本章では, いくらか異ったシステム構造の二つの「世界観」から生じる顕著な組織化戦略を研究する

SICPでは、このように異なるパラダイム、
「世界観」(two rather different “world views”) を対比するのが秀逸な特徴です。
けっして、マルチパラダイムがどうちゃら、とかごちゃまぜにして誤魔化して解説することはしていません。

第一の組織化戦略は オブジェクト(objects)に注目するもので, 巨大システムを, 時間とともに変化するいろいろなオブジェクトの集りと見るものである. もう一つの組織化戦略は,電気技術者が信号処理システムを見るように, システム内を流れる情報の ストリーム(streams)に注目するものである.

その2つの「世界観」とは、

  • オブジェクト(objects)に注目するもので, 巨大システムを, 時間とともに変化するいろいろなオブジェクトの集りと見るもの

  • システム内を流れる情報の ストリーム(streams)に注目するもの

です。もちろん、

前者は「オブジェクト指向」のことであり、ここで、
「時間とともに変化するいろいろなオブジェクトの集り」
ときちんと言及されていることに着目してください。

後者の、ストリーム(streams)とは、『変化している時にも静止している. 』時間を超越した、時間軸を、遅延評価される無限リストとして抽象化する、関数型リアクティブプログラミング(FRP)のことです。

Both the object-based approach and the stream-processing approach raise significant linguistic issues in programming. With objects, we must be concerned with how a computational object can change and yet maintain its identity. This will force us to abandon our old substitution model of computation (section 1.1.5) in favor of a more mechanistic but less theoretically tractable environment model of computation. The difficulties of dealing with objects, change, and identity are a fundamental consequence of the need to grapple with time in our computational models. These difficulties become even greater when we allow the possibility of concurrent execution of programs. The stream approach can be most fully exploited when we decouple simulated time in our model from the order of the events that take place in the computer during evaluation. We will accomplish this using a technique known as delayed evaluation.
オブジェクト準拠の解決法とストリーム処理の解決法は, どちらもプログラミングの重要な言語学的論点を持ち込む. オブジェクト間には, 計算オブジェクトが, どう変化出来, しかも同一性を保持出来るかという点に注意しなければならない. そのため, より機械的だが理論的には制御し難い, 計算の 環境モデル(environment model)の方がよく, 古い置換えモデル(1.1.5 節)を捨てることになる. オブジェクト, 変化, 同一性を扱うことの難しさは, 計算モデルに時を取り込む必要性の根本的な結果である. これらの難しさは, プログラムの並列実行の可能性を許すと大幅に増大する. ストリームの解決法は, 評価中に計算機の中で発生する事象の順序から, モデルでのシミュレートされた時を分離すると, 十分な利用が可能になる. われわれはこれを 遅延評価(delayed evaluation)という技法を使って達成しよう.

次の文章で、この双方の「世界観」について、対比の詳細が論じられています。

時間とともに変化するいろいろなオブジェクトの集りと見る、オブジェクト指向では、
変化、同一性を取り扱うことは難しい。
その根本的な原因として、「 計算モデルに時を取り込む」ことがあり、避けられない結果であると説明されています。

拙書でも、方程式の右辺左辺が異なる、という「枕」(この枕にいちゃもんつける変な人がずっと居る)から、コードの上下左右の時間が一致しないという問題を説明しています。
まずまず、このSICPの説明よりよほどわかりやすく展開しているわけですが、理解を拒む人にはまるで伝わりません。SICPという権威が書いているとこう説明すれば、彼らの脳は理解しはじめるのでしょうか??

さて、オブジェクト指向のもう一方のFRPですが、モデルと計算の時間を分離する、
つまり、拙書では「必要なときに必要な分だけ計算する方法」と一般化してますが、
FRPと表裏一体の遅延評価(delayed evaluation)によって、達成すると説明されています。

もうこれで、わかる人にはすべてわかる概要です。
ここで理解できれば、先を読む必要はたいしてありません。
しかし、このように「時間」とか言い出されたら、そんなことをきちんと自分の頭で考えたことがない人がほとんどなので、たいがいはパニクるわけですね。
そこで、オープンマインドな固定観念に縛られないキラメク知性があるかないかの分かれ目になってくるわけですが、結果は上記いろいろ書いた通りです。

関数型プログラミングの世界観の根幹には、このように時間を抽象化する手法があり、
遅延評価でなければなりません。ここを理解していないひとは、
関数型プログラミングでも、非正格(遅延評価)よりも正格のほうが良い、とか
いい加減なことを言うのですぐ見分けがつきます。どこかの東北大学の教授をはじめOCaml愛好者に非常に多いですね。なぜだか理由はわかりません。
とにかく、彼らがベストとして推奨する解説書でも、OCamlが採用されていて、まるでこのSICPの知見のレベルに到達していないので、仕方ないのかもしれません。非常にレベルが低いです。
 
Haskellがデフォルトで遅延評価になっているのも、当然こういう背景があるからです。
次期Haskellでもなんでも、それが正格評価戦略になる、なんてことはまずありえないでしょう。
いくらなんでもHaskellコミュニティはそんな愚鈍であるわけはないと私は信じています。

時が本質的

SICPの本論というべき、このパラダイムシフト後の、
Chapter 3の中でも、さらに、真骨頂、著者が一番言いたいことは、
もちろんChapter 3の冒頭での哲学的言及が示唆するとおり、

3.4 Concurrency: Time Is of the Essence
http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-23.html#%_sec_3.4
3.4  並列性: 時が本質的
http://sicp.iijlab.net/fulltext/x340.html

という部分です。
繰り返しますが「時」=「時間」Timeが
関数型プログラミングにおいて、本質的 the Essenceであると、
このように節をたてて堂々と解説しているプログラミング本は、拙書以前では、SICPしか存在しません。

We’ve seen the power of computational objects with local state as tools for modeling. Yet, as section 3.1.3 warned, this power extracts a price: the loss of referential transparency, giving rise to a thicket of questions about sameness and change, and the need to abandon the substitution model of evaluation in favor of the more intricate environment model.
局所状態を持つ計算オブジェクトのモデル化の道具としての力を見てきた. だが, 3.1.3節で注意したように, この力には参照透明性の喪失, 同一性と変化についての山なす疑問の到来, そしてより複雑な環境モデルに近づいたために評価の置換えモデルの放棄という代価があった.

要するに、オブジェクト指向は、命令型パラダイムで、破壊的代入する(同一性の喪失)、時間変化する(状態変数をもつ)、時間の同一性がなくなる、参照透明性がなくなる、と山ほど問題が出てきた、ということです。

The central issue lurking beneath the complexity of state, sameness, and change is that by introducing assignment we are forced to admit time into our computational models. Before we introduced assignment, all our programs were timeless, in the sense that any expression that has a value always has the same value. In contrast, recall the example of modeling withdrawals from a bank account and returning the resulting balance, introduced at the beginning of section 3.1.1:

(withdraw 25)
75
(withdraw 25)
50

Here successive evaluations of the same expression yield different values. This behavior arises from the fact that the execution of assignment statements (in this case, assignments to the variable balance) delineates moments in time when values change. The result of evaluating an expression depends not only on the expression itself, but also on whether the evaluation occurs before or after these moments. Building models in terms of computational objects with local state forces us to confront time as an essential concept in programming.
状態, 同一性および変化という複雑性の下に潜む, 中心的論点は, 代入を取り入れたため, われわれの計算モデルに時(time)を認めさせられたということである. 代入を取り入れる前は, プログラムには, 値を持つ式は常に同じ値を持つという意味で, 時はなかった. それに対し3.1.1節の最初に述べた銀行口座からの払出しと, 結果の残高を返すモデルの例を思い起そう:

(withdraw 25)
75

(withdraw 25)
50
同じ式の連続する評価は異る値を生じている. この振舞いは, 代入文の実行(この場合は変数balanceへの代入)が, 値が変る時の一瞬 (moments in time)をかいま見させることによる. 式の評価の結果は, 式そのものに依存するだけでなく, このような瞬間の前か後に起きたかにもよる. 局所状態を持つ計算オブジェクトを使ってモデルを作ろうとすると, プログラミングの本質的な概念として, 時に立ち向わざるを得ない.

ここですね。

(破壊的)代入によって、時間(time)の(不一致の)問題を認めさせられた。

このような瞬間の前か後に起きたかにもよる. 局所状態を持つ計算オブジェクトを使ってモデルを作ろうとすると, プログラミングの本質的な概念として, 時に立ち向わざるを得ない.

大事なところなので、さらにもう一度抜粋すると、

プログラミングの本質的な概念として, 時に立ち向わざるを得ない.

プログラミングの解説者として、これを、
きちんと読者に向かって言えるか言えないか、
もしくは、それ以前の問題として、
ひとりの技術者として研究者として、きちんと理解できているのか?できていないか?です。

破壊的代入、関数型プログラミングへのパラダイムシフトにおいて、
こういう極めて重要で本質的な「時間」の話をしている解説は驚くほど存在しません。

「時間」とは、「プログラミングの本質的な概念」なのです。

本稿の冒頭で引用した、関数型プログラミングの基礎とやらを解説しているらしい
「オススメ本」にも、こういうことはまったく論じられていません。
SICP以外にはないでしょう。あったら是非メールで教えてください。
その本は、おそらくかなり読む価値があります。

この部分の解説については、拙書では、Day3から一部引用すると、

n = n + 1 です。」

「それは『論理』と言えるのかしら?」

宣言型のコードは問題の論理のみを扱い、計算結果は扱わない 問題の論理には結果など含まれていない

セキヤは一瞬、眼を見開いた。
『インクリメント』にはあまりにも慣れ親しんでいて、
『論理』ではないとか、これまで一度も考えたこともなかったからだ。

ようやく意味が理解できたセキヤは悟りを開いた
禅僧のような落ち着いたトーンでサクラに言う。

「なるほど先輩。確かにこれは論理ではないです。
方程式の左辺と右辺の値が異なります。」

「そのとおり。これは論理ではないの。セキヤ君、もしもあなたが
数学の授業でこんな数式を答案用紙に書いて提出したらどうなるかしら?」

「軽く減点されちゃいますね。
そして中学校の数学からやり直せと教師に言われてしまうでしょう。」

「そうね。ありえないわ。
宣言型のコードは問題の論理のみを扱い、計算結果は扱わないの。
覚えているかしら?
問題の論理には結果など含まれていない。」

「あ、そうだったですね!」

論理を破壊する代入『破壊的代入』

 
「では、命令型プログラミングでは、何故、n = n + 1
という論理破綻が普通に起こるのかも理解できるかしら?」

「これは、数学の方程式というよりも、
命令型プログラミングのnn+1を代入する、という命令になっています。
だから、方程式の左辺と右辺は釣り合っていないのだと思います。」

「そうね。こういう論理を破壊するような代入のやりかたを特に
破壊的代入って呼んだりするわね。
宣言型のコードの上ではやってはいけないことよ。
理由は単に論理破綻だから。」

「破壊的代入ですか。」

「破壊的代入は計算の命令なので命令型のコードになる。」

命令型プログラミングのコードの上下左右に、同じ変数が異なる時間をもって異なる値で存在している混乱

「命令型のコードでの問題は、
『物質世界』の時間要素がコードの中に紛れ込んじゃうことよ。
n = n + 1という方程式の
右辺にあるnは、命令前の値。
左辺にあるnは、命令後の値。

命令前と命令後、つまり『時間』が違うの。
方程式という論理に『時間』が違う『同じ変数』があり、
されてしまっている。」

「あ、そう言えば、先輩、命令型のプログラミングのコードは、
とても単純に、上から下に順序良く順番に実行されていく、
つまり、上から下の方向に流れていく、という『フロー』でしたけど、
これも上と下では命令前と後なので『時間』が違うことになりますね。」

「そう、全くそのとおりね。
n = n + 1
と命令してみる。その下の行で、
n = 9
と命令してみる。
上で命令した後、下で命令するので、もちろん時間が異なるわ。」

「命令型プログラミングでそういうのはいつも無意識に普通にやります。」

nと言う同じ変数なのに、
コードの左右で時間が異なる、
コードの上下で時間が異なる、
コードの上下左右で時間が異なる、
そしてその上下左右の時間それぞれで値が異なる。

命令型のコードの上下左右で、同じ変数が異なる時間をもって
異なる値をもって存在しているという混乱。」

セキヤは思い当たることがあったので、
特訓の復習内容からフレーズをひっぱりだした。
「先輩、このことって
フローがバグの元凶であるのと同様に、状態変数もバグの元凶
っていうやつのことですね?」

「ああそうそう、今それを言おうと思ったのよ。
命令型のコードで、変数の破壊的代入をしていくのが状態変数ということ。
そもそも、『状態』っていうのはなんのことか?というと、
時間変化しながらその時々の値が違うっていう意味だから。」

「先輩、状態変数がバグの元凶になる、
っていう理由についてもうちょっと知りたいです。」

「そうね、命令型のコードで時間変化する状態変数の問題は
そのものずばり、命令型のコードの上下左右の位置によって、
時間が違う、値が違うってことなのね。

だってね、パット見て、n = n + 1
この左辺と右辺の同じn『時間』が違うってことがわかる?」

「うーん、これだけならなんとなくわかるかもしれません。」

「なんとなくとか無意識には理解しながらやってるでは全然ダメなのよ。」

「多分そうなんでしょうね。」

「だって、このnはこの式の部分だけには留まらず、
コードのあっちへ行ったり、こっちへ行ったり、そのあちこちで、
あらゆる場所で破壊的代入が繰り返される運命なんでしょ?」

「そうですね。」

「命令型のコードのありとあらゆる場所で、
この同じnが所属する時間が異なり、値が異なる。
おまけに、他のsっていう破壊的代入が繰り返される状態変数があって、
そのsの時間もまったくnとは無関係に独立して存在する。
こういうnとかsみたいにそれぞれバラバラに
お互い共有のしようもない時間をもって変化し続ける
状態変数が無数に存在することになる。
セキヤ君、あなたはこの状況をコントロールしていると言えるかしら?」

「先輩、そんなのは絶対無理です。」

命令型のコードで時間変化する状態変数っていうのは、
コントロールなんてできない存在だ、
ってもう最初の最初で認識しておいたほうがいいわね。」

と解説していますが。そんな難しい解説なんでしょうか??
これについて、珍妙な揚げ足取りにもなっていない中傷があって、

「n = n + 1 は論理破綻」か?
さて、「宣言型」の話が長くなってしまいましたから、次は軽く済ませましょう。
なるほど先輩。これは確かに論理ではないです。方程式の左辺と右辺の値が異なります。(……)宣言型のコードは問題の論理のみを扱い、計算結果を扱わないの。 (p. 144)
既にAmazonのレビューで指摘されている通り、命令型プログラミング言語でのn = n + 1というステートメントは、等式・方程式ではありません。そもそも=は等価性ではなくassignmentを表しており、また左辺のnは場所・記憶域を、右辺のnはそこに格納された値を指しています4。つまるところ、命令型プログラミング言語でのn = n + 1は端から方程式でもなんでもないので、登場人物セキヤによって「論理ではない」と言われるいわれもないのです。記号が←でありさえすれば、n ← n + 1となって、このような誤解を産まなかったのかもしれません。
こうしてみると、登場人物サクラが力説する
命令型のコードでの問題は、『物質世界』の時間要素がコードの中に紛れ込んじゃうことよ。n = n + 1という方程式の右辺にあるnは命令前の値。左辺にあるnは、命令後の値。命令前と命令後、つまり『時間』が違うの。方程式という論理に『時間』が違う『同じ変数』があり、=とされてしまっている(p. 145)
という主張がまったくの的外れであることも明らかになります。まずそもそもこのコードは方程式ではありません。しかも、左右でnの指示するものが異なっているのであり5、左辺はあくまで「場所」であって「命令後の値」なのではありません。むしろ両辺のnは同じ時間に属しています。ある時点でのある領域と同時にそこに収納されている値が取り扱われているのですから6。
なお、関数型のコードとして見た場合にも、これが「方程式」ではなく項書換えシステムの書き換え規則n → n + 1であるという点はDay2のレビューに述べたとおりです。
こういう論理を破壊するような代入のやり方を特に破壊的代入って呼んだりするわね。(p. 144)
……そういうことじゃないと思います。

ということをAmazonレビューでも、Qiitaの捨てアカウントでも延々と言っている輩が存在します。
というか、セキヤは、

「これは、数学の方程式というよりも、
命令型プログラミングのnn+1を代入する、という命令になっています。
だから、方程式の左辺と右辺は釣り合っていないのだと思います。」

と、はっきり書いてるし。本書を読んだことがない読者にはバレないとおもって、延々と嘘を書いているわけですね。それともなんだろう?一回思い込んだら、何も見えなくなるのか?
こういう思い込みが尋常に激しい輩を相手に物事を解説するのは不可能です。

さて、このように、プログラミングの本質的な概念を論じるときには、
「時間」「われわれの物理世界」という概念について、きちんと検討せねばなりません。
それは絶対に避けられない論点なのです。

SICP同じページ、続く文章、

We can go further in structuring computational models to match our perception of the physical world. Objects in the world do not change one at a time in sequence. Rather we perceive them as acting concurrently – all at once. So it is often natural to model systems as collections of computational processes that execute concurrently. Just as we can make our programs modular by organizing models in terms of objects with separate local state, it is often appropriate to divide computational models into parts that evolve separately and concurrently. Even if the programs are to be executed on a sequential computer, the practice of writing programs as if they were to be executed concurrently forces the programmer to avoid inessential timing constraints and thus makes programs more modular.

われわれは更に, 計算モデルを, われわれの物理世界の概念に一致させる構造化に進むことが出来る. 世界にあるオブジェクトは, 一時に一個ずつ順々に変るわけではない. それらはむしろ, 並列的に(concurrently)—一斉に起きると思っている. 従ってシステムを, 並列的に動く計算プロセスの集りとしてモデル化するのが自然なことが多い. モデルを, 別々の局所状態を持つオブジェクトを使って組織化することで, プログラムを部品化出来たのと同様に, 計算オブジェクトを別々に, しかも並列的に進化する部分に分割するのも適切であることが多い. プログラムは逐次型計算機で実行することになるにしても, プログラムを並列的に実行されるものとして書く習慣は, プログラマに非本質的な時の制約を避けさせ, プログラムをより部品化的にさせる.

というのは、拙書では、Day4、

『物質世界』全部まるごとひとつの『まとまり』にしてバージョンナンバーをつけたら?それは『時刻』になる

「セキヤ君、この私たちが暮らす、『物質世界』には、
バージョンナンバーがあるのは知ってる?」

「え?どういうことですか?
OSやアプリのバージョンとかあるのは知ってますけど、
『物質世界』のバージョンですか?」

「『時刻』よ。」
「あ。」

『物質世界』全部まるごとひとつの『まとまり』にして
バージョンナンバーをつけたものが『時刻』よ。」

World@2015/07/12-14:32:00
World@2015/07/12-14:32:01
World@2015/07/12-14:32:02
World@2015/07/12-14:32:03
World@2015/07/12-14:32:04

表計算アプリのA1…..B1…..は、すべて同じ『時刻』という世界のバージョンナンバーを共有しているイミュータブルなデータ

「『物質世界』全部まるごとひとつの『まとまり』にして
バージョンナンバーをつけたものが『時刻』。

関数型プログラミングで、
動的でミュータブルなGUIという『物質世界』を取り扱うためには、
この『物質世界』のイミュータブルなバージョンナンバーである、
『時刻』という考え方に着目する
というより、論理的に、道理として、着目することになる。」

「なるほど、大変興味深いです。」

「表計算アプリのA1…..B1…..というUIは
その『物質世界』全部まるごとひとつの『まとまり』のうちの
ごく一部の部品である、ということになるわよね?」

「ああそうなるのかあ。」

「つまり、表計算アプリのA1…..B1…..は、
すべて同じ『時刻』という世界のバージョンナンバーを共有している
イミュータブルなデータね。

表計算アプリのA1…..B1…..は、すべての『時刻』において、
同じ『時刻』という世界のバージョンナンバーを共有している。
あたりまえのように聞こえちゃうけれども、
宇宙の構造として原理的にそうなっているわけ。」

A1@14:32:00 B1@14:32:00
A1@14:32:01 B1@14:32:01
A1@14:32:02 B1@14:32:02
A1@14:32:03 B1@14:32:03
A1@14:32:04 B1@14:32:04

UIは、『物質世界』全部まるごとひとつの
『まとまり』のうちのごく一部の部品で、
『時刻』という『まとまり』のバージョンナンバーを共有している
のですか。なるほどなあ。」

というように、かなり懇切丁寧に解説申しています。
SICPのざっくりとした説明よりも、かなり具体的に書いているつもりです。

SICPの章のくくり、

残念ながら, 代入で取り込んだ複雑性は, 並列性の前には, 更に問題になる. 並列実行は, 世界が並列に動いているからか, 計算機がそうだからかで, われわれの時の理解を更に複雑にしている.

破壊的代入とは、並列的な物理世界で時間の一致を破壊するので、すべきではない、ということです。

ストリーム (SICP)

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html
http://sicp.iijlab.net/fulltext/x350.html

3.5 Streams
We’ve gained a good understanding of assignment as a tool in modeling, as well as an appreciation of the complex problems that assignment raises. It is time to ask whether we could have gone about things in a different way, so as to avoid some of these problems. In this section, we explore an alternative approach to modeling state, based on data structures called streams. As we shall see, streams can mitigate some of the complexity of modeling state.
3.5 ストリーム
モデル化の道具としての代入について十分理解し, 代入が惹き起す複雑な問題も認識した. これらの問題の幾分かを回避するため, 別の方向へいった方がよかったか考えてみよう. 本節では, 状態をモデル化する, ストリーム (streams)というデータ構造に基づいた, もう一つの解決法を調べてみる. すぐ分るように, ストリームは状態のモデル化の複雑さの幾分かを軽減する.

いよいよ、SICPで、関数型プログラミングのパラダイムにおいて、
「時間」の問題をいかに鮮やかに解決するか?その具体的な解法が示されます。

Let’s step back and review where this complexity comes from. In an attempt to model real-world phenomena, we made some apparently reasonable decisions: We modeled real-world objects with local state by computational objects with local variables. We identified time variation in the real world with time variation in the computer. We implemented the time variation of the states of the model objects in the computer with assignments to the local variables of the model objects.
少し後戻りして, この複雑さがどこから来たか反省しよう. 実世界の現象をモデル化しようとして, 明らかに合理的な決定をいくつかした: 局所状態を持つ実世界のオブジェクトを, 局所変数を持つ計算オブジェクトでモデル化した. 実世界の時間変化を計算機内の時間変化と同一視した. モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.

オブジェクト指向の「複雑さ」の「レビュー」=「反省点」が考察されます。

実世界の時間変化を計算機内の時間変化と同一視した

これがまずいんですね。
そして、その大前提として、
「実世界の時間変化」っていう論点化がちゃんと出来ているかどうかです。
ほとんどの論者、解説文では、こんなこという水準に達していませんから、そもそもこういう発想、考察自体が無理です。

モデルオブジェクトの状態の時間変化を, 計算機内では, モデルオブジェクトの局所変数への代入で実装した.

秀逸な知見です。
状態変数への破壊的代入を繰り返すことで、そのモデルの時間変化に対応させている。
破壊的代入、っていうのはモデルの時間変化のためにやっていた、
こういう「自覚」をもってるプログラマって今、日本に何人くらいいるんでしょうか?
拙書の読者には随分いるでしょうから、少しは増えたかもしれません。

Is there another approach? Can we avoid identifying time in the computer with time in the modeled world? Must we make the model change with time in order to model phenomena in a changing world? Think about the issue in terms of mathematical functions. We can describe the time-varying behavior of a quantity x as a function of time x(t). If we concentrate on x instant by instant, we think of it as a changing quantity. Yet if we concentrate on the entire time history of values, we do not emphasize change – the function itself does not change.52
(52 Physicists sometimes adopt this view by introducing the “world lines” of particles as a device for reasoning about motion. We’ve also already mentioned (section 2.2.3) that this is the natural way to think about signal-processing systems. We will explore applications of streams to signal processing in section 3.5.3.)
これ以外の解決法があるだろうか. 計算機内の時をモデル世界の時と同一視するのを避けることは出来るだろうか. 変化する世界の現象をモデル化するのに, モデルを時と共に変化させなければならないか. これらの論点を数学関数を使って考えてみよう. 量xの時間変化する振舞いを, 時の関数x(t)と書くことが出来る. xを時刻時刻に注目すれば, それを変化する量だと思う. しかし値の全時間の歴史に注目すれば, 変化を強調しない—関数それ自身は変らない.52
(52 物理学者は運動に関する推論の道具として, 粒子の 「世界線」を導入することでこの視点を採用する時がある. われわれは(2.2.3 節で)これは信号処理システムを考える自然な方法であると述べた. 3.5.3節でストリームの信号処理への応用を述べる.)

SICPの著者は、

物理学者は運動に関する推論の道具として, 粒子の 「世界線」を導入することでこの視点を採用する時がある.

この言及以外に何度も物理学の知見を披露しており、物理学の素養があります。
ここが非常に重要な論者の素養による洞察であり、
「計算機科学」を数学理論ではなく、我々が棲息する物質世界の一部の事象として捉えています。

これが重要。
ほとんどの「計算機科学」の研究者、あるいは技術者にはこの視点が徹底的に欠落しており、
だから、結構ろくでもない状況になっています。話してもまったく通じない。
ちゃんと勉強してるの?って私などは思ってしまうんですが。
知識としてあるだけで、異なる分野の関連を結び付けられないのであれば、それは知性のセンスのなさです。

私はだからこそ、拙書のDay1の関数型プログラミングのフックが終わった後の
Day2の最初部分で、もういきなり、物質世界のことを書き始めました。

コンピュータとは、ハードウェアとソフトウェアで成り立っている不思議な存在であり、
計算という事象も、物質世界で起こっているのである、論理世界の中で完結するものではない、
とさんざん強調しましたが、これを上記の書評のように「わかりやすい」充実した内容だ、
と素直に理解できる知性もあれば、何を言っても伝わらない愚鈍があったのは、
まさに拙書で予想したとおりとなりました。

この「計算機科学」が「物質世界」の挙動を考慮する必要があり、
物理学の知見と関係があると示すのは、最終的にはもちろん、このように最終部分のFRPのことまで一本の線をつなぐためには絶対に必要な地ならしでした。

そして、この物理学者が、物理で記述するのが、

これらの論点を数学関数を使って考えてみよう.
xの時間変化する振舞いを,
時の関数x(t)と書くことが出来る.
xを時刻時刻に注目すれば, それを変化する量だと思う.
しかし値の全時間の歴史に注目すれば, 変化を強調しない—関数それ自身は変らない.52

という結構、中学でも高校でも習うごくごく物理の基礎的な数式展開です。

関数それ自身は変らない.

これは要するに、時間変化であろうがなんであろうが、
時間変数=時刻にたいして、
物質世界はイミュータブルな関数として記述される、ということです。

そして、この時間変数の関数をプログラミングで実現する技術こそが、
何度も話しているFRPであり、拙書のDay4で具体的な技術として解説している、Facebook-Reactです。
もちろん、Facebook-Reactでは概念実証としては、極めて不十分ですから、
より時間の関数であることを完全に概念実証した自前の

timecomponent

を提示しました。計算可能な任意の時刻の値にイミュータブルにアクセスして
値を返す関数です。

そして、このFRP技術を可能にするのが、
まさに時間軸を無限の並びとして扱う、遅延評価なんですね。
SICPでは続いて、以下のように論じられています。

If time is measured in discrete steps, then we can model a time function as a (possibly infinite) sequence. In this section, we will see how to model change in terms of sequences that represent the time histories of the systems being modeled. To accomplish this, we introduce new data structures called streams. From an abstract point of view, a stream is simply a sequence. However, we will find that the straightforward implementation of streams as lists (as in section 2.2.1) doesn’t fully reveal the power of stream processing. As an alternative, we introduce the technique of delayed evaluation, which enables us to represent very large (even infinite) sequences as streams.
時を離散ステップで測るなら, 時間関数を(無限かも知れぬ)並びとしてモデル化出来る. 本節ではモデル化しようとするシステムの時間史を表現する並びを使い, 変化をモデル化する方法を見よう. そのためにストリーム (streams)という新しいデータ構造を取り入れる. 抽象の視点からはストリームは単なる並びである. しかしストリームを(2.2.1節のように)リストとして簡明直截に実装しても, ストリーム処理の力を十分に発現出来ない. その代り 遅延評価(delayed evaluation)の技法を取り入れよう. それを使えば非常に長い(無限でさえある)並びでもストリームとして表現出来る.

ストリームは遅延リスト

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.1
http://sicp.iijlab.net/fulltext/x351.html

3.5.1 Streams Are Delayed Lists
3.5.1 ストリームは遅延リスト

In general, we can think of delayed evaluation as demand-driven'' programming, whereby each stage in the stream process is activated only enough to satisfy the next stage. What we have done is to decouple the actual order of events in the computation from the apparent structure of our procedures. We write procedures as if the streams existedall at once” when, in reality, the computation is performed incrementally, as in traditional programming styles.
一般に遅延評価は 「要求駆動」プログラミングと考えることが出来る. ストリーム処理の各段階は次の段階を満足させるのに十分なだけ起動される. これまでやったのは計算における事象の実際の順を, 手続きの見かけの構造と 切り離すことである. われわれは伝統的なプログラミングスタイルでのように, ストリームがあたかも「みんな一緒に」存在したかのように手続きを書くが, 実際は計算が漸進的に実行される.

ここにも、SICPの著者のたいへん秀逸な知見があります。

遅延評価とは、一般化すると、「要求駆動」=イベント駆動(ドリブン)のプログラミングである、ということです。
これは、もちろん拙書でも、同じであるからこそ、
「必要なときに必要な分だけ計算する方法」とわざと書いていて、
それは、「イベント駆動」と同じである、
論理と計算が分離されたやり方である、そして宣言型である、と何度も説明しています。
そして、しつこいようですが、何度も言いたいのですが、
こういう解説は、拙書とSICP以外には見たことがありません。

無限ストリーム

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.2
http://sicp.iijlab.net/fulltext/x352.html

3.5.2 Infinite Streams
3.5.2 無限ストリーム

60 Eratosthenesは紀元前三世紀のアレキサンドリアギリシャの哲学者で, 地球の周囲の長さを初めて正確に測ったので有名である. 夏至の日の正午の影を観測して計算した. Eratosthenesの篩は, 古典的ではあるが, 特別目的のハードウェア「篩」の基礎を作った. それは最近まで大きな素数を探す, 存在する最も強力な道具であった. 70年代からはしかし, 1.2.6節で論じた 統計的技法の発展で置き換えられている.

別にこの節では本稿で特筆する箇所はありませんが、
とりあえず、このSICPの著者は、物理学、哲学の知見がしっかりとある、ということです。

関数的プログラムの部品化度とオブジェクトの部品化度

ここは、Chapter3の最後です。
SICPの関数型プログラミング解説の集大成として書かれています。

http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-24.html#%_sec_3.5.5
http://sicp.iijlab.net/fulltext/x355.html

そしてもちろん、期待に違わず、型破りで「穏当ではない考え方」が堂々と開陳されています。

A functional-programming view of time
Let us now return to the issues of objects and state that were raised at the beginning of this chapter and examine them in a new light. We introduced assignment and mutable objects to provide a mechanism for modular construction of programs that model systems with state. We constructed computational objects with local state variables and used assignment to modify these variables. We modeled the temporal behavior of the objects in the world by the temporal behavior of the corresponding computational objects.
Now we have seen that streams provide an alternative way to model objects with local state. We can model a changing quantity, such as the local state of some object, using a stream that represents the time history of successive states. In essence, we represent time explicitly, using streams, so that we decouple time in our simulated world from the sequence of events that take place during evaluation. Indeed, because of the presence of delay there may be little relation between simulated time in the model and the order of events during the evaluation.
時の関数型プログラミング的視点
本章の初めで持ち上がったオブジェクトと状態の論点に戻り, 新しい光でそれらを調べて見よう. 状態を持つシステムをモデル化するプログラムの部品化的構成の機構を提供するものとして, 代入と可変オブジェクトを取り入れた. 局所状態変数を持つ計算オブジェクトを構成し, これらの変数を修正するのに代入を使った. 世の中のオブジェクトの時間的振舞いを, 対応する計算オブジェクトの時間的振舞いでモデル化した.
ストリームが局所状態を持つオブジェクトをモデル化するもう一つの方法を提供することを見てきた. あるオブジェクトの局所状態のような変りゆく量を, 順次の状態の時間的歴史を表現するストリームを使ってモデル化する. 要するにストリームを使って時を明確に表現し, シミュレート中の時を評価中に起きる事象の並びから切り離す. 実際delayが存在するので, モデルのシミュレートされた時と評価中の事象の順の間にはあまり関係がない.

ここまでは、「時間」と関数型プログラミングの世界観の復習です。

興味深い記述が続くのは以下です。

Stream-withdraw implements a well-defined mathematical function whose output is fully determined by its input. Suppose, however, that the input amount-stream is the stream of successive values typed by the user and that the resulting stream of balances is displayed. Then, from the perspective of the user who is typing values and watching results, the stream process has the same behavior as the object created by make-simplified-withdraw. However, with the stream version, there is no assignment, no local state variable, and consequently none of the theoretical difficulties that we encountered in section 3.1.3. Yet the system has state!
This is really remarkable. Even though stream-withdraw implements a well-defined mathematical function whose behavior does not change, the user’s perception here is one of interacting with a system that has a changing state. One way to resolve this paradox is to realize that it is the user’s temporal existence that imposes state on the system. If the user could step back from the interaction and think in terms of streams of balances rather than individual transactions, the system would appear stateless.73
stream-withdrawは出力が入力によって完全に決定される, 明確に定義された数学的関数を実装する. しかし入力\linebreakamount-streamが, 利用者が入力した順次の値のストリームであり, 結果としての残高のストリームが表示されているとしよう. すると値を入力し, 結果を眺めている利用者の見え方からは, ストリーム処理はmake-simplified-withdrawで作り出されたオブジェクトと同じ振舞いをする. ところがストリーム版には代入も局所状態変数もない. 従って3.1.3節で直面した理論的困難は一つもない. しかもシステムには状態が存在する!
これは実に注目すべきことだ. stream-withdrawが, その振舞いが変化しない, 明確に定義された数学的関数を実装したとしても, ここでの利用者の認識は, 変化する状態を持つシステムと対話しているという認識である. この矛盾を解く一つの方法は, システムに状態を持たせるのは, 利用者の時間的存在であると認めることである. 利用者が対話から一歩下って個々の取引きではなく, 残高のストリームを使って考えるとすれば, システムは状態なしに見えてくる.73

これはもちろんFRPで「入出力」を取り扱うトピックなのですが、

from the perspective of the user
利用者の見え方からは

という表現が出てきます。

Yet the system has state! This is really remarkable.
しかもシステムには状態が存在する! これは実に注目すべきことだ

と、代入も状態変数もないのに、システムには状態が存在する!
それは実に注目すべきことである、ことが remarkable.であると、感嘆して強調されています。
これは、本当に大事なことなんですね。関数型プログラミングのパラダイムとしては。
最終節としてふさわしい総括です。

Similarly in physics, when we observe a moving particle, we say that the position (state) of the particle is changing. However, from the perspective of the particle’s world line in space-time there is no change involved.
物理学でも同様で, 動いている粒子を観測する時, われわれは粒子の位置(状態)は変化しているという. しかし, 粒子の時間空間の 世界線の視点からは, 変化はない.

関数型プログラミングは、状態をもつべきでない、イミュータブルなモデルであり、
物質世界も、物理学の知見でも、
「時刻」という時間変数と関数で記述される、イミュータブルなモデルであるので、
それはなんの齟齬も生まれません。世界はイミュータブルである。
これが、このChapter3の冒頭の、哲学的引用
(変化している時にも静止している.)
というテーマが示す結論です。
そして、これが、拙書の一大テーマで、延々と説明していることです。

続いて、SICPはさらなる深みに踏み込みます。

ここでの利用者の認識は, 変化する状態を持つシステムと対話しているという認識である. この矛盾を解く一つの方法は, システムに状態を持たせるのは, 利用者の時間的存在であると認めることである.

利用者の「認識」と矛盾する!
つまり、利用者にとっては、システムと現実にリアルタイムに対話しており、
世界は動いている、と認識しているわけだが、
モデル的には世界は静止している。
矛盾だ、というわけです。

この矛盾を解決するには、

it is the user’s temporal existence that imposes state on the system.
システムに状態を持たせるのは, 利用者の時間的存在である
ユーザの一時的な存在がシステムに状態を与えている (PDF版)

つまり、利用者だって、その止まっている時間関数で記述される世界の一部なんだよ?
the user’s temporal existence
である、と論じられています。

利用者の「認識」とは、時間関数で記述される、静止した物質世界の一部である、
利用者の一時的な存在によってもたらされる。

An example of a place where the object viewpoint fails is quantum mechanics, where thinking of things as individual particles leads to paradoxes and confusions. Unifying the object view with the functional view may have little to do with programming, but rather with fundamental epistemological issues.
オブジェクトの視点が失敗する場所の例は, 量子力学で, そこでは物を個々の粒子と考えると矛盾と混乱に陥る. オブジェクトの視点と関数的視点の統合は, プログラミングより基本的認識論に見るべきものがある.

オブジェクトの視点が失敗する場合の例は量子力学です。そこでは物を個別の点と
して考えることは逆説と混乱を招きます。オブジェクトの視点を関数型の視点と統一す
ることはプログラミングとはあまり関係が無いかもしれません。
しかしより根本的な認識論の問題と関係するのです。(PDF版)

これが、SICPのChapter3の一番最後に記述されている内容です。

計算機科学のほんとうの基礎には、根本的な、epistemological issues 認識論の問題と関連がある。

認識論(にんしきろん、独: Erkenntnistheorie、英: Epistemology、仏: Épistémologie)は哲学の一部門である。存在論ないし形而上学と並ぶ哲学の主要な一部門とされ、知識論(英: theory of knowledge)とも呼ばれる。認識、知識や真理の性質・起源・範囲(人が理解できる限界など)について考察する。日本語の「認識論」は独語の訳語であり、日本では人・人間を考慮した場合を主に扱う。英語と仏語の語源は「知」(希: epistēmē) + 「合理的な言説」(希: logos) 。フランスでは「エピステモロジー」という分野があるが、20世紀にフランスで生まれた科学哲学の一つの方法論ないし理論であり、日本語では「科学認識論」と訳される。

実際、Wikipedeiaで、認識論の項目を見ると、拙書で名前を出した哲学者の名前がズラリと並びます。

2 哲学的認識論の歴史
2.1 前史
2.1.1 古代
2.1.1.1 プラトン
2.1.1.2 アリストテレス
…….
2.2.2 デカルト革命
2.3 認識の起源
2.3.1 合理主義
2.3.1.1 デカルト
2.3.1.2 マルブランシュ
2.3.1.3 スピノザ

これこそが、SICPの序文でも表明されている一大テーマです。再掲してみましょう。

Our traffic with the subject matter of this book involves us with three foci of phenomena: the human mind, collections of computer programs, and the computer. Every computer program is a model, hatched in the mind, of a real or mental process. These processes, arising from human experience and thought, are huge in number, intricate in detail, and at any time only partially understood. They are modeled to our permanent satisfaction rarely by our computer programs. Thus even though our programs are carefully handcrafted discrete collections of symbols, mosaics of interlocking functions, they continually evolve: we change them as our perception of the model deepens, enlarges, generalizes until the model ultimately attains a metastable place within still another model with which we struggle. The source of the exhilaration associated with computer programming is the continual unfolding within the mind and on the computer of mechanisms expressed as programs and the explosion of perception they generate. If art interprets our dreams, the computer executes them in the guise of programs!
本書の主題との関係でわれわれは三つの現象: ひとの心, 計算機プログラムの集積と計算機に関る. 計算機プログラムは心に生れた物理的, 心理的プロセスのモデルである. ひとの経験と思考から生じたこれらのプロセスは数において巨大であり, 細部において複雑であり, 一時には部分的にしか理解されない. それらは計算機プログラムによって永遠に満足出来るようにモデル化されることは殆んどない. 従ってプログラムが注意深く細工した離散的な記号の集積, 相互作用する関数の組合せであっても, 絶えず進化する. われわれはモデルの認知が深まり, 広まり, 一般化するにつれ, まだ苦闘中の他のモデルの間で, モデルが究極的に準安定な場所を得るまで変化を続ける. 計算機プログラミング対応した陽気な気分の源泉は, プログラムとして表現した機構の心の中と計算機の上での絶えまなき解明と, それらが生成する認知の拡大である. 技術が夢を解釈するなら, 計算機はプログラムを装って夢を実行するであろう!
https://github.com/minghai/sicp-pdf による翻訳)
この本の主題は 3 つの事象に焦点を当てます。人の心、コンピュータプロ
グラムの集合、そしてコンピュータです。全てのコンピュータプログラムは人
の心の中で生まれる現実の、または精神的な過程のモデルです。これらの過程
は人の経験と思考から浮かび上がり、数はとても多く、詳細は入り組んで、い
つでも部分的にしか理解されません。それらはコンピュータプログラムにより
稀にしか永遠の充足としてモデル化されることはありません。従って、例え私
達のプログラムが注意深く手作りされた別個の記号の集合だとしても、連動す
る機能の寄せ集めだとしても、それらは絶えず発展します。私達のモデルの知
覚がより深まるにつれ、増えるにつれ、一般化されるにつれ、モデルが究極的
に準安定な位置に逹っするまで変更を行い、その中には依然として私達が格闘
xivするモデルが存在します。コンピュータプログラミングに関連する歓喜の源は
プログラムとして表現された仕組みの心の中とコンピュータ上で絶え間無く続
く発展であり、それにより生まれる知力の爆発です。もし技巧が私達の夢を解
釈するならば、コンピュータはプログラムとして現わされるそれらを実行する
のです!

  • human mind (ひとの心)
  • collections of computer programs (計算機プログラムの集積)
  • the computer (計算機)

拙書では、

  • 精神
  • 論理
  • 物質

と表現して論じている要素、

three foci of phenomena
三つの現象

です。これは、哲学史で考えると、
スピノザ哲学の汎神論であることは、拙書の読者にとっては、
今更また説明の必要はないでしょう。

このSICPが到達している、物質、精神、時間を超越する知見とは、
文字通り「神の眼」のレベルであり、
この世界観をもってプログラミングをしている技術者はほとんど存在しません。

まあ、「ダサい」状況だなあ、と思ったから、いろいろ書いたわけです。
もちろん当初の想定どおり、一部の訳知りからは、案の定、輪をかけて「ダサい」反応が広がったわけですが。
「無知の知」だのいろいろ牽制したのですが、無駄です。
通じる人には通じて、感動、パラダイムシフトを体験してもらうことができるが、
通じない人には通じない。愚鈍な知性にどういうINPUTを与えてもすべて無駄です。
それこそが拙書のテーマです。

そして最後に繰り返しとなりますが、拙書では、このようなSICPの権威を引用することはしませんでした。
普通の知性にとっては不要であるからだし、そんなことはすべきではないからです。

今回、無駄なことをした、と思っていますが、
権威主義の愚鈍な知性に、今回の権威主義による解説が通用しないとすれば、
もう本当にこちらには打つ手はありません。

まずまず、「岡部イズム」だの「神になりたかった男」だの、
そういう自分の無知無学を、押し付けないでもらいたいというか、
そういうのは、先達のビジョナリーに失礼だと思うんですよね。
私の知見なんて、彼らの偉大なる知見の上で、ささやかに構成されているにすぎないので。

だいたい、ちょっとばかり物理学と哲学の基礎があって、気が利いたら、
ちょっと触りを話しただけでも通じる「はず」のレベルの話です。
計算機科学が、数学だけで完結している、とか、まあ普通に考えたらありえないですが、
訳知り顔の愚鈍な知性にとっては、まずそのへんの思い込みを捨てることからはじめないと、
どうしようもないのだろうな、とは想像しています。

以上、
「計算機科学のほんとうの基礎」です。

今回はSICPの権威を借りることにひたすらフォーカスしたので、
次回、気が向いたら、自分自身の言葉で再度展開する、かもしれません。
だから一応【その1】です。

というか、SICPが刊行されたのは、1985年です。
今は、2015年ですから、もう30年も前です。
一体何をやっているんでしょうか?

・99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その2】関数型プログラミングのイミュータブルな世界観とイミュータブルな実世界を完全に統合

Popular Posts