【『関数型プログラミングに目覚めた!』のレビュー(Day-1)】へのレビュー
まず直近の著作としては、2021年末に公開した
関数型プログラミングが『銀の弾丸』であるという非常識な常識2022
がある。
その上で、2015年初に紙の書籍として出版した本へのレビューが
Qiita上にあり、
これは、当時、誹謗中傷、名誉毀損で刑事告訴して事件化していた犯人界隈がQiitaの捨てアカウントを使ってコメント欄で議論を茶化す、妨害するという惨憺たる結果となったレビューである。
主犯はこいつ。現在も継続している。
$ analyze @Sacchii-aum
投稿した記事
No data
LGTMした記事
No data
回答した質問
No data
またスパム捨て垢を急遽こしらえて荒らしに来たんだ?
@Sacchii-aum は僕が刑事告訴した誹謗中傷犯
ちくわ 芦田真一
でQiitaにも捨てアカウントを継続的に作成しながらネットストーキングしている。
https://twitter.com/tikuwa_zero
上のアカウントデータでも明白なとおり、極めて特異な挙動を示しており、本件専用にコメント欄を荒らす目的でQiita上に急遽作成した捨て垢。しょせんこれがQiitaの炎上の正体。
元のレビュー主は、今回の著作である
関数型プログラミングが『銀の弾丸』であるという非常識な常識2022
につっかかってきた連中
と同類のアレであるが、
自分はQiitaを「その当時の経営陣(今はもう売っぱらって総入れ替わりしている)」からBANをされて、うまく立ち回れなかったので、十分に誤りを指摘して反論する機会に恵まれなかった。
結局は、あろうことか、当時のQiita運営がこういう匿名炎上目的のアカウントの思惑に乗っかる形で、僕の反論コメントを消してしまったので、現状、間違ったネガキャン情報がそのまま残っている。
Qiita で散々やってたじゃん。
— 斜月三星堂 (@littleHaskeller) December 10, 2021
それでも理解できない君に、今さら同じような説明をしても無駄でしょ?🤣🤣🤣🤣🤣🤣
説明された内容を忘れたのなら、Qiita を読み直したら?
君と君の分身が書いた内容は読めなくなってるけどね。🤣🤣🤣🤣🤣🤣🤣
とか、今さら来るので、ああ馬鹿相手の沙汰でもちゃんとカタつけておかないと、馬鹿が延々やってくるんだな、と確認したので、本エントリでは一連のネガキャンを是正する。
まず、この本はES6(ES2015)以前の時代の著作であり、直近の本のように洗練されたことはなにもできていない。
これは当時のJavaScriptの限界であって、その総括もしたくて直近の本を書いたということもある。
2015年当時のその仕事は、現在の基準ではけして満足がいく仕事ではないが、至らない部分に目をつけられて不当なレベルでネガキャンをやられてしまったという不当性は、2022年バージョンの現在に至っても、同じようにネガキャンやられてるところをみると、結局は内容の不備とか、結局連中にはどうでもよくて、実際後で書くけれども、自身のいい加減な主張でも相手が差し出す渡船があれば乗ってしまう茶番とか、内容なんてどうでもよいなだろうなと強く再確認できる。
それに加えて、前述のような刑事告訴した誹謗中傷犯がQiita上で攻撃してきたので、このレビュー記事はグダグダになってしまっている。
0 から 9 まで列挙した配列、この本の問題として本質的ではないという意見。しかし、この例を選んでしまっているところにリスト、配列、空間コスト、評価戦略などの関数型プログラミングの大切な概念に対する無理解が見て取れるため極めて象徴的であるのです
— Jun Furuse 🐫🌴 (@camloeba) May 9, 2015
という文句もあるが、今回の2022年の著作でも踏襲した。もっとも適している題材だし、この人物は、
らくだの卯之助 (@camloeba)
プロフェッショナルな関数プログラマと紹介されているが、2chの僕を標的にした誹謗中傷スレッドで活躍していた。
プログラマでもなんでもない、橋にも棒にもかからない、じょうきの「ちくわ」はそのスレで、こういう技術的になんか言いいた中級プログラマ連中と一緒になって、個人攻撃をからめてありとあらゆる方策で攻撃を試みていた。
素人としては深入りを避けたいと思いますが、そうだとすればそもそもJavaScript選んじゃったのが関数プログラミングへの無理解を象徴的に示すものなのだということになるような気がします。)
結局はこれ。
ES6(2015)以降はかなり、こういうものいいは減ってきたものの、2022年になろうとしている今でも、JavaScriptと関数型プログラミングの相性が悪いというのは、こういう文句垂れの連中の一貫したテーゼだ。
ほぼ全員が同じことを言ってくる。
要するに、僕をコケにしたい裏にはベースとして、連中がそういうHaskellやらMLやらOCamlやら関数型言語と認識されている自分の世界で愉しんでいて、そこで得た考えから、JavaScriptは違う、と信じている。というより、自身の言語選択の好みをスキをみては押し付けてくるという感じか。
誤解のないように言っておきたいのだけど、僕は本書でもTC39を批判というか糾弾に近いことをしているし、言語としてJavaScript最高!みたいな信者でもなんでもない。
TypeScript含めて専門ではあるけれども、関数型の入門として、誰がMLの本を読みたいのか?と正直思うし、実際シェアとしてはJavaScriptは圧倒的で、小学生の入門言語としても採用されている実情があるので、その路線でアプローチしたいというのは、2022書籍の冒頭で書いている通りだ。
こういうMLやらOCamlの連中は、自己中心的な連中でそういう初学者に誘導という考えなんてない。
そして初学者むけに姿勢をさげたら、その姿勢をさげる、というのを弱みみたいにおもってなおさら攻撃してくるのがかなりタチが悪い。ようするに「ナメてくる」わけである。
「問題の論理」?
これについては、2022年書籍でいうところの「課題の本質」だ。
しかし、たとえば「与えられた配列
s
をソートせよ」という問題を与えられたらどうするんでしょうか。s.sort(isGreater)
と書け、ということなんでしょうか。肝腎のそのsort()
はどうやって書けばいいのかは、およそ「問題の論理」からは出てこないように思います。
まあそのとおりだね。
「課題の本質」か「課題の解法」が導かれるのではないのは自明のこと。
ここで書いているのは、「課題の本質」ではない制御構文、フローについて余剰の解決をする必要があるということ。
どうやら「クールなコード」を書こうとする限り、ソートを行うコードを書くことはできないようです6。とすると、「神の目」はどうやら役立たずだということになるでしょう。
「課題の本質」に即したコードを書こうとする限り、課題の解法は得られないようです。。。とか言ってるのと同じで、まあ単なる揚げ足取り。
ネガキャンやりたいんだなーってのが伝わってくる。
「関数という論理操作」?
これについては、まあ揚げ足取りの続き、とみなすこともできるが、ある程度正しい批判はしている。
ただし、関数が写像だ、なんてことはわかっており、あまりにも初心者の日常生活に寄せすぎて、アナロジーがうまくない、ということ。
実際これはありがちなミスであり、モナドをIOモナドの説明と同一化して、妖精がどうちゃらピュアな世界がどうちゃらとか書いてる悲惨な解説があるので、この要素については文句垂れたい気持ちは共有できる。
「『まとまり』は美しい単一の論理構造」?
これについても指摘は正しい。
といっても表現の問題ではある。
今らならこれはこんな抽象的なことではなく、Monoidという代数構造である、と変に数学的な概念をさけずに、ストレートに説明すべきだというのはわかるが、当時は、まさに「妖精とピュアな世界とモナド」みたいなアホなアナロジーが機能すると過剰評価していたきらいがある。
追記(2015/05/30):デスクトップアプリケーション??
これについては、最新のコードは、おおむね、FRPで
として公開している。
FRPでなければならない。
そのことは、
状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)
と書いてる本人も理解しているようだ。しかし、
結局のところ少なくとも現状のFRPも(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)本質的には銀の弾丸にはならないと言わなければなりません(関数プログラミングで書けるということの恩恵はもちろんあるとしても)。
というのは、間違いで、
(イベントのシグナルから状態のシグナルを構成する際に状態遷移をそうした関数で表現する必要が出てくるので)
となにかわけのわからない共通項をデッチ上げて有効性を否定するポーズは見せているがなんのことやらわからない、というのが事実。
ほかにも、著者が本書の執筆期間にStackOverflowというサイトに投稿した質問(
reduce
をmap
で定義するにはどうしたらいいかという質問です)を見れば、著者がmap
とreduce
について何も理解しないままに本書を執筆していたことは明らかです。
これは、2chででっち上げられたデマであり、このQiita記事を書いている人間が、その2chスレの住人であることを確認できた事案であった。
これは、直近の2022書籍でいうと、mapFunctorの挙動で、MonoidのFoldを表現することが可能か?ということを考えており、reduceからmapが構成される、なんてことは百も承知である。
StackOverflowの回答者の不遜さは当時特にひどかったので、その不遜さも、あたかも僕がコケにされたという印象を連中に利用されることになっていた。
誹謗中傷犯が2ch界隈でわーっとなっているタイミングでは「良い攻撃材料を見つけた」ということで頭がいっぱいになっているわけで、所詮この書き手も、ネガキャンやりたいのでその事実を最大限に拡大しようとしていることが見て取れる。
実際にmapではなくてモナドであるflatMapでは配列構造にアプローチできて、要素の数を増やすということができるので、当時、では要素の数を減らすことができるのか?と手っ取り早く確認するためにSOで質問したにすぎないのだが、回答者は馬鹿にするだけのアレだったし、その結果を悪用されたにすぎない。
従って、
逆に
reduce
を用いてmap
をどう定義すればいいかも関数プログラミングの勉強を始めたその初っ端に出会う練習問題に過ぎないような本当に基本的な話題に過ぎません。このような著者に対して関数プログラミングに関して技術的になにか意味のある「反論」を期待することはできず、つまるところ本書と著者についてはもはやこれ以上なにをしようもないのです。
というのは、誹謗中傷に過ぎない。
次のコメント
だが、こいつが、
— Jun Furuse 🐫🌴 (@camloeba) May 9, 2015
らくだの卯之助 (@camloeba)
による捨てアカウントである。
逆に、岡部氏のコードはよく見ると state = x; という部分で
カウンタ変数への破壊的代入を行っており、何ら関数的ではありません。
(無駄に複雑なスパゲッティ・プログラムですが、よく読むと要するに
state = state + 1; と同じ破壊的代入です。)
これについては、2022年書籍についても、まったく同様で「破壊的代入」を使っている。
その正当性はこういう中級者除けのためにもうちょっとうまく説明できていて、
からはじまり、
(引用終わり)
ということです。
FRPの実装では、「必ず」いずれかの時点で破壊的代入が行われています。
その理由については本書の
を読めばわかるでしょう。
もっというとこれでわかると期待したいのですが、もしわからないのであれば、加筆対象になりえます。
岡部氏は
『関数型プログラミングのパラダイム内で、そういうマウスボタンが押されているのか、押されていないのか?入力の状態が時間遷移していく場合、上記ブログエントリでも論じたSICPでも、拙書でも解説しているとおり、FRPの実装が必ず必要となります。
「時間」が本質的だから、時間をを集合、SICPの言葉でいえば「遅延ストリーム」とした実装が必要です。』と断言しているにも関わらず、現に私やnonstarter氏のコードのように
「時間」も「ストリーム」も出てこない関数的状態渡しによる実装が
容易である以上、岡部氏の誤りは明らかだと思います。ご参考まで。
基本的に、このOCamlのらくだなんとかは、FRPのなんたるかは勉強していないことが伝わってきます。
継続渡しなんぞ誤魔化しのテクニックでは、複雑な関数合成などでは通用しないとのはこのQiita記事書いてる人間もわかってることで、応用範囲の広いフレームワークはあくまでFRPです。
(編集済み)
hiyakashi_さん
著者がFRPを実施しているとは言えないと私は考えています(ブログに掲出されたクリックカウンターのコードでカウンター用の変数を破壊的に更新していることに鑑みても)。
foldp
については、以前に私がElmを試した際にfoldp
に渡す関数がやたらと複雑化・肥大化してしまったことの印象が強いせいもあるのでしょう。私の扱い方がヘタクソだっただけかもしれません。私はシグナルのもっとも重要な用途が状態の保持であると思っているので、先行する状態に依存する状態を与えるために必要なfoldp
(やその相当物)がFRPにとって非本質的だとは思っていません。ともあれ、ご指摘に対応して本文の該当箇所には手を加えました。
Lambadaさん
ご指摘についてはその通りかと思います。
まあ、なんかかなり適当なことを書いていますね。
2022の書籍では最後の方でReactiveFunctorからのMonad化と精緻に解説している。
基本的な考え方は2015年当時となんら変わっていない。
こいつらが、「ご指摘についてはその通りかと思います。」とかやってるのはネガキャンやりたいばっかりの茶番である。
たとえば、最初は
状態機械の数学的構成では状態遷移が状態と入力から状態への関数として表現されるというだけのことではあり(状態渡し)、状態遷移が複雑になれば状態遷移を純粋な関数として表現する作業も複雑になり困難になるので(そしてそれはしばしば綺麗な関数合成では上手くいかないようなものになることが多いので)
状態渡しでは複雑な応用局面になると困難になる、とわかっていた言及をしていたのに、FRPを否定したいばっかりに、
現に私やnonstarter氏のコードのように
「時間」も「ストリーム」も出てこない関数的状態渡しによる実装が
容易である以上、岡部氏の誤りは明らかだと思います。ご参考まで。
となんかネガキャン材料を渡されたら、
「ご指摘についてはその通りかと思います。」
と、ころっと立場を買えてしまったw
再度断言しておく。
状態渡しなんぞではできることは限られている。
FRPではすべての局面で利用ができる。
とりあえず現時点でUPしておく。
あー最後に。
参照透過性については別エントリでやる。
あと、
特に、状態渡しでFRP不要説をぶっこいている連中は、
本書(2022)で、
関数型プログラミングが『銀の弾丸』であるという非常識な常識2022
(引用終わり)
このコードは、そのOCamlの継続渡し(こっちが言ったんじゃない、かんたんに実装できるからFRPはいらんみたいなことをそちらが主張したんだ)でどうなるか、やってみて?
もしクリアしたら次の課題もだすから。