5

私はCourseraでMartinOderskyのscalaクラスを終えたところです。Scalaは私の最初のFP言語であり、可変状態を制限するというアイデアに興奮しました。これにより、並行性が大幅に向上し、コードの保守が非常に容易になります。

これらすべてを学びながら、可変変数がなく、不変オブジェクトのみを参照している限り、オブジェクトの可変性を保証できることに気付きました。これで、古い状態を変更する代わりに新しい状態を作成することですべてを実行できるようになりました。可能な場合は末尾再帰を使用してください。

素晴らしい。だから私はこれまでのところチェーンの上流でしかこれを行うことができません。ある時点で、アプリケーションは既存の状態を変更できる必要があります。私はこの時点で並行性制御をどこに置くかを知っています、ロック、何とか何とか。私は今でも、いつも使用している標準のマルチスレッド同時実行制御をデフォルトにしています。

ああ、scalaコミュニティ、もっと良い方法はありますか?モナド多分?

編集:この質問は少し一般的であるため、ユースケースを示したいと思いました。データのいくつかのコレクションを格納する機械学習アルゴリズムがあります。これらには、データの更新された表現(トレーニングなど)をすべて不変で返す関数があります。最終的には、このreturn-updated-stateパターンを、シミュレーションを実行している実際のオブジェクトへのチェーンを上っていくことができます。これは変更可能な状態であり、コレクションへの参照を保持します。マルチコアまたはマルチシステムに配布したい場合があります。

4

3 に答える 3

4

これは少し主観的な質問なので、「どちらが最適か」という部分には答えようとしません。マルチスレッド同時実行のコンテキストでの状態が主な関心事である場合、1 つのオプションとしてソフトウェア トランザクション メモリが考えられます。

Akkaが提供する STMの実装 (クイックスタートを参照)があります。ユースケースによっては、重量が重かったりやり過ぎたりする場合がありますが、ロックの混乱よりも望ましい場合があります。ロックとは異なり、STM はデータベース トランザクションと同様に楽観的である傾向があります。データベース トランザクションと同様に、共有状態をトランザクション コンテキストで明示的に変更すると、記述した変更は自動的にコミットされるか、競合が検出された場合に再試行されます。基本的に、「アトミック」ブロックでのみ操作できる参照ですべての状態をラップする必要があります-使用するクロージャーを取るメソッドとして実装されますRefs と ScalaSTM は、状態に対する一連の操作全体が成功するか失敗するかを保証します。途中での変更や一貫性のない変更はありません。

これは Scala の暗黙的なパラメーターを活用します。 sに対するすべての操作は引数としてトランザクションRefオブジェクトを必要とし、これは に与えられたクロージャーによって受け取られ、暗黙的であると宣言できるため、will 内のすべてのコードは非常に自然でありながら安全なスタイルで記述できます。atomicatomic

問題は、これを有効にするには、提供されているトランザクション データ構造を使用する必要があることです。TSetの代わりにSet、のTMap代わりに使用することを意味しMapます。これらは、トランザクション コンテキスト (アトミックブロック内) で使用される場合、オール オア ナッシングの更新セマンティクスを提供します。これは、 clojure の永続的なコレクションによく似ています。Refこれらのatomicブロック内で使用するために、 から独自のトランザクション データ構造を構築することもできます。

括弧が嫌いでないなら、refs の clojure の説明は本当に良いです: http://clojure.org/refs

于 2012-12-10T16:17:15.300 に答える
2

ユースケースによっては、実際に変更するのではなく、部分的にコピーする非常に不変のオブジェクト構造に固執できる場合があります(元のリストと接尾辞を共有する「更新された」不変リストに似ています)。いわゆるレンズは、そのような構造を処理するための優れた方法です。このSOの質問またはこのブログ投稿でそれらについて読んでください。

もちろん、不変の構造に固執することは、変更をグローバルに観察可能にしたくない場合にのみ機能します。不変の構造がオプションではない可能性が最も高い例は、共有リストで動作する2つの同時クライアントであり、クライアントAによって行われた変更はクライアントBによって監視可能である必要があり、その逆も同様です。

于 2012-12-10T15:44:09.020 に答える