F#の使用がC#よりも適切な領域はどこですか?[閉まっている]


210

ここ数年でF#は、OCaml、ML、Haskellで取り入れられた多くのアイデアを採用して、Microsoftが完全にサポートする言語の1つに進化しました。

過去数年にわたって、C#は、LINQ(リスト内包表記)、ラムダ、クロージャ、匿名デリゲートなど、より多くの関数型言語機能を導入することにより、その汎用機能を拡張してきました...

C#がこれらの関数型機能を採用し、F#の分類法が不純な関数型言語であるとすると(必要に応じて、フレームワークライブラリにアクセスしたり、関数が呼び出されたときに共有状態を変更したりできます)、2つの言語には強い類似点があります独自の極性の反対の主な強調。

これら2つの言語を本番のポリグロットプログラムで採用している成功したモデルと、過去1年以内にF#で作成した本番ソフトウェア(Webアプリ、クライアントアプリ、サーバーアプリ)の領域にも興味があります。 C#で記述されています。

回答:


258

発電所ポートフォリオの全国的な発電スケジュールとエネルギー会社の取引ポジションとのバランスをとるアプリケーションを作成しました。クライアントとサーバーのコンポーネントはC#で作成されましたが、計算エンジンはF#で作成されました。

このアプリケーションの中心にある複雑さに対処するためにF#を使用すると、エンタープライズソフトウェア内の言語のスイートスポット、つまり大規模なデータセットのアルゴリズム的に複雑な分析が明らかに示されます。私の経験はとてもポジティブなものでした。特に:

測定単位私が働いている業界には、単位が散らばっています。私が実装した方程式(多くの場合、幾何学的な性質のもの)は、時間、電力、エネルギーの単位を扱いました。型システムに関数の入力と出力の単位の正確さを検証させることは、テストとコードの読み取り/理解の両方の点で、大幅な時間の節約になります。これにより、以前のシステムで発生しやすいエラーのクラス全体が根絶されます。

探索的プログラミングスクリプトファイルとREPL(F#Interactive)を使用することで、従来の編集/コンパイル/実行/テストループよりも実装にコミットする前に、ソリューションスペースをより効果的に探索できました。これは、プログラマーが問題と設計上の緊張を理解するための非常に自然な方法です。

単体テスト副作用のない関数と不変のデータ構造を使用して記述されたコードは、テストする喜びです。物事を台無しにする複雑な時間依存の相互作用や、モックされる依存関係の大きなセットはありません。

相互運用私はC#で計算エンジンへのインターフェイスを定義し、F#で計算を実装しました。計算エンジンは、相互運用性をまったく気にすることなく、それを使用する必要がある任意のC#モジュールに挿入できます。シームレス。C#プログラマは知る必要はありません。

コードの削減計算エンジンに入力されるデータの多くは、ベクトルと行列の形式でした。高次関数は、最小限の手間と最小限のコードでこれらを朝食に食べます。綺麗な。

バグの欠如関数型プログラミングは奇妙に感じることがあります。アルゴリズムに取り組んでコードを型チェッカーに渡そうと頑張っていますが、型チェッカーが満足すると、それが機能します。ほぼバイナリで、コンパイルされないか、正しいものです。奇妙なエッジケースエラーは最小限に抑えられ、再帰および高次関数により、エッジケースエラーを引き起こす多くの簿記コードが削除されます。

並列処理結果として得られる実装の機能的な純粋さは、データのベクトル処理における固有の並列処理を活用するための熟成をさせます。たぶん、これが.NET 4がリリースされたので次に進む場所です。


18
F#が数値計算エンジンに非常に適している理由を説明するための+1。測定単位について言及するためのもう1つの(仮想)+1。言語のその部分はもっと頻繁に言及されるに値します。
2010年

5
素晴らしい答え、関連性があり、現代的で、F#が複雑さを処理するのに適していることを概説しています。私はそれを読んでたくさんのことを学びました、ありがとう
Peter McG

素晴らしい答えサイモン、そしてドンが昨夜述べたように、彼の最近のスライドで引用しました。「カートに追加」リンクを追加しますか?
Chris Ballard

1
こんにちは、アプリのアーキテクチャについて詳しく教えてもらえますか?
Nikos

76

Microsoft Researchでのインターンシップ中、私はVisual Studio IntelliSense for F#(それ自体はF#で記述されています)の一部に取り組みました。以前のC#プロジェクトでIntelliSenseを使用した経験があるので、2つを比較できると思います。

  • Visual Studio Extensibilityは引き続きCOMに基づいているため、.NETオブジェクトではない(そして機能しない)オブジェクトを処理する必要がありますが、C#とF#の間に大きな違いはないと感じています(スムーズに動作します) F#から)

  • F#でプログラムコードを表すために使用されるデータ構造は、ほとんどの場合、区別された共用体(C#では合理的な方法でサポートされていません)であり、これがこの種のアプリケーション(プログラムコードなどのツリー構造を処理する必要がある場合)に大きな違いをもたらします)。識別された共用体とパターンマッチングにより、コードをより適切に構造化できます(仮想メソッド内のすべての場所に関連する機能を1つの場所に置くのではなく、1つの場所にまとめます)

以前は、F#のCodeDOMプロバイダー(F#でも記述)にも取り組みました。実際には最初にC#で実験を行いましたが、コードをF#に変換しました。

  • CodeDOMプロバイダーは、.NETオブジェクトを使用して表される構造をトラバースする必要があるため、データの独自の表現を作成するためのスペースがあまりありません(F#が素晴らしい利点を提供できる領域です)。

  • ただし、タスクを容易にする小さなF#機能が多数ありました。文字列を生成する必要があるので、文字列を作成するためのカスタムオペレーターを定義し(を使用StringBuilder)、それらと高次関数を使用してコードを実装しました(たとえば、指定された文字列を使用して分離されたオブジェクトのリストをフォーマットするためなど)。繰り返し(そして退屈なforeachループ)。

これらは2つの比較的具体的な例ですが、どちらもプログラムの表現、または式、またはより一般的には複雑なツリーのようなデータ構造での作業に関連しています。この領域では、(C#の機能的な機能に関係なく)F#は間違いなく良い選択だと思います。


6
非常に興味深い、Microsoft内でのF#の取り込みが確かに高いことのより多くの証拠。
Peter McGは2010年

43

F#(可視化用F#)および2番目(F#for Numerics)で書かれた世界初の商用製品と、F#に関する最初の商用文献(The F#.NET Journal)を出荷し、現在のバージョンに関する唯一の本を書いて公開しましたof F#(Visual F#2010 for Technical Computing)。

私たちはC#で書かれた同様のライン(例:this)に沿って製品を出荷してきましたが、OCamlの商業的使用の強力な背景もありました。2006年にまだ研究プロトタイプであったF#の初期の熱心な採用者でした。なぜなら、産業用強度の.NETプラットフォームにまともなモダンOCamlに似た言語の可能性を認識し、その結果、製品化を推進したからです。その結果は信じられないほどの成功を収め、F#は私たちの高い期待をはるかに超えています。

私たちにとって、F#には多くの異なる利点があり、さまざまなアプリケーションに使用しています。数十万行のF#コードが運用されています。現在、すべてのLOBアプリにF#を使用しています。クレジットカードのトランザクションはF#コードを使用して処理され、製品通知はF#コードを使用して送信され、サブスクリプションはF#コードを使用して処理され、アカウントはF#コードを使用して実行されます。おそらく、ここで効果を発揮する主な言語機能はパターンマッチングです。F#を使用して構文を色分けし、最新の本を強調表示しています...

私たちの可視化ライブラリは大きな売り手であり、その機能はVisual Studioで実行されるF#インタラクティブを中心にしています。私たちのライブラリーは、最小限の労力でインタラクティブな2Dおよび3D視覚化を生成する機能(たとえば、Plot([Function sin], (-6., 6.))正弦波をプロットします)。特に、すべてのスレッドの問題は完全に自動化されているため、ユーザーはUIスレッドやディスパッチについて心配する必要がありません。ライブラリのこの部分を書くとき、ファーストクラスの関数と遅延は非常に価値があり、代数的データ型は他の場所で広く使用されていました。お客様がWPFのヒットテストでパフォーマンスバグにヒットし、関連するコードをF#で簡単に再実装して10,000倍のパフォーマンスを向上させることができた場合も、予測可能なパフォーマンスが重要であることがわかりました。この製品のGUIは自由形式であるため、GUIデザイナーとC#は有益ではありませんでした。

私たちの仕事の多くは、商用ライブラリと本の両方を含む数値手法を中心に展開しています。F#は、この領域ではC#よりもはるかに強力です。これは、パフォーマンスのペナルティを最小限に抑えながら、高レベルの抽象化(高次関数など)を提供するためです。この状況での最も説得力のある結果は、LAPACKのリファレンス実装からのFortranコードよりも20倍短く、ベンダーが調整したIntel Mathよりも最大3倍速い線形代数からのQR分解の単純で一般化された実装の作成でした。カーネルライブラリなど、より一般的です。これは、コードが任意のタイプの行列を処理できるためです。

現在、WPF / SilverlightコンポーネントをF#(gutsの場合)とC#(shimの場合)の組み合わせで開発しており、ソフトウェア製品のインタラクティブマニュアルとして機能するWPFアプリを構築しており、新しい本Multicore F#を書いています。 .NETでの共有メモリ並列プログラミングの決定的なガイドになります。


あなたは「科学者のためのF#」を書いたジョン・ハーロップと同じですか?
Andre Artus、2011

7
はい。5年前に科学者向けにF#を書きました。
Jon Harrop、2011

最後から2番目の段落で言及した、F#のQR分解コードのある種のリファレンスがありますか?ありがとう。
サミクR

@SamikR:いいえ、申し訳ありません。それは商用コードです。しかし、それは書くのは簡単でした。
Jon Harrop

@Jon Multicore F#の言葉は?
bigglesworth教授、16

25

過去6か月間、Visual Studio 2010のVimエミュレーションレイヤーに取り組んできました。これは、githubで無料で入手できるすべてのソースを備えた無料の製品です。

プロジェクトは、別個のレイヤーを表す3つのDLLに分割されます。各層には、対応する単体テストDLLがあります。

  1. Vimエンジン:F#
  2. 装飾とエディター統合のためのWPFレイヤー:C#
  3. Visual Studio Integrationレイヤー:C#

これはF#でこれまでに行った最初の主要なプロジェクトであり、この言語が大好きだと言わざるを得ません。多くの点で、F#を学習する方法としてこのプロジェクトを使用しました(この学習曲線は、プロジェクトの履歴を見ると非常に明白です)。

私がF#について最も驚くべきことは、言語がいかに簡潔であるかです。Vimエンジンはロジックの大部分を占めていますが、コードベース全体の30%しか占めていません。


19
エディター...関数型言語... viエミュレーション... emacsを再発明しました。NOOOOOOOOOOOOOOOOOOOOOOO!
Ben Voigt

2
「100%かっこなしの認証済み」であることを除いて:)
Pavel Minaev

@Pavel、もちろんタプルを除く、および.netメソッド呼び出し
JaredPar

26
ここで2つの注意点があります。まず第一に、タプルは()F#では必要ありません- ,演算子がlet x = 1,2タプルを作成するため、括弧なしの有効なタプルです。次に、F#のペアの括弧は、begin..のペアで置き換えることができますend(これはMLから継承されます)。たとえば、これ"foo".IndexOf begin 'a', 1 endは有効な.NETメソッド呼び出しです。したがって、
かっこなしにし

面白いコメントPavel!それを知りませんでした。大きなグループ化ブロックがある場合には、私は実際に好むかもしれないと思いbeginますend。また:VsVimルール!
ダンフィッチ

13

F#Visual Studioコンポーネントのユニットテストの多くはF#で記述されています。これらはVSの外部で実行され、さまざまなVisual Studioビットを模倣しています。インターフェイスを実装する匿名オブジェクトを解釈する機能は、モックフレームワーク/ツールの代わりに役立ちます。私はただ書くことができます

let owpe : string list ref = ref []
let vsOutputWindowPane = 
    { new IVsOutputWindowPane with
        member this.Activate () = err(__LINE__)
        member this.Clear () = owpe := []; 0
        member this.FlushToTaskList () = VSConstants.S_OK
        member this.GetName(pbstrPaneName) = err(__LINE__)
        member this.Hide () = err(__LINE__)
        member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
        member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
        member this.SetName(pszPaneName) = err(__LINE__)
    }            
DoSomethingThatNeedsA(vsOutputWindowPane)
assert( !owpe = expectedOutputStringList )

たとえば、IVsOutputWindowPane最終的にOutputStringandを呼び出す他のコンポーネントに渡すのインスタンスが必要な場合、テストの最後にオブジェクトをClear検査してstring list ref、期待される出力が書き込まれたかどうかを確認します。


興味深いのは、Microsoft内でのF#の取り込みが確かに高いことです。F#のインターフェイスを実装する匿名オブジェクトを作成できることを知りませんでした
Peter McG

9

F#のLex-Yacc実装を使用してカスタムルールエンジン言語を記述しました

編集してコメント返信を含める

C#にはlex / yaccの実装はありませんでした。(私たちが知っている限り、F#はそうでした)

それは可能だったでしょうが、自分で構文解析を構築するのは実に苦痛です。

このトピックでは、外部ライブラリなどの他の提案をいくつか示しますが、私たちの主任アーキテクトは関数型言語の老舗なので、F#を使用するという選択は非常に簡単でした。


+1以前にこれをC#で書いたとしたら、それは何らかの理由で不適切であるか、遅くなっていましたか?
Peter McG 2010年

@Peter McGrattan少なくとも執筆時点(ソフトウェア)では、C#にlex / yacc実装はありませんでした。それは可能だったでしょうが、自分で構文解析を構築するのは実に苦痛です。stackoverflow.com/questions/540593/lex-yacc-for-cショー他のいくつかの提案が、F#を使用するための選択肢は非常に簡単ではなかったので、私たちの主任アーキテクトは、関数型言語で古い手です
JOHNC

C#のlex / yaccがないと思った場合、私はそれを十分に見ていなかったと思います(F#より古いバージョンが1つあります)。 c#よりもその釘のハンマー
ルーンFS

私はfslex / fxyaccでF#を使用しましたが、「プロダクション」プロジェクト(まだリリースされていません)ではありません-VSのMSIL構文の強調表示とコード補完の拡張。F#を使用する主な利点は、解析ツリーを表すのに非常に便利なADTを取得できることです。また、ジッパー(en.wikipedia.org/wiki/Zipper_(data_structure))を使用すると、インクリメンタルレキシングを簡単に実行できます。また、ジッパーは機能的であるため、F#で簡潔に操作することが簡単です。
Pavel Minaev、

7

私は現在、プログラミング言語のコンパイルに取り組んでいます。コンパイラは完全にF#で記述されています。コンパイラー(lexおよびyaccを使用したlexおよびパーサーのビルドを除く)は、基本的には、構造のような複雑なツリーの多くの変換としてビルドされます。

他の人が指摘しているように、ユニオンとパターンマッチングを区別することで、この種のデータ構造での作業は、「あらゆる場所」の仮想メソッドでコードをダンプするよりもはるかに簡単になります。

コンパイラに取り掛かる前にF#の作業を行っていませんでした(ただし、モスクワMLと呼ばれる別のOCamlバリアントでコンパイラを作成していました)。Jaredが述べたように、最初に行った部分がコードから見えるようになっていますが、一般的にF#は簡単だと思いましたただし、主にOOを10年間コーディングした後でFPの考え方に再び慣れるには、少し時間がかかります。

木での作業はさておき、私は宣言型のコードFPの主な利点を書く能力を見つけるImは記述のC#とは対照的に実装しようとしたアルゴリズムについて説明し、コード持つ(F#が含まれています)どのように大きな利点である私はalgortihmを実装しましたが。


6

個人的な経験ではありませんが、F#についてマイクロソフトの人々と話をするDNRのエピソード(これはこれだと思います)を聞くことができます。彼らは、F#を使用して、Xbox Liveスコアリングシステムのほとんどを作成しました。システムは数百台のマシンにわたって大規模に拡張され、彼らはそれに非常に満足しました。


5

製品版かどうかはわかりませんが、「The Path of Go」のAIはF#で記述されています。

http://research.microsoft.com/en-us/events/techvista2010/demolist.aspx#ThePathofGo

Go of the Path:A Microsoft Research Game for Xbox 360

このデモでは、マイクロソフトリサーチケンブリッジで社内制作された囲碁のゲームをベースにしたXbox 360ゲームを紹介します。囲碁は東アジアで最も有名なボードゲームの1つで、4000年前に中国で生まれました。ゲームの紛らわしい単純さの背後には、大きな複雑さが隠されています。習得には数分しかかかりませんが、習得するには一生かかります。コンピューターはチェスで人間のスキルを上回っていますが、Go向けに競争力のあるAIを実装することは依然として研究課題です。このゲームは、Microsoft Research Cambridgeで開発された3つのテクノロジー(Go、F#言語、およびTrueSkill™をプレイしてオンラインプレーヤーと対戦できるAI)を搭載しています。AIはF#で実装され、Xbox 360の.netコンパクトフレームワークで効率的に実行するという課題に対応します。このゲームは、視覚的に素晴らしい3Dシーンの数にあなたを置きます。XNA環境を使用して、マネージコードで完全に開発されました。

(他の誰かがすでに「TrueSkill」について言及しました。)


魅力的な:XBoxのコンパクトフレームワークで実行されているF#。FSharp.Core.dllはFSharp.Core.optdata FSharp.Core.sigdataと共に非CFアセンブリを参照しませんか?
Peter McG

1
CTPには、.NETCF用にビルドされた個別のFSharp.Coreが付属しています。(Silverlight用の別のFSharp.Coreもあります。)
ブライアン

あなたが言うこのCTPは何ですか?
Jwosty
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.