21.1 F# の影響
2021-09-25 00:00:21
F# が最も明白に直接的な影響を与えたのはC# です。
C# 2.0(ジェネリクス)は、私たちがF# の作成に至る前に、特にML系言語を.NETにもたらそうという意図をもって行った作業に基づいたものでした。
C# 3.0(var x = …
)、C# 5.0(タスク/非同期)、C# 7.0(タプル、パターンマッチング)、C# 8.0(パターンマッチングの強化)、およびC# 9.0(非Nullポインタがデフォルト)はすべてF# の影響を強く受けていました[Mads Torgersen 2017]。
C# が今日最も広く採用されている言語の1つであり、2000年代に急速に進歩を繰り返した1ことを考えると、
Microsoft Developer Division内のF# の存在が、「関数型プログラミング」の一連のアイディアとC#とをつなぐ架け橋として重要な役割を果たしたと主張しても過言ではないでしょう。
とはいえ、アイディアは両方向に流れてきました。F#はC# 1.0(オブジェクト、プロパティ、イベント)、C# 3.0(LINQ)、C# 7.0(Span)の影響も受けています。
F# 以外の他のソースもC# に影響を与えました。たとえば、Icon(C# 2.0イテレーター)、Python(C# 4)、Gustafssonらによる内部プロジェクトAxum[Wikipedia 2014]などがあります。
ファーストクラスのイベントと合成可能なイベントコンビネータープログラミングをF# に追加したことは、 リアクティブ関数型プログラミングツールキットであるRxプロジェクトの開始に直接影響を与えており、 現在それは、RxJSを含む複数の言語でパターンとして再実装されています[Syme 2006b]。 この件における初期のF# の影響は、Wes Dyerから私に非公式に説明されました。
他の言語に対するF# の直接的な影響は測定が困難です。言語デザイナーは、直接的であれ間接的であれ、自分が受けた影響を言おうとしない傾向があるからです。
ElixirとElmはどちらも |>
演算子を使用しており、ScalaやRなどの他の言語ではその演算子をエミュレートする方法があります。
Scalaの設計者であるMartin Oderskyは、MSR CambridgeのテクニカルアドバイザリーボードやEPFLの研究での彼の役割において、
F# の歴史を通してF# を密接に認識していました。なお、その中にはF# の型プロバイダーをScalaにもたらす努力が含まれます[Burmako 2013]。
Scalaにおける抽出子の作成に対するF# の明らかな影響については、本稿の前半で説明した通りですし、
Scala 3.0にはインデントを意識する構文が後から採用されました。
SwiftはF# の影響を受けているようですし、Joe Pamer(訳注:Microsoftに在籍中はF#チームやTypeScriptチームに所属し、その後Appleに転職)は2014~16年にAppleで開発チームを率いてSwiftコンパイラーの開発をしていました。
KotlinはC#、F#、その他の言語を参照点として使用しているようです。
RustはOCamlの影響を受けているように思われます。設計者のGraydon Hoareは、Rustの後の「次は何か」について議論するときにF# を広範囲に参照しています[Hoare 2017]。
TypeScriptはF# の影響を直接受けていました:TypeScriptの創始者の1人にLuke Hobanがいて、彼はF# 2.0に関わった直後にTypeScript(当時はStradaと呼ばれていました)を始めました。
最近彼は、TypeScript設計の初期の部分におけるF# の影響について指摘しました[Hoban 2017]。
影響がどの程度あったとするのかは議論の余地がありますが、
私の意見としては、TypeScriptはF# の先進的な型チェックと型推論の経験にしっかり基づいていますし、
F# の影響がなければ、TypeScriptが現在の形に近い形でMicrosoftのチームから登場してはいなかっただろうと思います。
最初から、F# はNullを排除することを設計の中心としていました:
null
値は通常、F# で宣言した型と組み合わせて使用することはできず、実際にはNull参照例外はまれです2。
これは当言語における多くの細かな決定に影響を与えています。
OCamlの観点から言えば、これは明らかな選択であり、
MSR Cambridgeの文化的文脈 – 研究室にTony Hoareがいたこと、および彼の「10億ドルの間違い」の名言を含む – では、他の選択は考えられなかったでしょう[Hoare 2011]。
しかし、Scalaのような言語は同じ決断をしなかったので、2018年にいたるまで、JVMまたは.NET上で実行され、設計の中心にNullの排除が置かれている重要な言語は、唯一F# だけでした。
2020年2月の執筆時点では、C# 9.0は非Nullをデフォルトにすることを計画しています。
この劇的な変化が、プログラミング産業界に特有の問題を排除するための変化をもたらすだろうと私は願っています。
このプロセスの中心にあり続けたのはF# です。
F# は、“async” モダリティを導入し、言語の既存の制御構成体を局所的に再解釈できるようにした最初の言語です。
つまり、コードの一部を「同期」から「非同期」に変換するのに必要なことは、コードを「async {…}
」で囲み、
呼び出し元の地点を「await
」(F# では「let!
」)でマークアップすることだけでした。
これは、2012年にC# 5.0に追加されたasync/awaitメカニズムに直接影響を与えました –
F# バージョンがC# デザイナーに最初に紹介されたのは2007年でしたが、2012年までの間に多くの議論が行われました。
C# のasync/await機能は、TypeScript、Kotlin、その他の言語に影響を及ぼしています3。
言語に非同期モダリティを持たせることは、今や事実上の産業界標準となっていますが、いずれの場合も、この機能の系譜は部分的にF# にさかのぼることになります。
つまり、F# は2020年時点で使用されている主要な言語の多くに影響を与えており、C++は例外ですが、直接(C#、TypeScript、Scala、Kotlin、おそらくSwift)、または間接的(Rust、Python、Java、JavaScript)に影響を与えています。
-
この間、Java、C++、JavaScript、Pythonの言語設計はすべて進歩しましたが、C# に比べるとその範囲は小さいものでした。 ↩︎
-
F# コミュニティのジョークにこういうものがあります。「問題:C# にできてF# にできないことは?」「回答:NullReferenceException!」 ↩︎
-
非同期プログラミング、継続、コルーチンの歴史については、LISPまで遡って別の記事を書く必要があります。MLDonkeyがF# に影響を与えたことは先に述べたとおりです。C# 5.0では、ステートマシンコンパイルなど、ALGOL系言語に適した「async/await」の設計に新たな要素を加えていますが、それは先に述べたAxumのプロトタイプから派生したものです。このように考えると、F# asyncはC# async/awaitの前身ですが、後者は前者の単純なコピーではありません。 ↩︎