一部の関数型言語にソフトウェアトランザクションメモリが必要なのはなぜですか?


24

定義上、関数型言語は状態変数を保持すべきではありません。では、なぜHaskellやClojureなどがソフトウェアトランザクションメモリ(STM)の実装を提供しているのでしょうか?2つのアプローチの間に矛盾はありますか?


私は、この興味深い論文をリンクさせたいと思います。
ファルコン

1
明確にするために、すべての関数型言語は状態を維持しますが、純度は、変数の値が一度設定されると変更されないことを示します。
ロバートハーベイ

回答:


13

可変状態を維持する関数型言語には何も問題はありません。Haskellなどの「純粋な」関数型言語でさえ、実世界と対話するために状態を維持する必要があります。Clojureのような「不純な」関数型言語では、状態の変化を含む副作用が発生します。

主なポイントは、関数型言語は本当に必要場合を除き、可変状態を妨げるということです。一般的なスタイルは、純粋な関数と不変のデータを使用してプログラミングし、それを必要とするコードの特定の部分の「不純な」可変状態とのみ対話します。そうすれば、コードベースの残りを「純粋」に保つことができます。

STMが関数型言語でより一般的である理由はいくつかあると思います。

  • 研究:STMはホットな研究トピックであり、プログラミング言語の研究者は機能的な言語での作業を好むことがよくあります(それ自体が研究トピックであり、プログラムの動作に関する「証明」を作成するのが簡単です)
  • ロックは構成しない:STMは、異なるコンポーネントを構成することで複雑なシステムにスケールアップすると問題が発生し始める並行性へのロックベースのアプローチの代替として見ることができます。これが間違いなくSTMの主な「実用的な」理由です
  • STMは不変性によく適合します。不変の構造が大きい場合は、不変のままにしておき、他のスレッドが入ってサブ要素を変更したくないようにします。同様に、上記のデータ構造の不変性を保証できる場合は、STMシステムで「is」を安定した「値」として確実に扱うことができます。

個人的には可変性を許可するClojureのアプローチが好きですが、STMトランザクションに参加する可能性がある厳密に制御された「管理参照」のコンテキストでのみです。言語の他のすべては「純粋に機能的」です。

  ;; define two accounts as managed references
  (def account-a (ref 100))
  (def account-b (ref 100))

  ;; define a transactional "transfer" function
  (defn transfer [ref-1 ref-2 amount]
    (dosync
      (if (>= @ref-1 amount)
        (do 
          (alter ref-1 - amount)
          (alter ref-2 + amount))
        (throw (Error. "Insufficient balance!")))))

  ;; make a stranfer
  (transfer account-a account-b 75)

  ;; inspect the accounts
  @account-a
  => 25

  @account-b
  => 175

上記のコードは完全にトランザクションおよびアトミックであることに注意してください。別のトランザクション内の2つのバランスを読み取る外部オブザーバーは、常に一貫したアトミック状態を確認します。多くのトランザクションエンティティを持つ大規模で複雑なシステムで解決するため。

さらなる啓発のために、Rich HickeyはこのビデオでClojureのSTMを説明する素晴らしい仕事をしています


3

定義上、関数型言語は状態変数を維持すべきではありません

定義が間違っています。状態を維持できない言語は使用できません。

関数型言語と命令型言語の違いは、一方の言語には状態があり、もう一方の言語にはないということではありません。それは彼らが状態を維持する方法です。

命令型言語の状態はプログラム全体に広がっています。

関数型言語は、型シグネチャを介して明示的に状態を分離および維持します。そして、それが彼らがSTMのような洗練された状態管理メカニズムを提供する理由です。


2

プログラムには可変状態(たとえば、Webアプリのデータベースコンテンツ)が必要な場合があり、関数型プログラミングの利点を失うことなくそれを使用できると便利です。非機能言語では、可変状態がすべてに浸透します。何らかの特別なAPIを使用して明示的にすると、他のすべてが純粋に機能している間に、識別可能な小さな領域に限定できます。FPの利点には、簡単なデバッグ、反復可能なユニットテスト、痛みのない同時実行性、およびマルチコア/ GPUの使いやすさが含まれます。


おそらく、可変状態を意味します。 すべてのプログラムは、機能的なものであっても状態を維持します。
ロバートハーヴェイ

あなたが正しい。関数型プログラミングを行うのに十分な時間を費やしていないのは明らかです。
ウィルウェア
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.