パスワードを忘れた? アカウント作成
16633603 story
プログラミング

「配列のすべての要素が条件を満たすならtrueを返す」関数に空配列を渡したらtrueかfalseか? 280

ストーリー by nagazou
関数 部門より
あるAnonymous Coward 曰く、

ここ数日、Twitterのプログラマー界隈で「「配列のすべての要素が条件を満たすならtrueを返す」関数を定義するとき、空の配列を渡したらfalseを返すかtrueを返すかが、良いプログラマかどうかの一つの境目だ」というツイートを発端として、様々な意見が交わされているので、スラドにも共有したい。

発端となったのは上記のツイートだが、そのリプライや引用では「仕様によるのでは」「メソッド名次第」「コメントに書けばどちらでも良い」「使い方を間違えている可能性があるから例外を投げるべきだ」といったfalse肯定派もいれば、一方で「世の中の標準ライブラリはみんなtrue」「"配列のすべての要素が条件を満たすなら"なのだから論理的に考えてtrueに決まっている」という当然trueであるべきという主張も飛び交っている。

まさかこんなネタがこんなに盛り上がるとはという声もあるが、スラド諸氏はどうお考えだろうか?

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • 例外を投げる派はtrue派でもfalae派ででもないだろ

  • by Anonymous Coward on 2023年06月03日 9時13分 (#4471081)

    「配列のすべての要素が条件を満たすなら真」という定義で「入力が空集合なら、返り値は真か偽か」ってのは
    数学・論理学やそこら辺の話で、
    現実のプログラミングでは「関数を書く者がその想定する用途にあわせて定義し、その定義を関数の説明に明示すること」、
    「関数を使う人はそういう極端なケースが起きた場合の振る舞いに気を付けること」と言うので済む話。

    • by Anonymous Coward on 2023年06月03日 9時28分 (#4471088)

      同意します。
      この件は定期的に湧く「数学も出来ないプログラマなんてマウント」の亜種ですね。

      親コメント
  • 現実的には (スコア:3, 参考になる)

    by Anonymous Coward on 2023年06月03日 8時11分 (#4471046)

    こういうのはエラーチェックのために使うことが多いので
    条件を満さない要素が1つでもあればfalseで空ならtrueが普通と思う。
    空かどうかはまた別のチェックということで。

    • by minet (45149) on 2023年06月03日 8時25分 (#4471055) 日記

      私はこれに同意。

      ほかには、絞り込み検索の実装にも使いますね。
      ある要素が全ての絞り込み条件に適合していれば抽出する、って処理を書くときに、「絞り込み条件が空の場合は適合」となっているとシンプル。

      親コメント
    • by Anonymous Coward

      こういうのはエラーチェックのために使うことが多いので
      条件を満さない要素が1つでもあればfalseで空ならtrueが普通と思う。
      空かどうかはまた別のチェックということで。

      その用途だと「(別に行われてるべき)空チェックを正しくされてない」ことを検出できる、例外を投げる動作が一番理にかなってない?

    • by Anonymous Coward

      現実的にはって言うなら、自分の場合は、StreamAPI的に、配列にfilter()とかmatch()とかfind()とかで訊ねる、そういう感じで書く
      だからまず「配列を渡してtrueかfalseを返させる」って状況設定が変だし、trueが返ってくるのも気持ち悪い

      「エラーチェックのため」ならそう仕様に書けばいいっていうかそう書くべきで、一律にtrueを返すべきとかの暗黙の了解に委ねるのはちょっと怖いね
      良いプログラマなら、そこで仕様を確認するか、他の原則を適用して判断して欲しいと思う

  • 空の配列には、条件を満たす要素は一つも無い。
    つまり、falseだと思う。

    • Re:言葉尻? (スコア:4, すばらしい洞察)

      by Anonymous Coward on 2023年06月03日 10時52分 (#4471141)

      「すべての要素が条件を満たすか?」というだけ話に、「かつ最低でも一つは条件を満たすこと」という別の条件を勝手に加えて判断してるね
      論理的にも等価に言い換えるなら、「いずれかの要素が条件を満たさないことはないか?」だよ
      A and B and ... = not(notA or notB or ...)

      空配列は空であるが故に、いずれかの要素が条件を満たさないことはない、のでtrue

      親コメント
    • 「配列のすべての要素が条件を満たすならtrueを返す」関数というのは、配列の要素毎の条件判定の論理積を返す、と解するのが自然な気がする。Excel の AND 関数みたいな。

      論理積を計算するのにパラメータが 0個だったら、やっぱり例外を投げるべきではないかな。

      とは言え、そもそも人によって正解とするプログラムが違うのだったら仕様の定義が問題だと思うけど。

      親コメント
    • けど、私が普通にプログラムを書くと

      ①返り値の初期値としてTRUEをセット
      ②要素を一つづつチェックして、条件を満たさなければ返り値にFALSEをセット
       (FALSEになったらその先の要素のチェックはスキップ)

      という感じになるから、要素が0だとTRUEを返してしまいそうだ。

      やっぱり要件に「要素数が0の時の返り値」を指定してくれないと、最初に要素数のチェックまで思い至らないかも。

      親コメント
    • by Anonymous Coward

      同意。
      条件がキモで、
      大抵は配列の中にある値を使用して判定するよね

      まずは条件を定義してからの話ですね

    • by Anonymous Coward

      ところが、「店内で飲酒している人が全員20歳以上なら適法」という判定に「空ならfalae」を使うと、店内に客がいなかったり全員がノンアルを飲んでいたりするとアウトになってしまう。
      で、なぜかロジックは修正されず「誰か常に酒を飲む奴を配置する」なんてパッチが当てられたりするわけですな(笑)

      • by Anonymous Coward

        そらそうよ
        知りたいのは、店内に20歳未満なのに飲酒してるやつがいたら違法
        であって適法かどうかはどうでもいいもの
        要は仕様バグってこと

      • by Anonymous Coward

        「店内で飲酒している人が一人でも20歳未満なら違法」という判定に「空ならtrue」を使うと?

    • by Anonymous Coward

      Segmentation falutだったりして

    • by Anonymous Coward

      言葉尻ではなく本質だろう。
      そういう所を定義するのが良いプログラマ。

      これについては、問題の性質によるので、
      プログラムとしては「どれもありえる」。

      曖昧な処理は、仕様書に明記しろってことだな。

  • trueが正解 (スコア:2, 参考になる)

    by Anonymous Coward on 2023年06月03日 11時51分 (#4471186)

    falseが正解と書いてる人が居るので念のために言っておくが"true"が正解。
    これは論理学的には「Vacuous truth」で「全ての集合は空集合を部分集合として含む」「前提が偽なら命題は真(爆発律)」のように正当化される。
    空の場合は「全てが条件を満たす」で日本語的にもあってる。
    要素数が1兆・1億・1まで真な関数が0になると急に偽を返すのも直感に反する。
    プログラマーとしても最初はtrueで宣言したboolに&=したり、while(){}内でreturn false、外で`return true`したり、どう考えてもtrue。

    論理学なんかクソくらえと思うかもしれないが、論理学的にそうなら実務でも一貫してる。具体的な状況は、

    • 配列の一つのインスタンスでエラーが発生している場合に停止する→空なら問題ない
    • 同様に配列に処理不可能なデータが入っている場合例外を投げる→空なら問題ない
    • 年齢が18歳未満で注文品が酒を購入している場合、全て保護者の同意あるか→抽出後の判定で挙動が狂う
    • 配列のうち条件Aを満たすものを抽出し、かつ全ての要素がAかつBであるか判定する→Aを抽出後個数比較しB判定するコードの挙動が煩雑

    逆に空でfalseを返すべき状況は個数判定をすれば十分で、また0個が特別な意味を持つと考えた方が自然なケース。

    (なお単に「trueを返す」という条件だと空でもtrueが一貫してると言おうと思ったが、「falseを返す」だと空でfalseを返しそう。)

    個人的にはどうしても0個のケースを意識させたいならfalseや例外じゃなくてコールバック関数版を追加でもして欲しいところ。
    例外はJavaのように検査例外を採用してないと見逃す。こんな挙動は予想できん。
    falseはキレられ損害賠償でも当然。

  • and [] = True
    and (x:xs) = x && and xs

    ただし思わぬバグになる可能性があるので,不親切な気もする.

  • 純粋に処理の面だけで言えば変数(この場合は関数の返り値)の操作なんてInitとSetとGetの3つしかないんだから、
    これは良いプログラマかどうかなんて話じゃなくて
     (1)返り値のInitで何をセットするか
     (2)条件チェック処理で、条件を満たさないelseのケースでも返り値に何かをSetするか
    という仕様を決めて実装するかどうかだけのことじゃないの?
    もちろん仕様はありません動いているように動きます、ってのは論外だが、それが現場のプログラマの良し悪しだけで決まるかと言われると、、

    個人的には(1)でfalseをセットして、(2)ではelseでは何もセットしない(Setするのはifのケースのみ)だったことが多いかな。
    ツィートに似たケースとしては、ある{ステータス, イベント}のセットを受けて処理をする関数配列が思い浮かんだので、
    ここで空の配列が来た場合はどの関数も走らせちゃいけないからfalseを返させると思う。
    例外をthrowするかどうかはそのfalseを受けた後処理で決める。

    でもこうやって具体的に考えてみると(1)についてはtrueで返り値をInitするケースがないとは言い切れないな、
    ただ(2)で条件を満たさなくても返り値に何かをSetするケースは思い当たらないかも(条件合致以外で返り値の操作が必要なのはそもそもスジが悪い、ハズ)
    いずれにせよ仕様の思考実験としては面白いけど、これでプログラマーの良し悪しが分けられるとは思わないな。

    //知ってるか? 人間は大きく2つに分けると死んじゃう [twitter.com]んだぜ?

  • by Anonymous Coward on 2023年06月03日 11時01分 (#4471148)

    なぜこれが良いプログラマかどうかの判定にできるのかの根拠を知りたい。

    自分の狭い経験だけで、単純に判定しようとする人とは仕事したくないなあ

    • by Anonymous Coward on 2023年06月03日 15時41分 (#4471294)

      自分はこれは悪くないひとつの判定基準だと思う
      入力された配列のすべての要素が条件を満たす場合に~ってときに空配列が入ってきた場合を聞くのはその人が問題をどう扱うかを見れる

      回答は「このライブラリではtrueになります」とか「前職のプロジェクトではfalseになってました」でもいいんですよ
      一番ききたいのはそのtrue/falseにした理由
      そこでもし筋の通った理屈で問題を解決していればOK、もしも「このライブラリではそうなっています」とか
      「過去のプロジェクトでそうなっていたからです」という理由しか出てこなかったらNGね

      自分は良いプログラマというのは良い問題解決者でもあると考えているので、そういう意味でこれは良い質問かな、と

      親コメント
  • by st1100 (45287) on 2023年06月03日 11時09分 (#4471154)

    何をしたいかが重要で、
    それを明示するor明示されていなければ指摘して明示させるのがよいプログラマだと思う。

    配列に格納するのがなんかの調査データだったとして、空に対する戻り値は、何をしたいかによって次のとおり
    全ての条件を満たす優良事例を調べたい→良い条件が検出できないので、false
    条件に適合しない悪い事例を抽出したい→悪い条件が検出されないので、true
    入力されたデータを洗いたい→再入力等をさせるため、例外

  • by Anonymous Coward on 2023年06月04日 14時20分 (#4471610)

    30年前、学生だった時にプログラマのアルバイトに応募し、
    一対一の面接のなかで、「このプログラムコードを書け」という紙が渡された。
    確か、九九の表を作るような問題だったのだが、
    「出力例」の表は、一行ほど計算間違いが含まれていた。

    自分は、「ああ、誰かが打ち間違えたんだな」と思い、そのまま九九のコードを作って提出した。

    結果、面接に落ちた。

    結果に納得できずしばらく憮然としたが、
    今となっては、あれは「出力例について質問して聞く」が正解だったのではないかと思っている。
    つまり、コード作成能力ではなく「わからないことを聞く」というビジネスの基本を問うていたのだ。

    このトピックの問題も、もしあなたが何かのプロジェクトの一員としてこの問題に直面したのなら、
    正解はtrueでもfalseでもerrorでもなく、「質問して聞く」が正解なのではないだろうか。

  • by nekopon (1483) on 2023年06月05日 12時00分 (#4471921) 日記
    …みたいな議論になってないかコレ
    // うっかり「0は整数じゃねー」みたいな返答をしている人もいてカオス
  • by Anonymous Coward on 2023年06月03日 8時08分 (#4471044)

    良い悪いはない

  • > 「配列のすべての要素が条件を満たすならtrueを返す」関数を定義するとき、
    > 空の配列を渡したらfalseを返すかtrueを返すか

    https://www.perplexity.ai/ [perplexity.ai] :
    "「配列のすべての要素が条件を満たすならtrueを返す」関数を定義するとき、空の配列を渡した場合、trueを返すべきです1
    2
    3
    。空の配列は、すべての要素が条件を満たすという要件に反するものではなく、真偽値を返す関数においては、空の配列を渡した場合にtrueを返すことが多いです。また、空集合はあらゆる集合の部分集合であるため、空の配列を渡した場合にfalseを返すと、ある種の矛盾が生じることになります1
    。ただし、空の配列を渡した場合にfalseを返すという設計もあるため、プログラマーによって異なる場合があります。"

    > 空の配列は何も入っておらず、条件を満たすかどうかを比較する「要素」を含んでいない。だからfalseを返すべきではないのか

    "空の配列を渡した場合、すべての要素が条件を満たすという要件に反するものではなく、真偽値を返す関数においては、空の配列を渡した場合にtrueを返すことが多いです1
    2
    3
    。空の配列を渡した場合にfalseを返すという設計もあるため、プログラマーによって異なる場合があります2
    。空の配列は何も入っておらず、条件を満たすかどうかを比較する「要素」を含んでいないため、空の配列を渡した場合にfalseを返すべきだと考える人もいます4
    5
    。ただし、空集合はあらゆる集合の部分集合であるため、空の配列を渡した場合にfalseを返すと、ある種の矛盾が生じることになります1
    。したがって、空の配列を渡した場合にtrueを返すことが一般的です。"

    • とりあえず、書き込みする前に表示をチェックしないやつは良いプラグラマじゃない
      ついでに言うならせっかくコピーボタンが用意されてるのに、範囲指定で手作業コピペとかやるやつも向いてない

      で、説明しても何も『空集合はあらゆる集合の部分集合』って2度も書いてあるだろ
      『その配列は条件を満たす集合の部分集合か』ってのと同じなんだから空配列はtrueを返しとくのが無難とAI君はいってる

      親コメント
  • by Anonymous Coward on 2023年06月03日 8時39分 (#4471064)

    来週の会議で聞いてみよっと

    =18){$count_pass++;}}
    return ($count_all == $count_pass)?true:false;
    }

    var_dump( returnTrueIfAllOver18([20,30,40,50,60]) );// true
    var_dump( returnTrueIfAllOver18([1,3,5,10,90]) );// false

    var_dump( returnTrueIfAllOver18([]) );// true

typodupeerror

「科学者は100%安全だと保証できないものは動かしてはならない」、科学者「えっ」、プログラマ「えっ」

読み込み中...