2006年09月20日

副作用のあるメソッドはどれ?

  
しつこく、副作用について考えている。
以下のメソッドのなかで、副作用のあるメソッドはどれなんだろう。

public int Multiple(int x, int y) {
return x * y;
}

public int Divide(int x, int y) {
a = x / y; // a は、フィールド
return a;
}

public int Add(object o) {
_list.Add(o);
return _list.Count; // _list は、フィールド
}

public void Remove(object o) {
_list.Remove(o); // _list は、フィールド
(int)(OtherClass.GetInstance()).Number = _list.Count;
}

public void Inc(MyClass obj) {
obj.NumBer = obj.Number + 1;
}

public void Write(string s) {
Console.WriteLine(s);
}


こう考えると、いかに「副作用」という言葉をいい加減に使っていたかが分かる。
僕の感覚だと、Remove と Inc の2つが、副作用のあるメソッドだ。でも、Webページを検索してみると、どうも他の人の考えは違うような気がする。いったい、どれが副作用のあるメソッドなのか、どなたか教えて!


この記事へのコメント
Multiple以外は副作用ありなのかも知れません。
http://ja.wikipedia.org/wiki/%E5%89%AF%E4%BD%9C%E7%94%A8_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)
↑によると、代入もアウトですし。
Posted by mei at 2006年09月20日 04:50
「関数」は元々数学のものだったわけで、「引数で与えられた数値から計算結果を求める以外のこと」はすべて「副作用」と呼ばれます。

が、いまやあまり意味が無い気もします。

Posted by 渋木宏明(ひどり) at 2006年09月20日 08:23
mei さん、渋木さん
コメントありがとうございます。
やはり、フィールドに代入するのも副作用なんですね。

社内で利用する規約を作成しているときに、「副作用」という言葉が、人によって受けとり方が違うので、いったいどれがコンセンサスが取れているものなのか、知りたかったのです。
結局、「副作用」という言葉を使うのはやめました。

C言語などのクラスの概念がない場合、副作用という言葉の定義は、ほぼ明らかだったと思うのですが、クラスの概念がそこに入ると、どうも副作用という言葉の意味があやふやになってしまったように感じています。

>が、いまやあまり意味が無い気もします。

この言葉で、僕の気持ちも吹っ切れました(笑)。
Posted by Gushwell at 2006年09月20日 09:32
「オブジェクトの状態を変更しない」「I/Oしない」ことが副作用なしの条件だと認識しておけばいいんじゃないでしょうか。副作用のない関数は、オブジェクトの状態が変わらない限り、「同じ引数を与えれば同じ結果を返す」「何度呼んでも、どのような順序で呼んでも動作は変わらない」ということが保証されます。そのため副作用の有無を明示しておいたほうが安心してプログラミングできるかと。

上の例だと、
Multiple: 副作用なし
Divide: aを参照している他のメソッドの動作が変わるため副作用あり
Add,Remove: 副作用あり
Inc: 渡されたオブジェクトの状態を変えるため、副作用あり
Write: Write("hoge");Write("hage");とWrite("hage");Write("hoge");では動作が変わる→副作用あり

といったかんじですね。詳しくはHaskellを(略)
Posted by todesking at 2006年09月21日 14:42
todeskingさん、
一意性、順序性のどちらかが満たされないと、副作用があるということで良いですかね。
でも、これは本来の副作用という意味からは大きく逸脱してしまっているのが、個人的には気にいらないです。
だって、Writeによって起こる作用は、本来の求めている効果ですからね。
まあ、プログラミングの世界では、そういうもんだということで、諦めることにします。

ところで、Haskellは、副作用がないらしいですが、Consoleに出力するような関数?は、どうなってるんでしょう?
関数型言語は、さっぱりわからないので、Haskellの説明読んでもよく理解できませんでした。
Posted by Gushwell at 2006年09月21日 17:16
 

この記事へのトラックバックURL

http://trackback.blogsys.jp/livedoor/gushwell/50592177