プログラミングにおける副作用(side effect)とは、式の評価による主たる作用とは別に起こるそれ以外の作用である[1][2]。 式は、評価値を得ること(※関数では「引数を受け取り値を返す」と表現する)が主たる作用とされ、それ以外のコンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させる作用を副作用という[3][4][5]

副作用の例としては、グローバル変数や静的ローカル変数の変更、ファイルの読み書きなどのI/O実行、などがある。 一方、高水準言語における、正弦、余弦、平方根などの数学関数では、関数内でノーマルなローカル変数の変更ぐらいしか伴わないため、副作用がない[6]

なお、コンピュータの論理的状態(ローカル環境以外の状態)を変化させる機能、つまり副作用を起こす機能は、それ以降で得られる結果に影響を与える。 手始めに、与えられた数字を二倍して返す機能"double"があるとする。これは主たる作用しかなく、副作用のない例である。

double: x -> 2*x
例:
4 <- double: 2

このような機能では次のことが成立する。

  1. 同じ条件を与えれば必ず同じ結果が得られる
  2. 他のいかなる機能の結果にも影響を与えない

このような性質を参照透過性という[7]。参照透過な機能はそれ自身状態を持たないことで、副作用とは縁がない。

一方、状態を持つ機能"add"を考える。addが、機能内部からグローバル変数eを参照し、それを増加させて返すものとすれば:

add: x -> e:e+x
例:
e: 1
2 <- add:1
2 <- e
...

のようになるだろう。このような機能では機能の外側の状態を変化させてしまうために、参照透過性の一つ目の仮定が崩れ、また、eを利用する他の機能の結果も変化させるので二つ目の仮定も成立しない。add副作用を持つ機能である。

副作用を前提とするノイマン型アーキテクチャ、つまり、大半のプログラミング言語では、addのようなグローバル変数への破壊的代入、参照渡しされた引数に対するいわゆる“破壊的操作”、そしてインスタンス(レシーバ)に対する破壊的メソッドなどがある。一方、関数型言語では原則として副作用を存在しないものとみなし、モナドなどの手法で抽象化している。

機能が副作用を持たないことの利点は、いかなる状況でも常に同じ結果が得られるために数理論理学に基づく形式的な検証ができ、状況依存でのバグの発生が抑えられ、宣言型プログラミングができるということである[8]。反面、副作用を持たない言語設計はノイマン型アーキテクチャと反りが合わず、効率の点で不利になることが多い。また、単純な逐次処理を行う場合は状態を中心に命令的な思考をした方が扱いやすい場合がある。このためLISPMLなどは原則として関数型ながら、副作用を許容する設計になっている。

脚注

編集
  1. ^ トランジスタ技術 CQ出版
  2. ^ プログラム言語論 筑波大学
  3. ^ Cクイックリファレンス第二版 P64 オライリー・ジャパン
  4. ^ 英語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日確認]
  5. ^ Spuler, David A.; Sajeev, A. S. M. (January 1994). “Compiler Detection of Function Call Side Effects” (Document). James Cook University. CiteSeerx10.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).
  6. ^ ドイツ語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日確認
  7. ^ 厳密に言えば計算途上におけるコンピュータの物理的状態は変化しているし、OSやメモリ状態といった他のレベルでは参照透過性は崩れているかもしれない。しかし「この機能が考える世界」にはそのような変化は存在しないものとして仮想化される。
  8. ^ ダイクストラ構造化プログラミングでほぼ同等の主張を述べている。副作用の問題は関数型言語に特有というわけではない。

関連項目

編集

📚 Artikel Terkait di Wikipedia

抽象機械

 3?66, appearing in: Jan van Leeuwen, ed. "Handbook of Theoretical Computer Science. Volume A: Algorithms and Complexity, The MIT PRESS/Elsevier, 1990

間接参照

間接参照は、実装上のテクニックにとどまるものではなく、たとえばデビッド・ホイーラーによる格言 "All problems in computer science can be solved by another level of indirection." が示すように、問題の解決のためにしばしば必要なものである。

バッファオーバーフロー

CSCI 4968 - Spring 2015” (pdf). CyberSecurity group, Department of Computer Science, Rensselaer Polytechnic Institute (RPI). 2018年12月18日閲覧。 “2013-12-27

トライ (データ構造)

ドが子ノードを0側(1側)のひとつしか持たない時に格納される、その中間ノード下で最大(最小)値をもつ葉ノードへのリンク(descendant pointer)を持つことである。。階層にたいして二分探索をおこなうことで、木に格納する整数のビット数 w に対し、Successor, Predecessorの時間計算量がO(log

リード・コピー・アップデート

Lists (Technical report). Institute of Advanced Computer Science Studies, Department of Computer Science, University of Maryland. CS-TR-2222.1. ^ John,

Fortran

"A self-study course in FORTRAN programing - Volume I - textbook", Computer Science Corporation El Segundo, California, 1970. NASA(N70-25287). Valmer Norrod

メモリ安全性

している全ての言語がこの手法を採用している。CとC++では、実行時にメモリ安全性の検証を行うためにコードのコンパイル時変換を実行するCheckPointerやAddressSanitizer(英語版)などの多くのツールが存在し、これらを使用した場合に実行速度が2倍遅くなる。

General Instrument CP1600

Allen (1978). Encyclopedia of Computer Science and Technology: Volume 10 - Linear and Matrix Algebra to Microorganisms: Computer-Assisted Identification. CRC