マウンティングの語源調査の仕方

前回、思い出話として

nagise.hatenablog.jp

 

を書いたのだが、その中でネットスラングの「マウンティング」について、初出が

 

nagise.hatenablog.jp

であるということを書いた。この記事は 2008年9月20日で、以下の用例が見られる。

 

そんなテクニックはいかに相手のニホンザルを押さえ込んでマウンティングを成功させるかというテクニックでしかない。そんなことをやったところで疑問はなんら解決しないし、誤った意見をこうした手法で押し通しでもした日には、後で大きな惨劇が起こりかねない。勝った負けたなどと言っていても議論は進展しないのである。

 

 これは明確なエビデンスで、この時点でこのような用例があった、というのはひとつの道標となる。

 

 ここで、「筆者が発案したというのは本当か?」「より古い用例はないか?」という疑問が生じることだろう。では、そうした疑問が生じたときにどのように対処すればよいか。

 

書籍での用例

 書籍では 瀧波ユカリ・犬山紙子(2014)『女は笑顔で殴りあう : マウンティング女子の実態』筑摩書房 が最古とされており、インターネット上のネットスラングが先行して用いられていることは既知の通りである。この書籍を筆者が読んで着想を得て2008年に上述の記述をするにはタイムマシンが必要になる。

 

簡易検索結果|「マウンティング」に一致する資料: 4件中1から3件目|国立国会図書館サーチ

 国会図書館の検索では出版年別のカテゴリがあるので、古い時代の検索結果を確認していただきたい。上述の2008年のネットスラングより前に先行の用例があれば、それを見て剽窃したのだろうというシナリオもあるいは考えられることになる。

 

 注意しなくてはならないのは、2008年より前に生物学的な「マウンティング」という用語が既にあったことは周知の事実であり前提である。なので、それを人と人との間の関係性として用いた用例を見出さなければならないという点である。

 

 ※注 追記参照。より古い用例の情報を頂いた。まさに「マウンティング」というテーマそのものについて記述した本というわけではないが、用例として利用がある本が見つかったというのは特記するべきことだろう。

プログラマーの脳みそでの用例

 ブログ「プログラマーの脳みそ」では2008年9月20日の初出からその時期に集中的に利用が見られる。ここでは日付とタイトルのみを挙げる。

 思いつきで単一使用したわけでなく、ここで考察がされ人間関係におけるマウンティングという概念を見出したことが伺える。

検索エンジンで古い用例を探す

 例えばGoogleだと、「ツール」から検索対象となる年月日を指定することができる。

 

マウンティング - Google 検索 

 

 インターネット上の用例を探す場合はこの機能が便利だが、時折、新しい記事が古い時期の記事と誤認されることがある点に注意。該当サイトは実際に2006年に書かれたものではない。

 技術的には、ページを表示しようとHTTPリクエストを送った際の応答にこのコンテンツは何月何日のものです、という日時が入っているのだが、Googleのロボットがサーバーに情報収集に赴いた時に変な値がかえるようになっていたのだと思われる。

 

 ときどきこうした事例もあるので、検索でみつけた各ページを実際に確認して用例としても合致しているかを確認していく。

 

 2010年以前の用例を探すと分かるが、犬のマウンティングや、猿のマウンティングについての用例ばかりで、現代のネットスラングの人が人に対して優位をアピールする行為を指して「マウンティング」を用いている例は見られない。先の2008年の用例ぐらいである。候補を見つけたらぜひブログを書くなりして発表して欲しい。(注:情報をいただいた。追記参照)

 

 2008年以後、初期のネットスラングとしての「マウンティング」の用例としては、2011年7月5日の内田樹氏による 暴言と知性について - 内田樹の研究室 などが挙げられる。

 

今回彼が辞職することになったのは、政府と自治体の相互的な信頼関係を構築するための場で、彼が「マウンティング」にその有限な資源を優先的に割いたという政治判断の誤りによる。

 

 こうした初期の用例は、ネットスラングとしての「マウンティング」の黎明期を捉える上では貴重な資料となるだろう。

 

格闘技用語について

 現代ではネットスラングの「マウンティング」の類語として「マウントをとる」という言葉がある。こちらの用例はどうか。

 

 格闘技用語としての「マウントをとる」についてはネット上での検索では用例を遡ることが案外難しく、国会図書館の検索ではなかなか用例を見出せない。

 

2002年の書籍で「マウントポジション」の用例があることはみつけることができた

中井祐樹柔術バイブル (クエスト): 2002|書誌詳細|国立国会図書館サーチ

 

 筆者の調べでは1995年のヒクソン・グレイシーの試合についての記述でマウントポジション、マウントという表現がある。この記述が当時近くに書かれたものなのか、後に書かれたものなのかは少し判別しにくい。

静寂なる戦い【中井祐樹vsヒクソン・グレイシー】 両者は何を想う!?

 ちなみに日本のインターネットの普及は1995年末のWindows95発売からで、それ以前の時代のインターネットコンテンツはとても少ない。当時のコンテンツそのものではなくとも、ブログサービス移転などに伴い転記され残されているものである可能性もある。あるいは雑誌など紙媒体などに書かれたものがWeb公開されているようなケースもある。一概に言えないが、1995年当時に格闘技用語として「マウント」という概念があったことは筆者は疑っていない。エビデンスとしての傍証を出すのが難しいという話である。

 

 うろ覚えではあるが、マウントポジションについては川原正敏(1987-1996)『修羅の門』で見た覚えがある。そのぐらいの時期には格闘技用語としての「マウントポジション」「マウントをとる」は認知されていたと言えるのではないか。

 

格闘技用語からの転用の可能性は?

 さて、ここで重要なポイントとして格闘技用語では「マウントポジション」ないし「マウントをとる」といった表現である点。決して「マウンティング」という言い方ではないのだ。マウントポジションをとることを指して「マウンティング」と呼んでいる用例は少なくとも筆者が調査している間には見かけなかった。

 

 ネットスラングの「マウンティング」の語源を格闘技用語の「マウント」とする説は、なぜ「マウント」ではなく「マウンティング」という表現で用いられるのか?という疑問に答えなくてはならない。

 

 筆者の考えでは「マウンティング」という概念がスラングとして広まった際に、格闘技用語由来の「マウントポジション」や「マウントをとる」という表現と混用されるようになったのだとみている。初出の用例は明らかにニホンザルのマウンティングと表現されており、生物学的な用語としての「マウンティング」が由来であることは明らかである。

 

 なんせ、「マウンティング」も格闘技用語の「マウント」も、語源としては当然に英語のmountが由来なのであるから、語形が似ているのも当然だし、混同されやすいのも当然であろう。どちらも上に乗るニュアンスの言葉である。

 

説を否定するには

 以上が筆者の考察結果なのだが、異論がある人もいよう。

 

 古い時代に用例が「ない」ことを証明することは難しく「まだ見つかっていないだけ」の可能性は否定できない。「マウンティング」の発案者がなんらかの既存の表現を剽窃したとするのであれば、その元になったであろう候補を提示しなければ始まらない。

 

 それがみつからないことには、その初出を書いた人が発案者であろうとするのが自然な推定であろう。また、より古い用例が見つかったとして、剽窃があったのか、それぞれ独立に生じた表現なのかは検討が必要である。いずれも、より古い用例を挙げなければいけない。

 

 例えば、2008年以前の「マウンティング」の用例を見つけ出すとか、あるいは2008年以前に格闘技用語の「マウントをとる」という表現を、対人関係で優位をアピールする意味で用いている用例を見つけ出すとか。(注:追記参照。古い用例が見つかった)

 

 ここまで「マウンティング」の発案者は~と、さも他人事のように書いてきたが、当事者主観の証言をするならば、まさにニホンザルのマウンティングに着想してそれを人間関係に転用したものであり、既存の用例を剽窃したものではない。

 

 まあ、私見を言えば独立に誰かがそのような表現を産みだしていても不思議はないと思っている。その時は先行事例こそが初出ということになり、当用例はあくまでも2008年時点でのいち用例という扱いになることだろう。(注:追記参照。古い用例があったようだ)

 

追記

 

元記事側ではてブで情報を頂いた

素晴らしい。古い用例を見事に見つけ出して頂いている。

 いずれも未読の書である。独立に生じてなんら不思議のない用法であるから、そういう先行事例は筆者が見つけれられていないだけでありそうだなーと思っていた。謎がひとつとけて嬉しい。

 筆者の用例はせいぜい「はてなダイアリーでの初出」とかそんなもんだろう。自分が考え付く程度のことは他の誰かも考え付くだろうということの証左になった。

 

 話を少しでも盛るとこんなもんであるし、こうした新情報が得られたときに大事なのは、訂正することである。

 

諸君 - Google ブックス
1996年
「政界サル山の権力争奪戦で、小沢にマウンティングされた過去があるからだ。」

 

翻訳会社徹底比較スレ 2nd round

2005年
「小山の大将やボス猿になりたがるやつっているよね。
(中略)
サルと仕事をするかしないかは
マウンティングの例を書き込んでくれれば
あとは読んだ側が判断すればいいと思う。」

このあたりの用例はまさに猿のマウンティングの比喩であるとみて間違いないだろう。

参考資料

ゲームの歴史とハックルさんとの思い出

思い出話。今回はポエムと思って気楽に読んで欲しい。

 

 インターネットの世界には情報が溢れかえっていて、やれ、なんやらが炎上しただのそんなニュースもありふれていて特に興味もわかない。ふーん、ゲームの歴史について書いた本が噓八百で炎上してんのか、まあ適当なことを書きならべる人がトンデモ本を書きましたなんてのは昔から枚挙に暇がない話だ。

 

 その程度に思っていたのだけども、先日ようやくそのゲームの歴史なる本を書いた人が岩崎夏海氏であったことを認識した。

僕の古い古い記憶が、この人物を知っているぞ、と呼び掛けてきた。そう、あれは2008年のことだった。今から15年も前のことになるのか。

 

 岩崎氏ははてなダイアリーはてなブログの前身となるブログサービス)ではちょっとした有名人だった。彼はそのblogのタイトルから、ハックルさんと呼ばれていた。よく炎上していた人だったと記憶している。というのも、ハックル氏のblogははてなから消えてしまっていて、過去の経緯をエビデンスをもって示すことが困難になってしまっているからである。その後、ニコニコ公式ブロマガに移って、その際に過去のたくさんの名文を削除してしまった。

 

 いやいや、ハックル氏にとってはエビデンスベースドでどうであったかなんてことを言おうなどというのは失礼か。そんなのはAIがすればよろしい。

 

 歴史書としては偽書の謗りも免れない話だが「ゲームの歴史」という本では、実在人物が言ってもないことを言ったことにされたりしていたようだ。これこそエビデンスベースドの話が面白いエンタメになるわけではないという放送作家の感性なのだろう。そう、岩崎夏海氏は放送作家らしいのである。2008年当時の僕はそのようには認識していなかったけれども。

 

 2008年当時、彼はミリオンセラー作家というわけでもなく、僕にしてみればよく炎上するブロガーという認識だった。炎上でもなんでも話題になれば露出が増えるもので、はてなダイアリーはてなブックマークをよく使っていた僕は度々彼を、彼の書いたblogを目にすることがあった。僕と彼はその程度の関係でしかなかった。

 

 15年前のその日、僕はblogを書いていた。

 

nagise.hatenablog.jp

 

 《「意見が違うということ」=「喧嘩」という捕らえ方をされた》という話から、議論のあり方とは……といった内容に切り込んでいく。そこで僕はなんのけなしに悪い例として彼のblogを引用したのだった

 

どちらが勝ったか負けたかということを意識しているのだとしたら、それは議論ではない。だが、世間的には「言い合い」はみんな議論だと思っているふしがある。最近見かけたblogから例を挙げよう。

例えば議論に勝つための初歩的なテクニックというのがある。それは相手のプライドを刺激することだ。人間誰しも矜持というものがある。例えばぼくなら「面白い」ということについては一家言ある。あるいは「言葉」についても並々ならぬこだわりがあったりする。そういうぼくに向かって、「おまえの言ってることは正しいかも知れないけど面白くないよね」とか、「言わんとしていることは分からなくもないけど言葉の使い方を間違ってるから分かりにくいんだ」とか言うともうとたんにカーッとくる。それでペースを乱されて以降の物言いがはちゃめちゃになって結局議論に負けるというのもある。

http://d.hatena.ne.jp/aureliano/20080919/1221753236

そんなテクニックはいかに相手のニホンザルを押さえ込んでマウンティングを成功させるかというテクニックでしかない。そんなことをやったところで疑問はなんら解決しないし、誤った意見をこうした手法で押し通しでもした日には、後で大きな惨劇が起こりかねない。勝った負けたなどと言っていても議論は進展しないのである。

 

 議論に勝つテクニックだって?そもそも議論を勝ち負けだと思ってるのかこの人は。そして挙げているテクニックがまた酷い。相手がカーッとなって物言いがはちゃめちゃになって自滅するだって?まさにダメな議論の好例みたいな文章だ!と僕は嬉々として引用した。はてなダイアリーというのはトラックバックという機能があって、平たく言えば引用をすると相手に通知が行く機能と思えば分かりやすいだろうか。

 

 僕のblogに引用されたことはトラックバックによって氏の知るところになったのだろう。氏の反応は素早かった。僕がblogを書いた9月20日その日のうちにアンサーエントリが書かれたのだった。(当時のはてなダイアリーが残っていないのでweb archiveを載せておく)

 

web.archive.org

 

 氏によれば、僕は、《噛ませ犬のように誰かを引き立たせるために、あるいは闘牛のように誰かに屠られるためだけに生まれてきた者》なのだそうだ。

 

自重した方が良い。本当に自重した方が。ここは誰が見ているかも分からないインターネットなのだ。id:Nagiseがこれまで浸かってきた生ぬるいサークル内での議論ごっこではないのである。

(中略)

ぼくには見える。id:Nagiseが会社の中で、あるいはそれ以外のコミュニティでも、良いようにこき使われているのを。そうして、もう使い物にならなくなった時には、ボロ雑巾のようにポイとお払い箱にされてしまうだろうことを。

しかしそれでも良いのかも知れない。身も蓋もないが、人間社会には、そうした生け贄が必要なのだ。

 

 このエントリは名文だと僕は思う。この文章はなかなかAIでは書けない、魂の叫びのような文章だ。

 

この人は議論というものを無闇に信用し過ぎている。疑うことを知らないのだ。

なぜ疑うことを知らないか?

それは、自分で考えることを放棄しているからだ。楽をしようとしているのである。「議論」というものの存在価値を無闇に信奉し、そこに寄っかかることで楽をしようとしているのだ。「自分で考える」「責任を持つ」ということから逃げているのである。

 

 議論を信用するからには一般論として当然自ら議論をすることを前提としていることだろう。自ら議論に身を投じることを《疑うことを知らない》《自分で考えることを放棄》《「自分で考える」「責任を持つ」ということから逃げている》と断じるこの論理展開!凄い!

 

 何が彼にこのような支離滅裂な理屈を書かせるに至ったのだろう?当時の僕は気付かなかったけども、ハックル氏によって未来を予言するように書かれていた。

 

例えば議論に勝つための初歩的なテクニックというのがある。それは相手のプライドを刺激することだ

(中略)

もうとたんにカーッとくる。それでペースを乱されて以降の物言いがはちゃめちゃになって結局議論に負ける

 

なるほど、プライドが刺激されてカーッときてはちゃめちゃな物言いになったということか。ともあれ、氏のこのアンサーエントリでは結局そもそもの議題であるところの「議論の意義」はなんら進展しなかった。まさに僕が述べたように

 

そんなことをやったところで疑問はなんら解決しないし、誤った意見をこうした手法で押し通しでもした日には、後で大きな惨劇が起こりかねない。勝った負けたなどと言っていても議論は進展しないのである。

 

嘆かわしいばかりである。

 

 僕とハックル氏の邂逅は衝撃的なものだった。この邂逅の後、ハックル氏は2009年に「もしドラ」(もし高校野球の女子マネージャーがドラッカーの『マネジメント』を読んだら)をヒットさせ有名作家となる。一方の僕は、この邂逅が大ヒットネットスラングを産むことになるとは想像だにしていなかった。

 

 僕はハックル氏のテクニックとやらを

 

そんなテクニックはいかに相手のニホンザルを押さえ込んでマウンティングを成功させるかというテクニックでしかない。

 

と評した。改めて言うが2008年のことである。僕は「マウンティング」というネットスラングの提唱をしたと自負しているが、今の今までそのスラングの産まれた瞬間のことをすっかり忘れていた。

 僕が勝った負けたに終始して議論のできない人をニホンザルのマウンティングに例えて評したのは、その対象の第一号は、ハックル氏だったのか!ハックル氏こそ、日本で初めてその行動をマウンティングと評された人物だったのである!!

 

 翌9月21日、僕はblogを書いた。このハックル氏とのやり取りが僕にインスピレーションを与えてくれた。ホモサピエンスニホンザルのようにマウンティングをする本能を生来、持っているんじゃないだろうか?(これを厳密に科学の俎上で論じるのは難しい。与太話程度に思っていただければ)

 

nagise.hatenablog.jp

 

 議論をしようとしたときに勝ち負けにこだわってしまうこの行為に名前を与えた僕は、それ以来、「マウンティングしてはならない」を議論する際の戒めとした。議論は議題を進展させたいからするのであって、マウンティングのためにやるんじゃないんだよ、そういう思想に行き着いたのだった。

 

 このマウンティングというネットスラングはその後、2014年発行された瀧波ユカリ、犬山紙子著『女は笑顔で殴りあう:マウンティング女子の実態』

https://www.amazon.co.jp/dp/4480815198 によって広く周知された。今では辞書に載るほどである。

 

2023年3月18日追記

 「マウンティング」の初出という話が気になる方が多いようだ。どのような調査をして検証すれば良いのかを記事にしたので、気になる方は検証に参加してみてもらいたい。

nagise.hatenablog.jp

 

リファクタリングの価値の考察

リファクタリングには価値がある、とプログラマは確信していることだろう。しかし、その価値が何であるか?を上手く説明できるかというと難しいのではないだろうか。本稿ではリファクタリングの価値をテーマに筆者の説を提示していく。

 

 

品質特性の側面から

 

ソフトウェアの品質特性としてISO/IEC 9126が一般的に用いられている。大きく6つの特性と細分化された副特性からなり、ISO/IEC 9126 - Wikipedia から引用すると

 

  • 機能性(functionality) - 機能とその特性に影響する特性群
  • 信頼性(reliability) - ある状況がある時間続いたときにソフトウェアがどの程度機能するかに影響する特性群
  • 使用性(usability) - 利用するのにかかる手間、個人の努力などに影響する特性群
  • 効率性(efficiency) - ソフトウェアの性能やそれに要するリソース量に影響する特性群
  • 保守性(maintainability) - 何らかの変更を加えるのにかかる手間に影響する特性群
  • 移植性(portability) - 別の環境にソフトウェアを移行させる可能性に影響する特性群

となる。これらのうち、リファクタリングの影響を受けるのは主に保守性(maintainability)となるだろう。

 

ここで「リファクタリング」の定義について振り返っておきたい。リファクタリングのバイブルとされるマーチン・ファウラーの書籍「リファクタリング」からその定義を引用しよう。( ISBN4-89471-228-8 pp.53-54 )

リファクタリング(名詞):外部から見たときの振る舞いを保ちつつ、理解や修正が簡単になるように、ソフトウェアの内部構造を変更させること。

 

リファクタリング(動詞):一連のリファクタリングを行って、外部から見た振る舞いの変更なしに、ソフトウェアを再構築すること。

 

この定義からしても、品質特性の保守性をターゲットとしたものであることが分かるだろう。

保守性に含まれる副特性を以下に挙げておく。

 

  • 解析性(analyzability)
  • 変更性(changeability)
  • 安定性(stability)
  • 試験性(testability)
  • 標準適合性(compliance

 

引用元は旧版である。新装版が出ているので書籍の購入を検討している方は新装版を確認してみて欲しい。

 

www.amazon.co.jp

 

補足 品質特性の相互作用

 

過去の記事で取り上げているのだが、 ソフトウェア要求 | Karl.E.Wiegers, 渡部 洋子 |本 | 通販 | Amazon という2003年の書籍では「品質属性の相互作用」についての記述があった。品質属性(この書籍は ISO 9126 準拠で記載されていないので用語が異なっているし特性の分類も異なっている点があるので注意)のうち、一方の属性を上げると、他の属性に+ないし-の変化をもたらすことが記載されていた。

 

nagise.hatenablog.jp

 

この相互作用のISO 9126準拠版が欲しいのだが、ご存じの方がいれば教えて頂きたい。

この書籍の相互作用表では「保守性」と「試験性」が挙げられている。前述の ISO 9126 では「試験性」は「保守性」の副特性という形になっているので注意されたし。

 

「保守性」が向上した際の相互作用としては、「可用性」「柔軟性」「信頼性」「試験性」に+効果、「効率性」に-効果となっている。

 

「試験性」が向上した際の相互作用としては、「可用性」「柔軟性」「保守性」「信頼性」「使用性」に+効果、「効率性」に-効果となっている。

 

本稿では、リファクタリングは「保守性」(その副特性である「試験性」を含む)へと直接作用し、品質特性の相互作用によりその他の特性に間接的な影響を及ぼす、という立場をとる。

 

よって、間接的な影響を及ぼす「保守性」「試験性」以外の品質特性については本稿では扱わない。読者の方々から検討してくださる方が現れてくださるとうれしい。

 

リファクタリングの価値

リファクタリングの効果は品質特性でいうところの「保守性」であるということをまず述べた。これはつまり、作った後に「保守」が生じなければ価値がないということでもある。

 

これはきしださん @kis が

 

まず、リファクタリングはそれ自体では価値を示せません。人工衛星に搭載するプログラムで、動きだしたらメンテナンスできないようなコードを最後にリファクタリングしたとして、どのような価値を示せるかと考えると想像できるのではないかと思います。

きしだのHatena

 

と述べているが、こうした事情を鑑みたものだろう。

 

障害対応

 「保守性」の副特性のうち「解析性(analyzability)」「安定性(stability)」は障害対応などに影響してくる。

 

 ソフトウェアのビジネス的な価値というのは、そのビジネスがどれだけの金を産み出しているかに依存する。おなじ機能のソフトウェアだとしてもA社で使われるのとB社で使われるのでは価値が異なってくるということだ。

 

 A社でそのソフトウェアが機能不全を起こして1日止まった場合、しかしその被害は1万円程度だったとしよう。対してB社ではそのソフトウェアに大きく依存しており1億円の被害となった。同じソフトウェアであるが、その運用保守にかけられるコストはA社とB社で異なってくるだろう。

 

リファクタリングのコスト < 障害時のダメージ軽減効果

 

と考えられるなら、リファクタリングを行う価値が十分にある。

 

 障害というのはまず起こるかどうか?が未来の不確定要素であるわけだから、この確率をどうみるかが難しい。このあたりが判断を難しくする理由のひとつだろうか。

 

 また、「解析性」「安定性」を高めて備えておいたことが、備えてなかった場合と比べてどれほどの価値を産んだか?というのも計測が困難である。こうした部分をどう価値判断するか、その価値判断をビジネスサイドとすり合わせることができるかが課題であろう。

 

機能追加

 

 「保守性」の副特性のうち「変更性」はまさに機能追加といった際のコストとなって現れる。逆説的には機能追加などせず外的要因で動かなくなったならば打ち捨てるという確たる信念で運用しているのであれば、「変更性」などどうでもよい。

 

 筆者はしばしば「技術的負債の踏み倒し」という表現を用いるが、うまく打ち捨てて作り直しをするという戦略がちゃんと回るなら、それはそれで立派な戦略だと考えている。

 

 打ち捨てて作り直しするつもりが、いざ作り直しが必要になったときに金銭的コストにびびって「既存のものの改造で済ませられないか?」と打診するようなのが一番ダサい。そうなった際のコストを度外視することでこれまでコストを削ってきたものを全て台無しにする戦略の一貫性のなさがデスマーチを産み出すのだ。言わんこっちゃない。

 

 機能追加なり改修なりというのは、事前に予見できない性質のものである。あるいはほんのりと「こういうことがしたいなあ」という構想があって備えておくようなケースはあるが、詳細を詰めると事前の準備では不十分というのが通例である。また、構想が日の目を見ず、備えてあった拡張性が役立つことなく製品寿命を終えることも少なくはない。

 

 ここでも確率論がでてくる。コスト算定がしにくい理由のひとつだ。ごく簡単には

 

リファクタリングのコスト < 機能追加のコスト軽減効果

 

ということになろうが、この「機能追加のコスト軽減効果」が容易に算出できない。

 

 また、需要と供給の話で良く出てくる需要曲線・供給曲線とその交点の話があるが、システムの機能追加の話でも似たようなものがあり、品質特性「変更性」が高いとなると機能追加しようとしたときのコストが下がる。供給曲線そのものが全体に下にさがるわけで、ならば買おう、という判断になったりするわけである。

 

(この例えが微妙なところは横軸が需要曲線・供給曲線では数量であるところが、システムの話にしようとしたときに横軸はなんだっけ?となる点である。より工夫が求められる。何かアイデアがあればご提示いただきたい)

需要と供給

 つまり、単に機能のビジネス的価値と、製造原価が折り合うか?という話から、そもそも製造原価そのものが下がっていたら?という話が混ざりこんでくるので複雑になる。

 

 この製造原価を下げる効果、いろんな機能追加がビジネス的に採算に乗りやすくなってくるわけだから、ユーザー要望に対する即時性を備えたいならば必須となろう。逆に、10年以上の安定稼働を前提とした生活インフラ系の保守管理用のシステムのような機能追加・改修みたいなものをあまり求められないシステムのような例だと、こうした部分に言及してアピールしても顧客にはその価値が響かない。

 

 これがB2Cシステム(Business to Customerの略で企業と一般消費者の取引のこと)だと、ユーザーの反応を見て素早い対応をすることが強く求められるので、最初からある程度の「変更性」を備えたプロジェクト運用をしていないとユーザー満足度を高められない。日頃からの不断のリファクタリングによって「変更性」をキープし続ける必要がある。

 

 それでも劣化して「変更性」が失われてくると、ユーザー要望への追従が出来なくなり、そうしたサービス品質の低下がユーザー離れを加速し……といった負のスパイラルに入ることがある。資本力があれば、そうしたタイミングで抜本的な対策として大規模な作り直しが行われることがある。こうした「システムの製品寿命」がどれぐらいか?というところに「変更性」が関わってくる。

 

システムの製品寿命

 システムというのは、初期に大きく資本を投じてわーっと作り、その後は細々と保守運用フェーズになるというライフサイクルが多い。

 

 単純な例となるが、10億投じてシステムを作り、5年運用したところで「変更性」が失われビジネス要件の追従が限界であるとして新システムを作るという話になるのと、これが10年メンテしながら運用できるのでは、10年もった方がお得である。

 イニシャルコスト(初期コスト)を運用年で割って、単年度あたりに慣らすと、5年運用なら年度あたり2億円だし、10年運用なら1億円だ。

 

 このようにシステムの寿命を延ばすという点で「変更性」や「試験性」が効いてくるわけである。これらの価値がいかほどか?ということになると、結局のところそのシステムを使った場合のビジネスがどれほど金を産むかに依存する。

 

 大金を産み出すシステムであれば、できるだけ長く運用し続けたい。しかし、システムと言うのは外的要因で使えなくなったりすることもある。例えば税制が変わったりとか、セキュリティ上の理由で採用していたプロトコルが使えなくなって新プロトコルに切り替えなくてはならないとか。PCが廃れてスマホに対応しないといけなくなった、なんてのは2010年代にあったムーブメントである。こうした世間の動向もシステムの寿命を縮める外的要因である。

 

 しかし、十分に「変更性」が高ければこうした変更についていける。こうした事態のたびにシステムをいちから作り直すのに比べればコストは安く済むはずであるし、対応までのリードタイムも短くて済むことだろう。そうした「価値」に「保守性」はつながっているし、その「保守性」に「リファクタリング」は繋がっている。

 

まとめ

  • リファクタリングは品質特性の「保守性(maintainability)」に作用する
  • 保守性の価値は、システムのビジネス上の価値と関係している
  • ビジネス上の価値や未来の可能性みたいなものが関連してくるので価値の算出は容易ではない
  • 筆者の説は叩き台のようなものであるから、不備の指摘や異論を提示してもらえると、このテーマについてみんなの理解が深まるのではないか

 

 

 

 

 

なぜ自動テストの導入は失敗するのか?

 開発室の雑談。営業側のマネージャが言うには
「今のプロジェクトで自動テストの導入を試みている話をしたら、XXXさんのところでも過去にいくつか導入を試みたけどもみんな上手くいかなかったって話になって」

 なるほど?

 まあ確かに自動テストはシステム開発にとって魅惑の技法ではあるものの、では導入がうまくいっているか? というと普及率は低いと言わざるを得ない。私がお手伝いしたプロジェクトでは、元請け側から自動テストをやるお達しが来たわけだが、紆余曲折あって掛け声倒れのような状態になってしまった。

 ビジネス書の煽りタイトルのような本件だが、古式ゆかしき受注生産の業務システム開発プロジェクトに自動テストを導入しようとして失敗する事例を聞いたので、僕なりに分析して見出した要素を挙げておこうと思う。

V字モデル

 ソフトウェア開発の手法としてV字モデルというものがある。

 オーダーメイドでシステムを作るにあたって、どのような要求があるか、どう設計すればよいか、それを段階を踏んで細分化・詳細化していき、プログラムのコーディングに至り、そして単体テスト結合テスト、とパーツ単位の検品からその組み合わせとしての試験、といったように進めて成果を上げていくわけである。

f:id:Nagise:20210429133857p:plain
V字モデル概念図

CC 表示-継承 3.0, https://ja.wikipedia.org/w/index.php?curid=894431


 このV字モデルと、いわゆるウォーターフォール開発(定義や本来の意味は?といったことに踏み込むと難しいのでここでは触れない)において、自動テストの導入のネックとなるのはなんであろうか?


自動テストとは?

 自動テストとはこの文脈ではコンピュータ・プログラムが想定通りに動くかテストする工程を自動化するものだが、自動化といってもピンとこないかもしれないので簡単に触れておこう。全自動のコンピュータが何とかしてくれるという話ではない

 例えば、ふたつの数字を渡すとその和を返す機能を考えてみよう。

public int add(int x, int y) { … }

 これを試験する場合、ふたつの数字x, y にさまざまな値を渡して、得られる答えが期待通りかを確認することになるだろう。

  • 1, 2 を与えれば 3
  • -1, 1 なら 0
  • -2, -3 なら -5

 といった具合に。とはいえ、ひたすら並べていってもバグ検出の効果が薄いので、特徴のあるテストケースを用意するなどの工夫は必要だ。まあ、その辺の話も割愛。

 ともかく、こうした入力と出力があって、それが予見可能であれば、プログラムを呼び出してそういう値になるよな? ということを確認するプログラムが書ける。

assertEquals(3, add(1,2));
assertEquals(0, add(-1,1));
assertEquals(-5, add(-2,-3));

 こうした検証のためのプログラムが2021年時点のIT界隈で「自動テスト」と呼ばれるものの本体であって、「自動テストの導入」というのはこうした検証用のプログラムを書くことに他ならない。

 つまり、本来のプログラムのほかに、その検証用のプログラムを別途用意するというわけである。

 この検証用プログラムがうまく作れれば

  • 以後のテストは検証用プログラムを実行するだけで済む
  • 人力で膨大なテストを行うのに比べればコストダウンできるだろう
  • テストフェーズのリードタイムが短くなるだろう
  • 人力に比べヒューマンエラーが抑えれるだろう
  • 上記の総合的な作用により品質が向上するだろう

ということを夢見ていくつものプロジェクトが玉砕してきたというわけだ。


テスタビリティ

 先の自動テストのための検証用プログラムは非常に簡単な例だった。

 しかし、世の中にはテストしにくいプログラムというものがあって、検証用プログラムを書くことが非常に難儀することがある。ここでテストしやすさ、テスタビリティ(testability)という概念が出てくる。


 テストしにくいとはどういうことか? いろんなケースがあるが、テストしにくいモノのひとつには「状態を持つ」プログラムが挙げられる

 工学系の学部などで科学の学生実験とかやらされた人は身に染みていると思うが、「同じようにやって同じようになる」ためには、前提が揃っていることが大事である。

 状態を持たないプログラムを対象にして自動テストのための検証用プログラムを書くことは簡単である。同じ値をつっこめば、いつも同じ値を出力する。 1 + 2 = 3 であり、冪等(べきとう、何度繰り返しても同じ性質)である。

 しかし、内部で状態を持つプログラムは同じように操作したつもりでも突然違う挙動を示す。電卓でボタンを順に 1, +, 2, = と押した場合、3と表示されるだろうか? そのテストを始める前に誰かが 5, + と入力した状態から始めたらどうなるだろう? 期待される答えである 3 ではなく、8 が表示されてしまう。

 状態をもつプログラムのテストしにくさはこういうところで出てくる。まあ電卓の場合はCボタンを押してクリアしてからスタートすればいいわけだけども、じゃぁデータベースはどうしたら良い? データベースにリセットボタンが必要になってくる。データベースにテスト用のリセットボタン、用意してありますか?



 これは一例でしかないが、テスタビリティというのはなんとなくで上がる話ではなくて、テスタビリティを上げるための技法を駆使しなくては上がらないということの一端が分かっていただけただろうか。V字モデルでいえば基本設計、機能設計、詳細設計といった設計の工程で、あらかじめテスタビリティを上げるための配慮した設計をしておかねばならない。


自動テストはいつ作られるのか?

 冒頭に挙げたV字モデルの概念図では、要求分析に始まり、基本設計、機能設計、詳細設計と細分化してからコーディングを行い、単体テスト結合テストシステムテスト、受け入れテストと進んでいくように描かれている。

 オーダーメイドでシステムを作ろうとした際、こうした工程を経てシステムを作りましょうという提案がされることが多いことだろう。

 では、「自動テスト」を導入するとした場合、自動テストはこのV字のどこで作られるのだろう?



 単純に手動での単体テストを置き換えるものと位置付けるのであれば、V字モデルの「単体テスト」のフェーズで自動テストを作成するということだろうか? プログラムを一通り作り終えて、単体テストフェーズに移りましょう!というタイミング?

 😩😩😩

 この案、聞いただけでうんざりした顔をした人も多いのではないだろうか。



「導入を試みたけどもみんな上手くいかなかったって」

 そりゃそうだろう。うまく行くわけがない。



 いわゆるウォーターフォール開発の手法によって、書類で工程を分離して記録を残すやり方だと、設計フェーズと、コーディングと、テストフェーズは明確に分かれている。「分離することで上手くやってきた」と語る人もいることだろう。

 そうか、これが大きな阻害要因だったか。


自動テストが破壊するもの


 自動テストにはプログラムを「部分的に実行する」という意味合いもある。プログラムを書いて、動かしながら、その動きが狙い通りか確認しながら仕上げていく。この「動かしながら」のためには巨大システムの一部のパーツを、その一部分だけで動かす技法が必要で、自動テストのためのテスティングフレームワークがその答えの一つだ。

 プログラムを書きながら、自動テストのための検証用プログラムもまた並行して書いて、自動テストを用いることでプログラムを実行しながら進めていくというスタイル。その究極はTDD(テスト駆動開発)だけども、そうでなくともコーディング中から自動テストを書くのが良いやり方だ。

 早めに動かして、早めにバグを検出できるならそれに越したことはない。

 しかし、これはV字モデルにおけるコーディングフェーズと、単体テストフェーズを曖昧にする。従来のV字モデルのやり方で、明確に分離された単体テストフェーズに自動テスト作成を試みるようでは、自動テストの効能が十全には発揮されない。自動車を買って馬につないで牽かせるような話だ。



 また自動テストは、いかようなプログラムにも後付けで用意できるわけではない。これは先にテスタビリティの部分で解説した。自動テストをやるには自動テストしやすい設計である必要がある。極力ステートレスにするとか、モックに差し替えが可能なようにDIコンテナを駆使するとか。そこにはいろんな技法があって、そうした技法を凝らすことでシステムを自動テスト可能となるよう、先人たちが工夫を重ねてきた。

 それでも、より具体的なプログラミングを行っていると、後になってから「これはあっちに持って行ったほうがいいな」ということは多発するし、自動テストのために設計変更したくなることも生じてくる。これはV字モデル的にはコーディングフェーズから詳細設計フェーズへの手戻りだ

 また、自動テストの効能のひとつに「リファクタリングを可能にする」という大きなポイントがある。詳細設計フェーズとコーディングフェーズの分離はこの開発時のリファクタリングを大きく阻害する


 自動テストを活かすには、詳細設計フェーズとコーディングフェーズが分離されていてはいけない。コーディングフェーズと単体テストフェーズが分離されていてもいけない。



自動テストの導入のためには


 本稿の主張は、V字モデルこそが自動テストの阻害要因であるというものである。であるから、V字モデルに拘泥する限り、自動テストの導入は成功率が低いし、よしんば導入できたとしても効果が低く成果が上がらないものとなるだろう。


 おそらく、V字モデルでいうところの詳細設計~コーディング~単体テストのフェーズを再考する必要がある。この部分を大きく改革しないと自動テストの恩恵を得ることは難しいだろう。


 ある程度のスキルレベルにあるメンバーで行われるプロジェクトであれば、この詳細設計~コーディング~単体テストの一連の工程を、プロジェクトメンバーがうまいことやってくれていた。しかしこれは、そういう練度のプログラマで構成されたプロジェクトであればこそだろう。


 となれば。より低スキルの寄せ集めメンバーでベルトコンベアの流れ作業のようにシステムを作ろう! という思想でやるのであれば。少なくとも旧来のV字モデルの詳細設計~コーディング~単体テストに変わる新しい分業モデルを検討しなくてはならないはずだ。

修正履歴

  • 2021/04/29 自動テストのコードの値の誤りを修正

Javaのリテラル

Q. リテラル(literal)とは何か?
A. 言語による

なんでこんな記事を書いているかというと、リテラル禁止FizzBuzz大会がいまいち盛り上がらなかったので、ルール解説をして参加者を増やそうという目論見である。

Java言語におけるリテラル

プログラミング言語一般で「リテラル」というと

コンピュータプログラミング言語においてリテラルは、ソースコード内に値を直接表記したものをいう。言語によってリテラルとして表記できる型の種類や表記方法は異なる。

リテラル - Wikipedia

という感じで、 42 とか "hoge" とかそういう値を直書きしたものを言う。このあたりは雰囲気で把握している人も多いだろう。ではその明確な範囲としてどこまでがリテラルか?となると、言語ごとのルールブック、つまるところ言語仕様に当たらなければならない。

Java言語仕様は怖くない。インターネットでオープンにされており、非常にアクセスしやすい。 Java SE Specifications のページに各バージョンの言語仕様へのリンクがまとめられている。

2021年9月には次期LTS(長期サポート)版のJava17がリリースされるが、本稿執筆時点でのLTSはJava11なのでJava11の言語仕様を元に調べてみよう。
物事を調べるには原典にあたることが大事である。原典をみて誰かが本を書いたりblogを書いたりする。それを見て書かれたblogは原典を見たものより信頼度が落ちる。孫引きして書かれた引用元も示されてないような記事を信頼してはしてはいけない。

"The Java Language Specification, Java SE 11 Edition" の "HTML"のリンクを辿ると The Java® Language Specification Java SE 11 Edition の目次に辿り着ける。

リテラルについて書かれているのは 3.10. Literals の部分だ。Java言語仕様は英語で書かれているが、現代は機械翻訳が優秀なので、機械翻訳でもある程度概要をつかむことができるのではないだろうか。また過去には公式に日本語訳がされたものが出版されたこともあるが、Java5の内容の
Java言語仕様-第3版 (2006年)が出たのが最後となっている。

Java言語におけるリテラル

Literal:
 IntegerLiteral
 FloatingPointLiteral
 BooleanLiteral
 CharacterLiteral
 StringLiteral
 NullLiteral

と列挙されていて、各項目の説明が以下に続く。

リテラルの詳細な定義まではここでは立ち入らないが、ざっくりと表にすると

種類 概要
IntegerLiteral 整数の数値 42 0xCAFEBABE 0b0010_1111
FloatingPointLiteral 浮動小数の数値 1.234
BooleanLiteral boolean型の値 true false
CharacterLiteral charの値 'A'
StringLiteral 文字列 "hoge" ""
NullLiteral null null

といった感じ。

また、 3.10. Literals に記載されていないが 15.8.2. Class Literals という項目があって、classリテラルについて記載がある。これも Java言語における「リテラル」に含めそうだ。

これは Hoge.class などといったように、クラス名に .class とつけることで java.lang.Class オブジェクトをリテラルとして表す記法。

リテラルを使わないでFizzBuzzをしてみよう!

さて、以上でJavaにおける「リテラルの禁止」の指す範囲が明確になったと思う。

プログラミングパズルが好きな人は是非、リテラルを用いないFizzBuzzに挑戦してみて欲しい。たぶん、セミコロンを使わないFizzBuzzよりは簡単じゃないかな。(参考: セミコロンレスJava はチューリング完全か? - プログラマーの脳みそ

セミコロンレスJavaもそうだが、この手のプログラミングパズルは標準APIの範囲で行うことが暗黙の了解となっている。

僕も書いてみたけども芸術点がイマイチなのでまだ満足できていない。

空気を読んだ話

一般に「リテラルを使うな」というのはプログラムコード中にマジックナンバーなどを直接記載しないということを意図したものである。なんらかの意味のあるフラグの値などは定数定義(Javaの場合はstatic finalフィールドにするかenumにすることが多いかな)して間接的に用いることを指す。

言語仕様上のリテラルを一切用いないというのは揚げ足取り的な話で、しかしここではネタとしてその制限でプログラミングを書けるか?という設問がおもしろいので取り上げている。

訂正

2021.04.19 BuzzをBullと誤っていた箇所があったので修正

IT勉強会界隈の冬の風物詩といえば、飯テロ勉強会の異名を持つブリ会議 ―― burikaigi ―― だろう。
toyama-eng.connpass.com

そもそも富山で旬の寒ブリを食べようというIT業界人の同好の士が、ブリを食べるために勉強会を催したというのが始まりである。飯テロ勉強会なのは仕方ない。
しかし、勘違いしないで頂きたいのだが、あくまでもIT勉強会なので趣旨を誤解なきよう。講師陣は今回も豪華です。セッションの内容も充実。
例年、北陸にあって先端情報に触れる貴重な機会でもあります。地方勉強会のひとつの形ですね。


プログラマーの修学旅行とも評されるburikaigiなのだが、今年ばかりは新型コロナウイルス感染症 COVID-19 の情勢を見るに、大勢で集まって宴会というわけにはいかない。
しかし、松本魚問屋様の協力によってリモート・ブリしゃぶの目途が立ち、burikaigi 2021 オンライン開催とあいなりました。

matsumoto-uodonya.co.jp

なんと、参加者限定 burikaigi スペシャル商品を用意していただきましたよ。
懇親会参加登録者には特設サイトのURLをお伝えいたします。

もちろん、自前でブリを用意してもらっても大丈夫です。
全国からリモート懇親会でブリを楽しめるイベントとなっています。



さて、ここからはリモート・ブリの紹介です。(まるで通販番組みたいだな🤔)

ブリしゃぶは水揚げ当日に血抜き処理をし、丁寧に仕上げたものを瞬間凍結!
生のブリはどうしても獲れるかどうか不確かで、かつ、保存可能な期間も限られるためブリ会議当日にちょうどおいしく配送というのは非現実的なわけです。
冷凍配送ゆえの安定供給。最近の冷凍技術は凄いですね。冷凍品とあなどるなかれ。試食してみたけども、とても美味しかったですよ!
ただ、あくまでブリしゃぶ用とのことでご承知おきください。刺身では力を十全に出し切れない……。

今回はなんと、ゆずぽん酢、タイの昆布締、ぶりジャーキー、ほたるいか塩麴漬けをセットにした飲兵衛仕様でご提供!

とはいえ、懇親会だけ参加とかはダメだよ。ちゃんと勉強しような!

f:id:Nagise:20201217201311j:plain
burikaigi用の特別セット
f:id:Nagise:20210105204911j:plain
冷蔵庫で解凍
f:id:Nagise:20210105212648j:plain
しゃぶしゃぶ

西暦1年は閏年か?

閏年(うるうどし)の話題。

 Twitterで見かけた話題で「西暦1年は閏年かどうかぱっとわからん人おる?」という些か煽り気味のツイートを見かけたのだけども、反射的に「閏年じゃないに決まってるじゃん」とぱっと答えてしまわないだろうか。本当にそうだろうか? そう単純な話なのだろうか?

 プログラミングを学んでカレンダーを扱うことを学ぶ際に置閏法についても簡単に触れられることがある。置閏法というのは閏年や閏月(太陰暦では1年が13ヵ月になるケースがあり追加の月を閏月と呼ぶ)をどのようなルールで挿入するかという話で、まさにアルゴリズムであるからプログラミングの話題と相性がいい。

置閏法

 現代の西暦の置閏法(ちじゅんほう)は

  1. 西暦を 400 で割り切れる年は閏年
  2. 上記以外で西暦を 100 で割り切れる年は平年
  3. 上記以外で西暦を 4 で割り切れる年は閏年
  4. 上記以外は平年

といった手続きで閏年(つまり2月29日がある)か平年かを判定することができる。

 2000年問題といえば西暦を2桁で扱っていたシステムの桁溢れというのが表の問題だったが、裏の問題として閏年というのもあった。2000年は400で割り切れるから閏年なわけだが、どういうわけか100で割り切れるので平年だと判定してしまうバグが見られた。単に4で割るルールだけにしておけば結果的に2000年には問題が起きなかったのに、中途半端に100年ルールだけ追加しちゃったもんだから2000年2月29日にトラブルを出すことになったシステムがいくらかあったようだ。

 やるなら半端は良くない。

その暦はいつからのものか?

 そう、半端は良くない。

 先に述べた置閏法は現代の西暦の置閏法であるが、この暦をグレゴリオ暦という。2014年にJava8が出るまでの古いカレンダークラスの場合(Java8以降のDate Time API の話は後述)、抽象クラスである java.util.Calendar に対して具象クラス java.util.GregorianCalendar が定義されていた。グレゴリアンの名前の通り、グレゴリオ暦をモデル化したものである。さあこれで、ここまで漠然と「西暦」と呼んでいたものがグレゴリオ暦という名前をもって具体化してきた。このグレゴリオ暦ローマ教皇グレゴリウス13世の名前からきている。グレゴリウス13世によってそれ以前の暦であるユリウス暦の改良が命じられ、1582年10月15日からグレゴリオ暦が行用されるようになった。

 旧暦であるユリウス暦ガイウス・ユリウス・カエサルにより紀元前45年1月1日から実施されたものである。西暦1年を考える場合、当時の暦はユリウス暦であることに注意せねばならない。

 西暦1年当時は閏年だったかどうかぱっとわからん人おる? 僕はぱっとわからなかった。

ユリウス暦の置閏法

 ユリウス暦の置閏法は

  1. 西暦を 4 で割り切れる年は閏年
  2. 上記以外は平年

とシンプルである。なんだ、ユリウス暦だとしても100の倍数の年以外は一緒じゃないか、と安心した人も多いだろう。
ただし、上記は紀元8年以降の話である。

紀元前45年にカエサルがこの暦法を導入した際に閏年は4年に1回と決められたが、直後の紀元前44年にカエサルが暗殺された後、誤って3年に1回ずつ閏日が挿入された。この誤りを修正するため、ローマ皇帝アウグストゥスは、紀元前6年から紀元後7年までの13年間にわたって、3回分(紀元前5年、紀元前1年、紀元4年)の閏年を停止した

ユリウス暦 - Wikipedia

あぶない! 西暦1年というのはユリウス暦の導入直後の混乱期で閏年が正しく運用されていなかったようだ

 なお紀元前45年から紀元8年までの間に、どの年に閏年が置かれていたのかについては諸説ある。1999年にローマ暦とエジプト暦の両方の日付が記載された紀元前24年当時の暦が発見され研究に進展があったとのこと。日本語版Wikipediaには該当論文が示されていないが、英語版Wikipediaの記述からすると ALEXANDER JONES 氏の1999年の論文 CALENDRICA II: DATE EQUATIONS FROM THE REIGN OF AUGUSTUS (PDF)が該当のようである。このカレンダーに基づくC. J. Bennett氏の2003年の研究によれば紀元前44, 41, 38, 35, 32, 29, 26, 23, 20, 17, 14, 11, 8年が3年おきの閏年でAD 4から4年おきの置閏法へと戻ったとのことである。

暦法紀年法

 西暦1年あたりの閏年の混乱を見てきたが、そもそもカエサルの時代に「西暦を4で割る」なんて考え方はされていなかったはずである。何しろ紀元前なので。

 ここで暦法紀年法について確認しておきたい。おおざっぱに言えば紀年法は年を数える方法論で、1年をどのように捉えるかの暦と分離可能なのである。例えば日本では和暦が用いられるが、これは紀年法が和暦で、暦法としてはグレゴリオ暦を用いている。なお、日本が現代の暦になったのは明治5年(西暦1872年)11月の改暦以降のことなので、これより前の時代を扱う場合は暦が連続しないので注意が必要である。このあたりの変遷は国立国会図書館江戸から明治の改暦が読みやすいだろう。


 そもそも西暦自体が525年にローマの神学者ディオニュシウス・エクシグウスによって算出されたものである。

525年、ディオニュシウスはローマ教皇ヨハネス1世の委託を受けてキリスト教の移動祝日である復活祭の暦表(復活祭暦表)を改訂する際に、当時ローマで用いられていたディオクレティアヌス紀元(ローマ皇帝ディオクレティアヌスの即位を紀元とする)に替えて、イエス・キリスト受肉(生誕年)の翌年を元年とする新たな紀元を提案した。これはディオクレティアヌスキリスト教の迫害者であり、その迫害者の名を残す事が疎まれたからである[3]。

西暦 - Wikipedia

 つまり、西暦525年から遡って元年を決めたわけである。なお、ディオニュシウスの推定したキリストの誕生年と、ナザレのイエスの実際の誕生年にはズレがあるとされており、紀元前4年頃に生まれたと考えられている。これはヘロデ大王の治世(紀元前37年 - 紀元前4年)の末期に生まれたという記述による。

 では、西暦525年よりも前の時代の紀年法ディオクレティアヌス紀元で遡ればいいかというと、ディオクレティアヌス紀元の元年も西暦284年までしか遡れない。西暦1年は遠いのである。ディオクレティアヌス紀元以前はローマ建国紀元(Ab urbe condita, AVC/AUC)が用いられていたようである。ローマ建国紀元の元年は、紀元前1世紀のローマ人ウァッロによって推定された、都市国家ローマの建国年(紀元前753年)ということである。これもまた、推定で過去に遡って元年が定められたパターンである。さらに前は執政官ふたりの名前を挙げて表したようだ。(紀年法暦法についてはここで取り上げたもの以外もたくさんあるということは付記しておく)

 さて、ここで何が言いたいかというと「西暦を4で割りきれるなら閏年」というのはたまたまであるということ。神学者ディオニュシウスの推定で定められた西暦の紀元からの数字だとたまたま4で割りきれる年が閏年の年となった。後付けである。その西暦をもとに1582年に定められたグレゴリオ暦が、閏年の調整のためにきりがよい100で割りきれる年や、400で割り切れる年を用いた、という後付け設定によるものだ、という点である。

 グレゴリオ暦の前、ユリウス暦は「西暦を4で割りきれる年を閏年をする」と定められたわけではなかった。ユリウス暦が定めらたのは紀元前のことで、初期には閏年が誤って3年おきに入れられたりその調整で閏年がない期間があったりした。それから500年余りたった頃に後付けで西暦が定められた。そうすると、たまたまユリウス暦閏年が西暦を4で割り切れる年だった。しかし単純に4年1度の閏年では春分の日がだんだんずれてきて西暦1582年にグレゴリオ暦に改められ、閏年の100年ルールと400年ルールが生じた。西暦を100で割る、400で割る、というのは後付けの西暦の切りのいい数字を用いたに過ぎない


 なお、1582年から施行されたグレゴリオ暦暦法を、1582年以前にも適用したものは proleptic Gregorian calendar と呼ばれるようだが、日本語では定訳がなく、先発グレゴリオ暦、遡及グレゴリオ暦、予測的グレゴリオ暦、予期的グレゴリオ暦などと訳されるようだ。

曜日

 400年間のうち閏年は97日あるため、日数は 365 × 400 + 97 = 146,097 日 となる。これは7で割ることができ400年で20,871週間あることになる。グレゴリオ暦は曜日も含めて400年周期の暦と言える。

 曜日の算出にはツェラーの公式が用いられることがあるが、このツェラーの公式を用いた曜日計算も1582年10月15日のグレゴリオ暦への切り替え以前に適用できないことは注意が必要である。計算することはできても、それは実際にその時代に用いられた暦ではないナニカ(先発グレゴリオ暦)である点は理解しておきたい。

 ユリウス暦グレゴリオ暦との間には約10日のズレが生じていた。切り替えに際してこの10日のズレを調整したわけだが、曜日については連続した形で適用された。つまり、ユリウス暦での 1582年10月4日(木曜日)の翌日がグレゴリオ暦 1582年10月15日(金曜日)とされた。

 また、切替えはヨーロッパ各国で一斉に行えたわけではなく、イタリア、スペイン、ポルトガルなどごく少数の国であったという。ローマ教皇による発令だったが、ローマ教皇というのはカトリックのトップであって、プロテスタントやその他のキリスト教派閥にまでその威光が通じたわけではなかったのだろう。その後、徐々に広まっていったようである。

Javaの実装

 1995年の初期のJavaから存在するjava.util.Dateクラスは、当初は日付を表す文字列をパースしたりする機能も有していたのだが、1997年のJava1.1にはこれらの機能は早々に非推奨(Deprecated)になってしまっている。そうした機能はjava.util.Calendarに分離された。java.util.Calendarはカレンダーの抽象クラスで、グレゴリオ暦に相当するのはjava.util.GregorianCalendarである。

 Java8 (2014年)が出た際にはDate and Time APIというものが追加された。(JSR 310: Date and Time API
Java8以降でプログラミングするのであれば概ね新しいDate and Time APIを使いたいところだ。

 さて java.util.GregorianCalendar だが、

歴史的に、グレゴリオ暦を最初に採用した国々では、1582年10月4日(ユリウス歴)のあとに1582年10月15日(グレゴリオ歴)が続きました。 このカレンダはこれを正確にモデル化しています。 グレゴリオ暦への切換え日の前は、GregorianCalendarではユリウス暦を実装しています。 グレゴリオ暦ユリウス暦の唯一の違いはうるう年のルールです。 ユリウス暦は4年ごとにうるう年を指定しますが、グレゴリオ暦では、400で割り切れない世紀の初年をうるう年にしません。

GregorianCalendarは、先発グレゴリオ暦およびユリウス暦を実装します。 すなわち、日付の計算では、現在のルールを無限の過去あるいは未来に向けて適用します。 このため、GregorianCalendarはすべての年について一貫した結果を生成するために使用できます。 ただし、GregorianCalendarを使用して得られた日付は、歴史的に、現代と同様のユリウス暦が採用されたAD 4年3月1日以降の日付だけが正確です。 この日付より前には、うるう年のルールは不規則に適用されており、BC 45年以前にはユリウス暦は存在さえしていませんでした。

GregorianCalendar (Java SE 11 & JDK 11 )

マジか!

Calendar c = new GregorianCalendar(1582, Calendar.OCTOBER, 4);
System.out.print(c.getTime());
c.add(Calendar.DAY_OF_MONTH, 1);
System.out.print(c.getTime());

Thu Oct 04 00:00:00 JST 1582
Fri Oct 15 00:00:00 JST 1582

 1582年10月4日(木)の翌日が1582年10月15日(金)になっている……。
 100年ルールも確認してみよう。1600年は400年ルールが適用なので、1500年と1700年で比較してみよう。

Calendar c = new GregorianCalendar(1500, Calendar.MARCH, 1);
c.add(Calendar.DAY_OF_MONTH, -1);
System.out.println(c.getTime());

c = new GregorianCalendar(1700, Calendar.MARCH, 1);
c.add(Calendar.DAY_OF_MONTH, -1);
System.out.println(c.getTime());

Sat Feb 29 00:00:00 JST 1500
Sun Feb 28 00:00:00 JST 1700

 ユリウス暦である1500年3月1日の前日は2月29日となっている。一方、グレゴリオ暦の1700年は100年ルールが適用されて3月1日の前日は2月28日だ。
 先発グレゴリオ暦のつもりでjava.util.GregorianCalendarを使うと、予期しない動きをするかもしれない。

 なお、純粋に先発グレゴリオ暦として用いたい場合は setGregorianChange(java.util.Date) メソッドでグレゴリオ暦への切り替え日をより過去にすることで対処することができる。

ISO 8601

 ISO 8601 で日付と時刻の表記に関する国際規格が定められている。

 端的に言えばこのISO 8601は先発グレゴリオ暦で、1582年10月15日以前にも適用される。ただし、0000年から1582年の範囲は、事前に通信の送信側と受信側との間での合意がある場合にのみ使うことができるとされている。

 このISO 8601に相当するのが IsoChronology である。Java8 以降の Date and Time API での標準はこのIsoChronologyとなっている。

 java.time.chronoパッケージの解説によればIsoChronologyの他に

が標準で実装が提供されている。これらの暦にまで踏み込むと話が長くなりすぎるので打切り。太陽太陰暦での閏月などについては興味のある人は調べてみると面白いだろう。

結論

 結果的に言えば西暦1年は閏年ではなく平年である。

 しかし、その導出過程は「西暦を4で割り切れないから」ではなく、「ユリウス暦は初期には閏年が誤って3年おきに入れられ、その調整で閏年がない期間があり、西暦1年はその期間に該当するから」というのがより正確な回答であろう。

 なんらかのアルゴリズムを学んだ時に、なぜそのアルゴリズムなのか、その適用範囲はどこまでなのか、現実に人がそのように使っているのか? といった部分にも興味をもって目を向けてみると少し世界がひろがって少し面白い世界が知れるかもしれない。