yak shaving life

遠回りこそが最短の道

e-Taxとマイナポータル連携をフル活用して確定申告したらめちゃくちゃ大変だったので備忘録を残す

今年も確定申告の時期が近づいてきたので、e-Taxとマイナポータル連携について書こうと思う。去年頑張ってやってみたものの、マイナポータル連携の設定で非常に苦労したので、今年e-Taxとマイナポータル連携を使って確定申告してみようと思っている方にこの情報が届けば幸いである。

なお筆者は普通のサラリーマンで、副業収入が少しあるため白色申告をしています。確定申告用のソフト等は使っておらず、確定申告書等作成コーナーから直接申告書を作成しています。青色申告や各種ソフトについては詳しくないのでご容赦ください。

ここから先はかなり長くなるので、長文なぞ読んでいられないという方は TL;DR だけでも読んでもらえればと思います。

目次

TL;DR (全部読んでいられない忙しい方向けのまとめ)

基本的に下記のページからたどって情報収集すればなんとかなるが、説明やUIのわかりづらさによりハマるポイントがいくつもあり大変。さらに電子証明書の交付などに数日かかったりもするので、締め切りギリギリで始めてしまうと間に合わなくなる。余裕を持って準備を始めるべき。理想は1月中に始めること。時間の余裕さえあればなんとかなります。

www.nta.go.jp

背景

e-Taxというものを使えば確定申告を全て電子申請で済ませることができるらしいというのは知っていたが、マイナンバーカードがないとできないとか、カードリーダーとかいう専用デバイスがないとできないとかいう噂を聞いて敬遠していた。しかし2021年分の申告はPCとスマホアプリとマイナンバーカードがあればできるようになったということで、試してみることにした。

全て電子申請で確定申告が済ませられるなんてめちゃめちゃ楽では?最高!と思って意気揚々とやり始めたものの、ハマりポイントが大量にあってすごく時間がかかった上に精神力を消耗しまくったので、これからe-tax&マイナポータル連携をやろうという方がもう少し穏やかな気持ちで確定申告できるように知見を共有したいと思い筆をとった次第。

完全にペーパーレスで確定申告ができるようになるのでメリットは大きく、また初回が大変な分次回以降は楽になる(はず)のでやってみる価値はあると思われる。紙の申告書や控除証明書を利用して確定申告を実施している各位はぜひ本記事を参考に試してもらいたい。

用語

ごく簡単に用語説明をする。

e-Tax

まずe-Tax。「e-Taxについて知る」というページから引用すると、

e-Tax国税電子申告・納税システム)とは、所得税、消費税、贈与税印紙税、酒税などの申告や法定調書の提出、届出や 申請などの各種手続をインターネットを通じて行うことができるものです。

とのこと。詳しくは下記ページを参照。

www.e-tax.nta.go.jp

マイナポータル連携

e-Taxはすでに利用している方も多いと思うが、各種控除をうけるために必要な控除証明書などの書類は紙や電子データで取得していると思う。具体的には生命保険、ふるさと納税、住宅ローンなど。確定申告の時期が近づくと保険会社等から書類が郵送されてくることが多い。このような必要書類(の電子版)をマイナポータル経由で自動取得し、さらに申告書に自動入力してくれるという夢のような機能がマイナポータル連携。詳しくは下記。

www.nta.go.jp

何それ!めっちゃ楽そう!!夢!!!!最高!!!!自動化最高!!!!と思いきや、これまた落とし穴があり注意が必要。詳しくは後述。

マイナポータル

ところでマイナポータルって何?という人も多いと思う。マイナポータルとは、マイナンバーカードを認証キーとして様々な行政サービスや外部のWebサービスを利用することができるシステムで、PCでの利用を想定したWeb版とスマホアプリ版がある。基本的にはNFC搭載のスマホマイナンバーカードをタッチして読み取ることで認証を行う。

myna.go.jp

マイナポータル自体はとても便利なサービスで、これから機能も拡充していくと思われるので、まだ使ったことがないという方は利用者登録してみると良いと思う。というか、マイナポータル連携したいならこの登録が必須。

マイナンバーカード

これは説明不要な気もするが、基本的にマイナンバーカードがないと何もできないので、未取得の方は早急に取得しましょう。通知カードはダメです。

なお、マイナンバーカードを作るときにパスワードを複数種類設定する必要があり、特に「署名用電子証明書のパスワード」と「利用者証明用電子証明書のパスワード」は確定申告に必要なので必ず覚えておくかパスワード管理ソフトなどに登録しておきましょう。

e-Taxのやり方

ここからは、e-Taxによる申告方法を具体的に説明していく。色々なページを頑張って調べないとよく分からなかったので、必要な情報をなるべく網羅したいと思う。

e-Taxの認証方式について

e-Taxの認証にはマイナンバーカード方式とID/パスワード方式があって、推奨はマイナンバーカード方式。マイナンバーカード持ってない人は仕方ないのでID/パスワード方式でやってもいいよ、みたいな感じのようだ。

2020年分までは、PCで確定申告書を作ってマイナンバーカード方式でe-Tax申請するためには、ICカードリーダライタというデバイスが必要だった。スマホで確定申告書を作れば前からICカードリーダライタは不要であったが、PCと違って機能が限られているという話のようだった。

しかし、2021年分からはICカードリーダライタがなくてもスマホアプリ(マイナポータル)があればできるようになった。ので、準備する必要があるのはNFC搭載スマホiPhoneとか)とマイナンバーカードだけ。というわけで大多数の人が問題なくe-Taxを利用できる土台が整ったといえるだろう。

e-Tax利用のための事前準備

下記ページにある「1 利用者識別番号の取得」をやっておく。基本的には「取得方法①」でやれば良い。

www.e-tax.nta.go.jp

「2 電子証明書の取得」についてはマイナンバーカードがあれば不要。ただし電子署名用のパスワードを入力する必要が出てくるのでちゃんと覚えているか確認しておくこと。マイナンバーカード作成時に申請しているはず。5回間違えるとロックされるので注意。

マイナポータル連携のための事前準備

マイナポータル連携というのは基本的に「電子証明書を取得して確定申告書に自動入力をする」というもの。なので、電子証明書の取得を事前にやっておく必要がある。これが結構待たされたりするので注意が必要。確定申告期間ギリギリにやり始めると間に合わない可能性があるので、余裕を持ってこの事前準備をしておくこと。年始あたりにやるのが望ましいが、遅くとも2月の上旬くらいまでにはやっておいた方が安心。

まず、マイナポータル連携が一体なんなのかというのがそもそも分かりづらいので、国税庁が出しているYou Tube動画を観ることをオススメする。この動画もまたたくさんあってどれを見ればいいやら分かりづらいので、とりあえず下記の二つを観ておけば良いと思う。

www.youtube.com

www.youtube.com

一つめの動画にもあるように、マイナポータルの確定申告事前準備用のページがあるので、基本的にはこちらに従って準備を行う。

myna.go.jp

まず手順1で加入している保険会社等がマイナポータル連携に対応しているか確認する。もし対応していない場合はその保険会社のホームページなどから直接電子証明書を取得する必要がある。e-Taxを使う以上、紙の控除証明書は使えないので注意。

手順2、3で民間送達サービスなるものに連携する必要がある。この辺りはPCからやろうとしたら色々制限があってできないと言われて詰んだので、スマホでやった方が良い。上記の事前準備用ページをスマホで開きましょう。準備を進めるためにはマイナポータルの利用者登録をしておくあるので、まだの方はやっておきましょう。

事前準備ページの「利用者登録/ログインして使う」をタップしてログインしましょう。「マイナポータル」アプリが必要なので、まだ入れてなければインストール。ログインするときにマイナンバーカードの「利用者証明用電子証明書のパスワード」なる四桁の数値を入力する必要がある。ここがまずハマりポイント。このパスワードを覚えてなかったら詰む…というかパスワード再設定とかが必要なので、マイナンバーカード作成時にちゃんと覚えておくのが大切。

パスワードを入力したあとにマイナンバーカードをスマホにタッチする(NFCで読み込む)ことでログインできる。この動作はマイナポータルアプリを使っていると何度も何度もやることになるので、マイナンバーカードをすぐ取り出せるところに置いておきましょう。

ところで「民間送達サービス」とは何かというと、各企業から控除証明書を電子で受け取るサービスのことらしい。特に気にする必要はないけれども聞きなれない言葉だったので一応。

ここからはその民間送達サービスの設定をしていく。筆者の場合はふるさと納税、生命保険、住宅ローン控除の設定をする必要があり、そのために必要な設定は「e-私書箱」だけだった。生命保険は「MyPost」の設定も必要だと書いてあったが実際には必要なかった。なぜかはよくわかりません。ここもハマりポイントかも。筆者はMyPostの設定がうまく行かなすぎて二日くらい格闘してました。つらい。

記載してある通りにe-私書箱の連携設定を進めたらこれでマイナポータル連携の事前準備は完了。ここからは実際に控除証明書などを取得するための設定をおこなっていく。

マイナポータル連携の設定

基本的には先ほどの画面で必要な項目(生命保険、ふるさと納税など)を選び、指示された通りに進めれば良い。夜中だと各社のサイトがメンテナンス中とかで使えなかったりするので注意。運が良ければサクサク進んで終わる。ただし、設定をしてから実際に控除証明書を取得できるまでに数日程度かかることが多い。本人確認や電子証明書の発行などに時間がかかる様子。筆者の場合は最大で一週間程度待つ必要があったので、確定申告期間ギリギリにこの作業を始めると間に合いません。早めにやりましょう。

ただしここにもまたハマりポイントが。利用しているふるさと納税サイトや生命保険会社が選択肢に出てこないときがある。そういう場合は「サイト(会社)名 マイナポータル連携」などで検索して対応状況を確認しましょう。まだマイナポータル連携に対応していない会社もあるので、その場合は諦めるしかない。辛い。

この場合、そのサイトや会社のホームページに行けば電子証明書を交付してもらえることが多いので探す。確定申告書作成時にその電子証明書を添付すればOK。電子証明書をもらうこともできない場合は…あるのかわからないけど、その会社に問い合わせて相談してみましょう。

住宅ローン控除の設定

住宅ローン控除だけは少し特殊で、e-私書箱経由ではなくマイナポータルに直接控除証明書が送られてくる。ただしここも要注意で、マイナンバーカードを利用して確定申告をした次の年から10月頃に取得できるようになるので、初回は自分で手入力する必要がある。来年からは何もしなくて良いので便利です。

詳細はこちらのpdfを参照。

https://www.nta.go.jp/publication/pamph/pdf/0019012-034.pdf

なお、マイナポータル連携のサイトには住宅金融支援機構の住 My Noteとかいう謎のサービスと連携するように書いてあるが、これは実際必要ありませんでした。これも苦労して登録したのに…

余談

とある生命保険会社がマイナポータル連携に対応していなかったのでホームページで電子証明書の交付を申請したら、数日後にダウンロード可能になったのだが、対応している環境がなんと Windows / IE のみだった。筆者はMacを使っているので、Chrome, Safari, Firefox, Edge for Mac を試してみたがやはり全部ダメ。厳しい…。

こういう場合、Virtualboxを使ってWindowsの評価版(無料)を立ち上げて電子証明書をダウンロードするという方法がある。ちょいと難しいですが下記のサイトを参考にすれば多分できると思います。

tech-vb.com

もしくは、プログラミングがわかる方ならJavaScriptをごにょごにょやるとダウンロードできる可能性もあるかも…ですが自己責任でやりましょう。

医療費控除

年間の医療費が10万円を超えると医療費控除を申請することができる。個人ではなく世帯で10万円なので、配偶者等がいる場合は合算可能。

医療費もマイナポータル連携で入力できるが、本人以外の医療費情報を取りたい場合はその人もマイナポータル連携の設定をする必要がある。その人のマイナンバーカードで利用者登録したあと、自分のマイナンバーカードを読み取ってもらい「代理人登録」をすることでその人の医療費情報を取得できるようになる。

…はずなのだが、実際に医療費情報を取得するところでエラーになって取得できなかった。自分の医療費データは取得できるが、配偶者の分はなぜか取得できず。色々調べたが結局原因はわからず。しかもマイナポータル連携で取り込んだ情報とExcelの医療費フォームを併用することはできないらしく、結局自分の分も全部Excelに入れる羽目になった。不便。

ここが唯一解決できないハマりポイントだった。今年はどうにか解消してマイナポータル連携で済ませたいところ。

確定申告書の作成

マイナポータル連携の設定が全て終わり、各社の控除証明書が届くとマイナポータルアプリに通知がくる。あるいは自分でホームページを見に行って、証明書が発行されていたらダウンロードしておく。必要な証明書が揃ったらようやく確定申告書の作成に取り掛かることができる。

www.keisan.nta.go.jp

確定申告書の作成手順自体については割愛。マイナポータル連携で取得した控除証明書は自動で入力されるので楽だし打ち間違える心配もない。これぞあるべき姿という感じで素晴らしい体験。便利な世の中になったもんだ。

マイナポータル連携に対応していない分の証明書は自分でアップロードする。xmlとか。一部の保険はマイナポータル連携、一部は自分でxmlアップロードというように併用可能。

電子証明書もないやつは数値を手入力。筆者の場合は地震保険の控除だけは手入力する必要があった。源泉徴収額とかも今まで通り打ち込んで、なんやかんやと作成を進め、最後に最後にマイナポータルでマイナンバー読み取って、送信完了!!終わり!!

確定申告書の提出

確定申告書を印刷して提出する場合、郵送するか、お近くの税務署に行って人ごみの中無駄に並んで提出する必要があるが、e-Taxだとその必要がない。最高。

おわりに

無駄に長くなってしまった。ここまで読んでくださった奇特な方、ありがとうございました。本当はもっと細かいところで何度も何度もつまづいて、日々溜まるストレスと戦いながらなんとか提出まで漕ぎ着けたという感じだったのですが、無駄をなるべく省いて記載しました。もう2度と同じことはやりたくない…。

この記事を読みながら進めれば、比較的スムーズに提出まで持っていけると思います。こんな苦労はもう誰にもしてほしくない。俺の屍を超えていけ。一度やったら次の年からは自動的に必要書類が集まってとても楽になる。はず。今年の確定申告がどのくらい楽だったのかはまた終わったら報告したいと思います。それでは良い確定申告ライフを。

List.ofで作ったリストでcontainsするとNPEが出る?

タイトルの通り、JavaList.ofで作ったリストでcontains(null)するとぬるぽになった。

jshell> var list = List.of(1, 2);
list ==> [1, 2]

jshell> list.contains(1);
$2 ==> true

jshell> list.contains(3);
$3 ==> false

jshell> list.contains(null);
|  例外java.lang.NullPointerException
|        at Objects.requireNonNull (Objects.java:221)
|        at ImmutableCollections$AbstractImmutableList.indexOf (ImmutableCollections.java:170)
|        at ImmutableCollections$AbstractImmutableList.contains (ImmutableCollections.java:201)
|        at (#4:1)

jshell> list.getClass()
$17 ==> class java.util.ImmutableCollections$List12

別にcontains(null)してもよくない?と思ったので、他のリストでも試してみたら、Arrays.asListで作ったやつは大丈夫だった。new ArrayListでもイケる。

jshell> var list2 = Arrays.asList(1, 2);
list2 ==> [1, 2]

jshell> list2.contains(null);
$7 ==> false

jshell> list2.getClass();
$8 ==> class java.util.Arrays$ArrayList

jshell> list2 instanceof ArrayList;
$9 ==> false

jshell> var arrayList = new ArrayList<>(Arrays.asList(1, 2));
arrayList ==> [1, 2]

jshell> arrayList.contains(null);
$11 ==> false

jshell> arrayList instanceof ArrayList;
$12 ==> true

jshell> arrayList.getClass();
$13 ==> class java.util.ArrayList


jshell> list.add(3)
|  例外java.lang.UnsupportedOperationException
|        at ImmutableCollections.uoe (ImmutableCollections.java:72)
|        at ImmutableCollections$AbstractImmutableCollection.add (ImmutableCollections.java:76)
|        at (#14:1)

jshell> list2.add(3);
|  例外java.lang.UnsupportedOperationException
|        at AbstractList.add (AbstractList.java:153)
|        at AbstractList.add (AbstractList.java:111)
|        at (#15:1)

jshell> arrayList.add(3);
$16 ==> true

要はArrayListArrays$ArrayListはOKだけどImmutableCollections$List12はダメということみたい。ていうかこのクラス何?List12?

確かにデコンパイルされたコードを追っていくとList12containsにはObjects.requireNonNullがあったし、Arrays$ArrayListの方にはなかった。これは意図的なんだろうか…。

みたいな感じで色々考えていたのだが、よく見たら公式ドキュメントに書いてあった。

NullPointerException - if the specified element is null and this list does not permit null elements (optional)

結論:公式ドキュメントを読め。

docs.oracle.com

リボルバーを読んだ

原田マハの小説です。

なぜ読もうと思ったか

奥さんの勧めで。

どのような本か

原田マハはアートのキュレーターもやっている小説家で、美術を題材にした小説を多数執筆している。本作はゴッホが題材。帯の文章が作品の雰囲気をうまく表していて良い。

誰が引き金を引いたのか? 「ファン・ゴッホは、ほんとうにピストル自殺をしたのか? 」 「――殺されたんじゃないのか? ……あのリボルバーで、撃ち抜かれて。」

書評というか感想

面白かった。ミステリー調なんだけど難解な謎解きという感じではない。テンポが良いし、美術史の勉強にもなる(気がする)し、読後感がとても良い。ハッピーエンドというか。文章も読みやすくてサクサク読めた。

奥さん曰く他の作品も似たような雰囲気で読後感良くアートの知識も得られるので面白いとのこと。色々読んでみたい。

しかし、小説を読んだのはいつぶりだろうか。働き始めてからは一冊も読んでないような気もする。よく考えたら小説は結構好きなのに、活字を読むなら技術書を読まないといけないみたいな焦燥感に駆られて読んでいなかったのかもしれない。これからは時々読もっと。

GoFデザインパターンは2022年においても有用なのか?

もちろん有用だとは思うんだけど、自分でデザインパターンを用いた実装をした経験がほとんどない。「Storategyパターン的な感じだな」とか「こいつはFacadeだな」とか思ったりはするけど、明示的に名前をつけたり書籍にあるクラス構成をそのまま利用したことはない気がする。あ、FactoryとRepositoryは作ったことあるか。まあでもアプリケーション開発の実務でデザインパターンをバリバリに書きまくっているという人は少ないのではないだろうか。

フィヨルドブートキャンプでコードレビューをしていると、時々デザインパターンを使ったコードを見ることがある。練習という意味ではもちろん良いことだし、実際そのままレビューしてOKを出すことも多い。ただ、もし実務だったらと考えると「ユースケースに微妙にそぐわない」もしくは「抽象化が過ぎる」みたいな理由でこのパターンやめましょうというフィードバックをする気がする。

Java系ライブラリの中身を見ているとデザインパターンを使ったコードが山ほど見られるのだが、Rubyとかだと少ない気がする。ちゃんと数えたわけではないけれども。言語の特性や書かれた時期によって違うであろうことは察しがつく。おそらく柔軟な書き方ができる言語ほど、また新しい言語ほどデザインパターンを使わなくなっていそうである。というか、有用でよく使われるパターンはそもそも言語機能に組み込まれていて自分で書く必要がなかったりする。Iteratorとか。

それから、いくつかのパターンはシンプルにあまり有用でないように思える。Singletonとかね。あるいはパターンというほどでもないやつとか。まあでもよくある設計に名前をつけるという行為は意思疎通を便利にする意味では有用か。

既存のコードを読むときや、自分で設計を考える時にデザインパターンの知識があった方がいいのは間違いない。でも別になくてもそこまで問題ないような気がするし、自分で考えた設計が「よく考えたらこれってTemplate Methodだな」みたいな感じで後から気づくことも多い。デザインパターンを学んだことで得られた知見が設計の時に役立っているのかもしれないけれど、デザインパターンありきで物事を考えるというのはあまりないような気がする。

…とかなんとか色々考えていたのだけれども、正直そんなに詳しいわけでもないし、端的にいうとよく分からない。誰か現代のソフトウェア開発におけるデザインパターンの立ち位置を解説とかしてくれないかなー、と思ったらt_wadaさんがFukabori.fmでがっつりやってくれていた。

fukabori.fm

fukabori.fm

去年拝聴して感動したので身の回りの人には勧めていたのだが、一年経ってもう一度聞いてみるとやはり素晴らしい。ということで全プログラマに聞いてもらいたいくらいオススメです。

というか、GoFもしくはt_wadaさんはこの話題で書籍出してくれないかなあ。

JavaScriptで配列のコピー

四種類ある。全部動作は同じでshallow copy

arr = [1, 2, [3]]

// 下記全部一緒。三つ目の要素だけ参照型なので共有される。
arr2 = arr.slice()
arr3 = arr.concat()
arr4 = [...arr]
arr5 = Array.from(arr)

個人的にはArray.from()が一番しっくりくるかな。でもタイプ量は一番多い…

参考

Google Nest Camを買ってベビーモニターにしている

Pixel 6を買ったときにGoogle Storeのクレジットが11,000円分もらえたのだが、如何せん欲しいものがない。どうしたものかと思っていたが、Google Nest Camを買ってベビーモニターとして使えないかという案を思いついた。そして実行してみた。買ったのはこれです。

Amazonでも売ってるのね)

まだ使い始めて一週間くらいだけど、普通に使えます。良いです。部屋真っ暗でも映るし、物音も聞こえるし、人の動きを感知して通知してくれるのも割と便利。

どう使っているのかというと、まず本体は寝室に固定。下の子(0歳)を寝かしつけて寝室に置いたあと、リビングに戻ってきて前の携帯(Galaxy A10)でGoogle Homeアプリを開き、カメラをオンにして監視。泣いたりモゾモゾ動いたら様子を見に行く。という感じ。これがあることにより、夫婦共にリビングにいても安心感がある。ベビーモニターの有無で夜の快適さがだいぶ違うので、導入してよかった。

今のところ特に不満はないし、似たような境遇(Google Storeのクレジットが余っているetc)な方にはおすすめ。

他社のベビーモニターも結構高かったりするので、クレジットとかなくても普通にアリかと思います。

Vacuous Truth という概念を知っておくとプログラミングに(ちょっとだけ)役に立ちそう

TL;DR

空のコレクションに allMatch() 的な判定をするとtrueになるぞ!気をつけろ!

背景

あるリストの全ての要素がとある条件を満たすどうかを返すメソッドがあり、 allMatch(何かしらの条件) した結果をbooleanとして返すという実装になっていた。このメソッドを利用しようとした時、ふと頭に疑問が湧いた。これって、リストが空だったら結果はどうなるんだっけ…?

というわけでREPLを開いてちゃちゃっと確認してみたところ、結果はtrueであった。

# 空のリストに対して、「全ての要素が奇数である」という判定をしたら true になる…?
jshell> List<Integer> list = List.of();
list ==> []

jshell> list.stream().allMatch(v -> v % 2 != 0);
$3 ==> true

直感的にはfalseが返ってくるのかと思った(だって奇数は含まれてないし!)ので、何故こうなるのか、他の言語でも同じなのかなどを調べてみた。

プログラミング言語における実装

Java

その時使っていたのはJavaだったので、Stream APIallMatchメソッドの仕様を確認したところ、下記のように書いてあった。

If the stream is empty then true is returned and the predicate is not evaluated.

はい。普通に載ってましたね。公式ドキュメントちゃんと読めって話ですな…。でも、なぜそうなるのかは書いていない。なぜなんだろうか。

docs.oracle.com

Ruby

次にRubyArray#all?の仕様を調べてみると、arrayが空の場合については特に書いていない…と思いきや、例のところにこっそり(?)載っていた。

p [].all? {|v| v > 0 }           # => true

trueということなので、JavaallMatchと同じ挙動のようだ。しかしこれ、文章で説明書いといてくれた方が親切な気もするな。

docs.ruby-lang.org

Rust

もう一例くらい欲しいなと思ってRustの iterator::all の仕様を調べたところ、

An empty iterator returns true.

とあった。やはりtrue

doc.rust-lang.org

何故なのか

3例も調べたので、まあどのプログラミング言語でも同じ結果になると思ってよさそう1。ということは、なぜ true になるのかちゃんとした理由があるに違いない。

Vacuous Truth

どうやらこのような挙動は論理学でちゃんと定義されており、"Vacuous Truth"と呼ばれているらしい。対応する日本語はなさそうなので、Wikipediaも英語版しかない。

en.wikipedia.org

ここで書いてある例としては、「ある部屋にある全ての携帯電話は電源がオフである」という命題があった時、その部屋にそもそも携帯電話がなかった場合、この命題は真になるというもの。

ちなみに「ある部屋にある全ての携帯電話は電源がオンである」という命題もまた真になり、また「ある部屋にある全ての携帯電話は電源がオンであり電源がオフでもある」という支離滅裂な命題もまた真になる。このような命題は部屋が空であるときにしか真にならないため、"vacuously" trueと呼ばれているそうだ。へー。あ、vacuousは「空虚な」みたいな意味です。

で、結局なぜこの場合trueになるの?というところですが、「論理包含」というページ内の例に説明がありました。

ja.wikipedia.org

P が偽ならば、Q の真偽にかかわらず「P ならば Q」が真である ということらしく、直感に反している感はあるけどちゃんと説明可能とのこと。辞表の例が一番わかりやすそうな気がしたので引用します。

ある人が「この仕事が失敗したら辞表を出す」と言ったとしよう。この言葉が嘘となるのは、仕事が失敗したにもかかわらず辞表を出さなかった場合のみである。仕事が失敗して辞表を出したならば約束を守ったのであるし、仕事が成功して(失敗せず)かつ辞表を出さなかったならば、やはりその人は嘘を言わなかったことになる。仕事が成功したにもかかわらず(何か他の理由で)辞表を出した場合も、やはり嘘を言ったとはみなされないであろう。すなわち、先の宣言では仕事が成功した場合のことは何も言っていないのであるから、辞表を出そうが出すまいが本人の自由である。

なるほどなー。元の問題に立ち返ってみると、そもそも「コレクションに要素が存在するならば」という条件Pがあると考えればいいのかな。ここが偽になったらQがなんであれ真になると。

結論

ちゃんと数学の勉強をしている人なら当たり前に知っていることなのかもしれないが、Vacuous Truthという概念があり、これはプログラミングにおける「空のコレクションに対して全要素の条件マッチをするとtrueが返る」という実装に反映されている。概念レベルで一度理解してしまえばこの挙動を忘れることはないと思うので、Vacuous Truthについて理解しておくことはプログラマにとって一定の利益がある。ので理解しておきましょう。ということが言いたかったのでした。

余談

ちなみにですが、allMatchではなくanyMatchの場合、結果はfalseになります。Rubyならany?、Rustならany。いずれもfalse。何故こうなるのかはちょっとよく分かってません。

若干罠っぽい(なんで一緒じゃないの?直感的じゃない…と思いがちな)挙動ですが、allanyで結果が逆になると考えれば忘れなさそうです。


  1. 追記: よく見たら Vacuous Truth のWikipedia ページにJavaScriptPythonの例が載っていた。もちろん結果は true