副作用 (プログラム)
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2023/11/17 02:43 UTC 版)
![]() | この記事は検証可能な参考文献や出典が全く示されていないか、不十分です。(2016年3月) |
プログラミングにおいて、式の評価による作用には、主たる作用とそれ以外の副作用(side effect)とがある[1][2]。 式は、評価値を得ること(※関数では「引数を受け取り値を返す」と表現する)が主たる作用とされ、それ以外のコンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させる作用を副作用という[3][4][5]。
副作用の例としては、グローバル変数や静的ローカル変数の変更、ファイルの読み書きなどのI/O実行、などがある。 一方、高水準言語における、正弦、余弦、平方根などの数学関数では、関数内でノーマルなローカル変数の変更ぐらいしか伴わないため、副作用がない[6]。
なお、コンピュータの論理的状態(ローカル環境以外の状態)を変化させる機能、つまり副作用を起こす機能は、それ以降で得られる結果に影響を与える。
手始めに、与えられた数字を二倍して返す機能"double
"があるとする。これは主たる作用しかなく、副作用のない例である。
double: x -> 2*x 例: 4 <- double: 2
このような機能では次のことが成立する。
- 同じ条件を与えれば必ず同じ結果が得られる
- 他のいかなる機能の結果にも影響を与えない
このような性質を参照透過性という[7]。参照透過な機能はそれ自身状態を持たないことで、副作用とは縁がない。
一方、状態を持つ機能"add
"を考える。add
が、機能内部からグローバル変数eを参照し、それを増加させて返すものとすれば:
add: x -> e:e+x 例: e: 1 2 <- add:1 2 <- e ...
のようになるだろう。このような機能では機能の外側の状態を変化させてしまうために、参照透過性の一つ目の仮定が崩れ、また、eを利用する他の機能の結果も変化させるので二つ目の仮定も成立しない。add
は副作用を持つ機能である。
副作用を前提とするノイマン型のアーキテクチャ、つまり、大半のプログラミング言語では、add
のようなグローバル変数への破壊的代入、参照渡しされた引数に対するいわゆる“破壊的操作”、そしてインスタンス(レシーバ)に対する破壊的メソッドなどがある。一方、関数型言語では原則として副作用を存在しないものとみなし、モナドなどの手法で抽象化している。
機能が副作用を持たないことの利点は、いかなる状況でも常に同じ結果が得られるために数理論理学に基づく形式的な検証ができ、状況依存でのバグの発生が抑えられ、宣言型プログラミングができるということである[8]。反面、副作用を持たない言語設計はノイマン型アーキテクチャと反りが合わず、効率の点で不利になることが多い。また、単純な逐次処理を行う場合は状態を中心に命令的な思考をした方が扱いやすい場合がある。このためLISPやMLなどは原則として関数型ながら、副作用を許容する設計になっている。
脚注
- ^ トランジスタ技術 CQ出版社
- ^ プログラム言語論 筑波大学
- ^ Cクイックリファレンス第二版 P64 オライリー・ジャパン
- ^ 英語wikipediaのSide effect(computer_science)の項目を参考。「In computer science, an operation, function or expression is said to have a side effect if it modifies some state variable value(s) outside its local environment, that is to say has an observable effect besides returning a value (the main effect) to the invoker of the operation. 」の記述。2020/10/09日確認]
- ^ Spuler, David A.; Sajeev, A. S. M. (January 1994). "Compiler Detection of Function Call Side Effects" (Document). James Cook University. CiteSeerx: 10.1.1.70.2096.
The term Side effect refers to the modification of the nonlocal environment. Generally this happens when a function (or a procedure) modifies a global variable or arguments passed by reference parameters. But here are other ways in which the nonlocal environment can be modified. We consider the following causes of side effects through a function call: 1. Performing I/O. 2. Modifying global variables. 3. Modifying local permanent variables (like static variables in C). 4. Modifying an argument passed by reference. 5. Modifying a local variable, either automatic or static, of a function higher up in the function call sequence (usually via a pointer).
- ^ ドイツ語wikipediaの Wirkung (Informatik) の項目を参考。そのなかの Programmiersprachen という項に「In den meisten Programmiersprachen kann die Auswertung eines Ausdrucks eine spezifizierte Wirkung haben. Ausdrücke und Funktionen können entweder wirkungsbehaftet oder wirkungsfrei sein. Zur Gruppe der Funktionen mit Wirkung gehören beispielsweise in der Regel alle, die mit der Ein- oder Ausgabe von Daten zu tun haben. Wirkungsfreie Funktionen in Hochsprachen sind etwa mathematische Funktionen wie Sinus, Kosinus oder Quadratwurzel.」という説明。2020/10/09日確認
- ^ 厳密に言えば計算途上におけるコンピュータの物理的状態は変化しているし、OSやメモリ状態といった他のレベルでは参照透過性は崩れているかもしれない。しかし「この機能が考える世界」にはそのような変化は存在しないものとして仮想化される。
- ^ ダイクストラは構造化プログラミングでほぼ同等の主張を述べている。副作用の問題は関数型言語に特有というわけではない。
関連項目
「副作用 (プログラム)」の例文・使い方・用例・文例
- 薬の副作用
- 薬には副作用が有ります
- 副作用があるとは知らずに、クロラムフェニコール系の薬飲んでしまった。
- シンバスタチンの副作用は何ですか?
- ナルトレキソンには頭痛や吐き気などの副作用がある。
- エストリオール製剤の副作用は下記の通りです。
- 多くの歯医者がビスホスホネートの副作用を注視している。
- 化粧品の広告がハイドロキノンの効果と副作用を説明している。
- メチシリンは副作用のためもはや使用されていない。
- 会陰切開術のあと、何か副作用はありましたか。
- 副作用のリスクは高用量によって高まる。
- その使用による副作用は沢山ある。
- その薬はより重度の副作用を起こす可能性がある。
- この薬はまれに副作用が起こる場合があります。
- あなたは今まで薬による副作用が出たことがありますか?
- その薬品は人によっては強い副作用が起こる。
- 薬の副作用で寝ている。
- 私は薬の副作用で倒れてる。
- 私は薬の副作用に悩まされている。
- 患者に副作用が発生した。
- 副作用_(プログラム)のページへのリンク