今週の祭りは空配列
@fumieval: 「配列のすべての要素が条件を満たすならtrueを返す」関数を定義するとき、空の配列を渡したらfalseを返すかtrueを返すかが、良いプログラマかどうかの一つの境目だ 意外と意見が分かれた
true派
false派
例外派
要件次第派
そのパターンを設計が網羅してないなら設計に追加します
@nishio: これを別のたとえで説明すると「sumの実装、品物の値段の合計に使うから自動で10%の消費税をつけたらいいと思うんだ!」と言ってる人に対して「いいわけないだろ!!」とつっこんでるみたいな状態なわけです 自分のポジション
@vivid_UDON: そもそも大抵は標準ライブラリにあるんだからそれ使えって指摘もされてるのはおいておいて、部品のレベルでは数学的に一貫性のある挙動が確定しているのでそうしておけば良い派(標準ライブラリが結局どこでも同じなのも多分そう) 以前調べた時になんか名前がついてたような記憶はあるけどどんな名前かは全く思い出せなかった
アプリの要件と実装で使いやすい(バグりにくい/再利用性がある)パーツとは必ずしも一致しない その分岐をつぶすために例外的な処理のための例外的な処理
@vivid_UDON: たとえば配列aとbがあれば、 all(a) && all(b)と all(a.concat(b))は同じ結果を期待するが、空配列に対してfalseを返すと結果が異なる すると
1. allを使うあらゆる箇所で空配列でないことを確認する分岐を入れる 2. 常に最終結果であることが保証された配列に対してのみ呼ぶ
とかしないといけなくなる
@vivid_UDON: これ、1の方がまだマシなんだけど、1をやるなら最初から数学的に一貫したallを使っておいて、アプリケーション上の要求に関わる時だけ空配列だったらallを呼ばないコード書いた方が結局気を付けることも記述量も少なく済む アプリとしてfalseが欲しい可能性があっても結局こうなる
ただし、その関数の利用者に「例外を教えてもらってありがたい」という感覚が無いと破綻する
いちいちtry-catch書くのが面倒で、定義した関数を使わずに即席で同じ機能の物を書いたりする throwsがあるかどうかが違うから別の処理だよね!
そうしてバラバラに書かれたコードは下手すると実装者によって細かいケースの挙動が違い、どこが呼ばれるかによってまちまちな挙動を示したりする
例外を考慮することを強制出来ても、例外を考慮するのは開発体験が良くないのだ……