2009-09-22 9 views
6

私はf#とHaskellを使用して、しばらくの間関数プログラミングを学んでいます。私は私の会社で承認されたf#を得るまで、私はまだC#を使わなければなりません。私はまだいくつかの利点に気づいたように機能的なスタイルにとどまるように努めています。OOから10,000フィートの関数プログラミングへ

これは一般的な問題です。

  1. 3つのキー(650万 行)
  2. 媒体サイズに小の4つの他の支持 テーブルがあると データベース内のキーセットテーブルがあります。
  3. いくつかの入力に基づく複雑な数式があります。

上記のすべてのデータを使用して値を計算し、それを各キーセット行に関連付けてデータベースに戻す必要があります。他の4つのテーブルには多くのルックアップがあります。パフォーマンスのために、すべてがメモリ内で行われます。

私は静的な辞書、オブジェクトモデル、戦略パターンなどでオブジェクト指向で行う方法を正確に知っていますが、機能的な方法ではこれらの構文のいくつかを使用する悪い匂いを取り除くことはできません。

私は現在、機能的な解決策について以下の前提を定めています。

  1. スタティック辞書が不良です。それは機能が副作用を持つことができるようだ。

  2. 私はCalculate関数が必要です。不変なオブジェクトをとり、3つのキーと計算された値を持つ不変なオブジェクトを返します。この関数の中には同じスタイルの別の関数があるかもしれません。

  3. 伝統的なOOパターンは、おそらく動作しません。

これをどのように高レベルで設計しますか?

私は間違っていますか?私は何かを見逃しましたか?

答えて

6

いいえ、間違っているわけではありません。 OOPと関数型プログラミングの両方に利点と欠点があります。

開発者は、各開発スタイルの使い方と方法を知っておく必要があります。幸いなことに、C#は両方の開発スタイルをサポートしています。

私の意見では、私は日常的に機能的プログラミングスタイルとoopプログラミングスタイルの両方を使用しています。複雑な相互作用やさまざまな抽象的な人工物(エンティティ、名詞など)間の依存関係を扱うときには最高です。機能プログラミングは、アルゴリズム、データ変換などを扱うときに最もよく使用される。特定の問題を解決するために必要なステートメントの複雑さが大きい状況。

私は通常、自分のドメイン(エンティティ、集合体、値オブジェクト、リポジトリ、イベント)でオブジェクト指向プログラミングを使用し、サービスオブジェクトの機能プログラミングを予約します。

ほとんどの場合、臭いや感覚が最も良くなります。ソフトウェア開発では明確なカットケースがなく、経験や練習がしばしば特定の選択肢にとって最善の判断です。

0

OO言語の機能プログラミングは間違っている傾向があります。それはうまく行っていない、過度に冗長なコードを生成し、より多くのエラーが発生しやすくなります(たとえば、末尾再帰をサポートしていない言語に深く再帰関数を書くなど。)

BLOCKQUOTE 1.静的辞書が悪いです。それは機能が副作用を持つことができるようだ。

いずれかの副作用があります。静的な辞書は、OO言語でメモを実装するのに適した方法です。

ブロッククォート3.従来のOOパターンはおそらく動作しません。

OOパターンは、ホーンFP技術をOO言語に磨くと、冗長で脆いコードが生成されます。それはハンマー技術でスクリュードライバーを使用しようとするようなものですが、結果が得られるのは確かですが、より良い方法があります。可能な限り最良の方法でツールを使用してみてください。特定のFP技法は有用かもしれませんが、言語を完全に無視することは良質なコードを作ることにはならないでしょう。

+0

問題のOO言語に依存します。 C#は機能的なテクニックではかなり良い仕事をしています。そして、Javaのようなもっと難解な柔軟なオブジェクト指向言語では、かなり機能的な方法でいくつかのことを行うことができますが、その場合にはかなりの量の認知的摩擦があります。 – JasonTrue

+1

何か機能的なことをしようとすると、Java環境にある場合は、Clojureで行うのが最善でしょう。技術的にはLispでMLベースの言語ではありませんが、Javaアプリケーション(JVMバイトコードの生成)を扱い、機能スタイルの開発をサポートすることができます。 –

+0

C#は多くの機能テクニックでフラットになります。非常に限定された型推論は単なるデングブレイカーです。関数のディクショナリなど、いくつかの汎用パラメータを使用する関数の型を書き出してみてください。ああ。 – MichaelGG

2

スピードをお探しの場合は、使用している基礎となるデータ構造を検討してください。 C#のDictionary <はハッシュテーブルですが、C#のSortedDictionary <>はバイナリ検索ツリーです。

F#とHaskellは両方ともツリーデータ構造を表現するのに良い仕事をしています。 C#が提供するデフォルトのものよりも、より具体的なデータ構造を使用することを検討することをお勧めします。

高レベルでは、数式が表示するパフォーマンス特性を把握し、それらをさまざまなデータ構造と比較します(リフレッシャーが必要な場合は、wikipediaは良いソースです)。いったん使用するデータ構造を理解したら、使用する実装について心配します。

+1

Dunno C#については、正しく実装されたハッシュテーブルには低速ルックアップはありません。ルックアップ速度を維持するために、挿入は時々テーブル全体を再ハッシュする必要があります。 (しかし、これは大きな問題ではなく、BerkeleyDBでもディスク上のハッシュのためにこれを行います)。 ハッシュテーブルに対するツリーの利点は、参照場所です。テーブルのチャンクを「順番に」繰り返している場合、「次の」ノードをプリフェッチするのは簡単です。 – jrockway

+0

私は速いか遅いかについて私のコメントを削除しました。ハッシュテーブルとバイナリツリーの使い方によっては、さまざまなメリットとデメリットがあります。 C#Dictionary <>は実際に検索時間が速いです。 「プロービングを使用してハッシュテーブルを追加、削除、検索するための平均漸近実行時間は一定時間です、O(1)」http://msdn.microsoft.com/en-us/library/ms379571(VS.80).aspx – gradbot

1

これをどのように高レベルで設計しますか?

基本的に高次関数を使用して、構文上のオーバーヘッドの少ない再利用可能なコンポーネントを作成します。次に、命令型データ構造から純粋に機能的なデータ構造(IOのような副作用に包まれた純粋に機能的な計算)への移行を望むかもしれません。最後に、副作用(完全に純粋に機能的)を追跡することさえできます。

粗いガイドとして、これらの3つのグラデーションは、Lisp(主に不純な)、Standard ML(純粋に機能的なデータ構造のより重い使用)、およびHaskell(完全な純度)で最初に見られます。

私は正確な問題を知らなくても詳細を伝えることはできませんが、多くの人が毎日これをやっていることを確信でき、非常にうまく動作します。

関連する問題