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年4月30日木曜日

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

美しき国のガラパゴス・ネットスラング

「ガラケー」

かくも簡潔で語呂の良い、もはやネットスラングを超越した、広く市民権を得た言葉ですね。

「ガラケー」あるいは、ガラパゴス・ケータイとは、もちろん「グローバリズム」の潮流の中で出てきたネットスラングです。

「グローバリズム」とは特に歴史と伝統が深く豊かな我が国日本において、賛否が別れる考え方です。

音楽に国境はない、とは言いますが、それでもガラパゴス故に生まれた「J-POP」など、グローバリズムの中にあっても日本独自の優位性が発揮されているものがあります。

しかし学問の世界、特に数学やプログラミング技術は、国境がない真のグローバリズムの世界であると思います。

プログラミング技術の世界には国境はない真のグローバリズムの世界なのですが、日本のプログラミング技術の世界では、昨今「ガラパゴス」になっているようです。
少なくとも、とある珍妙なガラパゴス・ネットスラングというべきものが普及しており、その奇っ怪な状況を誰も咎めるものは居ないように、少なくとも、私には見えます。

先駆的なソフトウェア開発と根底にある哲学

あくまでグローバルなソフトウェア開発の世界では、たとえば、

UNIX哲学

という有名な言葉があります。
この言葉は、特筆性の条件を満たしているので、当然このように、
Wikipediaの項目にもなっています。

UNIX哲学とは、ソフトウェア開発に関する文化的な規範と哲学的アプローチのまとまりであり、UNIX OSの先駆的な開発者たちの経験に基づいている。

ソフトウェア開発、OSの開発が先駆的に進んだ欧米では、昔から常にその根底に位置する「哲学」が熱心に議論され語られてきました。
ソフトウェア開発、OSの開発では、「哲学」は尊重されました。リスペクトされてきました。
すべての技術の根底には「設計思想」があり「哲学」があると。

この潮流は特に欧米においては、現代にも脈々と受け継がれており、著名なハッカー、
たとえば、@substackも、自身のことを
unix philosopher (UNIX哲学者)
http://substack.net/
と称しています。
https://github.com/substack/stream-handbook
という頻繁に参照される著名記事の冒頭においてもその一端が垣間見えます。

enter image description here

また、
http://danieltao.com/lazy.js/
の開発者である、DanTaoは、シリコンバレーのGoogle社員ですが、彼も、
http://philosopherdeveloper.com/about.html
サイトドメインにあるとおり、

DAN TAO
the philosopher developer (哲学者の開発者)

と自身を称しており、

I’m a software developer currently residing in San Francisco. I work at Google on the Ads Review team. Previously I worked at Cardpool, and before that ThoughtWorks (and before that, an algorithmic trading company in Philadelphia that no one’s ever heard of).

I studied philosophy at Duke University, then a couple of years later went to Carnegie Mellon Silicon Valley for a graduate degree in software engineering (hence the name of this blog). In between I lived with my wife in Namibia for a year through WorldTeach, an organization that places volunteer teachers in developing countries around the world.

A disclaimer about my writing. I try to be humble, but I also form a lot of opinions over the course of my (thus far, pretty short) career. So I often write about how I think software should be developed, or how teams or even companies (especially tech companies) should operate. Bear in mind that I’ve never run my own company. It’s possible that I might like to some day; but I would never want to run a business just for the sake of running a business, so it’s also possible that I might not.

One principle I believe in quite strongly is that there’s really no place for arrogance in this world. Living in Silicon Valley, I can’t help but feel that most of us in this industry are encouraged to forget that. The culture here is one seemingly designed to inflate egos and reward self-importance. Having said that, I realize that I’m guilty of it from time to time as well. So let this page serve as my perpetual apology for ever letting my head get too big, or acting like I know what I’m talking about.

と自信の「哲学的立場と発言」について明確にしています。

これは、繰り返しとなりますが、特にソフトウェア開発、OSの開発が先駆的に進んだ欧米では、特に「哲学」が技術の根底にあるという広いコンセンサスとリスペクトの潮流にある技術者の通常のあり方だと思います。

「ポエム」と発するものたちの「体たらく」、何がしたい?

さて、もし彼らが、現在の我が国の「ガラパゴス」世界で同じ声明を出したらどうなるでしょうか?

「ポエマー」だと馬鹿にされるんですね。

たとえば、このような技術的状況にまつわる「随想」でさえ「ポエム」と「言い換えてレッテルを貼る」ものたちがいます。

念の為(揚げ足取りをあらかじめ祓うために面倒なこと)ですが「ポエム」という言葉自体は言うまでもなく中立でクリーンな言葉です。
しかし、哲学的行為を、自分自身の頭で考える行為、それを表明する行為を「侮蔑的な意図をもって」「ポエム」と愚弄するものたちがいます。

「随想」の何が悪いんでしょうか?
技術にまつわる話題で個人のオリジナルな視点を表明することの何が悪いのでしょうか?

一体何なんでしょう?この我が国の技術者たちの「体たらく」は??

逐一「ポエム」とレッテルをはり、侮辱する人は「いったいぜんたい何をやりたい」のでしょうか?

「呪詛」である「呪い」である、「怖い」から滑稽な「おことわり」「お札」を貼りまくる人たち

端的に説明しましょう。

技術記事に「ポエム」とレッテルを貼ることは、相手の言説に「呪詛」「呪い」を加えることです。
「ポエム」とレッテルを貼ることで「呪いをかける」ことができ、相手の言説に、なんとなーく嫌な雰囲気を与えることができる。

我が国の主要なプログラミング技術記事、投稿、共有サイト、
Qiitaの記事にしても、少し前から、自分の自由な考えを投稿する際に
「****ポエム」というタイトルであるとか、
記事の冒頭や最後に「*****というポエムです。」
という珍妙で滑稽な【言い訳】を書く人ばかりになりました。

なんで、自分の自由な考えを表明するのに、いちいち「ポエム」だっていう
「おことわり」を書かなければいけないんでしょうね?

「おことわり」を書かなければいけない理由とはただひとつ。「怖い」からです。

「これはポエムです」ってわざわざ、いちいち珍妙で滑稽な「おことわり」を入れる、
もっと言えば自分の記事を「まもるため」の「お札」を記事に貼り付け「なければ不安」なのは、
「怖い」からでしょ?

残念、それは「お札」ではない「呪い」である

でも残念だけど、それは「お札」じゃないんですね。
だって「呪いの言葉」が「お札」になるわけがない。
「ポエムです。」って自分自身の記事に、自分の考えに自分で呪いをかけているだけ。

「自由に自分の考えを表明する」という正当な行為にすでに「呪い」がかけられているものだから、その「呪い」を祓うために、自分で自分自身に呪いの言葉をかけなければいけない。
自虐のつもり?「ネタ」?
「自虐的」であることで、先回りして自分自身の言説を守っているつもりなのかしりませんが、
なんのことはない、低いレベルに自分自身の言説を貶め、加虐しているにすぎません。

じゃあ、あなたは自分の考えを表明するときには、
これからずっと、いちいちそういう自虐ネタとして扱うわけですか?
はい、これが自分で自分に呪いをかけた顛末なのですね。

「自由に自分の考えを表明する」という正当な行為で、文章ひとつ書くにも「呪い」の事を気にしなければいけない雰囲気が醸成されてしまっている現状に異常を感じないのは、彼らが「呪いまみれ」になってしまっているからですね。

奇っ怪で、異常な事態

あきらかに、奇っ怪で、異常な事態が進行しています。

私は、以前から「ああ、なんか異常な事態になっているな」と思っていたので、
「ポエム」だとなんだと言われようが、まったく気にせずに、
「関数型プログラミング」の「考え方」、「哲学的側面」について自分の考えを堂々と表明して投稿していました。

「関数型ポエム」そして、民族神道の精神に基づく「呪い返し」

もちろん連中からは、「関数型ポエム」という「蔑称」の「呪い」がかけられました。

そこで、今回、せっかくですからこの記事で、「呪い返し」をしてみたいと思います。

われわれ日本人は民族的に根本的には神道信者です。
聖徳太子の時代以降、学問とともに大陸から伝来した仏教が、
「神道vs仏教」の壮絶な宗教戦争の結果、勝利し、神道を圧倒しましたが、
根本では我々日本人の精神には神道が今も受け継がれています。
われわれ日本人は、お正月には初詣をすることが大好きですし、
神社で購入した、家内安全、恋愛成就、商売繁盛、交通安全、いろんなお守りを大事に携帯している人はとても多いと思います。
バチがあたる、という考え方にも馴染みは深いです。

家の宗教は密教であり、葬式は仏教の作法にのっとり粛々と行われますが、
母親の家系は神道の神主の家系です。
母親の実家には、仏壇、そして、かなりしっかりとした大きな神棚が双方別々に祀られています。

実は、私が読書の習慣があるのは、母親の家系の影響で、母親の実家の屋根裏部屋には膨大な書籍があります。
ちなみに父親の家系は、祖父は外資系の技術者(高給取りであったらしい)で、私が技術系、理系であるのは、その家系の影響です。

私は情報技術者ですが、母親の神道家系の血が流れていますから、多分、「呪い返し」の「神通力」も多少なりとはあると思います。たぶんね。

我々日本人の精神的土壌は神道であるので、「穢れ」を嫌います。
「呪われれる」ことを忌み嫌います。

「ポエム」とレッテルを貼るものたちは、同じ精神的土壌を共有するが故に、そういう、相手が忌み嫌うことを嬉々としてやっているわけですね。
相手が忌み嫌う、と理解している、ってことは、とりもなおさず、自分がやられた忌み嫌う、ってわかっているからだ。

同じ精神的土壌を共有しているから。

え?違う?じゃあ、君たち、なんでそんなしょうもないことやって嬉しいのでしょうか?

「呪い」が効力を発する精神的プロトコルを共有している自覚があるから。
精神的土壌を共有する、精神的プロトコルを共有している自覚がないならば、
「呪い」なんてなんの効力ももちません。ただの無味乾燥な言葉の羅列にすぎません。

「ポエム」と書くことにより、他者の自由な言説にたいして、「呪い」をかけるわけですが、
それが「呪い」である以上、同じように「呪い返し」をすることは極めて容易であり、
それは相手が同じ神道の精神的土壌を共有してさえおればよいわけです。

そもそも、誹謗中傷に勤しむ性向をもつ集団のメンバーはすべてもれなく他人に不当な「呪い」をかけて喜んでいるような異常な集団ですから、「呪い返し」というのは大きな効果があります。

言葉の暴力、呪いが横行するHatenaブックマークのコメント

特に、無責任な文責を負わない匿名の書き捨て、言葉の暴力、呪いが横行するHatenaブックマークのコメントを書き込むものに対して、この呪いを返します。

このエントリにたいしても、「ポエム」だと呪いのワードを書けば良いでしょう。
いくら屁理屈をこねても無駄。
それはそのまま「呪い返し」が自動的になされるようになっています。

「呪い返し」の絶対的アドバンテージの理由 それは「論理」の「宣言」にすぎない「関数」という装置だから

「呪い返し」の良い所は、「言葉の応酬」にならなくて済むところです。
「呪い返し」とは、命令形プログラミングの「手続き」あるいは「命令」ではなく、
「論理」の「宣言」にすぎません。いわば関数型プログラミングの「関数」です。

撃たれたら、逐一撃ち返すという「行為」の連続ではなく、
そこに「鏡」をポンとおくだけの、「論理」の「宣言」をしてやる。
ただそれだけです。

あとはその「鏡」が「入力」に呼応した「出力」を自動的に返します。
エネルギーはすべてその「入力」に依存しており、自身まったくエネルギーを必要としない、装置にすぎません。

やるな、やってはいけない、と咎められれば、余計やりたくなるのが、幼児的な衝動を抑えきれない彼らです。試みてもこっちが疲弊するだけ。
でも鏡を、論理的な巨大な鏡を宣言するだけなら、手間はかからない。
いくらでもやれ、それは「逐一もれなく呪い返される」ということです。

「呪い返し」とは、あくまで邪な「呪い」を撥ね返す受動者の防御行為であり、
呪い返すほうにリスクはまったくありません。
自発的に邪な動機で「呪い」を返すもの自身にたいして「自業自得」の道理を通すための術であって、「呪い返し」の「呪い返し」は原理的に成立しないからです。

人を呪わば穴ふたつ

一方で、「呪い」をかけるものには多大なリスクがあります。
「人を呪わば穴ふたつ」
この言葉を聞いたことがある人は多いでしょう。人に呪いをかけるとろくなことにはなりません。
この言葉は、まさに不当な「呪い」が「呪い返し」によってどのような顛末になるのか説明している言葉です。

実践!やってみよう!「呪い返し」

では、このエントリでは、その「ポエム」と「呪いをかける」すべての愚かな人々に呪い返しをしたいと思います。

プログラミングの世界で、「ポエム」とは、「ガラパゴス・ネットラング」であり、この言葉を優越的気分から侮蔑的な意味で、これまで用いた、そしてこれから用いるものは、まもなく必ず、世の中の侮蔑の対象となる、また周到に「ポエム」という言葉を避けながら、同じ立場で行為を支援し続ける同族に対しても、以上と同じ呪い返しの効力がある

「呪い返し」とは、論理性と正当性、つまり道理が必要とされます。
このエントリでは、すでに、その道理を説明しました。

遂に「書評」という、ごく普通の行為にさえも「レビューポエム」と自分で呪う、奇っ怪な現象が・・・

「ポエム」が「呪い」の言葉であると知っているのでしょう、
単純な書評でさえ、自身の書評にさえ「呪い」をかける(自分では防御する「お札」だと思っている)という、通常では考えにくい奇っ怪な現象が起こっています。

「書評」ひとつ書くにあたっても「いちいち【ポエム】と【自虐の呪い】を自分自身に向けてかけながら【言い訳】をせなければいけない」理由って一体どこにあるんでしょうか?

めがねをかけるんだ
レビューポエム “関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間” を読んで

本当は立ち読みですませる気だったんですが、買わないでレビューはフェアではないかなと思い……今は後悔しています。

以上、悔しかったのでブログのネタとしてなるべくライトに感想を書きましたが、本編は読んでいて本当に苦痛だったので、僕は、みなさんにはお勧めしません。

お買い上げいただき、どうもありがとうございました。そして、同情いたします。

もちろん、最初から腐すつもりであった本に1400円も支払ったのは、とてもお気の毒ですね。お買い上げいただき、どうもありがとうございました。

わざわざレシートの写真まで貼り付けておられて、よほど悔しかったのでしょうか?
最初から腐す目的の書籍に身銭を切るというのは、さぞや屈辱的であったでしょうから、その「悔しい」お気持ちは当方も想像するに余りあります。申し訳ありません・・・

著者としてフェアに言うと、こういう最初から反発して読みにかかる、そもそも私の解説の仕方に批判的な先入観がある連中を本書では、結構露骨に批判してしまっていますから(笑)、それは「読んでいて本当に苦痛だった」でしょうね。でも、そうならそうと正直に書かなきゃ不誠実でしょう??でも、お金を払って読んでいる自分の批判を展開されるのは悔しかったことでしょう。同情いたします。

自分の立場と他の人の立場は一致などしない

でも、先入観も何もない読者にとっては、その批判の相手は自分ではないので、なんら苦痛に感じないのですよ?ただ、その連中を反面教師として「学ぶ」だけです。知的に建設的な体験をします。 
自分の立場と他の人の立場は一致などしないのです。

だから自分が受けた感傷をもって、それがすなわち他者が受けるだろう感傷と一致する、と考えるのは重大な論理的誤りです。
主観的評価とは、客観的評価にはなりえない。基本ですよね。

たとえば、ここに別の方の書評があります。あなたの主観とはまるで異なるでしょう? 

先入観をもたない読者による書評

『関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間』を読んだ (Persistence)

全体的に好意的で、難しい部分についても抑制的な論調の書評ですが、一部、引用させていただくと、

この本の感想を3行でまとめると
- 命令型プログラミングから関数型プログラミングへのパラダイムシフトを体験できた
- 関数型プログラミングができるまでの歴史的背景を知ることができた
- 本を読む姿勢を改めて考えさせられた

パラダイムシフト

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

一方の後半半分は、FRP(関数型リアクティブプログラミング)の説明になるのですが、アリストテレス、ピタゴラス、プラトン、デカルト、などの哲学思想(これはこれで読み物としては面白かったですが)とFRPを対比させて説明が進んでいくのですが、正直最後の方はついていけなくなりました。まあこの辺は、FRPだけを説明するのはもっと簡単だけど、筆者としてはその根本的な思想を伝えたかったのだと思います。

会話形式で説明が進んでいく中でいくつものプログラミングに関する歴史が説明されており、読み物として面白かったです。例えばJavaScriptの生い立ちの話とか、命令形プログラミングから関数型プログラミングへのパラダイムシフトやの歴史、そして次のパラダイムシフトは何かなど。

「論理」と「計算」を分けて考えるという説明はわかりやすかったです。

というのは、しっかり伝わったことが確認できて、著者として書いた甲斐がありました。たいへん嬉しいです。

そして、「読み物として面白かったです」ということです。どうもありがとうございます。
「苦痛」とは程遠い感想ですね。

「先入観のない」「普通の読者」がよめば「普通に楽しめる」ように書いてあります。

「先入観のある読者」「先入観のない読者」何がどう違うのか?

きっと「呪い」のせいですよね。自分の書評にまで「呪い」をかけるのはもう重症です。その奇っ怪な様態の自覚はまるでないでしょうが。

こういう状況を「お祓い」するのが「呪い返し」であり、結果的に彼らを呪いの呪縛から救ってやること、憐れみの行為を与えてやることになります。もちろんそれは、彼らが「呪い返し」を十分受けて、十分に「禊」を終えてからの話となりますが。

【自称】関数型プログラミングコミュニティ、っていうのも「ガラパゴス」

【自称】関数型プログラミングコミュニティ、っていうのも「ガラパゴス」であることはすでに説明しました。

また、その中心的人物となる、どこかの大学の教師の言説にしても、「ガラパゴス」であることはすでに説明しました。

私は彼らからいろいろと呪いを受けましたので、当ブログのエントリにて「呪い返し」をしました。やり方は、ご覧のとおり、対象を明確に特定し、こちらの正当性を明確に説明する、という道理を通した正攻法です。「学問に王道なし」

彼らには今後「禊」が必要になってくるでしょう。
「説明責任」という「禊」です。

「関数型プログラミングの勉強会」というのが、もし愚かな「ポエム」という「ガラパゴス」な呪いをかける論調のメンバーが中心であるのならば、そこでは、私の「呪い返し」を受けて、誠実な説明責任を要求する真摯な学習者、技術者が出ることでしょう。
現在のところ、いかなる「禊」もネット上に存在しないからです。

学問の場でも、誠実な説明責任の要求とともに、議論が行われるでしょう。
現在のところ、いかなる「禊」もネット上に存在しないからです。
彼らはそういう「穢れ」「禊のない状態」は嫌うんですね。
納得などしていない。ごまかしも通用しない。権威主義は多分もう通用しない。
「呪い返し」を私がもうしたから。

関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い
で、説明したように、「ガラパゴス」でない広く国際的な説明は、私の論調と一致しており、
一方で、「ガラパゴス」な彼らの論調は広く国際的な説明と一致しない、
ボトムラインとして、誰でも確認できるこの事態について、これはなぜなのか?これまで一切の説明はない、「禊」がないことを追求されるでしょう。

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

多くの方に本書をお買い上げいただきましてお礼申し上げます。

著書、関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間
について、
「クロージャ」の説明が誤っています
と、また☆1のレビューが投稿されていますが、誤っていることを説明します。

PS.正直この人が何を言ってるのか、私にはまるっきり理解できないので、こんな曖昧な書き捨てじゃなくて、技術の言葉で翻訳できる人がいたら、コメントかメールください。こんな書き捨てからでも、万が一でもそれなりの議論ができるかも、と淡い期待もしています。(参照等価じゃなくって、参照透過、念の為)

ええともうほんとこういう誤った情報垂れ流されるのどうにかならないんですかねえ。閉じ込めるのは状態じゃなくて環境だよ何なんだこれは。それに状態を閉じ込めたところで参照等価じゃなくなるわけじゃないよホント

問題のレビュー

「お買い上げいただきありがとうございます」

enter image description here

102 人中、93人の方が、「このレビューが参考になった」と投票しています。
5つ星のうち 1.0
「クロージャ」の説明が誤っています, 2015/4/28
投稿者 λ

383~384ページに「関数型プログラミングでオブジェクトを作る仕組み クロージャ」との見出しで
「クロージャって何ですか?」「関数で副作用を起こして、その副作用が起こった環境そのものを閉じ込めておく関数のこと」
「クロージャは、参照透過ではない、命令型のハードウェアモードである、ってことは普通に理解しておきなさい」「はい、普通に理解しています、大丈夫です」
というような説明が具体例を交えて述べられています。しかし、クロージャはレキシカルスコープを実現するための仕組みであって、
副作用(ローカル変数への破壊的代入など)のないクロージャもごく普通に用いられますので、本書の説明は誤っています。
むしろ、クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられています。
「Javascript closure」や「function closure」で検索すれば、MDNや英語版Wikipediaなどですぐにわかるレベルのことです。
クロージャは関数型プログラミングにおける基本的概念の一つですので、重大な誤りだと思います。

えー、

102 人中、93人の方が、「このレビューが参考になった」

らしいです。
もちろんこういうのは不正な投票であることはすでに説明しましたが、
万が一、ほんとうに、

102 人中、93人の方が、「このレビューが参考になった」

のであれば、なんと罪深いデマ拡散行為なのでしょう。

おそらく、これまでこのレビューを眼にしたかなり多くの技術者が
「ああ間違った指摘をしているレビューだ」
と理解していることだと思いますが、

102 人中、93人の方が、「このレビューが参考になった」

というのは、繰り返しになりますが無論、不正な投票なので、
その見識が数値に反映されることは、今後も「絶対に」はないでしょう。
不正でなければ、良識、正しい知見の力学も働きようもありますが、不正投票によるものなので。

もしも、ほんとうに、このレビューをもって、

102 人中、93人の方が、「このレビューが参考になった」

というのが、正確な情勢を反映しているのであれば、
我が国の技術者のレベルは致命的に低い、ということになります。
もちろん、騙された学習者が多いとして、その数を汲んだとしても致命的です。

このレビューも単に、
私が「技術的反論は何一つ見受けられない」と宣言したことを「挑戦」と受け取り、
脊髄反射的に応じた、単なるネガティブキャンペーンが第一目的であり、
広い読者、技術者、学習者にむけて「正しい知識を共有すること」ではないのでしょうから、
罪の意識など感じるわけもなく、
このブログ記事の説明をもっても、今後そのまま誤ったまま放置され、訂正される、という良識は当然まったく期待していません。
訂正されない、という事実をもって、このレビューが技術の修正を装ったネガキャンであることを追認できると思います。

まず、なぜ、私の著書のほうが正しく、この反論者がいい加減な嘘を書いてまでネガキャンをしているのか?結論を直感的に手っ取り早く知りたい読者のために、ざっくりと結論を書きます。

手っ取り早く、ざっくりと

Wikipedia日本語版では、かなり簡潔にその答えがあります。

http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3

クロージャ(クロージャー、英: closure)、関数閉包はプログラミング言語における関数オブジェクトの一種。

はい、この一文は私の責任において断言しますが。正確です。
Wikipedia日本語版の記事はプログラミングの分野でも、首をかしげるものが多いことは、以前なんかの記事で私も書きましたが、これに限ってはかなり正確です。

クロージャ、関数閉包、という字面でも自明ですが、これは、
「関数」が一義的に関与する存在であり、
「関数」が
「なにか」を
「閉じ込める」
仕組みのことです。

その「なにか」っていうのは何か?
もちろん「状態」です。

「状態」を「閉じこめたら」「参照透過ではなくなる」のは、著書で解説していることですね。
「状態」を「閉じ込める」ものにアクセスできる「関数」の「オブジェクト」って何か?
当然、オブジェクト指向の「オブジェクト」とまったく同じものです。

さて、この反論者は、

しかし、クロージャはレキシカルスコープを実現するための仕組みであって、

とか、書いているわけですが、同じWikiepdia項目の続き、

いくつかの言語ではラムダ式や無名関数で実現している。引数以外の変数を実行時の環境ではなく、自身が定義された環境(静的スコープ)において解決することを特徴とする。関数とそれを評価する環境のペアであるともいえる。この概念は少なくとも1960年代のSECDマシンまで遡ることができる。

http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3

自身が定義された環境(静的スコープ)において解決することを特徴とする

上記つなぎ合わせると、
クロージャとは、

レキシカル(静的)スコープにおいて解決することを特徴とする、(by Wikipedia日本語版)
レキシカル(静的)スコープを実現するための仕組み (by 反論者)

となりますね。はい、さっそく論理破綻しました。

もちろん、論理破綻したのは、

レキシカル(静的)スコープにおいて解決することを特徴とする、(by Wikipedia日本語版)

が正しくて、

レキシカル(静的)スコープを実現するための仕組み(by 反論者)

が間違っていて、無理やり文章をつなげたからです。

クロージャとは、

レキシカル(静的)スコープを実現するための仕組み

では、ありません。

クロージャとは、レキシカル(静的)スコープがすでに実装されている環境の土台の上にある仕組みです。

以上がかなり、ざっくりとした説明ですが、より詳細に、精査してみましょう。

より詳細に精査してみる

反論者の論点が複数あり列挙します。

クロージャはレキシカルスコープを実現するための仕組み

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。

「Javascript closure」や「function closure」で検索すれば、MDNや英語版Wikipediaなどですぐにわかるレベルのこと

クロージャは関数型プログラミングにおける基本的概念の一つ

すべて間違いです。

順序は前後しますが、

英語版Wikipediaなどですぐにわかるレベルのこと

をまず精査してみます。
http://en.wikipedia.org/wiki/Closure_(computer_programming)

In programming languages, closures (also lexical closures or function closures) are a technique for implementing lexically scoped name binding in languages with first-class functions.

この表現は、わかりにくい、というか、この反論者のように誤読して勘違いする人が多いだろうからどうか?と思うわけですが、その下の、

History and etymologyを見ればより意味が明らかになります。

The concept of closures was developed in the 1960s for the mechanical evaluation of expressions in the λ-calculus and was first[citation needed] fully implemented in 1970 as a language feature in the PAL programming language to support lexically scoped first-class functions.

lexically scoped first-class functions
レキシカルスコープのファーストクラスの関数
をサポートするために実装された、ということです。

上記双方の文章で共通しているのは、
レキシカルスコープ + ファーストクラスの関数
と2つの要素がある、ということです。

MDN

で調べてみると、

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures

The solution to this puzzle is that myFunc has become a closure. A closure is a special kind of object that combines two things: a function, and the environment in which that function was created. The environment consists of any local variables that were in-scope at the time that the closure was created.

この謎の秘密とは、myFuncがクロージャになった、ということです。
あるクロージャとは、
1.関数
2.関数が生成された環境
の2つを結びつける特別な種類のオブジェクトです。
その環境は、クロージャが生成された時間のスコープにある、あらゆるローカル変数を保持しています。

(これはレキシカルスコープのこと。)

英語版Wikipediaから読み解ける
レキシカルスコープ + ファーストクラスの関数
であることと上記MDNの記述を合わせて整合的に確認できる事実とは、
まず、最初にレキシカルスコープという枠組みがあって、
その上に、クロージャという状態保持能力がある関数(ファーストクラスオブジェクト)の存在があるということ。

故に、

クロージャはレキシカルスコープを実現するための仕組み

というのは、完全な誤りです。

さて、次の要素、

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。

「ほぼすべて」とか書いてたら、「胡散臭いな」と疑いましょう。
正確性が担保できないから、あとあとの「逃げ道」を用意している欺瞞が多いです。
実際これは欺瞞で、著書の解説の誤りの指摘という文脈で考えるのならば、間違いです。

クロージャとは、上記で再確認したとおり、また著書に正確に書いている通り、
レキシカルスコープのローカル変数が閉じ込められた環境の「状態」を保持する関数オブジェクトですが、この人物の書きっぷりから読者が受ける印象とは、
 クロージャは関数型言語の実現に用いられる「必須の技術」なんだ!
 Haskellもそうなんだから、間違いない!
ってことでしょう。
「ほぼすべて」という逃げ口上は、もちろん著書の解説の反論文脈にあるので、あまり気にされません。

クロージャは関数型プログラミングにおける基本的概念の一つ

とダメ押しもされています。

レキシカル(静的)スコープでないほうのスコープ、動的スコープ
のWikipedia記事を参照すると、

動的スコープを採用している代表的な言語としては古典LISPやEmacs Lisp、LOGO、Perl4などがある。

とあります。これも私の責任で保証しますが、正しいです。

もちろん、

古典LISP
Emacs Lisp

は関数型言語ですよね。著書でもLispが関数型言語の古典であることは説明しました。

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。
クロージャは関数型プログラミングにおける基本的概念の一つ

であるのならば、なんで

クロージャはレキシカルスコープを実現するための仕組み

をもってレキシカルスコープになっておらない、動的スコープである、

古典LISP
Emacs Lisp

が関数型言語でありえるのでしょうか?たしか、

クロージャは(いわゆる純粋関数型言語であるHaskellを含め)ほぼすべての関数型言語の実現に用いられている。

「はず」だったのに・・・

結論

もう宜しいでしょうか?
当たり前なのです。
なぜならば、クロージャとは「状態を保持するオブジェクト」なのだから。

「状態を保持するオブジェクト」が
状態を保持しないことが基本中の基本の、
「関数型プログラミングの基本的概念」であるはずがありません。

もちろん、クロージャという「状態を保持するオブジェクト」が、
「関数型言語の実現のために用いられている」必須技術であるわけもありません。

なぜなら、クロージャとは、オブジェクト指向のオブジェクトと等価な存在なのだから。

本書では、それ故に、

383~384ページに「関数型プログラミングでオブジェクトを作る仕組み クロージャ」との見出し

として、最後の最後のDay5に、Day1-4の関数型プログラミングの本論と、しっかり分離して解説しています。別、というか、
関数型と対立するパラダイムに属する技術として、クロージャの解説は完全にわけました。

他の多くの関数型プログラミングの解説か書籍では、まさに、
クロージャが、まるで
「関数型プログラミングの基本的概念」
「関数型言語の実現のために用いられている」必須技術
であるかのごとく、ごちゃまぜにして、
読者がとんでもない勘違いをして当然の解説がされている、のでしょうか?

少なくとも、

「Javascript closure」や「function closure」で検索すれば、MDNや英語版Wikipediaなどですぐにわかるレベルのこと

とか、現状、「技術的反論など何一つ見受けられない」という当ブログ記事に反応して、
何がなんでも貶めてやろうと先走るから、意図的か、勘違いか早とちりか、わかりませんが、
挑戦する、そして、このエントリも読んでいることだと思いますが、
誤りを認識しながら、訂正もしないで、そのまま不当な指摘のレビューを残しているわけです。

Amazonレビューで嘘を書かないこと、それが技術的議論のための最低限の要件である

繰り返します。現状、「技術的反論など何一つ見受けられない」。
嘘まみれなので、「不正なノイズ」と分類されます。

2015年4月28日火曜日

Amazonレビューで嘘を書かないこと、それが技術的議論のための最低限の要件である

まず、多くの方に本書をお買い上げいただきましてお礼申し上げます。

このブログエントリで、反応して「戒める」と、ちょっとはネガキャン勢力も「反省」するのか、少しずつですが、著書のAmazonレビューが「マシ」になってきているようです。

ただし、現状☆1をつけているレビューは、以下に取り上げる直近のものを含めすべて「不正なノイズ」であり、賛否の「否」にカウントできるものはひとつもありません。

ここで書けば徐々にですが「マシ」になってくるようなので、あくまで

「どうしたらまともな技術論になり、
広い技術者、読者、初心者の役にたつレベルにまで達するのか?」

簡単な要件を筆者として示したいと思います。

要件はたった2つ。

1.技術論に色を付けない
2.嘘を書かない

たったこれだけです。

1.技術論に色を付けない

というのは、前回も書いたとおり、くだらないヘイト、誹謗中傷、個人攻撃、人格攻撃と、書籍の技術的内容をごっちゃまぜにして論じないこと。

そして、以前書いたとおり、自分が使用するプログラミング言語、あるいはオブジェクト指向的マルチパラダイムの嗜好をもって、いい加減な権威主義による宗教的より好みをあたかも一般的説明、あるいは絶対的真理がごとくみせかけない、こと。
関数型プログラミングとQiita界隈の騒動について
関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い

2.嘘を書かない

という要件を満たしてない以下の具体的なレビューで説明します。

以下のレビューは、嘘まみれなので、「不正なノイズ」と分類されます。

114 人中、112人の方が、「このレビューが参考になった」と投票しています。
5つ星のうち 1.0
タダでも読む必要のない(というより読むべきではない)書籍, 2015/4/28
投稿者 Kamuichikap

本書の技術的内容は質的にも量的にもその7割が「0から9までの数をすべて足すコードを書け」ということに尽きています。後はFacebook-ReactライブラリのサンプルコードとFRPの拙劣な説明です。3~4行を超えるコード片は殆ど出てきません(そしてその多くが繰り返しです)。したがって、関数型プログラミング自体に興味のある読者にとって本書の内容はほぼ

[0,1,2,3,4,5,6,7,8,9]
.reduce(plus); //をすべて足す

というものに尽きています。しかし、この説明は整数の加法がたまたま交換法則・結合法則を満たしているから成り立つように見えるにすぎません。reduce(f)を適用する際に、配列の最初の要素は関数fの第一引数の型を持たねばならず残りの要素は第二引数の型を持たなければなりませんからこの配列は本質的にヘテロジニアスなものですし、左畳込(いわゆるfoldl)と右畳込(foldr)の違いを考えれば、結局は関数fの適用順と蓄積の経過を理解しなければfoldを理解したことにはなりません。本書の説明は一見わかりやすく見えるのですが、結局は本質的な理解を妨げるものであると思います。また著者はreduce関数やrange関数やmap関数を命令型のループでしか書けないとしていますが(たとえばpp. 88,96,106)、これは明らかに誤りですし本書の目的からすれば関数型で書いてみせるべきものです。それでは効率が悪いように見えるかもしれませんが、それが本来の関数型のプログラミングスタイルですし、それが非効率になるのは関数型プログラミングを支援するように設計されていないJavaScriptという言語の問題であって、とりもなおさず関数型プログラミングの説明を本書のようにJavaScriptでしようとすることが最初から不適切な選択であることを示しています。

FRPの説明もごく拙劣です。状態を持った手続きは引数で状態を持ち回すようにすることによって純粋な関数にできる、という関数型プログラミングの基本的な技法を、その最も基本的な原理を説明せずに(或いはことによると理解せずに)、特殊事例について述べているに過ぎません。根本的には、時間による値の変化は時間から値への関数として表現でき、イベントによる値の変化は、値とイベントから値への関数として表現できる、というだけのことですが(簡単ですが重要な点ではあります)、そうした本質的な説明はなされずに、ひたすら著者の不明瞭な思弁が垂れ流されるだけです。また著者が、参照透過性や遅延評価やその他の関数型プログラミングにまつわる様々な概念を混同し或いは不当に同一視しているために、それらの記述を鵜呑みにしてしまえば読者は誤ったないし混乱した理解を得てしまうように思います。

また、著者は命令型言語での「n=n+1」のようなステートメントを「論理破綻」だと主張しています(pp.144-5)。また右辺と左辺で変数nが違う時間に属しているとしていますが、この珍妙な主張は著者が左辺値と右辺値という基本的な概念を理解していないことから生じています。そもそも「n=n+1」は数式ではなく各言語がそれぞれに意味を与えているものなので、数式として論理破綻していると言われても困るでしょう。問題は、著者が命令型プログラミングの基本を(そして恐らく関数型プログラミングの基本も)理解しないままに、それを口を極めて非難していることにあります。

本書の過半を占める、その意味が定義されたり説明されることの決してない著者の独自の「論理」や「計算」という語の用法とそれに基づいた大量の思弁は、おそらく殆どの読者にとって(技術的意義はもとより)そもそも意味をなさないナンセンスですし、たとえばp.238以降展開されるような哲学者や自由意志論への言及は単純に思想史上の問題としても誤解に基づいたものに過ぎません(そのついでにアラン・ケイやガリレオやデカルトを気取られたりするとどういう顔をして読めばいいのかもわかりませんが)。

最後に、もし本書を(ネタではなく)本当に読もうと思った人がいれば、本書ではなく浅井健一『プログラミングの基礎』サイエンス社(2007)と大川徳之『関数プログラミング実践入門』技術評論社(2014)などを読めば、金と時間をムダにせずに済みます

まず前提ですが、
最初の

114 人中、112人の方が、「このレビューが参考になった」と投票しています。

というのは、「嘘」です。
別の、☆5のレビュアも指摘していますが、ごくごく短時間に、
評価が高いレビューは「参考にならなかった」
評価が低いレビューは「参考になった」
とボタンを押しまくる「キャンペーン」か何かやっているのでしょう。
それは事前に想定されていた彼らの行動パターンでした。
まずまず内輪ではこのような「不正行為」を「世直しだ」などと言いながら、
対外的には「被害妄想だ」というのがこういう、先のエントリでも説明した連中の行動パターンです。

次に、この投稿者のkamuichikap氏ですが、
もちろん、私は知っています。
Qiitaで、
関数、値、圏論、モナド、評価戦略、純粋関数型、その辺りの「数学的基礎」について書いた記事で、私になんか書いてきた人です。
よくわからないですが、こういう人は「一方的に私に恨みのようなものを持っている」らしく、そういう腹いせを、嘘までついて、こういう著書をこき下ろすレビューでするのはアンフェアだと思うわけですが、いずれにせよ、何がなんでも機会をみてその恨みを晴らそうとするみたいです。

Kamuichikap氏は、私がこのブログで「技術的反論など何一つ見受けられない」とあしらったことを受けて、「ようしそれなら自分が」とでも思ったのでしょうか?
上記引用したAmazonレビューをされました。
読ませていただきましたが、怨恨から嘘をついてこき下ろすことしかやっていないわけで、論外です。

繰り返します。現状、「技術的反論など何一つ見受けられない」。
嘘まみれなので、「不正なノイズ」と分類されます。

本書の技術的内容は質的にも量的にもその7割が「0から9までの数をすべて足すコードを書け」ということに尽きています。後はFacebook-ReactライブラリのサンプルコードとFRPの拙劣な説明です。3~4行を超えるコード片は殆ど出てきません(そしてその多くが繰り返しです)。したがって、関数型プログラミング自体に興味のある読者にとって本書の内容はほぼ

[0,1,2,3,4,5,6,7,8,9]
.reduce(plus); //をすべて足す

というものに尽きています。

嘘です。
本書を読めば、これが嘘であると誰でもわかるでしょう。

まず、私は、フックのDay1、
そして、関数型ライブラリの概念を導入する、Day2、
そして、遅延評価の概念を導入する、Day3、
で、

「0から9までの数をすべて足すコードを書け」

という例題を繰り返しました。
それは、この極めてシンプルな例題をもって、違う角度から、別の技術的概念を解説するためです。

普通、別の技術的概念を解説するときには、別の例題に切り替えたくなりますが、
私はあえて、この極めてシンプルな例題をもって、同じ例題であっても、別の技術的な切り口で、それはこれこれこのようになる、と示すように構築しました。
同じ例題なので、違う技術を対比的に考えることができます。
これはひとつの芸当であり、非常に熟慮と工夫と手間と時間の要する作業でした。

後はFacebook-ReactライブラリのサンプルコードとFRPの拙劣な説明です。3~4行を超えるコード片は殆ど出てきません(そしてその多くが繰り返しです)。

嘘です。これも本書が手元にあれば誰でも、この記述が嘘であることは用意に確認できることでしょう。
パラパラめくっただけで、「3~4行を超えるコード片は殆ど出てこない」というのが虚偽が真実かくらい、数秒で判別できます。

買った人には、嘘はバレても仕方がない、関係ないが、とにかくこれから買う人には嘘でもなんでもネガキャンしてやろう、っていうことなんでしょうか?正直なんでこんな誰でも確認できる嘘をつくのか意味がわかりません。

3-4行以内で、Node.jsや、Reactのコードが説明できるわけがありません。
それは、このブログの著書サポートページ、

React (.js Facebook)解説 関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 サポート記事 静的HTML編についても、どなたでも閲覧して確認することができるでしょう。

私は、3~4行を超えるコード片は殆ど出てこない、拙劣な説明でお茶を濁すような仕事はしていません。

しかし、この説明は整数の加法がたまたま交換法則・結合法則を満たしているから成り立つように見えるにすぎません。reduce(f)を適用する際に、配列の最初の要素は関数fの第一引数の型を持たねばならず残りの要素は第二引数の型を持たなければなりませんからこの配列は本質的にヘテロジニアスなものですし、左畳込(いわゆるfoldl)と右畳込(foldr)の違いを考えれば、結局は関数fの適用順と蓄積の経過を理解しなければfoldを理解したことにはなりません。本書の説明は一見わかりやすく見えるのですが、結局は本質的な理解を妨げるものであると思います。

一見、難しいことを書いており、まるで正しい技術的な批判をしているように、みえるでしょう。

このブログでは、まさにこのDay1の章で、「本質的理解」を促す解説を無料公開しているので、広い読者は読み比べてみれば良い、それで明らかだ、と思いますが、上記の文章で、
「よし!関数型プログラミングの本質的な理解が促進された!」
「関数型プログラミングって便利そうだ!魅力的なのでやってみよう!」
と思う読者が果たしてどのくらいいるでしょうか?

「ヘテロジニアス」?もちろんググったら誰でも意味はわかるでしょう。
しかし、こういう無意味に難解な言葉をもってくるのは、
ただ単に自分を賢く見せようとしているだけで、相手に理解させようとする気持ちなんてない、
「本質的な理解」なんてこれっぽっちも気にしていない証拠です。
本当にこういう真似をする人は多いです。
相手の理解のための言葉遣い<<<<自分を賢く見せる言葉遣い
なんですね。
「ものごとを説明すること」「解説すること」には説明者、解説者にとってリスクがあります。
間違いを指摘されて馬鹿にされるリスク、馬鹿に見えるリスク、それをだいたいすべての人は怖れます。どう防御するか?っていうと、「ヘテロジニアス」みたいな初心者がわからなくて当然の言葉で、理解のハードルをあげちゃうんですね。相手が理解できない限り、自分は少なくとも馬鹿にはみえないから。

それで、種明かしをすると、私は、Day1では、関数型プログラミングの概略を凝縮して解説したのです。読者に一番最初に、ざっくりとした、まとまり(集合)、論理操作の話をしているところに、個別具体的な関数である、reduce(f)の「具体的特性」について、交換法則・結合法則だの「ヘテロジニアス」だの解説するのは、愚かな説明な仕方です。なぜならば、それは関数型プログラミングの概略の「本質」ではありえないからです。「具体的特性」とは「具体的」であり「本質」ではありません。誰でもすぐにわかることですね。

そういう愚かな解説本は私は書かなかった、一方でこの人は、そういう愚かな解説の仕方が良い、そういう本のほうが良いと言っているのですね。

そして私は実際に、このreduce(f)の「具体的特性」については、Qiitaでの貴重なフィードバックから重要性を認識していました。その結果どうしたか?というと、Day2で事細かく説明したのです。
それはフックのDay1で詳細に踏み込んで書くべき内容ではなく、きちんとレベルを分けて書くという手法をとっています。
以上の事実は、Day2読めば、わかることなんですね。購入していただいた人は確認できることでしょう。この人は「嘘」を書いているわけです。

また著者はreduce関数やrange関数やmap関数を命令型のループでしか書けないとしていますが(たとえばpp. 88,96,106)、これは明らかに誤りですし本書の目的からすれば関数型で書いてみせるべきものです。それでは効率が悪いように見えるかもしれませんが、それが本来の関数型のプログラミングスタイルですし、それが非効率になるのは関数型プログラミングを支援するように設計されていないJavaScriptという言語の問題であって、とりもなおさず関数型プログラミングの説明を本書のようにJavaScriptでしようとすることが最初から不適切な選択であることを示しています。

当たり前のことで、繰り返しますが、
reduce関数やrange関数やmap関数は、命令型のループでしか書けません。
なぜならば、ノイマン型コンピュータというハードウェアは究極的には命令型でしか動作しないからです。関数型の機械語なんて存在しません。

関数型プログラミングを支援するように設計されていないJavaScriptという言語の問題であって、とりもなおさず関数型プログラミングの説明を本書のようにJavaScriptでしようとすることが最初から不適切な選択であることを示しています。

あのですね。JavaScriptであっても、関数ライブラリを使えば、それは「関数型プログラミングを支援するように設計された」レイヤを整えることができます。
Day2(pp. 88,96,106)では、上記のreduce含め、この人の言葉を流用すると「関数fの適用順と蓄積の経過を理解」してもらうために、命令型のループをもって「車輪の再発明」の作業をやっているのです。

そして、「関数型プログラミングを支援するように設計」ってのは、ネイティブな言語仕様レベルで、その関数ライブラリが最初から、根本では命令型のコードをもって実装されているってことに過ぎないでしょう?

ただそれだけの違いです。

言ってることが、デタラメというか嘘だらけです。

FRPの説明もごく拙劣です。状態を持った手続きは引数で状態を持ち回すようにすることによって純粋な関数にできる、という関数型プログラミングの基本的な技法を、その最も基本的な原理を説明せずに(或いはことによると理解せずに)、特殊事例について述べているに過ぎません。根本的には、時間による値の変化は時間から値への関数として表現でき、イベントによる値の変化は、値とイベントから値への関数として表現できる、というだけのことですが(簡単ですが重要な点ではあります)、そうした本質的な説明はなされずに、ひたすら著者の不明瞭な思弁が垂れ流されるだけです。また著者が、参照透過性や遅延評価やその他の関数型プログラミングにまつわる様々な概念を混同し或いは不当に同一視しているために、それらの記述を鵜呑みにしてしまえば読者は誤ったないし混乱した理解を得てしまうように思います。

嘘です。

「拙劣」「拙劣」と繰り返したいだけなのか知りませんが、内容は嘘です。

本書では、他の日本語で出回っているどの書籍よりも、根本から関数型プログラミングとFRPの関係性について踏み込んで解説しています。

根本的には、時間による値の変化は時間から値への関数として表現でき、イベントによる値の変化は、値とイベントから値への関数として表現できる、というだけのことですが(簡単ですが重要な点ではあります)、そうした本質的な説明はなされず

この「根本」のところを、いかにして、しつこいくらいに解説しているのか?本書が手元にある読者は誰でも容易に確認できるでしょう。

また著者が、参照透過性や遅延評価やその他の関数型プログラミングにまつわる様々な概念を混同し或いは不当に同一視しているために、それらの記述を鵜呑みにしてしまえば読者は誤ったないし混乱した理解を得てしまうように思います。

「不当に同一視」。違います。

様々な概念の根底で共通する概念を見通しよく整理する作業を「不当に同一視」という表現はしません。この人自身が、どのように学習されたのかは存じ上げないし、その世界観を維持して、本書の解説を拒否するのも構わない。しかし、まるで自分の見方が、唯一無比のように絶対視して、
「不当に同一視」だの、
「鵜呑みにしてしまえば読者は誤ったないし混乱した理解を得てしまう」
だの侮辱していただきたくはない。これはこのブログで以前も書いたことです。

また、著者は命令型言語での「n=n+1」のようなステートメントを「論理破綻」だと主張しています(pp.144-5)。また右辺と左辺で変数nが違う時間に属しているとしていますが、この珍妙な主張は著者が左辺値と右辺値という基本的な概念を理解していないことから生じています。そもそも「n=n+1」は数式ではなく各言語がそれぞれに意味を与えているものなので、数式として論理破綻していると言われても困るでしょう。問題は、著者が命令型プログラミングの基本を(そして恐らく関数型プログラミングの基本も)理解しないままに、それを口を極めて非難していることにあります。

嘘です。

この珍妙な主張は著者が左辺値と右辺値という基本的な概念を理解していないことから生じています。

そもそも「n=n+1」は数式ではなく各言語がそれぞれに意味を与えているものなので、数式として論理破綻していると言われても困るでしょう。

これは「破壊的代入」という「意味」を解説、導入する際の枕の部分です。
あくまで、「破壊的代入」とはその名のとおり、論理を破壊する代入であると明示するために、
「n=n+1」のようなステートメントを「論理破綻」だと主張、ではなく、「正しく解説」したのです。

問題は、著者が命令型プログラミングの基本を(そして恐らく関数型プログラミングの基本も)理解しないままに、それを口を極めて非難していることにあります。

命令形プログラミングと関数型プログラミングの対比は、Day2でみっちりと説明しており、著者であり解説者である私自身が、理解しているのか?していないのか?それは読めば、「こういう人以外は」誰でもわかることでしょう。

本書の過半を占める、その意味が定義されたり説明されることの決してない著者の独自の「論理」や「計算」という語の用法とそれに基づいた大量の思弁は、おそらく殆どの読者にとって(技術的意義はもとより)そもそも意味をなさないナンセンスですし、たとえばp.238以降展開されるような哲学者や自由意志論への言及は単純に思想史上の問題としても誤解に基づいたものに過ぎません(そのついでにアラン・ケイやガリレオやデカルトを気取られたりするとどういう顔をして読めばいいのかもわかりませんが)。

問題はここですね。
「論理」や「計算」という語の用法とそれに基づいた大量の思弁。
これが本書のエッセンスです。
エッセンスをナンセンスだと感じるのであれば、たしかにどうしようもないでしょう。
そして、この「論理」や「計算」の関係性については、
私は誰よりもわかりやすく本書で解説している自負があります。

あと、哲学ですが、「誤解に基づいたものに過ぎません」とか、もう
「拙劣」「不当に同一視」「ナンセンス」「誤解」「理解していない」ととにかく、侮辱するための、まさに「ワードサラダ」(こういうときに使うのが適切)の最後のピースを揃えただけに見えます。

最後に、もし本書を(ネタではなく)本当に読もうと思った人がいれば、本書ではなく浅井健一『プログラミングの基礎』サイエンス社(2007)と大川徳之『関数プログラミング実践入門』技術評論社(2014)などを読めば、金と時間をムダにせずに済みます

ああまだワードサラダの最後のピースが残っていました。
「ネタ」「金と時間をムダにせずに済みます」ですね。

この一連の侮辱行為の原動力はただひとつ、
「事実に基づかない」「誰でも本みたらすぐバレる」「嘘」です。

最後に、唯一、嘘でない建設的な提案が提示されました。
ある本を推奨する、という行為です。
いつかどこかで、またよく見る光景ですが、これ自体は唯一褒められる行為です。
もちろん、その根底には、恨みつらみかなんか知りませんが、
嘘まで並べ立てて本書をこき下ろすためのろくでもない意図があるわけですが。

さて、いったいいつになったら、私は「不正なノイズ」ではない、まともな「批判」レビューを見ることができて、建設的な技術的論議ができるのでしょうか?

2015年4月27日月曜日

著書のAmazonレビューによる露骨な名誉毀損、業務妨害行為について

私の著書である、
関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間
のAmazonレビュー欄にて、以前からネットストーキングして執拗に誹謗中傷を繰り返す集団を中心に露骨なネガティブキャンペーンが展開されています。

もちろん、著書を出版した以上は、あるいは出版した著書のみならず公に世に出した表現については、相応の批判を受ける覚悟は必要であるし、多少の不正行為も見逃すつもりでいましたが、今回明らかに度を過ぎる行為があったので機微を見極めたうえで当事者として説明しておきます。

直近のレビューでは、

危険な作者が書いた本, 2015/4/26
投稿者 Amazon Customer (埼玉県) - レビューをすべて見る
レビュー対象商品: 関数型プログラミングに目覚めた! IQ145の女子高校生の先輩から受けた特訓5日間 (単行本)
amazonのレビューについて問い合わせた所、作者や出版社からの要望によってレビュワーの個人情報が漏らされる事はありません。
またレビューの内容がamazon側の規約に反していない限り消される事は無いそうです。

なんでここまで書かないといけないかと言うと、この作者は犯罪を捏造して警察に訴える事もあるほど問題のある作者だからです。Twitterで気に食わない相手がいるというだけで警察にしつこく相談し、やがて門前払いされるようになったような人です。twitterや2chで脅迫するなんて何度あったことか。

レビューに本文の引用を記載すると、「著作権の侵害だ!」と訴えられる恐れがあるのでおいそれと内容を書けません。
しかし内容を記載しないと「具体的に何も間違いを指摘していない!お前はデタラメを言っている!」と言われるでしょう。
同じことは何度も繰り返されてきました。
なんでここまで書かないといけないかと言うと、この前提を説明しておかないと、彼の妄言に騙される人が出てくるのです。

もし内容に興味の有る方がいらっしゃったら、一度で良いので関数型言語の勉強会に出席してみる事をおすすめします。Scalaの勉強会は都内で頻繁にやっているのでおすすめです。この本は勉強にも実務にも研究にも役立ちません。ただの一人よがりです。文章はデタラメで読みづらく、「私はこんなに難しい言葉を使ってるんだ。すごいだろう?」と言いたげな酷い内容です。

買うのはおすすめしません。目次を見れば良書では無い事が解るでしょうし、かいつまんで数ページ見てみれば十分なので、本屋さんで立ち読みしてみましょう。

http://www.amazon.co.jp/product-reviews/4798043761/ref=cm_cr_pr_top_recent?ie=UTF8&filterBy=addOneStar&showViewpoints=0&sortBy=bySubmissionDateDescending

enter image description here

まずまず、私も事情を知らずにこんなレビューを読めば、著者はなんて酷い人物なのだろう!と思ってしまうでしょう。公明正大なこのレビュアの言うことは正しい!と思ってしまうでしょう。

では、事実を知る当事者として事実を明らかにします。

まず、私はこのレビュアが誰か知っています。
東京都在住の安田正で、
Twitterアカウントは、@currysitaです。
この人物は、

amazonのレビューについて問い合わせた所、作者や出版社からの要望によってレビュワーの個人情報が漏らされる事はありません。
またレビューの内容がamazon側の規約に反していない限り消される事は無いそうです。

なんでここまで書かないといけないかと言うと、この作者は犯罪を捏造して警察に訴える事もあるほど問題のある作者だからです。Twitterで気に食わない相手がいるというだけで警察にしつこく相談し、やがて門前払いされるようになったような人です。twitterや2chで脅迫するなんて何度あったことか。

なとど書いていますが、もちろんこの記述は建前、「表向きの言い訳」であり、本当のところは、この人物が2011年よりもうかれこれまる4年近く私をネットストーキングし続けている集団の古参メンバーであり、私が彼のことをそれなりに知っている、ということをもちろん彼はネットストーカー当事者として知っており、実際に身元が明らかになれば訴訟リスクの大きいことを繰り返している自覚があり、それ故私に身元を知られると非常に都合が悪い、ということをあたかも公明正大な立場に見せかけて言い訳をしています。

法に抵触する行為を自ら、まるでなんの心配のないかのように先陣を切るようにして行い、同様の行為を助長する目的があからさまな極めて悪質な行為です。

この作者は犯罪を捏造して警察に訴える事もあるほど問題のある作者だからです。

というのは事実ではありません。事実ではない、ことはこのネットストーカー自身がよく知っているはずです。

この人物はネットストーカーによるストーキング行為であることを隠して、公明正大に見せかけたいが、なぜ素性バレているのか?というと理由は単純で、

この「Amazon Customer」のプロフィール、アクティビティを確認すると、
http://www.amazon.co.jp/gp/pdp/profile/AKKPK6R60BSR4/ref=cm_cr_dp_pdp
左下に「公開ほしい物リスト」というのがあります。
enter image description here

これは、以前Amazonの機能としていろいろ話題になったことがあるので知っている人は多いでしょう。

「公開ほしい物リスト」を開くと、
http://www.amazon.co.jp/gp/registry/wishlist/2Q20W91LVFTXZ/ref=pdp_new
enter image description here

お届け先住所 安田正, 東京都

とあります。「ああ、やっぱりね、またか」と私は思うわけです。

安田正@currysitaのTwitterアカウントは、現在非公開にされていますが、
過去の挙動は、サードパーティのログサイトに自身登録していたようで、記録が残っています。
http://twilog.org/currysita/

安田正@東京都板橋区@currysita
274フォロー 474フォロワー 46リスト
電源のあるカフェに出没します。
12/07/28更新 【うちの会社の人はフォロー非推奨!】 J-NSC会員。my日本は辞めた。注視してる政党は自民と共産。 Javaのプログラマ。 虚弱体質でたまに倒れる。 靴も靴下も穴が空くまで履く節約家。 母が山形、父が福島。曹洞宗。 政治と経済好き。 毎週金曜日にカレー食う。

だいたい、私を長年ネットストーキングする人物は、心身になんらかの問題を抱えている人物が多いです。
http://twilog.org/currysita/
をスクロールダウンしていくと、ページ右下に、Hashtagsという統計表があります。
これは、Twitterのハッシュタグでこの人物が言及した回数を示す表であり、引用すると、

Hashtags
日本翼244
英雄橋163
30thou87
ワーワー教80
アキヒロと極東情勢63
しょっぱい配信55
gohantabeyo51
放射脳49
太平観光47
福島45
毛の壁38
福島酪王カフェオレ会36
夜の黒討会32
ISW11F29
五輪27

とあり、「福島」「放射脳」「福島酪王カフェオレ会」という、
2011年の東日本大震災に関連するキーワードがあります。
「放射脳」というのは、当時関連して起こった原子力発電所の事故で、放射能被害を恐れて、ある種のパニック状態に陥った人々を馬鹿にする呼称であり、実は私とこのようなネットストーカーの接点はここに始まります。

私は震災後の当時、「オペレーション・コドモタチ」という、福島在住の乳幼児を抱える母親を支援する、音楽業界の人々のボランティア活動に知人経由で賛同しており、ネット上でそれなりに活動していました。
震災時の原発事故による放射能被害を懸念する混乱した状況のなか、Twitter上で匿名集団による、このような、「#放射脳」であるとか、主に混乱状態に陥っている母親をコケにし、馬鹿にする集団の言動がありました。
もちろん、そうやって混乱状態に陥っている母親をコケにし、馬鹿にする集団行為というのは、彼ら自身のパニック状態の裏返しの過剰な攻撃行為です。
「オペレーション・コドモタチ」のメンバーは本当に怒っておられて、私にも意見を言って欲しいと相談を受けました。
その過程で、私は彼らの匿名を悪用した社会通念上許されない卑劣な言動について批判しました。彼らにとっては、そういう「ネット人格」を否定されることは、それこそが彼らの本性であるので、自身の人格否定につながるわけで、必死に反発するのですね。
この人物はたまたま、安田正という実名ですが、これは非常に稀なことです。
日本翼244
英雄橋163
というのも、当時の放射能被害について憂いてある一定の発言を繰り返し、このような卑劣な集団の言動を批判したことにより、連中の反発を受け、やり玉にあげられた方々を侮辱するためのハッシュタグです。
毛の壁38
というのは、Ken Okabe kenokabeから変化させて、私を標的に侮辱するためのハッシュタグで、これは芦田真一@tikuwa_zero @tikuwa_oreという、児童ポルノを投稿したことによりTwitterから追放処置になった誹謗中傷の常習犯によって作成されました。@tikuwa_zero @tikuwa_oreは注意深く自身の実名をネットに露出させないように私に限らず複数人相手に誹謗中傷、ヘイト行為に勤しんでいましたが、なんで私が彼の実名を知っているのか?というと、後述する通り、この人物を刑事告訴した結果、神戸地検が処分結果を文書で被処分者名とともに通知してきたからです。

以上のハッシュタグは現在もずっと悪用されています。
Twitter本社はこのような、特定個人をバッシングするヘイト、Abuse行為については長年放置しており、無法地帯であり、これまで多くの被害を生み続けてきました。
近年、特にアメリカ本国ではその無法ぶりが強く批判されるようになり、ようやくAbuse行為については、厳格に取り締まる方針に変化してきましたが、Twitterの日本国内での運営は、客観的に評価して、その本国の方針にまるで追従しておらず実質このように野放しです。
私は何度もその旨、日本語で説明して改善するように申し出ましたが事態はこれまで改善されることはありません。

以上誰でも客観的に追認できるとおり、この、
安田正@東京都板橋区@currysitaは、以前から執拗なヘイト行為に加担している悪質な古参メンバーですが、もちろん私が彼を認識したのは、私を侮辱、誹謗中傷するための「毛の壁」というハッシュタグに熱心に書き込んでいるからその存在を知ったわけです。
一般に、ヘイト行為というのは常に一方的な犯罪行為であり、何もないのに被害者が加害者のことを言及するわけがありません。ヘイト行為の加害者は、常にこういう「集団で叩ける対象」を探し求めており、
日本翼244
であるとか、
英雄橋163
であるとか、
毛の壁38
であるとか、相手を変えながらずっと個人攻撃を集団的に一方的に繰り返しているわけです。

私は1年ほどずいぶんと辛抱しましたが、家族も巻き込まれはじめたこと、また過去のビジネスについて「詐欺師」などと書かれ、事実と異なるまとめが拡散され社会的、経済的に被害が出てきたことから、2012年に兵庫県警に相談しはじめて、最終的に誹謗中傷集団の中心メンバーであり「毛の壁」というTwitterハッシュタグを作成し、2chスレッドでのヘイト行為を開始した、芦田真一@tikuwa_zero @tikuwa_oreをはじめ複数人物を、名誉毀損罪と侮辱罪で刑事告訴しました。
もちろん、これは非常に手間も時間も費用もかかることであり、できればこんな面倒なことはしたくなかったですが、ネットのヘイト行為がどれだけ執拗で悪質で、その結果、甚大な影響と被害をもたらすのか?昨今特に世の中で大きく認識されていることだと思います。
結果的に、複数犯が神戸地検より、告訴事実の犯罪構成性がみとめれて起訴猶予処分となりました。
もちろん「告訴受理」や「不起訴処分」が最終的な問題解決になるわけもないので、今現在彼らが悪質に継続している事実も含めて、さらなる対応が必要でしょう。
今現在、巷では「毛の壁」という侮辱呼称を、なんの悪気もなく使っている人々を目にしますが、以上のような経緯から私には許容できないものであり、それは非常に悪質な誹謗中傷犯により考案されて、彼は「しめしめ、俺の作った毛の壁が世に広まって認知されている、俺は正しいことをした」と思っているわけです。

この作者は犯罪を捏造して警察に訴える事もあるほど問題のある作者だからです。Twitterで気に食わない相手がいるというだけで警察にしつこく相談し、やがて門前払いされるようになったような人です。twitterや2chで脅迫するなんて何度あったことか。

というのは事実ではありません。
「犯罪を捏造した」事実などはない、ことはこのネットストーカー加害者自身がよく知っているはずです。
「Twitterで気に食わない相手がいるというだけ」ではそんな面倒なことはしません。
「警察に訴える」というのも、それ相応の被害があったからであり、それがどういう被害なのかは、繰り返しになりますが、昨今のネット上の振り切った暴力、どれほど執拗でどれほど悪質な行為が集団的に行われるのか?それなりに見聞きして理解しており察することのできる人々は多いことでしょう。
「やがて門前払いされるようになった」というのも事実と異なります。
最終的に告訴は受理され、一応は捜査もされ、神戸地検から処分があったことは公に確認可能な事実です。繰り返しになりますが、もちろん「告訴受理」や「不起訴処分」が最終的な問題解決になるわけもないので、今現在彼らが悪質に継続している事実も含めて、さらなる対応が必要でしょう。

ネット犯罪については警察の動きが非常に鈍いことだけは、残念ながら事実であり、それはこういう加害当事者にとっては非常に嬉しいことなのですね。

以下、この人物によるレビューは論評に値しません。
目的は、単にまる4年間、ネットストーキングし続けている私の足を、この機会でも引きずり下ろすことであり、いかに自分が公明正大であるかのごとき装いながら、素性を隠し、私が異常な人物であるか不正な印象操作を公に拡散することです。

危険な作者が書いた本、というのも、それは実際に執拗で悪質な誹謗中傷行為を繰り返し、刑事告訴された集団にとっては確かに危険なのでしょう。

名誉毀損、というのは、言論の自由との兼ね合いによって判断される罪状です。
今回の安田正の行為については、まる4年に渡るネットストーキングによっても明白ですが、なんら正当性などなく、極めて一方的な個人攻撃であり、その悪質な目的は明白です。
またそれにとどまらず、著書に紐づけて、このような不当な個人の評価をもって売上を妨害する目的があるのも明らかです。業務妨害になる、と私は信じます。

そしてこのように被害を訴えると、それが「脅迫」である、と非常に盗っ人猛々しいと形容するしかない自身が被害者ぶるのが、この一連の加害者の手口であり、これは何度も繰り返されてきました。

この集団は、他者の心情、人権、もろもの権利に一切の配慮を示すことなく、自身の鬱積した現状の憂さ晴らし、暇つぶし、「面白いコンテンツだ」「いじり甲斐があるネタだ」などと愉快犯的感情をあらわにしながら、相手をとっかえひっかえしながら、ずっと個人攻撃し続けているわけです。

他者の心情、人権、もろもろの権利に一切の配慮を示すこともなく、ただただ面白おかしく特定個人を貶め、社会的信用を貶め、経済的被害を与えることを目的にヘイト行為を延々と繰り返するような人物、集団に情状酌量の余地などないわけですが、自身の権利だけには敏感で、「脅迫された」というのが彼らの手口です。

私は特に、今回の著書についての言論活動について、このような暴力行為が介入することは許せないと思っています。

レビューに本文の引用を記載すると、「著作権の侵害だ!」と訴えられる恐れがあるのでおいそれと内容を書けません。 しかし内容を記載しないと「具体的に何も間違いを指摘していない!お前はデタラメを言っている!」と言われるでしょう。

論評のための著作物の部分的引用は、常識的に社会通念上でも法的にも認められている正当な行為です。
具体的な技術的反論のために、引用するのは歓迎しますし、そもそも別に技術論で正確な文面の引用が必要なのかさえ疑問ですが。
いずれにせよ、少なくともこの安田という人物が、出来もしないことをあたかも出来るように見せかけ、出来ないことを言い訳しているだけです。

他の一部の良識あるコメントにもありましたが、「お前はデタラメを言っている!」と言うまでもなく、論外であるわけです。

言論、あるいは学術的、技術的主張を正すには、同じ土俵で語るべきであり、このような暴力行為によってねじ伏せようとする卑劣な手段が許せないと思っています。
「具体的に何も間違いを指摘していない」、そのとおりですね。
出来ないから、個人攻撃と結びつけて、こうやって言い訳をしているのでしょう?

経済的に多大な影響もあるので、今後私はやむをえず対応を取ることになります。
安田氏におかれましては、そのレビューの文言が事実であると信じるのであれば、そこで読み取れるとおり、公明正大であるとご自身の言動についてなんら恥じることがないのであれば、そのままそのレビューを掲載しつづけてください。以上のようにその証拠についてはすでに保存していますし、いずれにせよ今更「証拠隠滅」したところで、行為が消えることはありません。

今回の出版が公式にアナウンスされた途端、出版元の秀和システム社へTwitter
を中心に矛先が向きました。非常にわかりやすい反応です。

昨今社会的に大きく語られるようになった、子供たちの学校での卑劣で深刻なイジメ問題があります。
そして大人になってからもネットバッシングで、同じようなことを繰り返す愚かな連中がいます。

「イジメ」ネットバッシングで、一番効果的なのは、ターゲットを孤立無援にすることなんですね。
彼らはそういうことを悪賢いのか、あるいは本能的にわかっているのか一様にやります。
一様に同じように異口同音にやるパターン形成するので一目でそれとわかります。わかりやすいです。

「ずいぶんと酷い文章を書いているのね」と、編集者は著者の文章力を特訓すべき

だとか、

こんなオカルトが出版まで至ってしまったとは、編集者や出版社の罪は深いなと思います。

だとか、

稀に見る悪著。初心者は触るな危険。秀和システムは猛省を

だとか、

そのような著者の本を出した秀和システムは今まで技術者向け出版社としてあった一定の評価を
著しく下げざるを得ず、どのような経過は知らぬが猛省を求めざるを得ないレベルである。

などと、
彼らにとっては、担当編集者や秀和システム社に「出版の判断を間違った」とおもわせたら、私が出版業界で孤立することに成功するわけで、まさにそこを狙っているわけです。

これは、Twitterで、出版が告知されたと同時に、秀和システム社を名指しで叩き始めた群衆とまったく同じ心理ですし、同様に非常にわかりやすい言動で、まさに、その狙いが露骨に現れている、語るに落ちるレビューです。

ただし、無駄なんですね。
何故ならば、担当編集者の方、秀和システム社は、すべての事情を了解した上で、本書の企画を打診していただき、企画も社内一致で通していただき、実際このような反応は事前に見越した上で我々はここまで進めてきたのです。非常に勇気ある毅然とした出版社で、私は現在、秀和システム社に絶大なる信頼を置いています。 
もちろん事前に、このように卑劣なAmazonレビューが予想できることは我々は話し合っていましたし、当然の想定の範囲内でした。

誹謗中傷に勤しむ集団が思うほど、世の中は馬鹿であるわけもなく、良識ある人々が多いのです。

今回、私の不徳から、このように秀和システム社にご迷惑をおかけしていることは本当に申し訳ないと思っています。そして、秀和システム社は上記のような事情を理解していただいた上で、私を信頼していただき、従前からそのような卑劣な攻撃には影響を受けないと何度もわざわざご連絡いただいたことについても、多大な感謝をしています。
どういう卑劣な行為を試みようと、それは完全に見透かされており、連中が望むように、我々の信頼関係が崩れることはありませんし、私が孤立することもありません。

Qiitaの件については、
関数型プログラミングとQiita界隈の騒動について
また、
関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い
で、説明していますが、根本は、以上のような悪質なヘイト行為と関連があります。

私が投稿した技術記事には、記事内容とは無関係な、上記のようなヘイト行為を拡散すべくコメントが執拗に何度も繰り返されました。
私は、その対応についてQiiita運営に何度も通報、お願いを繰り返しましたし、抜本的な改善処置を取るように進言もいたしましたが、長期間いたちごっこのような状態が繰り返され、いざある一定の機能をようやく実装したら、面倒になった私のアカウントを凍結してしまいました。
たしかに「厄介払い」であったのは間違いないでしょうが、そもそもそのようイタチごっこを繰り返すのはいい加減したらどうか?という私の進言も考慮されることなく、その状態を許容したのは、運営の怠慢であると思いますし、結果的にその対処は、「社長の署名つきで追放された」と、誹謗中傷犯の中心メンバーである芦田真一@tikuwa_zeroをはじめ、一連のヘイトを執拗に繰り返すメンバーを大喜びさせました。
そして、私の技術的内容が間違っているとQiitaがお墨付きを与えたというような文脈で現在デマが拡散されており、もちろん彼らはそれが事実ではない、という情報を眼にしながらも、それは個人攻撃や技術的不正確さを喧伝するために障害になるので、見ないことにし訂正もすることなくデマを拡散し続けています。

一方、秀和システム社は、出版元に矛先を向けるという「ターゲットを孤立させたい」連中のわかりやすい目論見と裏腹に、彼らの風評に結果的に悪用されることになったQiitaの対応とは異なり、冷静に事態と事実を見極め、彼らの「暴力」に屈することはなく、「言論の自由」を担保する立派な出版社である、と今後評価は良識ある言論界において名声は高まると私は信じて疑いません。

秀和システム社は、このような前例を見ないプログラミング書籍の出版を英断されて、形にされました。それが気に食わない一定の層が存在するのも了解しますが、それを以上に説明したような「暴力」で牽制することは、この現代日本であってはならないですし、ターゲットを孤立させたい、関係を分断したいという邪な目論見をもって、出版社に矛先を向けて、それに大なり小なり加担する勢力は自らの言動を恥じて然るべきでしょう。

繰り返しになりますが、本書はプログラミング技術についてフェアに解説する書籍であり、その根幹となる技術の誤りがある、もしくは異論があるのであれば、同じ技術の土壌で論じるべきであり、それが広い技術者、入門者、学習者にとって有益で彼らが求めていることであるのは言うまでもありません。

また、同様に無責任な匿名発言が横行するHatenaブックマークでも、
「こんな人でさえ本出せるからみんな本書こうぜというエール」というコメントがありました。

はい、そうですね。「文句があるなら、同じ土俵で言論をもって対抗すればよい」のであって、「みんな本書こうぜ」と「こんな人でさえ」出来ることを「みんな」簡単に出来るのであれば、自由にやれば良いのであって、そうは言っても現実は厳しく困難でしょうから、少なくともブログでも、Qiitaの記事でもきちんとまとまったものを書けば良いのではないでしょうか?

言論において、批判的言説は重要ですが、現状ネットにはびこる多くの「悪口」は批判の体をなしていません。まず、そのほとんどすべてが匿名による文責を負わない無責任な書捨てであり、私が観察する限り、現状の私と著書に関する「かきこみ」についても、アンフェアで、不公正な、くだらない卑劣な誹謗中傷や当てこすりばかりで、そんなことを繰り返して本当に賢明な読者層が騙されると思っているのでしょうか?このように私は言うべきことはきちんと公表しますし、賢明な世論はどちらの言い分が正しいのかきちんと判断されることでしょうし、たとえ短期的にくだらない目論見が効力を発揮しているように見えても、中長期的にそのような不正な暴力が言論を圧倒することは古今東西ありません。

「ペンは剣よりも強し」というのは、現代においては、その剣っていうのは、連中が懸命に展開しているネットのヘイト行為、誹謗中傷行為である、と意味が変わってきました。ろくでもない連中が持て余す暴力は、現代日本においては厳しい法的管理下にあるので、その矛先をネット上の言葉の暴力へ転嫁させているのですね。そして残念ながらその暴力への規制は十分ではありません。

剣でなく、ペンであれば、私は大歓迎しますし、それならば、このような不快なエントリもする必要もなく、有意義な技術論が展開できることでしょう。それは世の中の役にたつはずです。

著者である私も出版社の編集部も、もちろん著書の評価は気になります。
そしてそれは以上のような、「暴力」が影響している評価ではありません。
それは単なる除去すべき不正なノイズであり、連中は不正なノイズを加える事自体に不正な愉悦を感じている異常な集団であるのは今更言うまでもありません。
何をどう頑張ったところで、不正なノイズ=公正な世の評価、と論理的になるわけがないのであって、我々が知りたいのはあくまで、公正な世の評価です。

もちろん、公正な世の評価にだって、一定の振り幅はあるでしょうし、賛否両論があるのでしょう。しかし、不正なノイズ、「暴力」は「否」にはカウントされません。それはノイズであって、論評には値しません。

暴力、不正なノイズを除去した後の評価から、賛否を見極めていきたいわけですね。
その賛否には、今後学ぶことが多いはずですし、批判には謙虚に学ぶ部分が大きいと思います。

いつか誰か、知見を持つ公正中立なポジションのオープンマインドな論者がフェアな書評を書いてくれたら良いな、と思っていますが、気長に待っています。
JavaScriptが世に公正に認められるまでには10年かかりましたが、本書もそうなるかもしれません。

2015年4月24日金曜日

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

関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間
enter image description here
で、内容の流れ、紙面、諸々の都合で書ききれなかった、React (.js Facebook)の補足解説で、本書の読者のためのサポート記事です。
著書では、前章からの流れを受けて、関数型プログラミングの考え方とReact公式ページによる導入を踏まえてReactを解説していますが、この記事はその延長かつ、別方向からの切り口での補足解説記事という位置づけです。
広い読者に向けて、この記事単独でもReactに入門できるように(なるだけ)書きます。

原始のWebのHTML 【宣言型コード】

HTMLコード
<html lang="ja">
 <body>
  <div>
   <h1 lang="en">HyperText Markup Language</h1>
   <p>HTMLは、<a href="http://ja.wikipedia.org/wiki/SGML">SGML</a>
      アプリケーションの一つで、ハイパーテキストを利用してワールド
      ワイドウェブ上で情報を発信するために作られ、
      ワールドワイドウェブの<strong>基幹的役割</strong>をなしている。
      情報を発信するための文書構造を定義するために使われ、
      ある程度機械が理解可能な言語で、
      写真の埋め込みや、フォームの作成、
      ハイパーテキストによるHTML間の連携が可能である。</p>
  </div>
 </body>
</html>
上記のHTMLコードをブラウザで表示(実行)すると、以下のような結果になります。


HyperText Markup Language


HTMLは、SGML
アプリケーションの一つで、ハイパーテキストを利用してワールド
ワイドウェブ上で情報を発信するために作られ、
ワールドワイドウェブの基幹的役割をなしている。
情報を発信するための文書構造を定義するために使われ、
ある程度機械が理解可能な言語で、
写真の埋め込みや、フォームの作成、
ハイパーテキストによるHTML間の連携が可能である。


HTMLは、
文書構造を定義する
宣言型コードであり、タグの入れ子構造と上下関係で、文書が定義されます。
あくまでWebページ=文書という静的な対象を定義するためのコードで、HTMLコードの上下関係→文書の上下関係と物理的に対応しています。HTMLコードの構造は単純明快です。
enter image description here

進化したWebのHTML+JavaScript 【命令形コード】

Webはあっという間に世界中に普及して、
静的なWebページ=文書

動的なWebアプリケーション=ユーザ・インタフェース
へと進化しました。
土台となる、静的で宣言型である、
コードの各要素(エレメント)を、オブジェクト指向のオブジェクトとして扱い、JavaScriptで動的に操作するという命令形プログラミングになりました。
enter image description here

さらに進化した次世代WebのReact JSX(HTML+JavaScript) 【宣言型コード】

動的なWebアプリケーション=ユーザ・インタフェースは、洗練され複雑化していきました。
Facebookは肥大化、複雑化する自サイトを再構築するために、新たな技術Reactを開発します。
Reactは関数型プログラミングの潮流にあり、コンポーネント指向の宣言型コードでWebアプリケーションを構築します。
かつては、HTMLで宣言的に記述して、JavaScriptで動的に操作していた、分断されていた構造は、Reactでは、JavaScriptを拡張したJSX言語で統合的に宣言型コーディングします。
HTMLはWebの既存のプロトコルとして、JSXを起動する枠組みだけが残ります。
enter image description here
この図のように、React JSXで、統合的に宣言型コーディングすると何故良くなるのか?というのは、何故、関数型プログラミングが良いのか?というのとまったく同じ事を語ることであり、まったく同じ理由なので、その辺りは延々と本稿の冒頭で引用している記事やその延長の著書で解説しているのでそちらを参照してください。
動的なWebアプリケーション=ユーザ・インタフェースを、静的な宣言型コードで書くために必要なのは、関数型プログラミングの潮流にある関数型リアクティブプログラミング(FRP)の手法です。
ReactはFRPの機能が実装されています。
FRPは著書でも関数型プログラミングの考え方、命令型プログラミングとオブジェクト指向からのパラダイムシフトとして解説していますが、重大な発想の転換が必要です。
Reactを理解するには、
1.HTMLからJSXへの移行
2.JavaScriptからFRPを伴うJSXへの移行
と複数の要素があるのですが、本稿では、特にFRPを必要としない静的なドキュメントを、HTMLからJSXへ移行させる基礎固めに、まず注力し、その後でFRPも含めて解説します。

静的なドキュメントをHTMLからReact JSXに移行、最初の一歩

HTML

単純なHTMLコード
classic00.html
<div>Hello</div>
表示結果

Hello

をJSXに移行させます。

React JSX

まずは、単にReact JSXを起動する枠組みだけのHTMLを用意します。
react00-0.html
<!-- The core React library -->
<script src="http://fb.me/react-0.12.1.js"></script>
<!-- In-browser JSX transformer, remove when pre-compiling JSX. -->
<script src="http://fb.me/JSXTransformer-0.12.1.js"></script>

<script type="text/jsx" src="react00-0.js"></script>
react00-0.js ←JSX
var HelloComponent = React.createClass(
{
  render: function()
  {
    return (<div>Hello</div>);
  }
});


var mount = React.render(<HelloComponent/>, document.body);
表示結果

Hello

ファイル名をreact00-0.jsとしていますが、
JavaScriptを拡張したJSXのコードであり、拡張子もjsxとしても構わないですし、そろそろそのような作法が推奨されてきています。
React JSXでは、コードの最後に必ず唯一の、document.bodyあるいはその他のHTMLドキュメント部分に唯一ReactのElement(エレメント)をマウントする宣言で終わります。
var mount = React.render(<HelloComponent/>, document.body);
上のコードでマウントしているElementは、
<HelloComponent/>です。

React JSXのElement(エレメント)は、ファーストクラス・オブジェクト

React JSXのElementはJSX上では、
<HelloComponent/>というように、従来のHTML(あるいはXML)のタグとまったく同じ表記ですが、JavaScript(JSX)のコード内でシームレスに、ファーストクラス・オブジェクトとして扱われます。
<HelloComponent/>は、ファーストクラス・オブジェクトであるので、普通に、
var HelloComponentEL = <HelloComponent/>;
というように、任意の変数として定義もできます。
var mount = React.render(<HelloComponent/>, document.body);
は、
var HelloComponentEL = <HelloComponent/>;

var mount = React.render(HelloComponentEL, document.body);
と、書くことも出来ます。

ReactのComponent(コンポーネント)

<HelloComponent/>というReactのElement(エレメント)は、
オブジェクト指向のオブジェクトのインスタンスに似ており、
その背後の設計としての
オブジェクト指向のオブジェクトのクラスに似た存在があります。
それが、ReactのComponent(コンポーネント)です。
<HelloComponent/>というReactのElement(エレメント)の背後にある、ReactのComponent(コンポーネント)は、タグ表記部分を外した、HelloComponentとして、
オブジェクト指向のオブジェクトのクラスのように、設計します。
var HelloComponent = React.createClass(
{
  render: function()
  {
    return (<div>Hello</div>);
  }
});
逆に言うと、設計したReactのComponentをタグ表記にすることで、ReactのElementに「インスタンス化」することができます。

ReactのComponent(コンポーネント)指向をオブジェクト指向との類似で理解し、オブジェクト指向との明確な差異を理解する

Reactはコンポーネント指向であり、
オブジェクト指向のオブジェクトのクラスとインスタンスにあえて類比させると、
Reactの
Component(コンポーネント)は、オブジェクトのクラス
var HelloComponent = React.createClass(
{
  render: function()
  {
    return (<div>Hello</div>);
  }
});
Element(エレメント)は、オブジェクトのインスタンス
<HelloComponent/>
と類比することができます。
以上はあくまで導入のための類比部分で、以下に差異を説明します。

ReactのComponent(コンポーネント)は、必ず、なんらかのElement(エレメント)を返す関数

オブジェクトと決定的に異なるのは、
Reactの
Component(コンポーネント)は、
必ず、なんらかのElement(エレメント)を返す、
 render: function()
  {
    return (<div>Hello</div>);
  }
ということです。
これは、関数型プログラミングにおいて、
すべての関数が、必ずなんらかの返り値を返す、
という仕組みとまったく同じであり、
コンポーネント指向のコンポーネントとは、
関数型プログラミングの関数と振る舞いが同一であるということです。
コンポーネント指向のコンポーネントとは、
何らかの入力を受けて何らかの出力を返す、関数であり、
Reactの場合、その出力は、常にElementです。
(もう少し広くコンポーネント指向のコンポーネントを定義すると、それは、上記のような関数を含めるすべてのファーストクラスオブジェクトであり、たとえば、
[0,1,2,3]というファーストクラスなも、
[0,1,2,3]という出力を常に返すコンポーネントであると見做すことができます。)
ReactのComponentは、<HelloComponent/>というように、
タグ表記で囲むことで、「インスタンス化」され、Elementとなるわけで、このようなElementを関数型プログラミングの最小単位としての関数と同様に、合成していきます。
そして、その合成の仕方とは、HTMLのタグで文書構造を構築するのとまったく同じ方法で宣言していきます。
Reactの目的はUIの構築ですが、HTMLの作法で、エレメントの物理的上下関係の構造をつくることで、そのままUIの部品の物理的関係の合成、構築となり、この作業を入れ子構造的に繰り返します。
Reactに限らず、コンポーネント指向のコンポーネントは、関数なので、外部の環境に命令すること、副作用は起こしてはいけません。
ReactのコンポーネントであるElementは、自律的に完結しており、外部からの入力を受けて、適切な別のElementを返す、という多重構造になっています。
そのための関数的な機構と、時間変化に対応するFRPとしての機構の2種類がありますが、後述、詳述します。

ReactのElement(エレメント)は、オブジェクトのインスタンスではない、物理的なDOMではなく、論理的な仮想DOM

ReactのComponentは、タグ表記で囲むことで、「インスタンス化」され、Elementとなりますが、これは、HTMLのエレメントと同じように、論理的構造を構築している論理的存在に過ぎず、明確にメモリを確保して物質的存在として振る舞う、オブジェクト指向のオブジェクトのインスタンスではありません。
このようなReactのElement(エレメント)のような存在を特に、VirtualDOM(仮想DOM)と呼びます。
もともと、DOM(DocumentObjectModel)とは、純粋に論理的存在であったHTMLタグ要素を、オブジェクトとして操作するためにオブジェクト指向で設計されたAPIですが、その単位であるオブジェクトを仮想化して、再び論理化した、VirtualDOM(仮想DOM)が、ReactのElementである、ということです。
Reactの内部設計として、VirtualDOM(仮想DOM)の計算結果から、実際にUIの更新操作に必要となる差分だけがDOM操作されることになります。プログラマは直接DOM操作することはありません。
もう少しフェアに言うと、React JSXコードの最後の、
唯一の、document.bodyあるいはその他のHTMLドキュメント部分に唯一ReactのElementをマウントする宣言部分のみが、リアルDOMと接触する箇所です。

もう一度、静的なドキュメントをHTMLからReact JSXに移行、最初の一歩

以上の理解を踏まえながら、もう一度、

HTML

単純なHTMLコード
classic00.html
<div>Hello</div>
表示結果

Hello
— をJSXに移行させます。

React JSX

react00-1.html ←JSXを起動する枠組みだけ
<!-- The core React library -->
<script src="http://fb.me/react-0.12.1.js"></script>
<!-- In-browser JSX transformer, remove when pre-compiling JSX. -->
<script src="http://fb.me/JSXTransformer-0.12.1.js"></script>

<script type="text/jsx" src="react00-1.js"></script>
react00-1.js ←JSX
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>Hello</div>);
    return el;
  }
});

var HelloComponentEL = <HelloComponent/>;
var mount = React.render(HelloComponentEL, document.body);
HelloComponentはReactのComponentなので、
必ず、ReactのElementを返すわけですが、
その、Elementは、
var el = (<div>Hello</div>);で定義しています。

鶏が先か?卵が先か?ElementComponentか?一番最初のパーツは何か

<div>というのは、
これは見ての通り、既存のHTMLでお馴染みのタグです。
既存のHTMLでお馴染みのタグ、のように見えますが、
実際は、すでに説明したとおり、これも、
ReactのVirtualDOM(仮想DOM)であり、
ReactのElementなので、
もともとは、ReactのComponentで、
HelloComponentと同じようにどこかで設計されていたはずだ、と考えてしまいます。

ReactのElementとは、Componentによって設計されて、
Componentをタグ表記で「インスタンス化」したものが、
Elementになっています。

Componentを設計する際には、必ず、Elementを返します。
そのElementは、必ずもともとは、どこかで設計されたComponentで、
と鶏が先か?卵が先か?の延々多重構造になっていることに気がつくことでしょう。
じゃあ、そもそもの一番最初の鶏か卵か、
ElementComponentか、
それは一体何だったのでしょうか??

ネイティブなReactのComponent(コンポーネント)

実は、<div>というElementは、どこかで、
var div = React.createClass(
{
  render: function()
  {
    var el = (????????????);
    return el;
  }
});
などと、わざわざ定義をする必要がない
ネイティブなReactのComponent(コンポーネント)です。
このdivのような、ネイティブなReactのComponent(コンポーネント)を起点として、ユーザはオリジナルなコンポーネントを設計して、いわば、カスタマイズされたHTMLタグ=Elementを「インスタンス化」して、HTML構造と同じような表記でコンポーネントを合成していくわけです。
実際、このような、ネイティブなReactのComponentと、ユーザが定義するComponentは、Reactでは厳密に区別されており、その印として、
ネイティブ・コンポーネントの名前は、頭文字は小文字、
オリジナル・コンポーネントの名前は、頭文字は大文字、
という独特の表記ルールがあります。この表記ルールを守らなければReactは適切に動作しません。
https://facebook.github.io/react/docs/jsx-in-depth.html#html-tags-vs.-react-components

もう少しだけ複雑な、静的なドキュメントをHTMLからReact JSXに移行


classic01.html


<div>
  Hello
  <div>child</div>
  <div>child</div>
  <div>child</div>
</div>
Hello
child
child
child

という、もう少しだけ複雑な、静的なドキュメントをHTMLからReact JSXに移行させることを試みます。
単純に、
  var HelloComponent = React.createClass(
  {
    render: function()
    {
      var el = (
        <div>
          Hello
          <div>child</div>
          <div>child</div>
          <div>child</div>
        </div>
      );
      return el;
    }
  });

  var mount = React.render(<HelloComponent/>, document.body);
というように、HelloComponentが返すElementである、
elの値を上記HTMLにしてやれば、いとも簡単に移行できます。
しかし、いざ、ReactのElementがファーストクラスであり、
自由自在に取り扱えると理解してしまった、少なくともその可能性を感じることができる今となっては、
<div>child</div>を何度も繰り返す冗長性が気になるはずです。
<div>child</div>は別のコンポーネントとして切り出して、別途定義してやったほうが、上のコードの冗長性は排除できるし、今後自由度が上がり、出来ることも柔軟に増えてくるはずです。

ChildComponentを定義して、コンポーネントを自由に組み合わせる

そこで、
<div>child</div>は、
ChildComponentとして、
別途切り出して定義しなおします。
定義した
ChildComponentというComponentを、
「インスタンス化」してやると
<ChildComponent/>というElementとなるので、
<ChildComponent/>= <div>child</div>
である、ということです。
実際は、上記のように、
ElementElement
というような定義の表記は出来ないので、
整合的に、まず
ChildComponentというComponentを定義してやり、
そこから、改めて、
<ChildComponent/>というElement
「インスタンス化」してやる、という作法です。
結果的に、
<ChildComponent/>= <div>child</div>
となるような、
ChildComponentというComponentを定義する方法は、
もちろん、
var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child</div>);
    return el;
  }
});
であり、結果的に、
<ChildComponent/>= <div>child</div>となるのだから、
HelloComponentの定義は以下のようになり、冗長性が排除されました。
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildComponent/>
        <ChildComponent/>
        <ChildComponent/>
      </div>
    );
    return el;
  }
});
普通に、全体のコードはその2つのコンポーネントの定義を並べた、以下になります。
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildComponent/>
        <ChildComponent/>
        <ChildComponent/>
      </div>
    );
    return el;
  }
});

var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child</div>);
    return el;
  }
});

var mount = React.render(<HelloComponent/>, document.body);
これが、Reactでコンポーネントを設計し、エレメントにして組み合わせて、また別のコンポーネントの返り値として設計する、という基本です。ひたすらこういうことを繰り返します。
単純な静的なHTMLコードをJSXに置き換えたのですが、HTMLのElementが、ReactではJavaScript(JSX)のファーストクラスとして扱えることにより、自由度が上がり始めたことがわかるでしょう。

ChildComponentから、ChildrenComponentを定義して、さらにコンポーネントの冗長性を排除することを試みる 


 もう、こうなると、次は、
<ChildComponent/>
<ChildComponent/>
<ChildComponent/>
という、「同じものの繰り返し」が気になってくるわけです。
現行では、3回の繰り返しでなんとかなってはいるが、
もし、これが100回の繰り返しだとどうするんだ?とかですね。
実際に、Webアプリを構築すると、こういうコンポーネント・エレメントが延々と繰り返して登場する、登場させたい設計は普通に出てくるわけです。たとえば、TwitterやFacebookのタイムラインもそうでしょうし、まさにああいうパーツを柔軟なコンポーネントとして定義して上手くやる、というのが、このReactの真骨頂なのです。
3回連なっている冗長な部分、
<ChildComponent/>
<ChildComponent/>
<ChildComponent/>
あるいは、TwitterやFacebookのタイムラインの枠組みとなるUI部分は、
ChildrenComponentとして、
ひとつのコンポーネントにまとめてしまいましょう。
故に、大枠である、
HelloComponentの設計は以下のようになります。
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildrenComponent/>
      </div>
    );
    return el;
  }
});
一番低レベルのコンポーネントである、
ChildComponentは同じ。
var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child</div>);
    return el;
  }
});
いよいよ、ChildrenComponentの設計ですが、
var ChildrenComponent = React.createClass(
{
  render: function()
  {
    var elArray = 
     [<ChildComponent/>,
      <ChildComponent/>,
      <ChildComponent/>];

    var el = (<div>{elArray}</div>);
    return el;
  }
});
となります。
ReactのElementはファーストクラスなので、
普通に値として、配列の要素になります。
だから、
 var elArray = 
     [<ChildComponent/>,
      <ChildComponent/>,
      <ChildComponent/>];
というReactのElementの配列が定義できます。
var el = elArray; return el;
と返したくなるのですが、ReactのElementは、必ず一番外側はひとつのエレメントで括られていないいけないと厳密な仕様なので、外側を更に<div></div>でくくる必要があります。
<div>elArray</div>としたいところですが、
これだと、単に、ただの「elArray」という文字列が返ってしまいます。
では、<div><elArray/></div>なのか?
というと、これも違って、
上記の、elArrayの定義は、ReactのComponentとしての定義ではないので、こういう、非ReactComponentを、
ReactのElementとして、仮想DOMとして「インスタンス化」するためには、少なくとも、それらの中に組み込んで同列に表記するためには、{}中括弧で、括ることで明示します。
だから、
var el = (<div>{elArray}</div>);となります。
全部のコードは、
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildrenComponent/>
      </div>
    );
    return el;
  }
});

var ChildrenComponent = React.createClass(
{
  render: function()
  {
    var elArray = 
     [<ChildComponent/>,
      <ChildComponent/>,
      <ChildComponent/>];

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

var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child</div>);
    return el;
  }
});

var mount = React.render(<HelloComponent/>, document.body);
となり、想定通りの表示となりますが、
ChildrenComponentの設計のElementの配列は、繰り返しの冗長さがそのまま残っているわけで、まだ改善しなければいけません。

Componentの関数特性としてのInputとOutput

ChildrenComponentの設計は、もうひとつ道具を揃えてから、あとでまとめてしっかり続きをやるとして、先に、そのもうひとつの道具立てをします。
ReactのComponentは、関数であり、Inputを受け取り、それに呼応したOutputを返します。
返り値は常にElementです。
このComponentの関数特性により、たとえば、前述の、TwitterやFacebookのタイムラインの枠組みとなるUI部分を設計するにしても、あるComponentに適切なInputを入力してやると、それに呼応したUI表示が得られる、というような堅牢な設計が関数型プログラミング、宣言型のコードで可能になります。
このReactのComponentの関数のInputを司るのが、
this.propです。
いわゆるHTMLタグのproperty属性をプログラマが自由に定義して、Inputし、Component内で、関数の引数のように受け取って値を取り回すための機構です。
たとえば、
<div>
  Hello
  <div>child0</div>
  <div>child1</div>
  <div>child2</div>
</div>
Hello
child0
child1
child2

こういう、HTMLコードをReact JSXで、HTML同様に宣言的に、かつ関数型プログラミング的にコンポーネント指向で柔軟に表現したいとします。非常にありがちで典型的なケースでしょう。
さっそく、その具体的コードを見ましょう。
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildComponent input={0}/>
        <ChildComponent input={1}/>
        <ChildComponent input={2}/>
      </div>
    );
    return el;
  }
});

var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child{this.props.input}</div>);
    return el;
  }
});

var mount = React.render(<HelloComponent/>, document.body);
前述の{}中括弧が、活躍しています。
JavaScript(JSX)内の値を、ReactのElement領域に変換して受け渡す糊みたいな役割を果たす表記が、この{}中括弧です。
<div>child0</div>
<div>child1</div>
<div>child2</div>
というのは、冗長なので、
ChildComponent化したやつですが、
今回はさらに、0,1,2と、さらにカスタマイズして表示できるように、コンポーネント化しなければいけません。
そこで、前回のコードをさらに推し進めて、
  <ChildComponent input={0}/>
  <ChildComponent input={1}/>
  <ChildComponent input={2}/>
という風にします。これで、inputというReactのElementpropertyに、それぞれ、012という値が受け渡され、ChildComponentというコンポーネント、あるいは関数の引数となります。
ChildComponentの返り値としてのElementelでは、
var el = (<div>child{this.props.input}</div>);
と、`this.props.input`で、引数が受け取れ、 `{}`中括弧でもちろん変換して`Element`に組み込みます。

ChildrenComponentのElement配列とComponentの関数特性の合わせ技

<div>
  Hello
  <div>child0</div>
  <div>child1</div>
  <div>child2</div>
  <div>child3</div>
  <div>child4</div>
  <div>child5</div>
  <div>child6</div>
  <div>child7</div>
  <div>child8</div>
  <div>child9</div>
</div>
Hello
child0
child1
child2
child3
child4
child5
child6
child7
child8
child9

というように、10個に増やしてみました。
しかも、同じように、カスタマイズ表示が必要です。
いよいよ、まさに、TwitterやFacebookのタイムラインなど、ああいうパーツを柔軟なコンポーネントとして定義して上手くやるReactの真価が発揮できる局面であり、これまでの、HTML+JavaScriptではだんだん実装するのが、しんどくなってくる領域であり、パフォーマンスチューニングの懸念も出てくるような局面です。仮想DOMでリアルDOMには差分でしか描写しないReactはその辺の煩わしさも一切ありません。あくまで論理的に、関数型プログラミングの領域で宣言的に淡々と進行させます。
まず、また冗長性を排除しながらカスタマイズが必要なUI領域を
ChildrenComponentとしてコンポーネントにまとめなおし、その上で、一番外側の最上位のHelloComponentを設計します。
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildrenComponent/>
      </div>
    );
    return el;
  }
});
そして、もっとも低階層のChildComponentは、さっきのコンポーネントとまったく同じです。
var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child{this.props.input}</div>);
    return el;
  }
});
そして、ChildrenComponentの設計です。
var ChildrenComponent = React.createClass(
{
  render: function()
  {
    var createChild = function(n)
    {
      return (<ChildComponent input={n}/>);
    };

    var elArray = [0,1,2,3,4,5,6,7,8,9].map(createChild);

    var el = (<div>{elArray}</div>);
    return el;
  }
});
コンポーネント内部に、
var createChild = function(n)
    {
      return (<ChildComponent input={n}/>);
    };
という、ChildComponentElementを引数nに応じて、自動生成する関数を設計して用意します。
0-9の配列、[0,1,2,3,4,5,6,7,8,9]を用意します。
それに、関数型プログラミング的に、
createChild関数をmapしてやります。
var elArray = [0,1,2,3,4,5,6,7,8,9].map(createChild);
この結果、map高階関数の返り値であるelArrayには、
elArray = 
     [<ChildComponent input={0}/>,
      <ChildComponent input={1}/>,
      <ChildComponent input={2}/>,
      <ChildComponent input={3}/>,
      <ChildComponent input={4}/>,
      <ChildComponent input={5}/>,
      <ChildComponent input={6}/>,
      <ChildComponent input={7}/>,
      <ChildComponent input={8}/>,
      <ChildComponent input={9}/>];
という値が格納されることになります。論理的に。
そして、
var el = (<div>{elArray}</div>);
というChildrenComponentの返り値となるので、
想定した通りの結果が表示されます。
もちろん、関数型プログラミングなので、
繰り返しのフロー、命令形のコードを書くことはありません。
React JSXで、統合的に宣言型コーディングすると何故良くなるのか?というのは、何故、関数型プログラミングが良いのか?というのとまったく同じ事を語ることであり、まったく同じ理由なので、その辺りは延々と本稿の冒頭で引用している記事やその延長の著書で解説しているのでそちらを参照してください。

Facebook-Immutable を使ってさらに関数型プログラミングでReactする

もちろん、
0-9の配列、[0,1,2,3,4,5,6,7,8,9]を用意する、というのは、言うまでもなくスマートなアプローチではないですから、ここも関数型プログラミングにします。
HTMLコードに、
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.6.4/immutable.min.js"></script>
とポインタを追加することで、著書でも解説している、
Facebookのもうひとつの関数ライブラリ、
Facebook-Immutable
が活用できるようになります。
配列、[0,1,2,3,4,5,6,7,8,9]を用意したければ、
 var array = Immutable.Range(0, 9).toArray();
とすれば、良いので、
 var elArray = array.map(createChild);
となります。 全部のコードは、
var HelloComponent = React.createClass(
{
  render: function()
  {
    var el = (
      <div>
        Hello
        <ChildrenComponent/>
      </div>
    );
    return el;
  }
});

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

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

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

var ChildComponent = React.createClass(
{
  render: function()
  {
    var el = (<div>child{this.props.input}</div>);
    return el;
  }
});

var mount = React.render(<HelloComponent/>, document.body);
となります。 念の為ですが、結果は、想定したとおり、
Hello
child0
child1
child2
child3
child4
child5
child6
child7
child8
child9

となります。
以上で、
FRPを必要としない静的なドキュメントを、
HTMLからJSXへ移行させる基礎固めは終了です。
おそらく、この解説で、時間変化を取り扱わない静的なHTMLページをReact JSXに移行することはだいたい出来るはずです。もちろん既存のテンプレートエンジン、プラグインなどをふんだんに利用しているページをなんでも移行できるという意味ではなく、スキルとして静的なHTMLページをより見通しよく冗長性を排除しながら再構築できるはずである、ということです。
時間変化を取り扱う動的なWebアプリケーションをReactで実現するためには、改めてFRPをReactでどのように具現化するか、より注意深く考察しながら取り組む必要があり、それは続く記事で執筆して公開します。

2015年4月17日金曜日

worldcomponent The tiny FRP

http://libraries.io/npm/worldcomponent

worldcomponent 1.0.1

world component tiny FRP module

Homepage: https://github.com/sakurafunctional/worldcomponent

Platform: npm

Language: JavaScript

License: MIT

View on registry: https://www.npmjs.com/package/worldcomponent/

npm test

var ___ = require('./worldcomponent');

var ___a = ___(0);
var ___b = ___(0);

___.world = ___a.compute(___.log('a:'));
___.world = ___b.compute(___.log('b:'));

___.world = ___a.compute(function(x)
{
  ___.world = ___b.appear(x * 5);
});

var f = function()
{
  ___.world = ___a.appear(___a.now() + 1);
};
var timer = setInterval(f, 1000);

a: 0
b: 0
a: 0
b: 0
a: 1
b: 5
a: 2
b: 10
a: 3
b: 15
a: 4
b: 20
a: 5
b: 25
a: 6
b: 30
a: 7
b: 35

worldcomponent.js

var worldcomponent = function(initialVal)
{
  var computingF = [];
  var value = {};
  var state;
  Object.defineProperties(value,
  {
    val: //value.val
    {
      get: function()
      {
        return state;
      },
      set: function(x)
      {
        state = x;
        computingF.map(
          function(f)
          {
            f(x);
          });
        return;
      }
    }
  });
  var o = {
    compute: function(f)
    {
      var f1 = function()
      {
        computingF[computingF.length] = f; //push  f
        value.val = initialVal;
      };
      return f1;
    },
    appear: function(a)
    {
      var f1 = function(){value.val = a;};
      return f1;
    },
    now: function()
    {
      return value.val;
    }
  };

  return o;
};

Object.defineProperties(worldcomponent,
{
  world: //our physical world
  {
    set: function(f)
    {
      return f();
    }
  }
});

worldcomponent.log = function(a)
{
  var f = console.log.bind(console, a);
  return f;
};

module.exports = worldcomponent;

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

enter image description here

バールーフ・デ・スピノザ(Baruch De Spinoza, 1632年11月24日 - 1677年2月21日)は、オランダの哲学者、神学者。一般には、そのラテン語名ベネディクトゥス・デ・スピノザ(Benedictus De Spinoza)で知られる。デカルト、ライプニッツと並ぶ合理主義哲学者として知られ、その哲学体系は代表的な汎神論と考えられてきた。また、ドイツ観念論やフランス現代思想へ強大な影響を与えた。
スピノザの汎神論はプラトン哲学的な一元論でもあり、後世の無神論(汎神論論争なども参照)や唯物論(岩波文庫版『エチカ』解説等参照)に強い影響を与え、または思想的準備の役割を果たした。生前のスピノザ自身も、神を信仰する神学者でありながら、無神論者のレッテルを貼られ異端視され、批判を浴びている。
スピノザの肖像は1970年代に流通していたオランダの最高額面の1000ギルダー紙幣に描かれていた。

純粋関数型プログラミング言語 spinoza

JavaScriptでつくられた、
JavaScriptで動作する、
純粋関数型プログラミング言語
spinoza (スピノザ)。

開発者である筆者の科学的世界観、宗教観である「汎神論」を形成した
哲学者スピノザをリスペクトした命名です。

spinoza Programming Language

spinoza

- is a Functional Reactive Programming (FRP) language

- employs Lazy evaluation strategy

- runs on JavaScript Engines (browsers & node.js)

- is written in JavaScript

spinoza 3.0.2

http://libraries.io/npm/spinoza

spinoza pure functional programming language

Homepage: https://github.com/kenokabe/spinoza

Platform: npm

Language: JavaScript

License: MIT

View on registry: https://www.npmjs.com/package/spinoza/

Hello world

spinoza.world = $('hello')(out);

spinoza.world> [ ‘hello’ ]

スピノザの汎神論はプラトン哲学的な一元論、
つまり数学世界の論理への一元論です。

何をどう一元化したのか?というと、
デカルトが「我思う故に我あり」と方法的懐疑の末に見出した
疑いきれない我々がもつ意識、人間の【精神世界】
そこから合理的に導出したプラトン哲学で語られるイデア論の【論理世界】
あともちろん、デカルトが終生解決できなかった、この我々の目の前に広がる【物質世界】
の3つの要素をすべてイデアの世界の論理へ一元化したのでした。

spinoza.world = $('hello')(out);

この方程式の左辺の
spinoza.world【物質世界】の「現在の事象」です。

この方程式の右辺の
$('hello')(out)【論理世界】の「論理」です。

この方程式の左辺と右辺が等しい、と決めたのはプログラマなので
=【精神世界】における人間的行為である「計算」です。

これら【論理世界】【物質世界】【精神世界】の3つの世界は、
コードという【論理世界】の「論理」として、
コード上で表現される数学の方程式により一元化されています。

$('hello')(out)は、純粋な「論理」です。
これ自体は、【論理世界】にある「論理」でしかなく、
これ自体では【物質世界】には全く反映されません。

しかし、
spinoza.world =と【物質世界】の現在事象と等しい、
と関係性を【精神世界】の人間の意識が規定すると
$('hello')(out)という【論理世界】の「論理」がはじめて
【物質世界】の現在事象として「物質」化されます。
つまり「計算」されます。

spinoza.world> [ ‘hello’ ]

とコンソールに表示されますが、
「論理」からそういう「副作用」として
この【物質世界】にあるコンソールで「物質」化されたという意味です。
この「副作用」は(out)という「論理」により引き起こされています。

$('hello')(out)

というコードならば、
「論理」がただそこにあるだけで、「計算」されません。(遅延評価)

spinoza.world = $('hello');

というコードならば、
「計算」という「物質」化をしても、
$('hello')という「論理」が計算機内部で「計算」されるのみで、
コンソールには何も表示されません。

spinoza npm test


$('hello');
// no computing, lazy evaluation

spinoza.world = $('hello');
// computing, but no output

spinoza.world = $('hello')(out);
// ['hello']

spinoza.world = $('------------')(out);

spinoza.world =
  $('one')(out)
  ($('two')(out))
  ($('three')(out));
//[ 'one' ]
//[ 'two' ]
//['three']


spinoza.world =

  ($('=================')(out))
  ($('hello')('world')(out))
  // [ 'hello', 'world' ]
  ($('------------')(out))
  ($('hello')(out)(out))
  // ['hello']
  // ['hello']
  ($('------------')(out))
  ($('hello')(out)('world')(out))
  // ['hello']
  // [ 'hello', 'world' ]
  ($('------------')(out))
  ($(1)(2)(3)(out))
  // [ 1, 2, 3 ]
  ($('------------')(out))
  ($(1)(2)(3)(plus10)(out))
  // [ 11, 12, 13 ]
  ($('------------')(out))
  ($($(1)(2)(3)(plus10))(out))
  // [ 1, 2, 3, [Function] ]
  ($('=================')(out));



===== spinoza =====
mode: node/io.js
spinoza.world> [ ‘hello’ ]
spinoza.world> [ ‘————’ ]
spinoza.world> [ ‘one’ ]
spinoza.world> [ ‘two’ ]
spinoza.world> [ ‘three’ ]
spinoza.world> [ ‘=================’ ]
spinoza.world> [ ‘hello’, ‘world’ ]
spinoza.world> [ ‘————’ ]
spinoza.world> [ ‘hello’ ]
spinoza.world> [ ‘hello’ ]
spinoza.world> [ ‘————’ ]
spinoza.world> [ ‘hello’ ]
spinoza.world> [ ‘hello’, ‘world’ ]
spinoza.world> [ ‘————’ ]
spinoza.world> [ 1, 2, 3 ]
spinoza.world> [ ‘————’ ]
spinoza.world> [ 11, 12, 13 ]
spinoza.world> [ ‘————’ ]
spinoza.world> [ 1, 2, 3, [Function] ]
spinoza.world> [ ‘=================’ ]

圏論の考え方とは?

圏論とは、もともとは、
【数】というものの代数的構造を論じるための数学理論です。

圏論で考える「【数】というものの代数的構造」とは?

【数】というのは、
無限に自己参照する再帰構造になっている「何か」です。

「1たす1」

で、

「1」という【数】

「たす1」という【数への操作】

が、まったく同じものであるという

【数】=【数への操作】

と、無限に自己参照する再帰構造になっている「何か」であり、
こういう代数構造を論じるのが「圏論」のはじまりです。

圏論で考える「【数】というものの代数的構造」をそのままプログラミングに適用してやると?

【数】

【数への操作】
はまったく同じものです。

プログラミングの言葉で、まったくそのまま言い換えると、

【値】

【値への操作】
はまったく同じものです。

また言い換えると、

【値】

【関数】
はまったく同じものです。

また言い換えると、
【集合】

【写像】
はまったく同じものです。

関数型プログラミングとは、【集合】と【写像=関数】で論理操作を繰り返す数学的なプログラミング手法である

関数型プログラミング言語では、

【関数】が【値】(オブジェクト)として扱える、
【関数】が「ファーストクラス・オブジェクト」であるのは、

プログラミングの土台として存在する数学の代数構造で、

【数】

【数への操作】

あるいは
【値】

【関数】 

あるいは
【集合】

【写像】

の区別が一切ない、同じものである、という根源的な原理をそのまま反映しているのです。

純粋関数型プログラミング言語「spinoza」

以上のような極めてかんたんで至極明快な事実をそのままプログラミング言語としてJavaScriptで実装したのが、

純粋関数型プログラミング言語「spinoza」である、ということになります。

【値】

【関数】
はまったく同じものである必要があるので、
いくら、JavaScriptという関数型プログラミング言語では関数がファーストクラスになっているからといっても、あくまで
【値】≠【関数】
と別々の存在として扱われてしまっています。

これでは我々が希求する「純粋関数型」のプログラミング言語としてははかなり都合が悪いので、
JavaScriptでも徹底的に、
【値】=【関数】
となるようにハックしてやります。

spinozaの基本構造

spinozaの基本構造はもちろん
【値】であり【関数】であり、その両者の区別がまったくない「何か」です。
代数の基本構造として
【数】が【数への操作】とまったく区別がつかない「何か」であることを論じる
「圏論」と同じはなしです。

Lispデータ構造の問題点

ジョン・マッカーシーが開発したLISPは

(関数 引数 引数 引数)

という

S式
で表記され、プログラミング構文が存在しません。

> (+ 1 2)
3

データ=コード
コード=データ
という(一見)美しい構造で、コードを変更するにはデータを変更すればよい、というコード自身を第一級(ファーストクラス)オブジェクトとして扱うことができます。

最近、巷で若干注目を集めている、Javaでも実装されはじめた リフレクション
の最上級機能を言語構造として先天的に実装しているようなもので、自己定義する人工知能研究の分野(マッカーシーの専門分野)でよく使われてきたようです。
 
しかし、私がLISPを関数型言語の大御所として試すなかで問題だと思った事をざっくばらんに書きます。

すでに【脱アルゴリズム宣言】シリーズで述べたように、関数型パラダイムは、まず最初にデータをまるごと用意し、そこに関数操作を加えていくという宣言をするという思考・指向でした。

こういうデータをまるごと用意する、データのコレクション、リストという発想は、LISPのリストがオリジナルなのですが、遺憾なことに

(関数 引数 引数 引数)

っていうのが命令型パラダイムであるのに気づくでしょうか?

(Do what what what)

という構造になっている。

関数型パラダイムであるならば、こう書くべきでしょう。

(What Do Do Do)

(データ 関数 関数 関数)

そして、実際のところ

(関数 引数 引数 引数)

というデータ構造のために様々な目に見える弊害がLISP/Schemeにはあります。

(関数 引数 引数 引数)とS式の最初が(データでなく)関数と決め打ちしているので、

(データ データ データ) たとえば

(1 2 3)

というデータをそのまま書くとエラーになるんですね。だってまず 1を関数として実行しようとするけど、関数ではないので。

すべてがデータでありコードであり、コード自身を第一級(ファーストクラス)オブジェクトとして扱うことができる、という看板の割にあまりにもお粗末な結果です。

これを回避するために、

>(list 1 2 3)
(1 2 3)

という、見た目、カッコの位置がずれてデータ構造が変わってしまう方法
だったり

カッコの位置が一緒のデータ構造を維持しようと思えば、

> (quote (1 2 3))
(1 2 3)

あるいは、quoteのショートカット記号を用いて

> '(1 2 3)
(1 2 3)

と書く必要があります。このクオート記号すぐ打つの忘れるんですよね。非常に面倒くさい。美しくない。

そしてよく考えてみると、S式の要件定義によれば、

(関数 引数 引数 引数)

なので、

この

(quote (1 2 3))

の中身のかっこ(1 2 3)
はS式じゃないだろ!ってことになります。

そもそも(1 2 3)ってそのまま書いたらエラーになるから、quote付けたけど、定義どうりならばどっちにせよ無理で、

最初の

(list 1 2 3)

って書くしか整合性を保つ方法がない!ってことになります。
どうなってるのか?

実は、

(quote (1 2 3))

の場合、引数である
(1 2 3)
っていうのは、S式として評価されません。

S式でない評価しない特別なデータとして扱います。例外です。

例外、美しくないですね。余剰なルールが追加されるわけで単純さが損なわれるからです。

こんな調子では、

「すべてがデータでありコードであり、コード自身を第一級(ファーストクラス)オブジェクトとして扱うことができる」

と鵜呑みにして統一的に操作できると突き進んでも、いろいろ面倒なパッチを加えながらやるしかない未来が待ち受けているのは明々白々な状況です。

  • 命令型オリエンテッドなS式の表記

  • 破綻したデータ表現

どうにか回避策は無いものか?と試行錯誤しましたが

「ありませんでした」

「そして根本的な理由がわかりました」

S式のリストは、
Singly_linked_list
というリスト構造になっています。

LISPのすべてを束縛するS式の表記は、このSingly_linked_list
というリスト構造と等価であり、問題を解決するにはここからどうにかしないといけない。

LISPのリストで
((a b c)(d e f)(g h i))
は、
http://www.ki.nu/OHP/dot.emacs/list-drawing.html
(ToDo 図作成)

のようになっており、データの末尾を示すため終端にnilという空データをにつけます。

これは美しくない。

  • データの末尾を示すため終端にnilという空データをにつける

というのもルールの一つです。

このルールどおりのものをPureList(純リスト)とし、LISPのS式はそれで構成されているのですが、このルールをぶちやぶって、任意のアトムを終端につけることだって可能です。この場合は
PureListじゃないので各種操作は破綻する。

セルを自由自在に組み合わせられる、柔軟な表現方法だとおもいきや、こういうルールがある。
そしてルールどおりにするならば、新たなリストを既存のリストに結合する際には、終端のnilを一旦外し、そこに接続するという2ステップの置換になる。
自由に接続じゃなくて、置換です。

何かがおかしい、何もかもがしっくりこない、と思ったので、思案の上、自分が理想とする純粋関数型言語をJavaScript上で書きました。

LISPを純粋関数型言語として全面的に書きなおす。

LISPと逆方向のリスト構造を基盤とする。

リストはEmplyPairという無限再帰構造をもつ0に相当するペアから始まる任意の構造である。

終端に特別な操作がない、特別ルールがないのですべての構造がPureである。

遅延評価であり、必要な構造のみ随時評価されていく。

関数はファーストクラスオブジェクトであり、さらにLISPのように関数とデータの区別はしない

すべての関数はデータである。

すべてのデータは関数である。

(1 2 3)というデータは(1 2 3)とクオート無しでクリーンにデータどおり表記され遅延評価される。。

もはやLISPとは別物の新言語である。

JSで書かれている、JSで動作する。

そこで私はLispのリストデータ構造を逆にしてみました。

enter image description here

こういうパーツがあるところまでは同じ。
でも、最初のパーツは必ず自分自身を参照させることにした。

enter image description here

要するに、リスト構造の頭に、数学の0(ゼロ)に対応するものを用意した。

enter image description here

こいつは、当然、無限再帰構造を成します。

数学の0が無限と対称になっているのと同じ構造です。

この0もしくは無限を起点に

enter image description here

こうやってどんどん別のパーツを接続していけば、
何をどうやろうと、全部が全部「純リスト」になります。
ターミネーターをつける置換も必要ありません。


【値】=【関数】なので、
【値】を【関数】として作用してやると、
自分自身を新たに含めた【値】=【関数】という配列になります。

[ 1 ][ 2 ]を作用させると、[ 1, 2 ] になります。

[ 1, 2 ][ 3 ]を作用させると、[ 1, 2, 3 ]になります。

あらゆる階層でこの無限ループになります。

リスト構造の頭に、数学の0(ゼロ)に対応するパーツ
enter image description here

enter image description here

数学の0が無限と対称になっているのと同じ構造の無限再帰構造です。

spinozaによる「評価=計算」

【値】であり同時に【関数】であるものは、
「計算」される必要があるのですが、
同じものなので、唯一の「計算機」しか必要ありません。

それがcomputeです。
いわゆるEVALとAPPLYを融合した唯一の「計算機」です。

computeは当然無限再帰構造をなします。

数も操作も、
値も関数も、
まったく同じもので自分自身を参照する無限再帰構造になっているのだから、
それを計算する「計算機」だって無限再帰構造になるんですね。

実際「1」っていう数は代数の世界で、
無限再帰構造になっているというのは最初から説明しているとおりです。

論理の世界ではそうなんです。
しかし、プログラミングの世界では、
「1」は「1」としてしかもはや表現のしようもないもので、
「1」を延々と計算すること、物質化することは不可能ですし、
そんなことをする必要は一切ないわけです。
数学でも「1」は紙に「1」って書いてしまうだけで、
1+1というような問題を計算するときに、
「1」が無限再帰構造であるからという理由で延々と無限ループの計算にはなりません。

spinozaの数学的基礎

Foundation


Inspired by John McCarthy’s LISP

spinoza is founded on an inverted data structure of
Singly linked list and S-expression.

Pair

001

This is the fundamental unit of spinoza.
Pair has a pair of hands to point a pair of any objects.


Pair points a pair of objects

Now, a Pair points objects: a and b.


Pair notation

When a Pair points objects: a and b, it’s expressed as {a b} in Pair notation.


Pair can point itself


Empty Pair

When a Pair points itself, since it’s a form of Self-reference, an Infinite recursion occurs.

Accordingly, the Pair notaion is { { {…} {…} } { {…} {…} } }, so we simply express the entity as { }, and let’s call it Empty Pair.


Push Pair

A Pair can point another Pair so that we can joint Pairs.

Now let a pair point another Pair and 5 by each hands.
Let’s call this special action Push.

In this case, we push 5 to an Empty Pair.

The Pair notation is { {} 5 }.


Push another Pair

In the same manner, we can push another Pair.

We push 2 to the previous sequence.

The Pair notation is { { {} 5 } 2 }.


Push to any sequence


Sequence

Here, spinoza explicitly defines a term Sequence for this form.
Please note this is the same term and meaning of Sequence in Mathematics.

At the same time, instead of Pair notation : { { { {} 5 } 2 } 7 }, it can be simply expressed as ( 5 2 7 ).


Push function

A Pair can point function.

Accordingly, we can push function to any Sequence.

In this case, we push a function to (5).


A case of Push function

When we push a function : plus2 to (5), the result is (7).


Function is Sequence

The function : plus2 is fundamentally some Sequence.

plus2 consists of a Sequence : ( plus (2) ).

(2) is an attribute Sequence of the function.

( 5 (plus (2)) ) is equivalent to (7).


Everything is a function and Sequence

Everything is function in spinoza.

In this case, 3 is a function that maps a source : ( 5 ) to a target : ( 5 3 ).

Consequently, since function is Sequence in spinoza, everything is Sequence in spinoza.

Therefore, 3 is a function and at the same time, is a Sequence.

However, 3 is 3. There is no other way to express than just 3 in spinoza.


Every Sequence is a result of function to Empty Pair


Function composition

Function composition is naturally expressed in a form :
( source function fucnction ) in *spinoza.

Please note the source = ( 1 ) as a Sequence, not 1.


1 +2 +3 = 6

spinoza has a short-cut notation : + corresponding to plus function.


1 +(2 +3) = 6

( 1 (+ ( 2 (+ ( 3 ) ) ) ) ) = ( 6 )


Popular Posts