タグ付けされた質問 「side-effect」


9
有害と考えられる返品?コードがなくてもコードは機能しますか?
さて、タイトルは少しクリックされていますが、真剣に私は言いました、しばらくキックを求めないでください。私は、メソッドが真のオブジェクト指向の方法でメッセージとして使用されることを奨励する方法が好きです。しかし、これには頭の中のガタガタする問題があります。 よく書かれたコードは、オブジェクト指向の原則と機能の原則を同時に満たすことができると疑うようになりました。私はこれらの考えを調和させようとしています、そして、私が着陸した大きなこだわりポイントはreturnです。 純関数には次の2つの性質があります。 同じ入力で繰り返し呼び出すと、常に同じ結果が得られます。これは、不変であることを意味します。その状態は一度だけ設定されます。 副作用はありません。呼び出しによって引き起こされる唯一の変更は、結果の生成です。 それでは、return結果を伝える方法として使用することを誓った場合、どうすれば純粋に機能的になりますか? TELLは、聞いていない、いくつかの副作用を検討するものを使用してアイデアの作品を。オブジェクトを扱うとき、その内部状態については尋ねません。何をする必要があるかを伝え、その内部状態を使用して、私がそれを行うように指示したことで何をすべきかを見つけます。一度言ったら、何をしたのかは聞かない。私は、それがするように言われたことについて何かをしたと思っています。 Tell、Den's Askは単にカプセル化の別の名前以上のものだと思います。私が使うとき、私はreturn何が私を呼んだのかわかりません。私はそれのプロトコルを話すことができません、私はそれが私のプロトコルに対処することを強制する必要があります。多くの場合、これは内部状態として表されます。公開されているものが正確な状態ではない場合でも、通常は状態と入力引数に対して実行される計算にすぎません。応答するインターフェースがあると、結果を内部状態や計算よりも意味のあるものにマッサージする機会が与えられます。それはメッセージパッシングです。この例を参照してください。 昔、ディスクドライブには実際にディスクが搭載されていて、指で触れるにはホイールが冷たすぎるときに親指ドライブが車で行っていたものでした。void swap(int *first, int *second)とても便利に見えましたが、結果を返す関数を書くことが奨励されました。それで私はこれを信仰で心に留め、それを追い始めました。 しかし、今では、オブジェクトを構築する方法によって結果の送信先を制御できるアーキテクチャを構築する人々がいます。以下に実装例を示します。出力ポートオブジェクトを注入することは、出力パラメーターの考え方に似ています。しかし、それが、tell-don't-askオブジェクトが他のオブジェクトに何をしたかを伝える方法です。 副作用について最初に学んだとき、それを出力パラメーターのように考えました。私たちは、仕事のいくつかを驚くべき方法で、つまりreturn result慣習に従わないことによって人々を驚かせないように言われていました。確かに、副作用が発生する並列非同期スレッドの問題が山積みになっていることはわかっていますが、戻り値は実際には単に結果をスタックにプッシュしたままにしておくため、呼び出されたものは後でポップオフできます。それだけです。 私が本当に求めていること: あるreturnすべてのその副作用の悲惨さを回避し、ロックせずに、スレッドの安全性を取得する唯一の方法は、など、または私は従うことができます聞いていない、言う純粋に機能的な方法で?

7
同じ入力が常に同じ出力を返すだけでなく、副作用がある関数を何と呼びますか?
次のような通常の純粋な関数があるとします function add(a, b) { return a + b } そして、副作用があるように変更します function add(a, b) { writeToDatabase(Math.random()) return a + b; } 私の知る限り、純粋な関数とは見なされていません。なぜなら、人々は純粋な関数を「副作用のない関数」と呼ぶことがよくあるからです。ただし、同じ入力に対して同じ出力を返すという点では、純粋な関数のように動作します。 このタイプの関数には別の名前がありますか、名前が付けられていないのですか、それとも実際には純粋であり、純度の定義について間違っていますか?

5
関数型言語での非同期プログラミング
私はほとんどC / C ++プログラマーです。つまり、私の経験の大部分は手続き型およびオブジェクト指向のパラダイムに関するものです。ただし、多くのC ++プログラマーが認識しているように、C ++は長年にわたって機能的なスタイルに重点を移しており、最終的にC ++ 0xにラムダとクロージャーが追加されました。 とにかく、C ++を使用した関数型スタイルでのコーディングの経験はかなりありますが、LispやHaskellなどの実際の関数型言語の経験はほとんどありません。 私は最近、これらの言語の研究を始めました。なぜなら、特に並行性と分散コンピューティングへの応用に関して、純粋に機能的な言語の「副作用なし」という考えが常に興味をそそっていました。 ただし、C ++のバックグラウンドから来ると、この「副作用なし」の哲学が非同期プログラミングでどのように機能するかについて混乱しています。非同期プログラミングとは、ユーザーが提供するイベントハンドラーをディスパッチして、非同期に発生するイベントを処理するフレームワーク/ API /コーディングスタイルを意味します(プログラムのフロー外)。これには、Boost.ASIOなどの非同期ライブラリ、または単なる古いCさえ含まれます。シグナルハンドラまたはJava GUIイベントハンドラ。 これらすべてに共通することの1つは、非同期イベントハンドラーが呼び出されたことをプログラムのメインフローが認識するために、非同期プログラミングの性質が副作用(状態)の作成を必要とするように見えることです。通常、Boost.ASIOのようなフレームワークでは、イベントハンドラーはオブジェクトの状態を変更するため、イベントの効果はイベントハンドラー関数の有効期間を超えて伝播されます。本当に、イベントハンドラは他に何ができますか?コールポイントがないため、コールポイントに値を「返す」ことはできません。イベントハンドラはプログラムのメインフローの一部ではないため、実際のプログラムに影響を与える唯一の方法は、状態を変更することです(またはlongjmp、別の実行ポイントに変更することです)。 そのため、非同期プログラミングは、副作用を非同期的に生成することがすべてのようです。これは、関数型プログラミングの目標と完全に矛盾しているようです。これら2つのパラダイムは、関数型言語でどのように(実際に)調整されますか?

3
モナドを見るさまざまな方法
Haskellの学習中に、モナドとは何か、Haskellでモナドが重要である理由を説明しようとする多くのチュートリアルに直面しました。それぞれが類推を使用していたので、意味をつかみやすくなります。結局のところ、私はモナドが何であるかの3つの異なるビューになりました: 表示1:ラベルとしてのMonad 時々、モナドは特定のタイプのラベルとして考えます。たとえば、次のタイプの関数: myfunction :: IO Int myfunctionは、実行されるたびにInt値を生成する関数です。結果の型はIntではなくIO Intです。そのため、IOは、Int値がIOアクションが行われたプロセスの結果であることをユーザーに警告するInt値のラベルです。 その結果、このInt値はIOを持つプロセスからの値としてマークされているため、この値は「ダーティ」です。あなたのプロセスはもはや純粋ではありません。 見解2:モナドは、厄介なことが起こりうるプライベートな空間として。 すべてのプロセスが純粋で厳格なシステムでは、副作用が必要になる場合があります。そのため、モナドは、厄介な副作用を実行するための小さなスペースです。この空間では、あなたは純粋な世界から脱出し、不純なものに行き、あなたのプロセスを作り、価値を持って戻ってくることができます。 表示3:カテゴリー理論のようなモナド これは私が完全に理解していない見解です。モナドは、同じカテゴリーまたはサブカテゴリーの単なるファンクターです。たとえば、Int値があり、サブカテゴリとしてIO Intがあります。これは、IOプロセスの後に生成されるInt値です。 これらのビューは正しいですか?どちらがより正確ですか?

4
副作用を処理するためのIOモナドパターンの利点は純粋にアカデミックですか?
さらに別のFP +副作用の質問で申し訳ありませんが、私にこれに完全に答える既存の質問を見つけることができませんでした。 関数型プログラミングの私の(限られた)理解は、状態/副作用を最小限に抑え、ステートレスロジックから分離する必要があるということです。 また、これに対するHaskellのアプローチであるIOモナドを収集します。IOモナドは、プログラム自体のスコープ外であると見なされる、後で実行するために、ステートフルアクションをコンテナにラップすることによってこれを実現します。 私はこのパターンを理解しようとしていますが、実際にはPythonプロジェクトで使用するかどうかを決定するため、Haskell固有の仕様を避ける必要があります。 原油の着信。 私のプログラムがXMLファイルをJSONファイルに変換する場合: def main(): xml_data = read_file('input.xml') # impure json_data = convert(xml_data) # pure write_file('output.json', json_data) # impure これを行うためのIOモナドのアプローチは効果的ではありません: steps = list( read_file, convert, write_file, ) その後、実際にそれらのステップを呼び出すのではなく、インタープリターにそれを行わせることで、責任を放棄しますか? または別の言い方をすれば、それは次のように書くことです: def main(): # pure def inner(): # impure xml_data = read_file('input.xml') json_data = convert(xml_data) write_file('output.json', json_data) return …

5
なぜメモリからの読み取りは副作用ではなく、ファイルからの読み取りが副作用なのですか?
プロセスメモリからの読み取りを純粋な操作とするのは何ですか?グローバルメモリに100個の整数の配列を作成し、この配列の42番目の要素を取得したとします。副作用ではありませんよね?では、なぜファイルから100個の整数の同じ配列を読み取るのが副作用なのでしょうか?

2
ステートフルライブラリ上の副作用のないインターフェイス
でジョン・ヒューズとのインタビュー彼はアーランとHaskellの語る、彼はErlangでステートフルなライブラリを使用することについて言うために、以下があります。 ステートフルライブラリを使用する場合は、通常、その上に副作用のないインターフェイスを構築し、残りのコードで安全に使用できるようにします。 これはどういう意味ですか?私はこれがどのように見えるかの例を考えようとしていますが、私の想像力や知識は私に失敗しています。

5
スケーラブルで副作用のない統合テストを作成する方法は?
私の現在のプロジェクトでは、副作用のないスケーラブルな統合テストを作成するための優れたソリューションを思いつくのに苦労しています。副作用のないプロパティに関する少しの明確化:それはほとんどデータベースに関するものです。テストが完了した後、データベースに変更が加えられるべきではありません(状態は保持されるべきです)。スケーラビリティと状態保存は一緒にならないかもしれませんが、私は本当にもっと良い解決策を求めています。 一般的な統合テストを次に示します(これらのテストはデータベース層に影響を与えます): public class OrderTests { List<Order> ordersToDelete = new ArrayList<Order>(); public testOrderCreation() { Order order = new Order(); assertTrue(order.save()); orderToDelete.add(order); } public testOrderComparison() { Order order = new Order(); Order order2 = new Order(); assertFalse(order.isEqual(order2); orderToDelete.add(order); orderToDelete.add(order2); } // More tests public teardown() { for(Order order : ordersToDelete) order.delete(); …

3
「メソッドは値を返すか副作用があるはずですが、両方ではありません」の起源
私は一度、メソッドには戻り値があり(参照的に透過的)、または副作用がありますが、両方ではないことを読みました。このルールへの参照は見つかりませんが、それについてもっと学びたいです。 このアドバイスの起源は何ですか?どの人またはコミュニティからそれが生じましたか? 追加クレジット:このアドバイスに従うことの利点は何ですか?

3
参照の透明性を壊す副作用
Scalaの関数型プログラミングは、参照の透明性を壊すことに対する副作用の影響を説明しています。 副次的影響。これは、参照の透明性に対する何らかの違反を意味します。 「置換モデル」を使用してプログラムを評価するSICPの一部を読みました。 参照透過性(RT)を使用した置換モデルを大まかに理解しているので、関数を最も単純な部分に分解できます。式がRTの場合、式を分解して常に同じ結果を得ることができます。 ただし、上記の引用が述べているように、副作用を使用すると置換モデルが壊れる可能性があります。 例: val x = foo(50) + bar(10) 副作用がない場合はfoo、どちらの関数を実行しても常に同じ結果がに返されます。しかし、それらに副作用がある場合、それらはレンチを置換モデルに混乱させる/投げる変数を変更します。bar x 私はこの説明に満足していますが、完全に理解していません。 私を修正して、RTを壊す副作用についての穴を埋めて、置換モデルへの影響についても議論してください。

2
副作用の多いコードの単体テスト
ロボットを実行するためのC ++コードを書き始めていますが、実際にできる場合は、単体テストを組み込む方法がわかりません。私は、自動的にスケジュールされて実行されるロボットの「コマンド」の作成を可能にするライブラリーを提供されています。これらのコマンドを作成するためのメカニズムは、それらが提供するコマンドの基本クラスをサブクラス化し、仮想実装することでvoid Initialize()、void Execute()、およびvoid End()方法を。これらの機能は、ロボットに対して何かを行う(モーターの実行、ピストンの伸長など)副作用のためにのみ実行されます。このため、ライブラリ全体をモックしてロボットの状態の前後を確認できるようにするまでは、ユニットテストをコードに添付する場所は実際にはありません。過度に負担にならない、これを単体テストする方法はありますか? 編集する ライブラリの機能について誤解を招いていたと思います。ライブラリは、ロボットへのインターフェースのほとんどとコマンド/スケジューリングシステムを提供するため、コマンドの基本クラスをモックするほど単純ではないため、ハードウェアへのインターフェース全体をモックする必要があります。残念ながら、そのための時間はありません。

2
計算と副作用を分離するとき、「世界に尋ねる」コードをどこに置くのですか?
よるとコマンドクエリ分離原則と同様に、データにおける思考とのClojureとDDD 1は、計算や意思決定から(世界の変更)の副作用を分ける必要があるプレゼンテーションので、両方の部分を理解し、テストするために容易になるという。 これは未回答の質問を残します。境界に対して相対的に、「世界に尋ねる」ことをどこに置くべきでしょうか?一方では、外部システム(データベース、エクステンションサービスのAPIなど)からのデータの要求は参照透過的ではないため、純粋な計算コードや意思決定コードと一緒に置かれるべきではありません。一方で、どのデータを要求する必要があるかが事前にわからない場合があるため、計算部分から切り離して引数として渡すことは問題があるか、おそらく不可能です。

2
関数型プログラミング言語は副作用を許可しませんか?
ウィキペディアによると、宣言型である関数型プログラミング言語は、副作用を許可していません。一般に宣言型プログラミングでは、副作用を最小限に抑えたり、排除したりします。 また、ウィキペディアによると、副作用は状態変化に関連しています。したがって、関数型プログラミング言語は、その意味では、状態を保存しないため、実際には副作用を排除します。 しかし、それに加えて、副作用には別の定義があります。副作用 値を返す以外に、呼び出し側の関数または外界との観測可能な相互作用があります。たとえば、特定の関数は、グローバル変数または静的変数の変更、その引数の1つの変更、例外の発生、ディスプレイまたはファイルへのデータの書き込み、データの読み取り、または他の副作用のある関数の呼び出しを行う場合があります。 その意味で、関数型プログラミング言語は実際には副作用を許容します。外部の世界に影響を及ぼし、他の関数を呼び出し、例外を発生させ、ファイルに書き込むなどの無数の例があるからです。 それで、最後に、関数型プログラミング言語は副作用を許可するかどうか? または、何が「副作用」とみなされるか理解していないため、命令型言語では許可され、宣言型言語では許可されません。上記と私が得た結果によると、副作用を排除する言語はないため、副作用について何か見落としているか、ウィキペディアの定義が誤っています。

4
条件付きに副作用があっても大丈夫ですか?[閉まっている]
休業。この質問は意見に基づいています。現在、回答を受け付けていません。 この質問を改善してみませんか?この投稿を編集して、事実と引用で回答できるように質問を更新してください。 5年前休業。 アメリカの誰もが聞いたことのある大学でCS MSプログラムに参加するための前提条件として、中間データ構造コースを受講しています。クラスで記述された1行のコードが私の目に留まりました。 if (a > 33 | b++ < 54) {...} これは私の職場でのコードレビューに合格しません。インタビューでこのようなコードを書いた場合、これはあなたに対する重大なストライキとなるでしょう。(副作用のある条件付きであることに加えて、それは明快さを犠牲にして賢いです。) 実際、副作用のある条件式を見たことがなく、グーグルもあまり現れません。授業後も別の学生が留守にしていたので、変だと思ったのは私だけではありません。しかし、教授はこれが許容できるコードであること、そして彼がそのようなものを職場で書くことになることをかなり断固としていた。(彼のFTの仕事は、ご存知の会社のプリンシパルSWEです。) このコード行が受け入れられる世界は想像できませんが、望ましいことは言うまでもありません。私が間違っている?これでよろしいですか?より一般的なケースはどうですか?副作用のある条件付き?それらは大丈夫ですか?

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