正しさについて考えさせられた

ことのはじまり

職場で偉い人と雑談してる時に

世の中わりと適当でもやっていけるんだから、あまりカツカツするのもアレな感じでよくないのかもしれないねえ

という話がありました。

多分に共感できるところがあって「ですよね~」なんて相槌を打ってたらとあるソースコードを見せられまして……

とあるソースコード

それはクライアントからソケットでデータを受け取ってゴニョゴニョするC言語で実装されたプログラムでした。

仕様は聞かずコードを眺めているとrecv(2)の返り値が期待値と異なっていた場合はロスト扱いするという実装です。

微妙な空白の時間が生まれました。

recvは確か受け取ったバイト数が返り値だから0になるか-1(error)になるまで呼び出さないといけなかったんじゃ…などと遠く消えそうな記憶を辿りよせるも不安だったのでMan page of RECVを確認しました。

recv(), recvfrom(), recvmsg() コールは、 ソケットからメッセージを受け取るのに使用される。 これらはコネクションレス型のソケットにも接続指向

中略

これらの三つのシステムコールはいずれも、成功した場合にはメッセージの長さを返す。

中略

ソケットに受け取るメッセージが存在しなかった場合、 受信用のコールはメッセージが到着するまで待つ。

記憶は正しかったようです。

これで上手く動いているのか確認したところ、動いてはいるけどロストも多いそうだよとおっしゃっていました。

正しさとは何か

ロストを許容するというのが仕様制限として謳われているため、ロストの原因を如何を問わずロストはロストなのです。これは仕様制限としているのだから問題ない。ロストの多寡が問題視されていないという現状も含めこれでよいということでした。

この事例が示唆しているのは、実装として間違っていたとしてもその正しさを決めるのは別のレイヤにあるということです。言い換えれば、このプログラムが拾ってくる情報の価値がこのプログラムの正しさを定義する尺度なのです。

まとめのようなもの

プログラマの端くれとしてはまったく腑に落ちない話で、プログラミング上の問題が発生しないコードを予算内に収めて書くことがプログラマとしてのあり方、正しさだと信じています。しかしその正しさも異なるレイヤで見れば必ずしも正しいとは限りません。悪く言えばいい加減な実装でも費用対効果があると判断されるのならそれでいいのだからプログラミング上の正しさなんてどうでもいいんだと強弁することもできます。

しかし、もしロストが多いことが問題となった場合はどうでしょうか。ネットワーク上の問題でロストしているのか、プログラミング上の問題でロストしているのか分析する必要が出てくるかもしれません。その時、この実装には問題があると判断できるプログラマでありたいと思います。