2014-01-08

bzrは死につつある。Emacsは移行しなければならない

bzr is dying; Emacs needs to move

Emacsのソースコードは、Bazaarでバージョン管理されてきた。しかし、Bazaarは分散バージョン管理システムとしては、Gitに敗北したし、もはや死につつある。Eric S. Raymondは、Emacsは他のバージョン管理システムに移行しなければならないと書いている。

私がこの投稿をしている理由は、バージョン管理システムとその周辺ツールのエキスパートとしての責務であって、この議論に参加したいがためではない。

bzrバージョン管理システムは死につつある。ほとんどの点で、もはや死んでいる。dev listは死んでいるし、Canonicalのほとんどの内部プロジェクトはbzrを捨ててgitを使っているし、古参開発者の一人が、なぜbzrが失敗したかについて書いている:

http://www.stationary-traveller.eu/pages/bzr-a-retrospective.html

[訳注:翻訳:本の虫: Bazaar-NG: 分散バージョン管理システムを7年ハックしてきて]

全Emacs開発者はこれを絶対に読め、そして一晩寝て、またもう一度読め。この記事の著者が書いたような罠に、Emacsも陥っていると言いたいからではない。「ソレ」は別の話だ。いま議論すべきなのは、bzrの失敗の重力圏から脱出するということについてだ。

理論的には、bzrのコードベースが十分にまともで、これ以降も継続して使うことができるならば、このbzrの失敗は、我々には何らの影響も及ぼさぬはずである。私が思うに、bzrは十分にまともである。

現実的には、bzrにとどまることは、Emacsの将来性とイメージに悪影響を与える。失敗したバージョン管理システムを使い続けるということは、プロジェクトに新しい開発者を惹きつけられないことを意味するからだ。

苦々しい事実としては、多くの若いハッカーたちは、すでにEmacsは恐竜であると考えている。難しく、ゴテゴテとして、重量級で、まあ一般的に言えば前世紀の遺物だ。このイメージを払拭するためには、我々はヘンテコで異質で前時代的なものにとどまることはできないのだ。

現在、bzrの利用を継続するということは、そういうことになってしまうのだ。bzrは学習コストが高いというわけではなく、小難しく時代遅れだという理由で、我々は新人を得る機会を損失してしまうのだ。現状から脱却するコストは、時間経過と共に上昇するばかりだ。

gitがこの戦争を勝ち抜いた。悲しいことだ。個人的にはMercurialの方が好きなのだが、だが、Mercurialにしたって、最近ははかばかしいことは聞こえてこない。私はgitの勝利に納得し、移行した。私はEmacsプロジェクトにも同様にするよう強く主張する。

私は以降にあたって技術的に主導できる、reposurgeonの作者として、私はそのためのスキルと経験を持っている(私は最近、GNU troffをCVSからgitに移行させた)。しかし、プロジェクトの主導者が、最初に決断をしなければならないのだ。

--
Eric S. Raymond

No one who's seen it in action can say the phrase "government help" without either laughing or crying.

メールで参照している記事は、このブログで日本語訳している。

本の虫: Bazaar-NG: 分散バージョン管理システムを7年ハックしてきて

Bazaar-NG: 分散バージョン管理システムを7年ハックしてきて

Bazaar-NG: 7 years of hacking on a distributed version control system

Bazaarの開発者が、Bazaarが失敗した理由について、当時を振り返って書いている。なかなか面白い。

Bazaar-NG: 分散バージョン管理システムを7年ハックしてきて

この7年間、筆者はBazaarプロジェクトに関わってきた。筆者はプロジェクトから距離を置き始めている今この時、筆者のこのプロジェクへの関わりや、何が良くて何が悪かったのかの意見などを、振り返ってみるべきだと思う。

この回顧録には多くの複雑な詳細が出てくるので、筆者の誤りもあるかも知れない。間違いを見つけたら知らせてくれ。

黎明期

< ddaa> dscmsには2種類ある。古臭いやつと、実験中なやつ。

2004年、筆者は、 SambaのコントリビューターであるMartin Poolのブログをたまに読んでいた。当時、Martinは異なるバージョン管理システムを調べて、ブログに記していた。筆者も当時、 CVS から Subversionに移行したところで、そこで紹介されている、別の新しいソース管理システムには興味があった、たとえばdarcsやtlaといったものだ。tlaは少し試してみたが、そのモデルは気に入ったものの、実際に使うには面倒すぎると考えた。

2004年末か2005年はじめあたりに、MartinはCanonical Ltd.に入社して、新しい実験的なバージョン管理システム、Bazaarを開発していると発表した。コマンドラインではbazであるBazaarは、GNU archのforkである。

その年の春、筆者は Linux.Conf.Au in Canberraに参加した。MartinはBazaar-NGについてのトークを行った。とうじはそういう名前で呼ばれていて、その場で簡単なデモも行われた。当時のストレージフォーマットは、まだバージョン管理されたファイルの完全なテキストを保持していたので、それほど効率的ではなかった。筆者は単純なUIと分散バージョン管理システムの信頼できる機能が気に入った。そこで、筆者はBazaar-NGを注目しておくリストに付け加え、メーリングリストを眺めた。

LCA 2005における、別の有名なイベントとしては、BitKeeperプロトコルに関する tridgeの悪名高いプレゼンがあった。このトークにより、Larry McVoyはBitKeeperの無料版をやめたし、LinusはGitをハックし始め、Matt MackallはMercurialを始めた。もちろん、当時これを予想できたものは誰一人としていない。

Sambaのbzrの利用

その年の暮れ、SambaははじめてGoogle Summer of Codeに参加した。我々はすべての生徒にSubversionのメインレポジトリへのコミット権を与える管理をしたくなかったので、Bazaarを試してみることに決めた。我々はBazaarにインポートしたソースコードを提供し、生徒たちに、変更を含んだクローンを公開するように言った。

筆者はMartinと知り合いだったし、Bazaar-NGはm当時のDVCSの中ではいい選択だったのだ。すべてのソースコードをSubversionからBazaarに変換するのは大変だった。当時はまだfastexport/fastimportはなかったし、そもそもSubversionからBazaarに変換するためのサポートも一切なかった。ただ、Tailorという、あらゆるVCSからあらゆるVCSへのへんかんをさぽーとしようとしていた ツールがあっただけだ。

Tailorをどう使おうとも、バグは避けられなかった。筆者はいくつかのバグ修正に貢献することになったが、結局信頼できるほど動かすことはできなかった。明らかに欠点は、変換方法であるディスク上のすべての変更を再生にあった。とてつもなく遅かったのだ。

Samba Summer of CodeにBazaarを使うのは、どうみても成功とは言えなかった。とても遅かったし、バグにぶち当たりまくった。明らかに、bzrはSambaのようなサイズのプロジェクトに使うほどには成熟していなかったのだ。筆者はまだ熱中していた。モデルはいいし、bzr開発者はバグ報告への対応が早いし、それに単純でとっつきやすいUIがとても気に入っていたのだ。小さなプロジェクトには筆者は使っていて、とてもよく動いた。

Bazaarは他の分散バージョン管理システムとも組み合わせて使うこともできるが、Subversionとの組み合わせはとりわけてひどく、欠けている部分も多かった。筆者は、この当時、GitのUIがとても基本的で、かろうじてまともに使うためにはラッパースクリプト("cogito")が必要だったことを記憶していている。

最初の貢献

夏過ぎに、筆者は最初のbzrパッチで貢献した。Tailorのソースをいじったことを別にすれば、これが筆者の最初の公開したPythonのコードだ。パッチを受け付けてもらうためには、色々と苦労が必要だった。

その年の暮れ、Gustavoがsvn2bzrの最初のバージョンを公開したので、筆者はテストを開始し、貢献し始めた。svn2bzrの発表に対する私のreplyは、この後、数年にわたって我々が遭遇し続けた問題を的確に言い表している。

sambaレポジトリを変換しようとしたのだけれど、最初の10コミット(~11000コミットのうち)を変換するだけで6時間かかった。tailorだと10時間以内に終わる(メインブランチの6000コミットの変換だけど)

比較のためにいうと、2012年に昔のSambaのSubversionレポジトリの最初の6000のメインラインリビジョンをインポートするのは、5分以内に終わる。

当時を振り返るに、Bazaar-NGは、今よりもずっと、コミュニティプロジェクトだったのだろう。そりゃ、Canonicalは主要な開発者を雇っていたし、ほとんどのファイルにCanonicalのコピーライトはあったが、それよりもずっと多くの人々が貢献していたし、ロードマップはCanonicalの都合ではなく、自由ソフトウェアプロジェクトの需要に従って決められていた。Bazaar-NGは、"bazaar-ng.org"という独自のドメインを持っていた。最初の数年は、貢献者ライセンス同意に署名する必要もなかった。

筆者が興味を持った機能に、Foreign Branchesがあった。Aaronがwikiに書いたように、Bazaar-NGの多数のファイルフォーマットを隠匿する既存の機構は、たとえばSubversionのような、他のバージョン管理システムのフォーマットをサポートするのに使うことができるはずだ。これに触発されて、筆者はBazaarにSubversionを取り込むためのプラグインのハックを始めた。名前は無難にbzr-svnとした。その当時、Sambaは近い将来にSubversionから移行する予定はなかったので、筆者はこれにより、Sambaをbzrからハックできるようになるとも期待していた。

初めてのスプリント

2006年の5月あたりに、LarstiQと筆者は、ロンドンで行われたBazaarのスプリントに招待された。筆者にとっては初めてのスプリントとなる。このスプリントは初めてにして唯一の、Bazaar-Mercurial合同スプリントで、Canonicalのオフィスで行われた。

スプリントには6人参加した。Martin Pool, Robert Collins、John Meinel、Aaron Bentley、Wouter van Heijst、それと筆者だ。この当時、MartinとRobだけがCanonicalで働いていた。他のCanonical社員が遊びに来ることもたまにあった。RobはGNU archのユーザーフレンドリーなforkであるbazにとりかかり、JohnとAaronはtlaとそのforkに、それぞれとりかかった。

スプリントはとても強烈で、部屋に皆で集まると、新しいことが次々と起こるものだ。私自身はそれほど大量のコードを書いたわけではないが、人生であの数日以上に、多くの物事を学んだ日はない。私はエクストリームプログラミングやユニットテストやテスト駆動開発や高度なPythonプログラミングに触れた。あらゆる種類の新しいバージョン管理の概念には、不思議な名前がついていて、まるでX-Filesを見過ぎたような人間が名づけたようだった(ghost rivision、patience diff、history horizon、nuclear launch codesなどなど)

その日の印象は今でも残っている。筆者は小さなホテルの会議室に座って、Robと最初のCommitBuilder APIの実装をペアプログラミングしていた。JohnとWouterがbzrをunicode互換にするためにJohnのどでかいブランチをハックし、最後にしぶとく残るテストを通そうとしていた。Aaronは筆者にrevision id aliasとghostを昼飯を食べながら説明してくれた。小さなCanonicalのオフィスに収まりきらなくなったので、誰かのキッチンテーブルの上に座っていたのを思い出す。David Alloucheは、ホテルのバーでビールをやりながらBazaar-NGの前身とtlaについて筆者に語った。筆者はネストされたツリーについて語った。6年後、われあれは未だに議論している。楽しかった。あのやる気と効率といったら。

あのスプリントの印象は強烈だった。あの時、良き指導者に恵まれなかったら。Martinがスプリントを開催してくれて、Canonicalがスポンサーしてくれて、あの4人のハッカーの辛抱強さには、本当に感謝している。

bazとarchの影響

Bazaar-NGのモデルは、Bazaarの前身(baz)が受け継いだ、archモデルの欠点を埋めることを目的としていた。とはいえ、まだtla/baz/archのレポジトリをインポートして、ユーザーに既存のレポジトリをアップグレードさせることができるはずだった。もともと、Bazaar-NGは次世代のbazのためのPythonで書かれたプロトタイプ的な位置づけだった。モデルの正しさが実証できたならば、baz 2.0として、Cで再実装される予定だったのだ。ある時点で、筆者にも正確には断定できないが、Pythonで書かれたbzr自体が、bazの次世代となることが決定され、既存のbazコードベースは、放置された。

私はArchやBazの利用にあたって不満があったわけではない。ただし、長年、そのモデルについて学ぶにつれて、その欠点も見えてきた。Archはユーザーがリビジョンやディレクトリーやタグに付けられる名前に、かなりの制限を設けていた。学習曲線は急峻で、ユーザーは複雑な内部モデルや、多くの操作用のサブコマンドを熟知しなければならなかった。自分が何をしているかわかっていない場合、自分の足を撃ちぬくのはとても容易で、取り消しできない操作も一部にはあった。誰か他人のブランチから派生する場合に、単に既存のデータをコピーするのではなく、派生先ブランチを歴史としての親ブランチとして参照するようになっていた。もし、他人のレポジトリ(とリビジョン)がネット上から消え失せれば、自分のリビジョンより他の歴史をたどることはできなくなってしまうのだ。

bzr(と既存のArchデータフォーマットの互換性がある部分に関しては、その前身にあたるbazも含めて)はもっとユーザーフレンドリーかつロバストになろうと努力した。ユーザーインターフェースは、馴染み深いCVSやSubversionのコマンドラインに少し近いものになった。リビジョンを内部的に区別する長ったらしい擬似乱数文字列にくわえて、リビジョン番号をユーザーに表示するようにもなった。ほとんどすべての操作はやり直し可能だ。レポジトリはすべてのデータを含むため、歴史へのアクセスは高速で、自分以外の誰かのHTTPサーバーが問題なく稼働しているかどうかに依存する必要もなくなった。WindowsとMacも二級市民ではなくなった。bzrは、UNIX風のスラッシュにくわえて、バックスラッシュもパス区切り文字として認識するようになったし、ファイル名のエンコード方式も規定した。

データフォーマットはデータモデルの結果であり、その逆ではない。データモデルに変更がくわえられたならば、その変更に会うようにファイルフォーマットが変えられる。これは従来のデータベースではとても厄介なことだが、DVCSレポジトリのような分散データベースでは、それほどでもない。

bzrはarchからいくつかの基本的な機能を受け継いだ。ブランチはネット上から消えやすいため、リビジョンも失われることがある。バージョン管理システムはそのことを知っている(なぜならばどこか別の場所へのリファレンスであるから)が、その中身にアクセスすることはできない。これは"ghost rivision"とよばれている。bazではブランチを素のhttpを経由して共有することができた。bazにおけるリビジョンとファイルはユニークな識別子が振られていて、名前が変えられたとしても、その正体を追うことができる。bzrはリビジョンIDとファイルIDという概念は保持したが、その制約を変えた。IDを単に擬似乱数文字列としたのだ。目的はgitがやっているような「おバカ」な中身のトラッキングではなく、正体のトラッキングだ。

これらの機能はとてもいいものなのだが、果たして苦労に見合うだけの利点があったかどうか疑問だ。どうも思うに、bzrは人々がarchやそのforkに対して思いつくあらゆる機能をサポートすべきだ、ひとつのDVCSはすべてを統べる、といった感じの風潮があったのではないか。一部の機能がどのくらい役立つかは、当時としても疑問だった。

筆者はghost revisionの熱烈な支持者であった。ghost revisionは別のフォーマットをサポートするのにとても便利だったからだ。しかし、パフォーマンスに悪影響を与え、fetch操作における失われたリビジョンを見つけるアルゴリズムも複雑になった。また、我々は、オホン、幽霊と相いれぬ多くのバグに悩まされてきた。bazからのインポートさえなければ、ゴーストのサポートは、もう少し後まで遅らせるべきだったのだ。

愚直な転送のサポート。ブランチの提供元にbzr専用のコードを必要とせず、HTTPやFTP経由でアクセスできることは、とてもいい機能だ。この利点としては、通常のHTTPやFTPサーバーを開発ブランチのホストに使えるということだ。特に、クラウド以前の時代には、CVSやSubversionのように、独自のコードをサーバー上で動かす必要があることに比べて、とても大きな利点だった。

Bazaarの転送の隠匿により、同じコードがローカルレポジトリにもリモートレポジトリにも利用できた。bzr logをフルクローンせずにリモートレポジトリに対して走らせることができるのは感動だ。このような方法で愚直な転送をサポートするには、ツケも支払わなければならなかった。HTTP越しのパフォーマンスに影響するため、レポジトリへのアクセスは、あまりシークできないし、巨大なデータを読み込むこともできなかった。

だが、その代わりに、リモートレポジトリにもあらゆる操作ができるのだ。ただ、ユーザーがフェッチしてローカルで自前で行うのではなく、レポジトリとブランチに対するすべての操作をサーバー側で行うbzrスマートサーバーを実装するときには、これは問題になったのだが。

bazにあった素晴らしい機能が、パフォーマンス上の理由で捨てられたものもある。cherry-pick merge trackingのサポートだ。

(Some of Martin's early notes on Arch).

当初、Bazaarのリリースは頻繁だった。しばらく、月齢リリースがあった。三週間の開発と一週間の安定化とプラグイン修正だ。開発は小刻みで、すぐに採用された。ファイルフォーマットや設定にほんのわずかでも、以前のバージョンのbzrが読み込めない可能性がある極小の新機能が追加されたツォいても、ファイルフォーマットバージョンがインクリメントされた。変更は積み重ねるのではなく、即座に適用したのだ。これにより、数ヶ月おきに新しいフォーマットが出ることになった。その後、フォーマットの変更は収まり、2009年からは、新しいフォーマットは追加されていない。残念ながら、bzrは二週間おきに新しいファイルフォーマットを追加しやがるぜ、というイメージを払拭させることはできなかった。

オーガ

筆者が参加していたもうひとつのプロジェクトは、「オーガモデル」と呼ばれていた。なぜならば、オーガのように、そしてソフトウェアとしては珍しく、レイヤーを持っていたからだ。

Bazaarが新しいバージョンのファイルフォーマットをこれほど頻繁に追加できた理由は、UIと、APIと、ファイルフォーマットの実装が、綺麗に隠匿されているからだ。これはgitとはえらい違いだ。gitはディスク上の様々なものをUIに露出させている(例えば、ディスク上のリビジョンを識別するためのsha1チェックサムだとか)。既存のgitのツールを、全く別のファイルフォーマットに対応させるのはとてもむずかしい。Bazaarにとっては、とても簡単だ。

思うに、この点こそが、どちらも似たようなモデルを使っているBazaarとGitの重要な違いなのだろう。このために、Bazaarは昔の日効率的なweave formatからpack formatに簡単に移行できたわけだし、別のフォーマットも第一級市民としてサポートできるが、大量のグルーコードや余計な複雑さがついてまわる。様々な点で、Bazaarはトップダウンに作られているのだ。Gitのようなボトムアップとは違う。

ただし、これはBazaarがGitより優れていると主張しているのではない。David Wheelerかだれかが言ったはずだが、

All problems in computer science can be solved by another level of indirection... Except for the problem of too many layers of indirection.

コンピューター科学におけるあらゆる問題は、さらに一段階の間接参照を挟んでやれば解決できる。ただし、あまりに間接参照のレイヤーが重なり過ぎるという問題だけは解決できない。

パッチの採用が困難

Bazaarは変更に対してかなり厳しい要件を設けていた。これは良くもあり悪くもある。すべてのバグフィクスや挙動の変更は、テストスイートにも変更を反映させたり、あるいはテストスイートを拡張したりする必要がある。すべての変更は、二人のコミッターによってレビューされる必要がある(ただし、コミッターはセルフレビューできるので、あと一人だけでもいい)。CanonicalがBazaarのほとんどのソースコードの著作権を保有する(歴史的な理由による例外もある)。それから、2009年からは、Canonicalのcontributor license agreementに署名する必要もでてきた。

筆者の初めてのパッチが採用されるには相当に時間がかかった。修正自体は簡単だったのだが、適合するテストを書くのは難しかった。たまに現れる貢献者も、この問題と格闘していたし、実際、何人かには貢献を避けるだけのものがあった。やがて、CanonicalのBazaarハッカー達は貢献者からのパッチを代行するようになったので、バグ修正や変更が採用されるのが、だいぶ簡単になった。

もちろん、れびゅーとテストにここまで厳格であることで得られる恩恵もあった。採用されるほとんどの変更は高品質だった。テスト、リファクタ、その他の些細な変更が自身を持って行えた。筆者はBazaarに大きなデータロスのようなバグを見たことがない。regressionは起こるには起こったがまれだった(プラグインの互換性を壊すAPIの変更は別だが)。筆者は何年も、bzrのtrunkを快適に使っていた。

ただ、品質要求が貢献者を遠ざけたわけではないと思う。GitやMercurialにしても、そこまで厳格ではないかも知れないが、似たような要件を課していただろう。彼らとて、そのために行われなかった貢献もあったはずだ。

あるいは、Bazaarがよそに比べて複雑なところが、貢献の大小のちがいなのだろうか。ほとんどのGitユーザーはファイルフォーマットの詳細を知っているし、たとえ知らないにせよ一日で学べる。Gitのバグをソースファイル上で見つけるのは、様々なレイヤーが関係するBazaarを理解するよりも、だいぶ簡単だ。新し目のBazaarのファイルフォーマットは、たいていドキュメント化されていない。bzrの世界にいて何年も経た後でも、いまだに筆者は、gitのpack実装のバグを修正するほうが、Bazaarのバグを修正するより簡単だと感じる。

あるいは、違いを如実に語る例として、Gitの詳細のLWN記事が、Gitのリリースから5日後に公開されたことが挙げられるだろうか。

これはファイルフォーマットについて知りたい一部のギークどもが臆病風にふれられて逃げ出すから問題というわけではない。ユーザーが何か低級層のコードの問題に出くわした時、その問題を修正するだけの力がないことが問題なのだ。ユーザーがbzrのバグに出くわして、レポジトリにアクセスできなくなり、悪態をつきながら離れていったのをみるとき、とても残念に思う。そのバグがどんなに些細なものであったにせよ。

プラグイン

Bazaarの良くも悪くもある別の点としては、プラグインだ。bzrlibのほぼすべての箇所は、プラグインで拡張可能だ。Bazaarを変更するプラグインで最も多い利用方法は、新しいサブコマンドの追加だ。プラグインがインストールされれば、常にbzrlibに読み込まれて初期化されるのだ。

Pythonを少しかじっていればプラグインを書ける。いいドキュメントが揃っているし、基礎的なプラグインを書くのには、bzrの詳細についてそれほど知っている必要はない。プラグインではほとんど何でもできる。例えばレポジトリのファイルフォーマットのサポートだとか、bzr logの出力フォーマットのオーバーライドだとか、レポジトリにアクセスできるプロトコルの追加だとか。

ある意味、プラグインはbzr本体に新しいコードが採用されにくい状況への対象方法として使われていたのだ。わざわざレビューワーを説得する必要もない。テストを書く必要もない。要するに、プレグインは新しい機能を試すのに最適だったということだ。Canonicalへの著作権譲渡も必要ない。

プラグインはBazaar本体より遅れていることが多かった。APIに対する変更は、そのAPIを使うプラグインをぶち壊してしまう。古いAPIを非推奨扱いにして、ユーザーに新しいものを使うように促す機構も用意されていた。ただし、bzrlibには大量の公開されたAPIがあったのだ。現実には、プラグインで使うのはその一部で、公式な方法で非推奨扱いにするのは時間がかかったので、しばしば見送られた。

新機能をプラグインに突っ込むのがとても簡単であるがために、変更を上流に採用させるためのインセンティブに欠けていた。実際、これにより、インストールされたBazaarを最新版に保つというのは、Bazaarバージョンとプラグインのバージョンをジャグリングしているようなものだ。お互いに互換性がなければならないのだ。

我々はBazaar自体にもっとプラグインを盛り込むべきだったのだ。Pythonのように、バッテリーまでついてます[訳注: batteries includedとは、Pythonの標準ライブラリがとても充実している様を言い表す慣用句]とね。MercurialもGitもやっていたことだ。

急速な開発

2005年から、CanonicalのBazaar部署はゆっくりと5人にまで増えていった。2006年と2007年は、新しい楽しい変更が常にあった。スプリントももっとあったし、筆者もさらに大勢のbzrの貢献者に対面した。Andrew Bennetts, Vincent Ladeuil, Ian Clatworthy, Martin Albisetti。

Bazaarはファイルフォーマットをとても改良した。そしてさらにpackファイルに入れるためにも変更した。高パフォーマンスのスマートサーバーも入ったが、ただし、「高パフォーマンス」という部分は、当時はやや理論的なところがあった。我々はシリアライズされたリビジョン(バンドル)をメールで送りあった。Bazaarのグラフィカルなフロントエンドを作る人や、Webフロントエンドを作る人も出てきた。

Bazaar開発の議論は、ほとんどIRCかメーリングリストで行われていた。変更を提案するには、パッチか、マージリクエストをメーリングリストに送る。するとコミッターがレビューして、メインのBazaarブランチを管理するBOTに送る。やがて、Aaron BentleyがBundleBuggyというWebサイトを立ち上げたので、メーリングリストに提出された変更とその状態をトラックすることができるようになった。

大移行

2007年の終わり頃、最初の大き目の自由ソフトウェアプロジェクトが分散バージョン管理に目をつけ始めた。2008年から2009年にかけて、大量のプロジェクトが中央バージョン管理から移行してきた。

前回のVCS移行、すなわちCVSからSubversionからの移行は、Sambaではとてもうまくいった。2007年10月に、ある開発者が、Gitへの移行を提案した。筆者はSambaに貢献するために、bzr-svnを長年使っていて、GitのかわりにBazaarを提案したかったが、パフォーマンスという点で、まだGitには遠く及ばないと気がついた。Sambaが移行した後、筆者はbzr-gitをハックし、Bazaarを使い続けられるようにした。

2008年1月、BazaarはGNUプロジェクトになった。現実に、特に何かが変わったというわけではなかった。

2008年、さらに多くのプロジェクトが、三大分散バージョン管理システムに移行し始めた、Mercurial、Git、Bazaarだ。筆者はまだforeign branchプラグインや、bzr-gitや、Robが始めたbzr-hgプラグインに関わっていたし、さらにbzr-svnや、 bzr-gtkにも関わっていた。

さて、Launchpadはマージの提案をまともにサポートしたので、BazaarはLaunchpadに移行して、メーリングリストに送られたbundleに変わって、Launchpadを使ってマージの提案を行うようになった。

一方、DVCSツールもだいぶ発達してきた。多くの人が、Visual StudioやEclipseやNautilusにDVCSを組み込みはじめた。Ian Clatworthyはドキュメントをまともに整備し、bzr-explorerを始めた。CanonicalのBazaarチームは、Bazaarに移行したい様々なプロジェクトからの要望に答えるべく働いた。

筆者は、様々な外部ツールとの連携が十分にとれていないことが、ユーザーからとっつきにくくしているのではないかと危惧していた。当時を振り返るに、おそらく筆者は、原因と結果を取り違えていたのだろう。

改変不可能性と、完全な歴史

Bazaarは、それ以前にあったArchやSubversionのように、歴史を忠実に記録することに力を注いでいた。歴史は参照されるが失われることもある(ghost rivision)。理由は単になくなったか、あるいは誰かが意図的にレポジトリから消したか(たとえば、誤ってパスワードをコミットしてしまったとか)

Bazaar開発者は常に、歴史の改変は邪道であると考えていた。歴史が正確ではなくなるという以外の、改変可能な歴史に対する反論としては、歴史を改変させることを許してしまうと、ユーザーが容易に自分の足を撃ち抜けるようになってしまうからだ。歴史の改変は、同じデータに対する2つの微妙に異なるバージョンを生み出す。このような改変を拡散させるのは、関わりたくないほどに難しくなる。

当初の計画では、Bazaarにアノテーションをつける予定だった。Gitでオブジェクトにノートを付与して、コミットメッセージの誤字脱字を修正できるのと同じだ。

その他のBazaarの設計思想としては、後で必要となる場合に備えて、可能な限りの情報を保持するということだ。Bazaarは明示的に、リネームを記録しているし、たとえば、一連の変更点を提出させるときなどに、歴史を組み込むことを推奨している。

パッチのためにユーザーの歴史を破棄するのではなく、変更をもたらす新しい"mainline"コミットとして参照される。

"mainline"とは、左手側の祖先である、いうなれば、tip(ノードの最初の親)からDAGの左手側に潜っていって、ツリーの根本まで戻っていったときにみるリビジョンだ。

BazaarのUIはmainlineの概念を反映している。たとえば、ドットなしのリビジョン番号はmainlineのリビジョンで、"bzr log"と"bzr qlog"は、デフォルトでmainlineしか表示しない。貢献者がパッチを提出する前の変更点である右手側の歴史は、本当に必要とするときのために記録されているが、通常は隠されている。

この時点で、多くのプロジェクトが、既存の歴史を、次世代DVCSにインポートしてテストしようとしていた。Git、Mercurial、BazaarメーリングリストとIRCチャンネルは、どのシステムが、他のシステムには存在する必要不可欠な機能を欠いているかという議論とフレーム戦争であふれかえっていた。多くのプロジェクトが、それぞれ思い思いにピカピカの次世代ソースコード管理ツールを選んでいくに連れ、bzrの問題点が、次第に明らかになってきた。

パフォーマンス

長年、パフォーマンスは次第次第に向上してはいたものの、Bazaarはまだ、中規模から大規模のプロジェクトで、十分な速度ではなかった。プロジェクトは、Bazaarを使うと、Gitやmercurialを使った時に比べて、より多くのディスク容量を必要とした。

運用

Bazaarが提供しているいくつもの運用は、人々を混乱させた。bzrは、独立したブランチからお互いにpullしたりpushしたりといった真の分散型として使うこともできれば、SubversionやCVSのような、中央環境でやるような、中央ブランチに束縛されたローカルブランチとして使うこともできた。Bazaarの主要な開発者は中央管理的な運用をすることはなかったので、これはやや特殊な用法だが。

一つのブランチにつきひとつのディレクトリという方針は、小規模なプロジェクトにはうまく動くが、レポジトリのサイズが増大するにつれて破綻した。ユーザーはディスク効率のため、複数のブランチから共有されるレポジトリの作成を余儀なくされた。Cプロジェクトではたいてい、同じworking treeを複数のブランチで再利用するのは便利なことだ。これはBazaarでも可能なのだが、それほど便利ではなかった。

ヒストリートラッキング VS コンテンツトラッキング

History is a set of lies agreed upon.

歴史とは、合意された嘘の集合である。

Bazaarの思想の3つ目の問題は、完全に改変不可能な歴史である。ソフトウェア開発者は歴史家でも法律家でもない。多くのユーザーは、歴史を簡単にしておきたいと思うものだ。ユーザーが気にかけるのは、trunkに起こった変更を追って、変更の経緯を明らかにすることであって、trunkに入るに至ったパッチに対する個々のコミットや間違いではない。Gitは"rebase"を提供してる。これは、単に上流ツリーにローカルの変更を再適用するものだ。Gitはしばしば、バージョン管理ツールではなく、コンテンツトラッカーと呼ばれている。そういう名前で呼ばれたほうが理解しやすいのだ。

これに関係するが、Gitは単純なコマンドラインツールによって、レポジトリを低級層からひっかきまわすことができる。例えば、SVNからインポートされたレポジトリから、巨大なISOを除外することができる。Bazaarは長年、rebaseプラグインはなかったし、ようやくrebaseプラグインが出てきた時も、パフォーマンスが遅すぎたし、あまり強力ではなかった。Bazaarには、必要とあらば変な歴史を改変するためのツールは、あまりなかったのだ。

当時、筆者が少し驚いたことには、多くの人は、Gitのリネームの検出が100%の精度をもっていないことを、あまり気にしていないことだった。どうやら、リネームの誤検出に出くわすのは、それほど頻繁ではなかった(それに簡単に対処できる)ようなので、十分にやっていけたようだ。筆者もやっていけたし、問題に出くわしたのは、数えるほどしかなかった。

Bazaarのリネームに対する解決方法にも問題はあった。Bazaarはユニークな識別子を、ファイルが最初にワーキングツリーに追加される際に割り当て、ファイル名が変更されたとしても、ファイルをトラックしていた。これはファイルが独立してバージョン管理され、ユニーク識別子が2つある場合に、とても問題になった。

技術的に、BazaarとGitのデータモデルは、それほど違ってはいないというのは、興味深い点だ。Bazaarは明示的にディレクトリをトラックし、ファイルにIDを付与してリネームもトラックしていた。一方、Gitはヒューリスティックを使った。違いはむしろ思想や、ツールや、ディスクのレイアウトだ。

CanonicalのBazaar人員は、パフォーマンスの問題と、レポジトリのディスク上のサイズを解決するために、新しいフォーマットを設計した。brisbane-cre (2a)は2009年の夏頃に公開された。ただし、バグもかなりあった。特定の利用例でのパフォーマンスregressionもあった。残念なことに、この時点で、Bazaarは遅いものだという評判が定着していたため、光のように速い新フォーマットでも、揺さぶりをかけることはできなかった。

一部の人間は、Bazaarはそれほどコミュニティによる貢献がなく、完全にCanonicalの塀の中で開発されたと主張する。皮肉なものだ。Bazaarの大部分はCanonical社員に寄って書かれたことは確かだが、それはCanonicalがBazaarに貢献していた人間を雇ったからにすぎないのだ。多くの者は、Canonicalのその他のコードの開発に移っていった。

筆者も、2009年にCanonicalに入社して、Lunchpadのパッケージ側(Soyuz)の開発を、AGPLでリリースされた数カ月後から行っていた。筆者は暇な時間にBazaarの開発をしていた。

利用者減少とUbuntuへの注力とUDD

2009年の終わり頃、GitがDVCS戦争の商社となりつつあることは次第に明らかになっていった。Bazaarへのコミュニティの貢献は次第に減っていったのだ。

2009年末、CanonicalはBazaar業界に姿を現し始めた。Canonicalは商用サポートを売りはじめ、同時に、オンラインにパッチを提出した貢献者は、まず contributor agreementに署名するよう求められた。2010年のどこかで、ドメイン名がbazaar-vcs.orgから、bazaar.canonical.comに変わった。

CanonicalのBazaarチームの目的は、BazaarがUbuntuプロジェクトのパッケージ管理をうまく扱える、まともな汎用のバージョン管理システムとすることになった。CanonicalにおけるBazaarの当初の目的は、すべてのソースパッケージに使えることにより、未だにtarballとdiffに固執するUbuntu開発者に、バージョン管理の利点をもたらすことだった。

筆者はBazaarの人気のなさに失望していたものの、まだBazaarには期待していたし、Ubuntuのソースコードの管理ツールとなるという役割をはたすことにも期待していた。foreign branchのサポートは、世の中にいくつもあるVCSツールを、共通のインターフェースで扱えるという点で、重要だと考えていた。筆者はLaunchpadのテクニカルアーキテクトになったRobのかわりに、Bazaarチームに移った

James Westbyは、bzr-builddebプラグインを土台にして、すべてのUbuntuのソースパッケージをBazaarに自動的にインポートするスクリプトを書いた。Bazaarチームは、Jamesの実験的な実装を引き継いで、1万7千ほどあるすべてのUbuntuのソースパッケージを、Bazaarにインポートすることを試みた。すべてのパッケージに適用することができた暁には、Launchpadのtarballアップロードは無効化され、Launchpadにブランチをpushするという新しいアップロード方法になるはずだった。

問題なくすべてのパッケージをインポートするということは、とてもむずかしい問題であった。ヘンテコなファイル名のパッケージあり(UTF-8ではない文字や、バックスラッシュや改行)、奇妙な祖先あり(Debianからの変更をマージ、nativeからregularに変更してさらに戻すなど)、とてもでかいファイルあり、debianの複数のtarballあり、他にもあらゆる奇妙なものであふれかえっていた。

長い間、癌と闘病してきた末に、 Ianが亡くなった。Ianはbzr-explorerのドキュメントに尽力してきたし、それ以上に、陽気で、とてもいい奴だった。

パッケージブランチが古くなったことに伴うfetchが、古き良きtarball(これは広くミラーされている)より遅いとあっては、Ubuntu開発者から、あまりいい目でみられなかった。当時を振り返るに、すべてのパッケージをBazaarに移行する前に、すべてのパッケージをBazaarに正しくインポートするというのは、間違っていたのだろう。パッケージを一つづつBazaarに移行させていくほうが良かったのだろう。そもそも、Ubuntuにとって重要なパッケージは限られているわけだし、パッケージインポーターを正しく動かすという難しい作業も省ける。

負け組Bazaar

CanonicalのBazaarチーム以外の外部の人間による貢献は、2011年の半ば辺りには、まれになってしまった。2012年の初頭には、CanonicalのBazaarチームは他のプロジェクトに配置転換されてしまった。まだ、たまにBazaarのバグフィクスぐらいはするのだが。Martinは2012年4月にCanonicalを退職した

2012年の前半6ヶ月、筆者は暇な時間で、作業中のブランチを完成させた。その後は、なるがままに任せようと考えた。

そろそろ、先に進むべき時だろう。まだ気に入らない部分もあるにせよ、Gitはまともなソースコード管理システムだ。Bazaarは、これ以上発展しない。数年後にも新しいユーザーは出るだろうし、バグ修正の貢献者もいるだろうが、筆者が願っていたほど広く受け入れられてはいないのだ。

bzrはGitファイルフォーマットへの別のUIとして、つまり、Gitと競合するのではなく、Gitの一部として、第二の人生を歩むことができるだろうか? まあ、できるかもしれない。筆者も含む何人かは、そういう提案もしていた。そうするとしても、まだやるべき作業が多すぎる。bzr-gitは未完成なのだ。Bazaarが単にUIだとするならば、bzr風のGit UIをスクラッチから、libgit2とかDulwichとかの上にでも作ったほうがいいだろう。

結論

Bazaarにはもっと可能性があった。Bazaarは人気で書きやすいプログラミング言語で書かれていた。コードは綺麗で、コメントも大量にあり、テストのカバー率も高かった。Bazaarには簡単なコマンドラインUIがあり、ナイスなグラフィカルフロントエンドがあり、まともなクロスプラットフォームのサポートもあり、十分にドキュメント化されていた。何年もの間、フルタイムのエンジニアが働いていて、活発なコミュニティも存在した。

我々には、大切なものがわかっていなかったのだ。いい機能だけれど、思ったほどには必須ではない機能に注力してしまった。あまりにもやりすぎてしまった。無意味に込み入った不必要な機能を削ぎ落とさなかった。理解が難しく、貢献が難しく、巨大なレイヤー化されたコードベースのパフォーマンスの修正も難しかった。コードベースが大きくなるに連れ、バグの範囲も広くなり、リファクターも難しくなっていった。

これは筆者の専門である、foreign branchプラグインにも言えることだ。bzr logやbzr diff -c 1200やBazaarの標準APIが、GitからBazaarへのレポジトリの変換を介さずに、Gitレポジトリを直接扱えるのは、便利であるのは確かだ。しかし、そのために余計に複雑になり、余計にアーキテクチャー上の(パフォーマンスの)バグを出してまで、価値のあるものだっただろうか?

Bazaarを、いい奴、才能のある奴と開発できたのは楽しかった。筆者はとんでもなく多くを学べた。何か、新しいことを始めるべき時だ。

2014-01-05

なぜ私が飲み屋に行かないのか

久しぶりに飲み屋に行って、なぜ私が飲み屋に行かないのか思い出した。

タバコだ。

タバコを吸う人間は許しがたい。

2014-01-04

主要なハード屋がVP9のハードウェア支援のサポートを表明

[Phoronix] Intel, NVIDIA To Support Google's VP9 Codec

どうやら、GoogleはVP9のハードウェア支援の約束を主要なハード屋と取り付けたらしい。

Herb SutterがCairoのMLにC++標準規格にCairoを入れられないか打診中

[cairo] Cairo and ISO C++

[Phoronix] Cairo Proposed To Become Part Of ISO C++

Herb Sutterが、CairoのMLに登場して、CairoをC++標準規格の軽量描画ライブラリとして採用できるかどうかの質問をしている。

軽量グラフィックライブラリーについては、私のブログの去年の10月の簡易レビューでも解説している。本の虫: 2013-10 post-Chicago mailingの簡易レビュー

こんにちは。私はHerb Sutterと申します。ISO C++標準化委員会の議長を勤めております。Behdadさんが質問の場として、このMLを紹介してくださいました。

C++標準化委員会は、ISO C++の標準規格に取り入れることができる、基本的な2D描画ライブラリを策定しておりまして、その土台となる(あるいは、バインディングなどでそのまま取り入れる)ことができる、先例となる既存のライブラリを探しております。現時点での、目的と議論については、以下のふたつの論文で閲覧できます。

2つ目の論文に書いてある通り、C++標準化委員会は機械的にC++化された版のCairoを提案する方向を検討しております。特に、「機械的にC++化」と申しますのは、Cairoをそのまま取り入れて、1ページ程度のリストで定義できるような変換を施すこと、たとえば、_create系の関数をコンストラクターにして、(mystruct*, int length)系の関数仮引数をvector<struct>&仮引数にして、などといったような変換です。設計と隠匿と関数は変わりません。これにより、C++標準化委員会は、同じ変換を更新版のCairoにも適用することで、将来のCairoの進化に追随することができるのです。

Cairommのことは存じておりますが、あまり活発に開発されていないようでありますので、我々といたしましては、C++ではないとはいえ、Cairoを土台としたいのです。Cairoはとてもよく書かれたCであると存じております(すでにオブジェクト指向で、すでに正しくconstされていてなどなど)

C++標準化委員会は、これを正しいやり方で、団体の合意のもとに行いたいと考えておりまして、フィードバックをいただけたらまことにありがたく存じます。また、Cairoのドキュメントの一部を標準規格で使いたいと考えておりまして、これは、MPL 1.1であるように思われますが、権利関係の合意が得られるかどうかを確認したく思います。

今後とも宜しくお願いいたします。

Herb

本気か? 正気か?

2014-01-02

星の王子様

たまたま、サンテグジュペリの星の王子様の新訳が転がっていたので、暇つぶしに読んだ。

基本的に、私は一度読んだ小説などは、あまり読み返したりしない。なぜならば、次に続く文章が分かっているので、それほど面白くないのだ。ただし、星の王子様を読んだのは、確かまだ小学生の時で、もはや話の筋をあらかた忘れている。それに別人の翻訳というのも気になる。

さて、読み終えたので、感想を書きたいのだが、どうもこの本に対しては、うまく感想を書きにくい。この本をグダグダと批評するのは、大人のやることではないか。少なくとも、この本を読み終えた後しばらくは、そんなつまらない大人にはなりたくないものだ。

ただ、どうしても一言だけ書いておくと、名作と呼ばれるだけの不思議で味わい深くでどこか物悲しい話だ。ああ、結局、批評してしまった。つまらない大人になったものだ。

実は、このブログを本の虫と名づけたのは、もともと、読書感想を書くつもりでいたのだ。

2014-01-01

X.Orgのセキュリティは最悪だというプレゼン

[Phoronix] X Server Security Disaster: "It's Worse Than It Looks"

CCC-TV - X Security

C++11の新しい関数の宣言

以下はC++03の関数の宣言である。

// int型の仮引数を一つ取り、int型の戻り値を返す関数
int f( int ) ;

以下は、C++11から追加された、新しい関数の宣言である。

auto f( int ) -> int ;

もちろん、関数へのポインター型の宣言にも使える。

// C++03
int (*fp)(int) ;

// C++11
auto (*fp)(int) -> int ;

新しい関数の宣言は、単に文法が変わっただけで、意味は変わらない。ただし、戻り値の型を後置できる文法なので、そのためにコードがわかりやすくなる。

例えば、ポインターを返す関数へのポインターが書きやすくなる。

// C++03
int * (*fp)() ;

// C++11
auto (*fp)() -> int * ;

他にも、複雑な関数テンプレートを書く際にも使いやすくなる。

C++14では、新しい関数宣言の文法をさらに拡張して、戻り値の型推定の機能が追加された。

// 戻り値の型はint
auto f( )
{
    return 0 ; 
}

2013-12-29

C++03とC++11の違い: 文字列ライブラリ編

今日も今日とて、C++03とC++11の違いを解説する。今回は、文字列ライブラリー編だ。

変更: basic_stringをリファレンスカウントで実装することを禁止

C++が設計中の時代は、文字列を保持するストレージを文字列クラスで共有して、参照数を記録しておき、変更された時だけ書き換えるような実装が、主に使われていた。


class String
{
private :
    char * storage ;
    unsigned int * count ;

public :
    String()
        : storage( new char[100] ), count( new unsigned int(0) )
    { }

    // コピー時に共有する
    String( String const & s )
        : storage( s.storage), count( s.count )
    { count++ ; }

    // 誰も所有していなければ解放
    ~String( )
    {
        --count ;
        if ( count == 0 )
        {
            delete count ;
            delete[] storage ;
        }
    } 
} ;

このようなCOWによる文字列クラスの実装は、30年前はともかく、今となってはとても効率が悪い。なぜならば、マルチコア、マルチスレッドが当たり前になってしまったからだ。今は文字列クラスをCOWで実装すべきパフォーマンス上の理由がないので、C++11では、COWで実装することは規格で禁止された。

変更: Small-string optimizationの許可

Small-string optimizationとは、文字列クラスの最適化手法のひとつである。多くの文字列クラスのオブジェクトは、短い文字列を扱うという点に着目して、あらかじめ短い文字列を、クラスオブジェクト自体に格納できるようにしておくのだ。


class String
{
    std::size_t size ;
    char sso[8] ;
    char * storage ;

    String( char const * ptr )
    {
        size = std::strlen( ptr ) ;

        if ( size > 8 )
        { // usual allocation
            storage = new char [ size ] ;
            std::copy_n( ptr, size, storage ) ;
        }
        else
        { // small-string optimization
            std::copy_n( ptr, size, sso ) ;
        }
    }
} ;

このように非常に短い文字列の場合はクラスオブジェクト自体で保持できるようにすれば、短い文字列ならば、動的にストレージを確保せずに保持できる。そして、文字列クラスの利用には、このような短い文字列のりようがとても多い。

small-string optimizationは、最近の文字列ライブラリの一般的な最適化手法になっている。従来の規格では、イテレーターが無効になる条件の都合上、small-string optimizationは、規格上許されていなかった。その制限はC++11で緩和された。

次回は、コンテナーライブラリー編だ。

2013-12-28

C++03とC++11の違い: 汎用ユーティリティライブラリー

今日も小粒な、C++03とC++11の変更点

変更: 最小限のガベージコレクションサポート

C++11にガベージコレクションは入らないが、GCを入れるための、変なビット演算でポインターの内部表現を戻したりしない、リーチ可能なポインターというものを規定している。これにより、C++03とC++11の規格に準拠したそれぞれのプログラムの挙動が変わる可能性が、規格上存在する。

変更: 標準ライブラリの関数オブジェクトは、std::unary_function, std::binary_functionから派生していない。

もう、C++11ではメタプログラミングが発達したので、このような基本クラスは必要がない。

次回はstringライブラリの違い

ACアダプターが断線

吉田寮で、うかつにもラップトップを起動したまま寝てしまった。起きた時にはラップトップの電源が落ちていた。不思議だ。ACアダプターをコンセントに挿しておいたのに、なぜバッテリーが切れるのだろうか。よくみると、コンセントが抜けている。なるほど、寝ている間に、誰かがつまづいたのだろう。

コンセントを挿しなおしてみるが、なぜか電源が入らない。不思議だ。挿し直すと入るが、またすぐに電源が途絶える。まさか・・・ACアダプターの断線。

そのまさかだった。ACアダプターが断線していた。線を動かしつつ断線箇所を探すと、ACアダプターとコンセントをつなぐ三叉のケーブルの中で断線しているようだ。ACアダプター本体は問題ないようだ。ああ、よかった。こちらなら、まだ何とかなる。

その日、寺町に行って、ジャンク品のケーブルを買った。新品は、ものすごく短いものしかなかったのだ。ただ、今から考えれば、単に電源タップを使うという運用でも良かったのかも知れぬ。このACアダプターから先のコンセントに差し込む方の線は規格化されているらしい。

やれやれ、はやくACアダプターも規格化してほしいものだ。思うに、もはやACアダプターに画期的な技術革新はないのではないか。なぜ規格化しないのか。ラップトップのACアダプターは、ひどいものになると、ある型番専用になっている。大量生産できないために値段も高い。ACアダプターが故障したために、使えなくなってしまったラップトップも多いのではないか。なんという無駄なことをしているのだ。

2013-12-27

ほっしー、連絡を乞う

連絡されたし by 江添亮 a.k.a 人柱

追記:連絡完了

XKCD What If: 致死量のニュートリノ放射ってどのくらいなの?っと

XKCD What If: 致死量のニュートリノ

超新星にどれだけ接近すれば、致死量のニュートリノ放射を浴びることができるの?っと

(物理屋の事務所から聞こえてきたセリフ)

「致死量のニュートリノ放射」というセリフは、いかにも奇妙だ。私はこのセリフを耳にした後、何度も首をかしげざるを得なかった。

もし、読者が物理屋でなければ、読者にはさほど奇妙に聞こえないかも知れない。そこで、この驚くべき発想の意味をちょっとわかりやすく書いてみよう。

ニュートリノとは、幽霊のような粒子で、この世界とはほとんど干渉しない。試みに読者の手の平を観察せよ。毎秒10兆個ほどのニュートリノが太陽から降り注いでいるのだ。

読者が膨大なニュートリノの存在に気が付かない理由は、ニュートリノというものは、通常の物質とほとんど干渉しないからだ。平均して、このような大量のニュートリノは、数年に一回ぐらい、読者の体の一個の原子と衝突する[1]。

[1]: 読者が子供であれば頻度が下がる。なぜならば、衝突すべき原子が少ないからだ。統計的に、筆者の初めてのニュートリノとの干渉は、10歳ぐらいのときに起きたはずである。

実際、ニュートリノはとてもこそこそしているため、太陽からの膨大なニュートリノは、地球全体を、何の影響もなく通り抜けてしまうのだ。ニュートリノを検知するために、人間は百トンもの物質で満たされた巨大なタンクをこしらえて、太陽からのニュートリノのひとつと、どうにか衝突してくれることを祈っているのだ。

これはつまり、粒子加速器(ニュートリノを生成する)が、ニュートリノビームを、世界のどこかの検出器に送りたいときは、検出器の方向にビームを向けるだけでいいのだ。たとえ、地球の反対側であったとしてもだ!

だからこそ、「致死量のニュートリノ放射」というセリフは、とても奇妙に聞こえるのだ。ありえないスケール同士の組み合わせだ。ことわざでいうならば、「羽で殴り飛ばされる」とか、「サッカー場の上までアリを詰める」[2]、といったところだ。もし、数学の素養があるのあらば、"ln(x)e"のような式を見たようなものだ。これは、文字だけ読めば、完全に意味をなさないというわけではないが、このような式を適用すべき状況が思いつかないのだ。[3]

[2]: それでも世界のたった1%程度の量のアリなんだけどね。

[3]: もし、数学科の一年生を苦しめたいのならば、この微分させた、ln(x)e dxについて質問してみるといい。1のようでもあり、他のなにかのようでもあるが、そうではないのだ。

このように、ニュートリノをたった一つの物質と作用させるだけの量を集めるのも難しいのだ。読者に影響を与えるほどの大量のニュートリノは、想像が難しい。

超新星(Supernovae)[4]は、そのような状況を提供してくれる。この問題を話してくれた物理学者は、超新星に関わる数字を推測するときの原則としては: どんなに超新星を大きなものと考えようが、超新星は想像よりもっと大きい

[4]: Supernovasでもいい。Supernoviiは非推奨。

このスケールの大きさを読者に認識させるための問題:

以下のいずれかが、読者の角膜に与えるエネルギーという点で、よりまぶしいか。

  1. 太陽と地球ほどの距離ほど離れた場所から観測した超新星
  2. 読者の眼球にくっつけて起爆させた水素爆弾

物理学者の原則を適用すれば、超新星のほうが眩しい。実際にそのとおりである。9桁もの差がある。

だからこそ、これが適切な質問になるのだ。超新星は想像できないほど強力で、ニュートリノは想像できないほど非力なのだ。いったい、どこまでいけば、このふたつの想像できないもの同士が打ち消し合って、人間のスケールで影響を及ぼすのか。

被曝の専門家、Andrew Karamの論文が、その答えを提供してくれている[5]。この論文は、超新星において、星の核が崩壊して中性子星になるとき、1057個のニュートリノが放出されると説明している(星のすべての陽子が崩壊して中性子になるのだ)

[5]: Karam, P. Andrew. "Gamma And Neutrino Radiation Dose From Gamma Ray Bursts And Nearby Supernovae." Health Physics 82, no. 4 (2002): 491-499.

Kramは、1パーセク[6]離れた場所におけるニュートリノ被曝量は、約0.5ナノシーベルト、あるいはバナナを一本食べた場合の500分の1の被曝量であると計算した。

[6]: 3.262光年、もしくは、ここからアルファケンタウリまでよりすこし短い。

[7]:xkcd.com/radiation

致死量の被曝量は約4シーベルトである。逆2乗の法則を使えば、被曝量を計算できる: \[ 0.5\text{ nanosieverts} \times\left ( \frac{1\text{ parsec}}{x}\right )^2 = 5\text{ sieverts} \] \[ x=0.00001118\text{ parsecs}=2.3\text{ AU} \] 2.3AUは、太陽と火星より少し遠いぐらいの距離だ

核が崩壊する超新星は、巨大な星に発生する。そのため、このような距離から読者が超新星を観測したならば、読者はおそらく、その超新星をつくりだした星の外層の中にいたはずだ。

ニュートリノ放射による被害という考え方は、いかに超新星が強力なものかを改めて思い知らされる。もし、読者が超新星を1AU離れて観測したとして、読者は何らかの方法で、発火、消失、そして何らかのエキゾチックなプラズマに変換されるのを免れたとしても、幽霊のようなニュートリノが、まだ読者を殺せるほどの量を持っているということだ。

もし十分に速ければ、羽は確実に読者を殴り飛ばせる。

2013-12-26

C++03とC++11の違い:言語サポートライブラリ編

江添とボレロ村上の京都C++勉強会は終わってしまったが、C++03とC++11の違いシリーズは続ける。

変更:operator newとoperator deleteの違い

C++11では、単体確保のためのoperator newとoperator deleteは、その他の確保関数、解放関数の基本的な関数として、呼ばれるようになった。

この変更の結果、以下のコード


#include <cstdlib>
#include <iostream>
#include <new>

void * operator new( std::size_t size )
{
    std::cout << "allocated" << '\n' ;
    return std::malloc( size ) ;
}

void operator delete ( void * ptr ) noexcept
{
    std::cout << "deallocated" << '\n' ;
    std::free( ptr ) ;
} 

int main()
{
    int * ptr = new int[3] ;
    delete[] ptr ;
} 

これを実行した結果は、

allocated
deallocated

となることが、C++11では保証されている。C++03では保証されていない。

つまり、C++11では、デフォルトの実装の配列型の確保関数、解放関数に、単数形のものが、使われることが保証されるようになったということだ。

変更:operator newがstd::bad_alloc以外の例外も投げるかもしれないようになった

C++03では、std::operator newには、動的例外指定、throw( std::bad_alloc ) が指定されていた。C++11では、動的例外指定は廃止予定になり、その意味も、単に例外を投げる可能性のある関数程度のものになったので、std::operator newが、std::bad_alloc以外の型を例外として投げる可能性が、規格上出てきた。そのための違い。

次回に続く。

2013-12-24

18日から24日までの日記

今回はかなり他人のプライバシーに土足で踏み込む内容なので、これでもかなり抑えて書いている。ここに記述された人で、問題があればboostcpp@gmail.comまで、あるいは私につながる方法で連絡をくれれば、すぐに該当箇所を削除する(が、削除しても遅いだろうから、先に謝っておく。申し訳ない。)

18日

早朝、卓球ハウスで起床。すぐに出発。

今回、東京には用事で呼ばれているのだが、せっかくだから一週間ほどは滞在することにした。

どういう結果になるにせよ、これ以上C++の啓蒙を続けるには、他人に物理的に会ってC++を教育しなければならず、そのためには、プログラマーのいる場所に行くしかない。一極集中の日本では、プログラマーのいる場所といえば、ほぼ東京しかないのだ。なにかいい仕事があればいいのだが。

そのために東京に住まねばならないが、東京に縁もゆかりもない人間が、いきなり住んだところで、孤立するに決まっている。吉田寮のような場所が東京にもあればいいのだが。

すると、プログラマーを含めた多種多様な人間が集まりそうなシェアハウスにでも住むのが一番手っ取り早いわけだ。

というわけで、この機会に東京のシェアハウスを見て回ることにした。そこで、珍しく色々と計画と事前の予約を行った。

ギークハウス水道橋

ここには、ブインの提督、銀天すばる (SubaruG)さんが住んでいる。あいにくと、部屋はぜんぶ埋まってしまったようだ。

知り合いがいたからか、中に入ることはできたものの、やはり事前の調査通り、今のギークハウス水道橋から、吉田寮的雰囲気は感じられない。至って普通の平和なシャアハウスに成り下がってしまっている。これが普通なのだが、少し寂しい。当時から残っているという住人に昔の話を振ってみたが、昔は昔だったというだけで、とくに話したがらないようだ。全員働いているので、午前中のかなり早い時間に人はいなくなってしまった。すばる君の紹介があったからか、クッキークリッカー記事でブログが知られていたからか、「誰もいないけれどごゆっくり」とは言われたが、本当に誰もいないし、いてもどうしようもない平和で退屈な場所なので、すぐに次の場所に向かった。

ギークハウス文京護国寺

ギー水の崩壊に寂しさを覚えながら、私はギークハウス文京護国寺に着いた。ここは私から連絡したわけではなく、CyLydianの方から来てみないかと誘われたのだ。誘われた以上は行くのが礼儀というものだ。こちらは一転、すこし熊野寮のような感じがする。ただし、最近の熊野寮の閉鎖性も持ち合わせているようだ。ここは遊びに来るには面白そうだが、私の住むべき場所ではないように感じた。

ドワンゴ

先月の歌舞伎座tech#2で、ドワンゴに呼ばれて、C++14の新機能についての講演を行ったが、どうももう一度、今度は社内の講習会の講師として、C++の歴史について話してほしいということで、再び呼ばれた。

プログラミング言語の魔導書Vol.1で書いたように、私は以前からC++の歴史について興味があり、ひと通り調べている。基本的には、Bjarne Stroustrupの書いたHOPL-I, HOPL-II, D&Eが参考文献として使える。ただし、さすがに1990年代から2000年代前半にかけてのC++WG JPの事情はわからないため、この機会に、当時からC++標準化委員会に参加している人に色々と話を聞いた。それをまとめあげたのがこのスライドで、GitHubで公開している。

EzoeRyou/cpp-history

スライドでも書いたように、実に日本のC++事情は寒い。お寒い事情とは、すなわち、日本企業は独自のC++コンパイラーを社内の閉鎖的な環境で自作したかったが、それには技術力が足りないので、かわいそうな日本人でも実装できるC++のサブセット規格を作ろうとしていて、EC++の業界団体を立ち上げた。それがC++標準化委員会の日本支部と合流した。そのため、日本のC++標準化員会のスポンサーというのは、EC++という黒歴史のスポンサーだったわけだ。

当時のEC++関係者には気の毒だが、他ならぬBjarne Stroustrup本人にまでこう言われているのだ。

To the best of my knowledge EC++ is dead (2004), and if it isn't it ought to be.

私の知る限り、EC++は死んだ(2004年)、もし死んでいないとするならば、死ぬべきである。

Stroustrup: FAQ

もっとも、当事者によると、そういうわけではなくて、あくまで8-bit, 16-bit用のマイコンでも使えるC++のサブセット規格を策定したかったそうだ。

ただし、筆者はどうしても、まともなC++コンパイラーを自作できず(不自由ソフトウェアにこだわる以上必然なのだが)、だから日本人でも実装できる手抜きC++を作りたかったのではないかと邪推してしまう。

卓球ハウス

18日も一泊させてもらった。

さて、昨日今日と泊まっているこの卓球ハウスは、シェアハウスをやってみたい男たちが立ち上げた。狙ったわけではないものの、全員Web系のプログラマーだ。彼らはシェアハウスをギークハウスの混沌とした雰囲気にはしたくなかったらしく、まず、名前をギークハウスとはしなかった。曰く、「どうしても一度来てみたいという人がいれば拒むわけでないけれども、ギークハウスとは違い、平和にやりたい」とのことだ。そこで卓球ハウスと名づけた。名前が卓球ハウスなので、卓球台を調達した。その住所や住人は、Twitterなどの公の場で発言しているので、ここに書いても特に問題はないが、特に書くまでもない。

ただし、卓球ハウスは家の作りが豪華すぎるということだけは記しておいても問題にならないだろう。

卓球ハウスは普通の平和なシェアハウスだが、住人が全員プログラマーだけに、住んでみたくはある。

19日

卓球ハウスで起床、phaさんの住むところに向かう。

phaさんの住むところ

pha (pha)さんとは、ギークハウスの発起人だ。phaさんは元熊野寮生で、熊野寮の雰囲気を持つようなシェアハウス、すなわちギークハウスを立ち上げた。ギークハウスという概念は、もはや自治療も存在しない東京には新鮮だったらしく、だいぶ流行した。phaさん以外の人が、ギークハウスを名乗って、似たような性格のシェアハウスを建ち上げるようになった。ただし、他の人によって立ち上げられたギークハウスは、吉田寮や熊野寮を経験していない人によるものも多く、少し性格が異なっている。phaさん自体は、今は賑やかな生活にも嫌気が差し、静かな環境で暮らしている。結局、今のphaさんの住むところは、熊野寮の性格を表しているのではないかと思う。熊野寮と吉田寮は違うのだ。

phaさんの住むところは、今は少しネット上からは見つけにくい情報だ。詳細な住所は公開していない。厳格に隠している様子ではないとはいえ、積極的に公開もしていないようなので、ここではあえて具体的には書かないでおく。

phaさんの住むところには人懐っこい猫がいてとても和んだ。ただし、膝の上で眠りだすので動けなくなるのが、嬉しい悩みといったところか。

phaさんの住むところは、あまりにも静かすぎる。特に猫がいるので、それも人懐っこい猫がいるので、人懐っこくなくても猫がいるので、たまに遊びに来たいが、私の住むべき場所ではないように思う。

20日は、phaさんの住むところに一泊させてもらった。

20日

起床、猫が可愛い。ねこー、ねこー、ぬこー、ぬこー、ふぁぁぁ

ハッ、いかんいかん、これはまずい。いつまでも猫とたわむれていたいが、私は東京の滞在中に、なるべく多くのシェアハウスを見学して、住めそうなところを探さねばならないのだ。

私は吉田寮に入り浸っているので、必然的に気になるのは、妖怪ハウスだ。これは、吉田寮的雰囲気が崩壊して、今や退屈で平和な普通のシェアハウスに成り下がってしまった、ギークハウス水道橋に、崩壊前まで住んでいて、しかも元吉田寮生の平田朋義 (tomo3141592653)さんが、新たに吉田寮的雰囲気を構築するために立ち上げたシェアハウスだ。

ただし、私は20日には、ギークハウス秋葉原の見学も兼ねて、飲み会に出席しようと連絡していた。東京にいつまで滞在するかというのも問題だ。週末には帰ろうかと思っている。ここはギークハウス秋葉原には断りの連絡をいれて、最後に妖怪ハウスに行ってみようかと、平田さんに連絡を取ってみたところ、なんと、平田さんもギークハウス秋葉原の飲み会に出席するという。都合がいいので、今日はギークハウス秋葉原に行くことにした。

ギークハウス秋葉原

この場所に案内なしで地図だけをみて辿り着くのは不可能である。神田駅から5分というとても近い場所にあるのだが、絶対に案内なしにたどり着くことはできない。

ギークハウス秋葉原は、とても便利な場所にあるが、まだ始まったばかりで、今は住人が少ない。ただ、とても便利な場所ではあるので、住んでみたいとは思った。

さて、飲み会では様々な人が集まった。平田さんも来たので、近日中に妖怪ハウスに伺うということを伝えた。

平田さんは、飲み会を途中で抜けだしてクラブに行くという。私も誘われたが、私はクラブの喧騒は嫌いなので、やめておいた。私は音楽にもダンスにも興味はない。仮に聞くとしても、静かな音楽を聞きたいものだ。ただ騒がしいだけでは騒音でしかない。しかも、聞くところによれば、クラブはニコチン中毒者の巣窟であり、したがって常に忌まわしき煙が充満しているという。「誘われた以上、行くのが礼儀」とは書いたが、そんなドラクエで言えば毒の沼のような場所には行きたくない。ましてや、東京で住めそうなところを探すことには直接関係ない。

ただし、クラブには多種多様な人間が集まるであろうことは確かで、もし、静かで過密しておらず禁煙なクラブがあれば行ってみたい気はする。

さて、その後、Hanabiというカードゲームをした。このゲームは、全員で協力して花火を完成させるゲームだ。競争ではない。ただし、自分の手札は見ることができないので、他人に自分の手札の情報を教えてもらわなければならない。このゲームは、とても面白かった。競争させずに、ここまで面白いゲームが設計できるとは、フランス人もなかなかやるではないか。このゲームはいずれ買おう。

20日はギークハウス秋葉原に泊まった。

21日

卓球ハウスでカタンを行った。同日宿泊。

22日

起床。妖怪ハウスに向かう。

妖怪ハウスは、元吉田寮生の平田さんが、吉田寮を再現すべく努力しているだけあって、だいぶ吉田寮に近かった。ここはとても居心地がいい。住人のうち、プログラマーの割合こそ低いものの、ここに住んでいれば、多種多様な人と会うのに困ることはないだろう。

ただし、ここは吉田寮ではなく、平田ホスピタルである。

その肝心の平田さんは、今日はここにはいない。どうも、渋ハウスでイベントをやるらしく、そこに参加しているそうだ。渋ハウスもだいぶ開かれたシェアハウスであると聞いているので、多種多様な人と会えるのではないかと思う。ただし、聞けばイベント会場は、よその場所を貸しきって行うらしく、渋ハウスではないそうだ。東京で住める場所を探すという目的からは外れるので、行くのはやめた。

渋ハウスにも行ってみたいが、どうも聞けば、美術、芸術系の住人ばかりで、プログラマーはほとんどいないらしい。実際に現地を見ていない以上、まだわからないが、おそらく私が住むには適さないのではないだろうか。

22日は妖怪ハウスに泊まった。

23-24日

当初の予定では、週末頃に帰るはずだったが、妖怪ハウスの居心地がいいのと、年末に吉田寮に一週間ほど滞在してみたいという学生がいるので、案内がてら同道して京都に帰るため、もう少し東京に滞在することにした。

この妖怪ハウスには、将来的には住んでみたいと思うので、とりあえず住人に受け入れられるかどうかをみるために、今週もまだ何日か滞在しようと思う。あるいは、まだ行っていないシェアハウスを見学してみるべきか。

年末には帰る予定だ。

GNU/LinuxでMac OSのバイナリを動かす互換レイヤーの開発が停滞

[Phoronix] Hope Seems Lost In Running OS X Binaries On Linux

以前、本の虫: Mac OS XのバイナリをGNU/Linuxで実行するソフトウェアで取り上げた、Darlingという、Mac OSのバイナリをGNU/Linuxで実行する互換レイヤーだが、どうやらここ数ヶ月ほど、何の活動もないらしい。主要な開発者も去り、どうやら死んだようだ。

Wineもそうだが、この手の互換レイヤーは、あまり好ましくない。なぜならば、バイナリのみで提供される不自由なソフトウェアの実行を容易にしてしまうからだ。まだ盲目的にWindowsを使っていた頃は、Wineについて詳しく調べていたのだが、その知識は、未だに役立っていない。結局、Windowsでどうしても動かしたいソフトウェアなど、ゲームぐらいしかないのだ。その肝心のゲームも、いまはまるでつまらないときている。もはやWindowsの時代は終わったのだ。

xkcd: 永続性

xkcd: Permanence

[!] ネットワーク設定

システムのホスト名を入力してください

妻「ずっとその画面眺めてるわね」
夫「いいサーバー名を決定するのは大事なんだ」

妻「でもうちの子の名前は15秒ぐらいで「キャロライネ」に決めたじゃない」
夫「でも、これはサーバーだぞ!」
夫「それに、あのままほっとくと、お前「コーマクガイ」とか名づけそうだったじゃないか」
妻「あら、いい麻酔じゃない」

ホスト名は人の名前より変更するのが難しい。

テンプレートの実体化の実装方法とODR違反について

問題

以下のC++コードを考える。

int plus( int a, int b )
{
    return a + b ;
}

double plus( double a, double b )
{
    return a + b ;
}

このC++コードは、int型とdouble型以外、コードはほぼ同じである。

しかし、ほとんどのコンピューターではint型とdouble型は操作方法が異なるため、この2つの関数は、全く別のコンピューターが処理できるコードに変換される。

ところで、古典的なC言語やC++コンパイラーの実装方法として、ソースコードのファイルをそれぞれ、一つ一つの翻訳単位としてコンパイルし、翻訳単位ごとにオブジェクトファイルを生成し、リンカーで複数のオブジェクトファイルを結合(リンク)して、単一のプログラムを生成するというものがある。

よくある実装では、オブジェクトファイルは、その翻訳単位では定義されていないの関数や変数などを、その名前を「シンボル名」として、未解決のまま参照しておき、リンカーがすべてのオブジェクトファイルが揃った時点で解決する。

// f.cpp

// 定義
void f() { }
// main.cpp

// 宣言
void f() ;

int main()
{
    f() ; // fは定義されていない
}

C++規格では、単にソースファイルとか翻訳単位とか、複数の翻訳単位を合わせて単一のプログラムにするなどと規定されているだけでが、典型的な実装では、このようなソースファイルを分けて、別々にコンパイルして、オブジェクトファイルを生成し、後でリンクして単一のプログラムにすることを、俗に、「分割コンパイル」と呼んでいる。

またC++では、仮引数の型が違うが同じ名前の関数を、複数定義できる。そして、呼び出す際に、型の一致度の優先度を判定して、最適なものを呼び出す。これをオーバーロード解決(Overload resolution)という。

// 別の翻訳単位で定義されている
void f( int x ) ; // #1
void f( double x ) ; // $2

int main()
{
    f( 0 ) ; // オーバーロード解決、#1
    f( 0.0 ) ; // オーバーロード解決、#2
}

しかし、これは古典的なコンパイルしてリンクという実装では、どのように実現すればいいのだろうか。どちらも同じ名前である。

C++の典型的な実装では、シンボル名に関数のシグネチャを埋め込む。これを、名前マングリング(name mangling)という。

// 名前マングリングの例
void f_int_( int x ) ;
void f_double_( double x ) ; 

int main()
{
    // オーバーロード解決済み
    f_int_( 0 ) ;
    f_double_( 0.0 ) ;
}

このように、シンボル名にシグネチャを埋め込んでしまえば、賢くない古典的なリンカーでも、単にシンボル名の一致だけでリンクできる。C++では、名前マングリングの詳細は規定されていない。シンボル名が規定されていないのと同じだ。

さて、テンプレートの場合はどうか。

template < typename T >
T plus( T a, T b )
{
    return a + b ;
}

int main()
{
    f( 1, 2 ) ;
    f( 1.0, 2.0 ) ;
}

関数テンプレートは、実引数推定(Argument Deduction)という機能により、テンプレート実引数を推定できる。これはつまり、以下のように呼ぶのと同じ意味である。

int main()
{
    f<int>( 1, 2 ) ;
    f<double>( 1.0, 2.0 ) ;
}

テンプレート実引数は、< >という文法で指定する。関数の実引数が( )という文法で指定することと比較すれば、わかりやすいだろう。

テンプレート自体は、オブジェクトコードを生成しない。テンプレートは、コンパイル時に具体的なテンプレート実引数を与えられて、その実引数に対して、実体化する。テンプレートが実体化すると、あたかもコードを手で書いたかのように、実態が生成されて、使われる。もちろん、これにも名前マングリングが使われる。

さて、テンプレートも分割コンパイルしたいと思うだろうが・・・残念ながら、実装上の都合で、色々と難しいのだ。

テンプレートは、コンパイル時に実体化する必要がある。しかし、翻訳単位ごとに分割されていると、その実体化ができないのだ。

// plus.cpp

// 定義
template < typename T >
T plus ( T a, T b )
{
    return a + b ;
}
// main.cpp

// 宣言
template < typename T >
T plus( T a, T b ) ;


int main()
{
    plus( 1, 1 ) ; // 実体化の生成が必要
}

今、plus.cpp、main.cppが、それぞれ別の翻訳単位であるとする。main.cppは、テンプレートplusの宣言から、テンプレートを実体化しなければならない。しかし、実体化するには、テンプレートの定義が必要だ。

実装方法

翻訳単位を超えたテンプレートの実体化を、どのように実装するかというのは、とても難しい問題だ。とくに、古典的な翻訳単位ごとにコンパイルしてリンクするというコンパイラーの場合、翻訳単位ごとに完全な定義が与えられていなければ、コードの実体化ができないという問題がある。

CFrontの実装

Bjarne StroustrupによるC++のリファレンス実装は、Cコードを出力して、Cコンパイラーでコンパイルする都合上、当時の古典的なコンパイラー技術で実装する必要があった。

名前マングリングは、そのために考案された。古典的なリンカーは、単にシンボル名の文字列一致だけをみてリンクするので、シンボル名にテンプレート実引数を埋め込んでおけば、その実体化へのリンクができる。

CFrontの実装は以下の通り

  • シンボルに名前マングリングする
  • テンプレートを実体化せずにコンパイル
  • 実体化していないために発生するリンクエラーメッセージをパース
  • 実体化の必要のあるテンプレートの特殊化を抽出
  • テンプレートの実体化を行う

この処理は、リンクエラーを吐かなくなるまで、繰り返し実行する必要がある、なぜならば、テンプレートを実体化した結果、別のテンプレートの実体化が必要になるからだ。

template < typename T >
struct A { } ;

template < typename T >
struct B
{
    A<T> a ;
} ;

CFrontの、リンクエラーを用いたテンプレートの実体化の実装は、とてつもなく遅かった。ある大学は、他の方法で実装されたコンパイラーならば数時間でコンパイルできるコードが、CFrontでは一週間もかかると報告した。

SunのC++コンパイラーの実装

SunのC++コンパイラーは、いかにもSunらしい実装をしている。

  • プログラムを構成するすべての翻訳単位で共通のデータベースを用意
  • ある翻訳単位でテンプレートの実体化が必要ならば、データベースを参照
  • もし、すでに最新版の実体化が存在すればそのまま利用
  • もし、データベースに実体化が存在しなかったり、最新のソースコードより古く生成されたものであれば、実体化してデータベースに格納

いかにもSunらしいデータベースを活用した実装だ。この実装は、技術的には極めて自然であり、並列コンパイルによるコンパイル時間のスケールも特に問題はない。

問題といえば、実装が難しいことと、Makefileのような単純にファイルスタンプだけ比較するような古典的なビルドシステムを使うのが難しいということだ。

BorlandのC++コンパイラーの実装

この中で、彗星の如く現れたのがBorlandのC++コンパイラーだ。

  • テンプレートの定義をヘッダーファイルに書く
  • テンプレートの実体化を必要とするすべての翻訳単位から#include
  • 翻訳単位ごとに独立してテンプレートを実体化
  • リンク時に重複を取り除く

この実装では、リンカーが単にシンボル名の一致で参照を解決するものから、重複を取り除くということまでやるようになったので、古典的なリンカーとは言えないかも知れない。しかし、当時もリンカーはすでに相当複雑になっていたわけだ。

どうせリンク時に重複を取り除かれるのに、同じテンプレートを翻訳単位ごとに実体化するのは、一見すると非効率的のように思われるが、パフォーマンスは全く問題なかった。

そして何よりも、実装が簡単だった。

しかし問題になるのは、ODR(One Definition Rule)[§3.2]だ。単一定義の原則だ。C++では、定義はひとつしか存在できないのだ。

// file1.cpp

template < typename T >
struct S { } ;
// file2.cpp

// 定義の重複
template < typename T >
struct S { } ;

int main()
{
    S<int> s ;
}

いま、file1.cppとfile2.cppがひとつのプログラムを構成するソースファイルであり、ソースファイルごとに翻訳単位が存在するとすると、当時のドラフト規格では、このコードは違法となる。

Borlandが最初に考えだしたこの実装方法を、規格上許容すべきかどうかは、標準化委員会でもかなり揉めた。ある者は、Borlandの実装方法はODRに明確に違反しており、本質的に汚いので、規格で禁止すべきだと主張した。また、この実装では、テンプレート定義はすべてヘッダーファイルに書いて、ソースファイルに字句的に取り込まなければならない。非テンプレートコードのように、宣言と定義を分けることができない。実体化を必要とするテンプレートであっても、宣言と定義を分けられるべきだという主張もされた。

とはいえ、Borland式の実装はとても実装が簡単で、多くのC++コンパイラーがBorland式の実装を使い始めた。そのため、さすがに現実を無視することもできず、規格で特別に、主にテンプレートに限り、別の翻訳単位に現れるまったく同じトークン列、全く同じ意味の定義を、特別にODR違反から除外することを許可した[§3.2 paragraph 6](実際にはもっと複雑に規定されている)

全く同じトークン列を保証するには、ヘッダーファイルとして書いて、#includeで取り込めばよい。まったく同じ意味とは、テンプレートの特殊化で呼び出す関数などが、テンプレートの実体化やオーバーロード解決を経た後でも、すべての翻訳単位で、同じでなければならない。

// file1.cpp

void f( int ) { }

// 同じトークン列
template < typename T >
void g()
{
    f( 0 ) ;
}
// file2.cpp

void f( long ) { }

// 同じトークン列
tempalate < typename T >
void g()
{
    f( 0 ) ;
}

このような複数の翻訳単位からなるプログラムは、違法である。

先週、この問題を解説する必要があったが、なかなかこのような問題は口頭で解説するのが難しく、おそらく正しく理解してもらえなかったと思うので、ブログに書いておくことにした。

実は、これと似たような歴史的経緯を、株式会社ロングゲート - プログラミングの魔導書 ~Programmers’ Grimoire~ vol.1で書いた「C++の歴史」でも解説している。そういえば、私は魔導書のVol.3には関わっていない。今回、C++色は薄かったようだ。Vol.4はどうなるのだろうか。

ミハイル・カラシニコフ死去

BBC News - AK47 assault rifle designer Kalashnikov dies at 94

AK-47として知られている7.62mm小銃を設計した、Михаил Тимофеевич Калашников(ミハイル・チモフェエヴィチ・カラシニコフ)が、94歳で亡くなった。

アラン・チューリングに恩赦

BBC News - Royal pardon for codebreaker Alan Turing

1952年、ホモセクシャリティ罪で検挙され、保護観察下におかれ、しかも化学的去勢を行われた、暗号解読者にして、コンピューター科学にも多大な貢献をしたアラン・チューリングに対し、ホモセクシャリティ罪に対する恩赦が与えられた。

あまりにも遅すぎる。

2013-12-23

人との再会は難しい

今、筆者は東京にいる。東京は、人の集まる場所である。実に、大勢の人間が地方からやってくる。

結局、一極集中は効率的なのだろう。それに、地方には仕事がない。

ということは、田舎に住んでいた頃の私の昔の同級生は、東京に住んでいる可能性があるわけだ。

せっかく東京に滞在しているのだから、そのような昔の同級生だった者と再会し、つもる話をもし、成功したのか失敗したのか、近況を聞きたいものだ。

筆者はすでに、京都に住んでいて、昔の友人と再会したことがあるのだ。それは友人側からこのブログをみて連絡が来た。

実は、ネット上で検索した結果、そういう人間が一人だけ、少なくとも去年は東京で働いていたらしい。特別に仲が良かったわけではないが、当時、同じ町内に唯一住んでいた同級生なので、印象には残っている。

ただし、連絡方法がない。いや、あるにはある。実家に紙の手紙を送るという方法がある。しかし、そこまでして会いたいかというと、なかなか難しい。

その同級生が女であることも、連絡を躊躇させる要因となっている。

2013-12-22

アニメにおけるセルシェーディングの利用について

セルシェーディング技術は、非常に発達している。3Dモデルを描画する際、あえて似通った領域を単色で塗りつぶすようにするのが、極端な簡略化した説明だが、とにかく、いかにも3DCGという奇妙な違和感を消し、まるでアニメ塗りのような描画ができる。

ゲームでは、セルシェーディングはよく使われている。例えば、不自由なゲームだが、最近のゼルダの伝説や、Borderlandsといったゲームだ。

では、アニメではどうなのか。実は、意外と積極的には使われていない。

たとえば、プリキュアというアニメでは、エンディングの映像に、セルシェーディングが使われている。非常に高品質で、しかもヌルヌル動く。プリキュア本編はまったくつまらないのだが、、エンディングだけはとても面白い。しかし、本編には、ごく一部の、動きの激しいシーンなどにしか使われていないという。しかも、手で修正を加えた上、フレームも極端に間引いているという。しかし、現に修正をくわえずともそれなりの品質になっているではないか。なぜフレームを間引かずに、大規模な手動の修正も行わずに、そのまま使わないのか。

なぜだ。なぜ手動風の劣化を加える必要があるのだ。なぜぬるぬる動くアニメにしないのだ。

プリキュアを見ていると、明らかに全面的に手で書かれた場所が出てきて、そのような場所は、フレーム単位でみると、とても作画品質の低いことがある。これは、俗に「作画崩壊」と呼ばれている。それに、肝心のアニメーション自体も貧弱だ。しかし、セルシェーディングならば、常に一定した品質を提供できるではないか。なぜセルシェーディングにしないのか。

ある者曰く、ぎこちないアニメーションのほうがむしろ自然なのだという。しかし、トムとジェリーは、ヌルヌルと動くアニメーションで、それでいて最高に面白いではないか。

多くのアニメでは、徒手格闘が出てくる。そういうシーンを、ぬるぬる動くアニメーションに、なぜしないのか。映画マトリックスのようなものがある以上、そこそこの品質でぬるぬる動くアニメーションのほうが素晴らしいと思うのだ。手動で描くと、作画は悪いはアニメーションは悪いはと、劣化でしかないと思うのだ。

あるいは、映画は24 Frame Per Secondで撮影しないと、映画らしくならないという話と似たようなものなのだろうか。つまり、我々が、映画なら24FPS、アニメなら作画崩壊貧弱アニメーションに慣れてしまっているので、あまりにも高品質すぎる物を見せられると、違和感が生ずるのだろうか。

しかし、現に私は、プリキュアに関しては、本編の人の手による悲惨な劣化作画と見るに耐えない劣化アニメーションよりも、、エンディングのセルシェーディングされてヌルヌル動く映像のほうが、圧倒的に高品質であると感じる。圧倒的に魅力がある。もし本編がこのように作られていたならば、ぜひとも見たいと思う。現に、プリキュア本編は見るに耐えない内容であったが、エンディングの映像だけは食い入るように眺めてしまった。なかなか悪くないセルシェーディングだからだ。

あるいは、人の手で描かれたものを尊ぶ風潮でもあるのだろうか。しかし、それならばもっと抽象的で極端なデフォルメの絵にすればいいわけで、プリキュアはまだその抽象度とデフォルメ度が十分ではない。それよりは、セルシェーディング技法に技術的観点から興奮すべきではないのか。

もちろん、エンディングは繰り返しつわれる短時間の映像だから、セルシェーディングした後に、手動でフレームごとに修正を加えているのかも知れない。しかし、私は近年のセルシェーディング技法の発達を知っている。もちろん、セルシェーディングもそのようなシェーダーを書くのは職人技だが、フレームごとにひたすら手動でやるよりも、よほど筋のいい職人技だ。一度素晴らしいシェーダーを書けば、それにより全体が向上する。

そういう意味では、アニメは完全にセルシェーディングにして、ビルドして映像生成という形にすべきではないのか。すなわち、ソフトウェアだ。ソフトウェアである以上、自由ソフトウェアにすべきだ。そうすれば、稚拙な3Dメッシュが直されたり、シェーダーが改良されたりするのではないか。

いい加減に人の手で努力しただけのものを評価するのは、やめようではないか。もはや、写実画は写真に負けている。人間がまだ優位に立てると安心しているデフォルメの世界だって、例えばアニメ塗りのようなものは、セルシェーディングで近似できる。セルシェーディング技法は今後もますます発展することに疑いはなく、人間の優位性はいよいよ危うい。

将来は、ピカソのような絵や、デフォルメ化された3Dメッシュなども、自動的に生成できるようになるだろう。

私の観測できる範囲では、プログラマーとアニメの親和性は高い。私はアニメが好きではないから、これは不思議なことだ。私には、なぜ彼らがアニメを尊ぶのか、理解できない。現行のアニメが、単に人の手による単純作業で作られている。アニメ制作者が安く買い叩かれているのは、やはり、ある程度の画力があれば、代わりはいくらでもいるような単純作業だからだろう。

変えようではないか。現状を。アニメは技術者が作ればいいのだ。作画は3Dメッシュに取って代わられる。塗りはセルシェーディングに取って変わられる。高品質な3Dメッシュを作成するのは困難だが、一度作成してしまえば、後はアニメーションを作ればどのようなシーンもアニメーションできる。破綻しない自然な塗りをシェーダー言語で記述するのは困難だが、一度書いてしまえば、後はどのようなシーンでもレンダリングできる。

怠惰は美徳である。機械的な作業は機械に任せようではないか。もし、ある手動作業が自動化できるとするならば、我々はむしろ自動化するための準備に労力を注ぐべきなのだ。そうすれば、後は全て自動化される。我々人間は、機械を作るべきなのだ。その身を機械におとしめてはならない。

なるほど、私がアニメを好まない理由が、今にしてわかった。アニメは手動の単純作業だから感動しないのだ。そして、その映像の描画方法、すなわちソースコードが公開されていないから嫌悪するのだ。ああ、残念ながら、この考え方はあまりにも先進的すぎる。おそらく、数百年は理解されないことだろう。

ただし、2013年にこのような考えを持つ進んだ一個の人間がいたということは、ここに記しておく。

2013-12-21

Google、Chrome Web Storeから多目的の拡張を禁止する

GoogleはChromium Blogで、Chrome Web Storeから、複数の目的を有する拡張を禁止する発表を出した。

Chromium Blog: Keeping Chrome Extensions Simple

本日、我々はChrome Web Storeポリシーの変更を告知する。Chrome Web Storeの・拡張は、必ず、狭く簡単に理解できる単一の目的を有さなければならない。これはChrome拡張システムの意図であるが、すべての拡張はこの理想に従っていない。奴ら、多目的拡張(mutli-purpose extensions)は、ブラウザーのUIをごちゃごちゃとさせ、Webブラウジングを愚鈍にし、時には悲惨なことになる。我々はこの問題を修正し、ユーザーにブラウザーの支配力を与えるために、今回のポリシー変更を行った。

簡潔で高速なブラウジング体験は、Chromeのはじめからの、基本理念である。簡潔性は我々にとって重要なことで、その理由は、ブラウザーはとても複雑になり、重量級のユーザーインターフェース(俗に"chrome"(ブリキ化)と呼ばれている)を持っているからだ。この複雑なUIは、ブラウザーのそもそもの存在理由である、ページ内のコンテンツから注意を空してしまう。"Chrome"という名前は、我々は「コンテンツ」に注力したいというこの理念からきている。

現在、ブラウザーの重量化に強力に貢献しているのは、万能ツールバーのような拡張だ。ユーザーが複数のそのようなツールバーをインストールした結果は、悲惨なものになる。

我々の簡潔性の理念を維持するため、我々は異なるアプローチをとることを決定した。Chrome拡張は自然に簡潔で単一の目的用になり、単一のbrowser actionか単一のpage actionという、単一の可視UI「サーフェイス」しかサポートされない。ツールバーは設計上サポートされず、ユーザーはこれによりブラウザーに追加する機能について一層のコントロールを得ることとなる。

残念ながら、一部で、このような設計を技術的に矯正できない。 content scriptにより、拡張の開発者はページに対する完全なコントロールを得、結果として、どんなUIでも実現できる。たとえ、ツールバーをページに作成するような機能であったとしてもだ。他には、content scriptを使って、多数の機能がごちゃまぜになったような、どのような拡張とも分類しがたいものをつくりだす。多くの場合、Chrome Web Storeは、ある拡張が変な挙動をしていることを、低評価により示しているが、そうでもない場合もある。

なお悪いことに、拡張がローカルのコンピューターに、間接的に読み込まれた時(たとえば、他のインストールしたソフトウェアに同梱されていたなど)、ユーザーはChrome Web Storeの恩恵を受けることができない、そのため、望まない機能や低評価の拡張のインストールにユーザーが同意したことに気が付かないことがある。

このため、当初の単一目的の設計を強制させるため、Chrome Web Storeのポリシーを変更した。我々は、これにより既存の拡張に大きな変更が必要になることを承知している。一部の拡張は、複数の拡張に分離する必要があるだろう。開発者は、我々が追加した、拡張への送金方法を簡単にする方法に変えて、別の方法による課金方法に切り替えないといけないだろう。これらの変更には実装に少し時間がかかるため、2014年6月まで強制を見送る。新しい拡張については、このポリシーは直ちに適用される。

Googleもだいぶ邪悪になってきたようだ。ある拡張がどう実装されようとどうでもいいわけで、これはユーザーにコントロールを与えるなどというのは詐欺もいいところだ。問題の本質は、Windowsにまともなパッケージマネージャーがないことに起因すると思うのだが。

Google announces ban on "multi-purpose" Chrome extensions | ZDNet

Google announces ban on "multi-purpose" Chrome extensions | Hacker News

2013-12-19

2013年12月16日から17日の日記

16日

いつも通り、吉田寮で起床。最近、私は吉田寮に入り浸っている。吉田寮は人を選ぶが、私にとっては、とても居心地のいい空間なのだ。

今日は、はてなのセミナールームを借りて、勉強会を行う。また、狂える中3女子ボレロ村上さんを案内しなければならない。ひとまず自宅に戻って身支度をした。

午前中は、修理に出していたJ-PRESSのダッフルコートを取りに行った。これから一週間ほど東京に行くので、なにかまともなコートがほしいと思っていたのだ。実家には、父親があまり着ていない昔のコートがある。もう30年ほど前に、当時7,8万で買った、いいコートだ。今は、もはやこんないいコートは金を出しても買うことができないという。何でも、復刻版があるそうだが、父親いわく、どうも劣化しているとのことだ。合皮のような革で、水牛のツノもまるでプラスチックのような見た目だという。

このダッフルコートは、生地の端を布で覆っているのだが、その布がボロボロになってしまっている。私はそれでもいいと思うのだが、父はこだわる人間で、着るならばと修理に出すことにしたのだった。

ただし、これを修理するには、一度服をバラバラにして、再び縫い合わせなければならない。技術的には可能なのだが、とても手間がかかる作業だ。材料費こそ三千円程度なのだが、あまりにも手間がかかるため、結局3万円ほどかかってしまった。三万あれば、普通のコートは買えるだろう。しかし、このコートは買えない。このコートは三万出してまで治す価値のあるコートだ。

王将で餃子を食べて家に帰ってみると、なんと、ボレロ村上さんが、予定より早く、すでに京都駅に着いているという。私は急いで京都駅に向かった

聞説、ボレロ村上さんは長髪で作務衣を着用しているという。京都駅でそのような人物を探すが見つからない。はて、どうしたものか。携帯電話を持たない私にとって、唯一の通信手段はラップトップとモバイルWiFiルーターだ。そのような大掛かりな通信装置を広げるのは面倒だが、見つからない以上、やるしかない。と、そう思いかけた瞬間、とても筋骨たくましい男が声をかけてきた。なるほど、最近の中3女子はだいぶ屈強な体格をしているのだな。長髪ではあるものの、作務衣ではない。まあ、今の季節に作務衣はいかにも寒すぎる。

我々はバスに乗って吉田寮へと向かった。吉田寮は人を選ぶ場所である。果たしてボレロ村上さんは吉田寮を受け入れることができるのか、それは気がかりではあったが、この漢であれば、問題はないだろう。

さて吉田寮に到着し、暖房の入った部屋に通したボレロ村上氏は、おもむろに外套を脱ぎ始めた。するとみよ、なんと氏は、外套の下に作務衣を着ているではないか。今にして筆者は、氏の陶芸家としての姿を目にしたのだ。

さて、しばらく吉田寮でだらだらと過ごし、たこ焼きを食べた後、我々ははてなのセミナールームに向かった。そして、C++の勉強会を開催した。

勉強会というものは、今、とても流行している。筆者もC++の啓蒙活動をしている身で、過去に二回、勉強会で発表したので、やはりここは、勉強会を主催してみるべきだと考えたのだ。

結論だけ書くと、勉強会を個人で開催するのはとても難しい。今回は、はてなが場所と人を提供してくれたので、便利にもUstreamによる配信付きの勉強会を開くことができたが、長期的には色々と工夫しなければならない。

詳しい内容については、以前の記事を参照してほしい(もちろん、すでに終わった勉強会であるので、申し込みはできない)

本の虫: 江添とボレロ村上の京都C++勉強会、開催の告知と参加者募集のお知らせ

本の虫: 江添とボレロ村上の京都C++勉強会のスライド資料

本の虫: 江添とボレロ村上の京都C++勉強会を終えて

さて、勉強会を終えて、ボレロさんを囲んで吉田寮で鍋をつつくことにした。ボレロさんは吉田寮との親和性が高く、初日にコタツで寝るという離れ業を披露してみせた。

17日

吉田寮で起床、というか昼ごろまで雑談

ボレロ村上さんは、本当に吉田寮との親和性が高く、我々が大声で雑談している中、ぐっすりと熟睡していた。なかなかに常人のできることではない。

その日の雑談はとても面白く、もっと話していたかったのだが、残念ながら私は用事があるので、昼ごろに抜けて、身支度をし、夕方過ぎに東京へと向かった。

明日は朝早くから色々と用事があるので、その日は早めに就寝。

続く

Ubuntu 14.04がTRIMをデフォルトで有効にする

[Phoronix] Ubuntu 14.04 Finally Enables SSD TRIM By Default

Ubuntu 14.04が、SSDのTRIMをデフォルトで有効にするそうだ。

Linuxカーネルは2.6.33からTRIMをサポートしているが、これを有効にするには、discardマウントオプションを指定する必要がある。Ubuntuは、デフォルトでこのマウントオプションを有効にしていなかった。

「十分なテスト」の結果、Ubuntu 14.04では、TRIMをデフォルトで有効にする決定がなされた。

2013-12-17

clang_completeのvimプラグインの開発が停滞中

Clang_completeという、Clangを使ったCファミリー言語の静的解析ツールがある。これは、Clangの素晴らしいフロントエンドをそのまま使い、高度で規格準拠な名前補完機能を提供してくれるツールだ。

このclang_completeを、Vimという最高のテキストエディターから使えるようにするプラグインがある。

Rip-Rip/clang_complete

ところが、このプロジェクトは、最近開発が停滞しているようだ。例えば、以下のような簡単な修正のPull Requestすらマージされずに半年放置されている。

Fixup jumpToLocation loc.file is NoneType by visitor83 · Pull Request #336 · Rip-Rip/clang_complete

Silex commented

@xaizek: このプロジェクトの状況はどうなっているんだ? この程度のものはマージされるべきだろ。@Rip-Ripのアクティビティをみるに、最近は何もしていないみたいだな。

xaizek commented

@Rip-Ripのアクティビティは、この春からみてないな。たぶん、今はプロジェクトを保守する時間もないんじゃないか。

さて・・・いずれVimのプラグインの開発方法も学ばなければならないな。

江添とボレロ村上の京都C++勉強会を終えて

江添とボレロ村上の京都C++勉強会が、無事終了した。

今回の勉強会にあたって、一番苦労したのが、場所の確保である。勉強会を開催するには、数十人を格納できる場所がなければならない。さらに、単に場所だけでは不十分で、椅子、テーブル、プロジェクター、電源、無線LANが提供されていなければならない。

勉強会での発表には、スライドを映す必要があるので、プロジェクターは必須である。

さらに、聴衆もラップトップは使いたいであろうし、インターネットにも接続したいだろうから、電源と無線LANも提供されていなければならない。となると、椅子とテーブルも必要である。

勉強会の主催は相当に面倒だが、やはり、変化しなければならないと決めた以上、新しいことをやらなければならないのだ。

私は人前でスカスカのスライドを映して口頭で60分ほど話すことによる教育効果には疑問だ。まず、スライドというのはそれほどの情報量を含めることができない。たまに、アホなスーツが情報のぎっしり詰まったとても読みづらいスライド資料を使うことがあるが、あんなものは到底読めたものではない。それゆえ、スライドは自然とスカスカとなる。それに、口頭で使える情報は、とても伝達効率が悪い。まず、人間の話す速度は遅いという問題がある。それに、私は弁舌の徒ではない。

したがって、勉強会というのは、具体的な詳細を解説するのではなく、こういうものもあるという紹介程度の内容にならざるを得ない。ことC++においては、その情報さえ、日本語では不足しているということもあるだろうが。

とにかく、勉強会に使える場所を確保しなければならない。色々と探したあげく、京都駅の近くに、プロジェクターと電源と無線LANがついて、一時間三千円で借りられる部屋を見つけた。

京都の貸し会議室・レンタルスペース|ベーコンラボ

収容人数が、テーブルを出すと20人、椅子だけで最大38人ぐらいと、ちょっと狭いのだが、京都駅の近くなのでわかりやすいし、何より、プロジェクター、電源、無線LANの条件を満たす部屋というと、京都市内は本当に少ないのだ。

当初はベーコンラボを使おうと思っていたのだが、にわかに京大の教室を借りるとか、はてなのセミナールームを借りるなどという話が出てきた。

京大の教室は、土日も借りられるし、なにしろ大学の教室なのだから、プロジェクターと電源と無線LANはあるし、それに100人ぐらいが入れる大部屋もあるという点で、とてもすばらしいものだ。日本の大学機関はそういう立派な設備を持っていながら、なぜC++のような実用的な言語を教育できる人間がいないのか。理解に苦しむ。聞けば、京大では初年度にSICPをやり、二年目にC言語をやるのだそうだ。C言語! ああ、C++はC言語を改良し、なおかつC言語と同じシステムプログラミングを提供できるように設計されてきたというのに。

そして、さらにひどいことに、京大ではJavaのような一個の民間企業に独占された不自由で使いにくい言語を教育しているという。これはありえないことだ。C++にはそのような独占がないからこそ、安心して使えるのだ。しかも、Javaはその機能からして明後日の方向に向かっている。単にアルゴリズムやデータ構造を記述するために書きやすく、しかも実用的な言語というのであれば、今は便利な言語も多いというのに、なぜあのようなクソみたいな設計のJavaを選んでしまうのか。背景には、即戦力になる安い組み込みプログラマーを量産したいという業界の思惑があるらしい。情けないことだ。

はてなのセミナールームは、すこし条件が厳しい。プロジェクター、電源、無線LANこそ提供されているものの、椅子だけ並べて収容人数が40人(一応、机もあり、さる有名なCプリプロセッサーメタプログラマーは空気を読まずに使っていたが)、それも、土日はだめで平日の夜のみという、難しい条件だ。

平日の夜というのは、多くの職業プログラマーの参加を難しくしてしまう。それに、午後7時から始まる都合上、使える時間がせいぜい二時間ぐらいと短いので、そう何人も発表できない。

ただし、はてなのセミナールームには、この悪条件を吹き飛ばす、ある特別な設備が備わっている。Ustream配信のための設備だ。なんと、はてなは当日の勉強会をUstreamで配信してくれるという。

USTREAM: hatenatech

Ustreamとは、動画配信のためのプラットフォームで、閲覧者に不自由なFlash Playerを要求する邪悪なSaaSSである。そのため、一般的に言って、読者はUstreamを使うべきではない。

しかし、勉強会というのは所詮、物理的な場所で開催しなければならないわけで、場所をどこにしようとも、遠方であるために参加できない人間が出てくるものだ。開催日時を土日にしたところで、やはり物理的に己の肉体をその場所に持っていく都合のつかない人はいる。Ustreamのような閲覧に不自由ソフトウェアを要求するSaaSSは、紛れもなく悪であるが、この場合、もたらす善もゼロではないのではないか。

悩んだ挙句、今回は、はてなのセミナールームを借りて勉強会を行うことにした。

そして、講演者は、私ともう一人、コンパイル時プログラミングの権威、ボレロ村上に依頼した。当日の勉強会の動向は、近いうちに、日記として公開する。

将来的には、自分でカメラを用意して録画し、自由な動画、音声、コンテナーフォーマットで公開するべきだろう。ただし、そのためには私以外の撮影者が必要だ。それに、今回は初めて自分で主催する勉強会なので、そこまで手を広げることもできない。まず何としても、勉強会を計画し、場所の手配をし、告知して人を集め、発表して無難に終えるという、一連の仕事をこなさなければならないのだ。

少なくとも今回、積極的に新しいことをやり始めた結果、色々と可能性が広がってきた。京大の教室を借りての勉強会も、来年に行うよう調整中だ。現在の予定では、来年の春休み、つまり2月末から3月にかけての休日の昼間に、京大の教室を借りて勉強会を行うよう、調整中だ。内容は、今回のようにC++14の新機能でもいいし、あるいはなにか別のものでもいい。

さて、今回初めて、勉強会を主催した経験からいうと、勉強会を個人の力で開くのは色々と難しい。勉強会は最近の流行だが、実際に開催しようとすると、普通の営利活動では、到底正当化できないほどの費用と手間がかかる。私が今後もC++の啓蒙活動を続けるためには、どういう形であれ、私に金が入らなければならない。結局、私は霞を食べて深山に修行するわけにはいかないのだ。しかし、勉強会は、営利目的としてはいかにも無理だ。

やはり、さらなる劇的な変化が必要なのだろう。

2013-12-16

江添とボレロ村上の京都C++勉強会のスライド資料

今日の勉強会の、ボレロ村上さんの発表に使う資料が公開された。

すごい constexpr たのしくレイトレ!

江添によるスライド資料

C++14の新機能

まだ少し人数に余裕があるので、早いうちに参加申し込みをすれば、まだ間に合う。

江添とボレロ村上の京都C++勉強会 | 集客ならイベントアテンド

2013-12-15

xkcd: gitコミット

xkcd: Git Commit

  • メインループ作成&タイミング処理
  • 設定ファイルのパース有効化
  • 細かいバグ修正
  • コード追加/編集
  • もっとコード
  • それ、コード
  • ああああああああ
  • くぁwせdrftgyふじこlp;
  • なにか適当に入力
  • 手ーーーーーーー

プロジェクトが進むにつれて、俺のgitコミットメッセージが適当になっていく。

さもありなん。

xkcd What if?: 液体の水銀や臭素やガリウムやタングステンや窒素やヘリウムの上でボートをこぐとどうなるの?っと

エクストリーム・ボート

水銀の湖の上でボートをこぐとどうなるの? 臭素は? 液体ガリウムは? 液体タングステンは 液体窒素は? 液体ヘリウムは?

–Nicholas Aron

一つづつみていくことにしよう。

臭素と水銀は、室温で液体になる唯一の純粋な元素だ。

水銀の海の上でボートをこぐのは、おそらく可能だ。

水銀はとても密度が高いので、鋼鉄球すら水面に浮かぶほどだ。

ボートは浮きすぎて、水銀にあまり沈まないかも知れないので、パドルに体重をかけなければ水面下に棹させないかもしれない。

結論としては、ちょっと難しいかも知れないし、あまり早く焦げないかも知れないが、おそらく水銀上でボートをこぐのは可能だろう。

読者は水かけ合戦をしないほうがよい。

臭素は水とほぼ同じ密度を持っている。そのため、標準的な手こぎボートは、理論的には、浮かぶはずだ。

ただし、臭素は悲惨だ。まず第一に、臭いがひどい。臭素(bromine)という名前は、古代ギリシャ語の"brōmos"から来ていて、意味は「臭う」だ。それだけではなく、臭素は、多くの物質と激しく反応する。読者はアルミニウム製のボートを使うのはやめておいたほうがよい。

これでもまだやめる気にならないのであれば、臭素の物質安全データシートには以下の文面があることを記しておこう。

  • 深刻な火傷及びに潰瘍
  • 消化器官の穿孔
  • 永続的な角膜混濁
  • 空間識失調、不安感、失望感、筋肉協調運動不能、情緒不安定
  • 血を伴う下痢

読者は臭素の湖で水かけ合戦をしないほうがよい。

液体ガリウムは不思議な物質だ。ガリウムはバターのように、室温の少し上の温度で溶ける。手のひらの上で長時間保持することはできない。

それなりの密度はあるが、水銀ほどの密度はないので、ボートをこぐのは水銀よりは簡単だろう。

ただし、これも、アルミニウム製のボートはやめておいたほうが良い。なぜならば、アルミニウムは、その他の多くの金属と同じく、あたかもスポンジが水を吸い込むように、ガリウムを吸収してしまうからだ。ガリウムはアルミニウムの中に急激に広がり、その化学的特性を変えてしまう。変化したアルミニウムは、とても脆く、湿った紙のようにちぎることができる

水銀とガリウムに共通の性質で、アルミニウムを破壊してしまうのだ。

「ガリウムの湖でアルミニウムのボートを漕ぎだしちゃいけないよ」とは、筆者の婆ちゃんがよく言っていたことだ(筆者の祖母はすこし変わっていたのだ)

液体タングステンは難しい。

タングステンはどの元素よりも融点が高い。これはつまり、我々はその特性について、あまりよく知らないということである。特性を検証できない理由は、すこし馬鹿げたように思えるかも知れないが、液体タングステンを保持できる容器がないためである。並大抵の容器では、タングステンが溶けるより先に、容器を構成する物質が溶けてしまう。炭化タンタルハフニウムのようなごく一部の化合物のみが、わずかに高い融点を持つだけだ。ただ、そのような化合物で液体タングステン用の容器を作成できた者はいない。

液体タングステンがどのくらい熱いのかということを実感させるために、その具体的な融点の温度(3422℃)を書くということもできるが、以下のように説明したほうがわかりやすいだろう。

液体タングステンはあまりにも熱いため。もし溶岩に滴下したならば、溶岩はタングステンを凍らせてしまうのだ。

言うまでもなく、もし読者が液体タングステンの海にボートで漕ぎだしたならば、読者とボートは両方共、瞬時に発火炎上するだろう。

液体窒素はとても冷たい。

液体ヘリウムはさらに冷たいが、どちらも絶対零度に近く、南極の最低温度よりも下だ。そのため、ボートで漕ぎだす目的のためには、温度の違いは瑣末なものだ、。

液体窒素の安全性に関するDartmouth工業ページには、以下の文面が並ぶ

  • 有機物と激しく反応
  • 爆発する
  • 室内の酸素を減らす
  • 激しい着衣の炎上
  • 前兆なしの窒息

液体窒素は、水に近い密度を持っている。そのため、手こぎボートは浮かぶだろう。ただし、読者は長時間生存できないだろう。

もし、実験開始時点で、窒素の上の空気が室温であったならば、急速に冷却され、読者とボートは、空気が凝縮された濃い霧に覆われて窒息するだろう。(これは液体窒素をそそいだ時に発生する湯気と同じ効果である)。凝縮は凍結を引き起こし、読者をボートを急速に雪に埋もれさせるだろう。

暖かい空気は、窒素の表面を蒸発させる。これは湖面の酸素を減少させ、読者は窒息するだろう。

もし、空気(あるいは窒素)が、蒸発を防ぐほど十分に冷たいのであれば、読者は低体温症により、死亡するだろう。

液体ヘリウムはさらにひどい。

まず、液体ヘリウムは水の8分の1しか密度がないため、自重を支えるために、読者のボートは8倍の大きさを有していなければならない。

「俺らにはでっかい船が必要だ」
「まあでも、サメは問題にならんよな」

ただ、ヘリウムは厄介だ。もし、2度ケルビン以下に冷却された場合、超流動になる。これには不思議な特性がある。毛細管現象により、容器の壁を登り上がるのだ。

約秒速20cmほどで登るので、30秒以内に、ボートの底に液体ヘリウムがたまり始める。

液体窒素の時と同じく、低体温症により急速な死をもたらす。

ひとつ慰めになるとすれば、横たわって死につつある中、読者はとても奇妙な現象を観察することになるだろう。

読者の体を急速に覆いつつある超流動のヘリウムの層は、ほとんどの物質と同じく、音波を伝える。しかし、液体ヘリウムには全く別の形の波、ヘリウムの層をゆっくり伝わる波があるのだ。これは超流動でしか観測されていないもので、不思議で詩的な、第三の音という名前が与えられている。

読者の鼓膜はもはや機能しておらず、そもそもこの種類の振動を検出することはできないだろうが、巨大なボートの床の上で凍てついて死につつある読者の耳には、人間が未だかつて聞いたことのない、第三の音で満たされていることであろう。

これは、少なくとも、とってもクールだ。