📄

JavaScriptを大きく変えうる Dataflow Proposals の概要と論点(Call-this, Pipe Operator)

に公開
5

Discussion

のヮののヮの

パイプ演算子は今のところ |> で、TC39 内では特に議論がない。しかしコミュニティからは、将来 F# Style も導入する可能性のために |> は残し、:> にするべき、という意見が出ている
(tc39/proposal-pipeline-operator#237)。

とありますが、Hack-styleのオペレータとして
https://github.com/tc39/proposal-pipeline-operator/issues/237
で提案されているのは
:> ではなく、 |: だと思います。

Ken OkabeKen Okabe

これらはパラダイムをも変えうる大きな提案

F#の本当のPipeOperator |> が導入されそうになるまでは、まさにそのとおりでした。

f(x)x |> f に書き換えるだけ、と表層的にしか理解していない人々がほとんどなので、こういうF#スタイルかHackスタイルか、という非常に愚かな二択議論が行われた結果Hackスタイルにしよう、とか表記スタイルの決定みたいになっているのですが、これは、数学の二項演算子であり、Monadという基本的な代数構造のうち、さらにもっとも基本的な構造です。

では、なぜF#スタイルという本当の二項演算子がStage2で却下されたのか?というと、

https://github.com/tc39/proposal-pipeline-operator/issues/205#issuecomment-918256173

Given that the committee wants a pipe operator that support async / await, it isn't a distraction but a core requirement & point of comparison between the two syntaxes.

async/await 構文にはまる、というのがコア要件であり、実際はまらないからです。

そもそも、async/await構文というのは、Promise then というこれも二項演算の代数構造を形成する式を、命令型パラダイムを模倣するために作られたSyntaxSugarです。

そういう、元々あった自然なPromiseの数学構造を単に人工的なSyntaxSugarにしたにすぎない命令型の構文にはまらない、という理由で、自然な数学構造であるF#スタイルの本当の二項演算子PipeOperatorを却下してしまった。

数学構造が人工的な構文にはまらない、破綻する、っていうことは、その構文のほうが数学的整合性がない出来の悪いもの、ということにすぎず、その不都合さを、PipeOperatorという二項演算子の本来の数学構造のあり方をゆがめることで都合をつけようとしているわけです。

そうなったときに、現実的にそれらのパラダイムをどう組み合わせるかという観点でも議論されている。

パラダイムの問題ではありません。プログラミングは本質的には数学なんで、その構造を示す、Promise thenという代数構造の式をasyn-awaitという命令型構文のSyntaxSugarにしたければすればいいが、後々不都合が起こらないようにそれは上手にすべきです。しかし実際は失敗したことが証明された。

async-await構文という技術的負債が生まれたのだが、それを覆い隠すために、またHackPipeという新たな技術的負債を作る、一般社会でいえば、借金を補填するために新しい借金をつくる、嘘の上に嘘を塗り重ねる、という愚行と本質的には全く同等の事象です。

この事の重大性と決定の愚かさを理解しているコミュニティのメンバーは(自分も含めて)長大な反発、反論を行いましたが、単に上位下達の権威主義により聞き入れられなかったのはご覧のとおりです。

個人的にそのTC39に参加しているメンバーのコメントを見ましたが、関数型プログラミングのことなどナニも理解していませんでした。Googleの担当社員も含めてです。

彼らはHackスタイルのことそ a little bit なんちゃらとF#スタイルからの軽微な修正、というように捉えていますが、本質的にMonad構造を破壊しているのであり、これは実際スタイルの問題でもなんでもありません。

https://mametter.hatenablog.com/entry/2019/06/15/192311

F# がパイプライン演算子を取り入れたことで、パイプライン演算子は広く一般に認知されました。F# の主設計者である Don Syme も、著書の "Expert F#" でパイプライン演算子を「おそらく最も重要な演算子」と言っています。

長大な論争であったので、TC39でのコメントは逐一引用できないですが、このF#PipeOperatorの却下からの得体の知れないHackOperatorは、基本的数学構造の破壊でしかないので、むしろ関数型スタイルにおいては甚大な後退である、と考えるコミュニティメンバーが多いです。

繰り返しになりますが、それにまともに反論できるような知見がある人らがいるわけでもなく、単にモデレータは、2回TC39にチャレンジしたけどF#スタイルは通らなかったのでどうしようもない、理由はasync/await構文にハマるように、というコア要件を満たせなかったからだ、というものです。

|> は残し、|: にするべき、

というのは、数学的にまるで別物の得体の知れないものを、本来のPipeOperatorのように騙るべきでない、という妥当な信念を共有する人からの紳士的なかろうじての妥協案です。

個人的には、開発者の混乱を考えるとパイプ演算子が2種類導入されるとは考えにくく、そのために構文を妥協するべきではないと感じている。

考えにくい、というかありえないのは、すでに関数型プログラミング界隈で一般的になっているPipeOperoator |> の表記をまるで別物のなにかがOverrideしてしまうことであり、単にasync/await構文で使いたいという人は、|: でやればいい、そんなことに関与せず、従来のF#PipeOperatorを使いたい人は |> を使えばいい、ということです。

r-sugir-sugi

Call-this operator での体験は Golang での構造体とメソッドをイメージするとわかりやすい。

完全に同意。プロポーザルを応援しています。
あと、わかりやすい記事をありがとうございます!

rana_kualurana_kualu

3年経った現状。

Pipe operator → Stage2のまま進展無し。最終commitが2年前
Call-this operator → Stage1のまま進展無し。有意なcommitも3年ほど無し
Partial application(PFA) → Stage1のまま進展無し。最終commitが4年前
Extensions → Stage1のまま進展無し。有意なcommitも3年ほど無し
Function.pipe and flow → 撤回された。

いずれも全く進んでいません。
この中から最初に動くとすればPipeOperatorですが、JSSugarの最初のターゲットにしようみたいな話が上がっており、そうなると益々後ろ倒しになりそうです。