2013-05-31

もし大工の採用面接がプログラマーのように行われていたら

If Carpenters Were Hired Like Programmers | DawO_od

面接官「なるほど、あなたは大工なのですね」
大工「そうです。私は大工として今までやってきています」

面接官「実務経験は何年ほどでしょうか?」
大工「10年です」

面接官「すばらしい。それはいい。さて、これから職場にふさわしいかどうか、いくつかの技術的な質問に答えてもらおうと思うのですが、よろしいでしょうか?」
大工「はい」

面接官「まず、弊社は茶色の家の建築が主な仕事内容でして。以前に茶色の建築の経験はおありで?」
大工「えーと、私は大工です。だから家は建てますよ。塗装の色の好みは人それぞれでしょう」

面接官「ええ、それはわかります。ですが、茶色経験は何年ほどでしょうか?」
大工「おいおい、分からんよ。建築したあと、どういう色で塗装されるかなんて私の知ったことじゃありません。たぶん、6ヶ月ぐらいでしょうか」

面接官「六ヶ月? いやまあ、弊社はもっと茶色経験の豊富な人材を求めているのでありまして、とりあえず他の質問に移りましょう」
大工「ああ、いいけど。でも塗装は塗装だろ」

面接官「まあ、そうですね。ウォールナット(訳注:木材としてのクルミ)はどうでしょう?」
大工「それがなにか?」

面接官「以前、ウォールナットで働いたことはおありでしょうか?」
大工「ええ、ウォールナット、松、オーク、マホガニー、なんでも経験がありますよ」

面接官「ですが、ウォールナットの経験は何年ほどでしょうか?」
大工「おいおい、知らんよ。ウォールナットを扱うたびに数えてろとでも?」

面接官「まあ、推測で構いませんので」
大工「分かったよ。ウォールナットは一年半ってとこだな」

面接官「あなた自身を評価すると、ウォールナット初心者でしょうか、ウォールナット上級者でしょうか」
大工「ウォールナット上級者? ウォールナット上級者ってなんだよ。そりゃ、私はウォールナットぐらい使うさ」

面接官「でも、ウォールナット上級者ではないと?」
大工「いや、私は大工ですよ。木材は何だって経験があるし、違いはあるにしても、私は自分でも腕のいい大工だとは思っています」

面接官「ええ、ええ。でも弊社はウォールナットを使っているのです。大丈夫でしょうか?」
大工「ウォールナットでいいですよ。何でもいいんです。私は大工なんですよ」

面接官「ブラックウォールナットについては?」
大工「それがなにか?」

面接官「いえ、弊社にはウォールナット大工が何人がおりますが、誰もブラックウォールナット大工ではないんですよ。ブラックウォールナット経験はおありで?」
大工「ええ、少しは。まあ、私のレジュメは豊富というわけですね。そういう意味では」

面接官「わかりました。ちょっと記録するので時間をください」
大工「どうぞ」

面接官「はい、今日最後の質問です。弊社は釘打ちには石 5.1を使っています。石5.1を使ったことはありますか?」
大工、顔面蒼白になりながら、「ええと、確かに職人組合が採石場を購入したので多くの大工が釘打ちに石を使っているのは知っていますが、でも、率直にいいますと、私はネイルガンのほうが得意です。ハンマーのほうがまだマシです。石を使うと指を打ってしまうことが多く、それに石は大きすぎるので、手を痛めてしまいます」

面接官「でも、他社さんも何社か石を使っていますよね。石ではうまく動かないと仰るのですか」
大工「いや、石が動かないと言ってるんじゃなくて、つまり、私はネイルガンの方が得意です」

面接官「ええ、うちのところの設計士はみんな、石を使い始めてましてね。みんな気に入っているようですよ」
大工「まあ、そりゃそうだろうけど、でも私は釘を一日中打つんだ。ええと、まあ、私は仕事に就きたいんだ。やれと言われれば石でもやりますよ。心は広い方ですから」

面接官「わかりました。他にも候補者が何人かいらっしゃいますので、検討の上、日を改めて連絡をさし上げるという形で」
大工「ええ、本日はどうもありがとうございました。」

次の日:

リンリン

面接官「もしもし」
大工「もしもし、覚えていらっしゃいますか。ブラックウォールナットの仕事の件で面接を受けました大工ですが、採用されるかどうかの判断は決まったのかどうか気になったもので」

面接官「実のところ、決まりました。あなたの経験は悪くありませんでしたが、茶色経験の豊富な他の人を雇うことにしました」
大工「マジで? 茶色が十分でないから落ちたってわけか」

面接官「ええ、まあそれも一部ではあるのですが、他の人はもっと安く雇えるもので」
大工「そうかい。で、その人はどのくらいの経験が?」

面接官「ええ、彼は大工ではなくて、車のセールスマンなのです。でも、彼は茶色の車を売った経験が多数あって、しかも車のインテリアにウォールナット経験が豊富でして」
大工、ガチャリ

Mark ShuttleworthがUbuntuバグ#1をクローズした

[Phoronix] Shuttleworth Closes Bug #1, Microsoft's Market Share

2004年、Ubuntuの開発会社であるCanonicalの出資者であるMark Shuttleworthは、自身の手で、Ubuntuのバグトラッカーの初めに、以下のバグを登録した。

Bug #1 (liberation) “Microsoft has a majority market share” : Bugs : Ubuntu

Mark Shuttleworth本人によって書かれたバグ報告は以下の通り。

マイクロソフトがデスクトップPCの新製品の市場において、大多数の市場シェアを占めている。このバグはUbuntuと他のプロジェクトによって修正されるべきである。Ubuntuプロジェクト発足の思想は、「我々の労力はソフトウェアは自由であり万人に利用可能であるべきだという信念によって突き動かされている」というものだ。

「Ubuntuソフトウェアは自由である。常にそうであったし、今後も常にそうである。自由ソフトウェアは万人に望むままの方法で使い、望むままの人間と共有できる自由を与える。この自由は多大な利点である。これにより、あるいはUbuntuコミュニティは成長し、集産された経験と技能を共有し、Ubuntuのあらゆる点を改良できる。また、ソフトウェアを入手する手段を持たなかった人たちにもソフトウェアを提供でき、これは世界中の個人並びに団体が利点と考えるところのものである」

不自由ソフトウェアは利用者をソフトウェア所有者の慈悲に委ね、技術を中央管理し、我々の社会の力を少数の手に委ねることになる。さらに、プロプライエタリ・ソフトウェアはイノベーションを阻害し、見せかけの希少性を演出し、DRMのような悪意ある非機能や、監視や、その他の単一政治的手法を有効にする。

このバグはPC業界において顕著である。

再現方法:

  1. 近所のPCショップに行く
  2. プロプライエタリ・ソフトウェアのないマシンの購入を試みる

実際の挙動:

ほぼ常に、大多数の販売されているPCはMicrosoft Windowsがプレインストールされている。珍しい場合では、GNU/Linuxオペレーティング・システムか、あるいはオペレーティング・システムなしのものがあるが、ドライバーとBIOSはおそらくプロプライエタリである。

期待する挙動:

大多数の販売されているPCは、自由ソフトウェアのみを含むべきである。

その「バグ」とは、「マイクロソフトが大多数の市場シェアを占めている」というものであった。

これは私を含む2089人も同じバグに遭遇しているとマークし、バグは確認(Confirm)され、その重要度(Importance)は、深刻(Critical)であると設定された。

本日、この記事より6時間前のことだが、このバグが、Mark Shuttleworth本人の手によってクローズされた。

その本人のクローズ時のコメントに曰く。

Comment #1834 : Bug #1 (liberation) : Bugs : Ubuntu

今日のパーソナル・コンピューティングは2004年当時より裾野が広がった。携帯電話、タブレット、ウェアラブルやその他のデバイスはすべて、我々のデジタル生活に混ざっている一部である。競争的視点からいえば、このような広い市場は健全な競争をもたらす。IOSとAndroidは実力あるシェアを獲得した(http://www.zdnet.com/windows-has-fallen-behind-apple-ios-and-google-android-7000008699/や、特にhttp://cdn-static.zdnet.com/i/r/story/70/00/008699/meeker620-620x466-620x466.jpg?hash=ZQxmZmDjAz&upscale=1を参照)

Androidは私や諸君のLinux選択として第一のものではないかもしれないが、疑いなく、オープンソースプラットフォームのひとつであり、実用的かつ経済的利点の両方を利用者と業界にもたらしている。つまり、我々には、パーソナルコンピューティング内で、競争と、オープンソースの知名度の両方を得たわけだ。

我々はこの転換の一部を占めるに過ぎないとはいえ、思うに、市場に転換が訪れたということを認識することは重要である。そのため、Ubuntuの視点からいえば、このバグは今やクローズされた。

もちろん、このバグリポートには社会的な要素も含まれている。多くの人にとって、これは意思宣言のようなものであった。しかし、もはや他人の製品に対する影響力ではなく、我々の優秀さに注力する意図を持ったほうがよい。このバグが報告されてから多年、我々はクラウドですばらしく思われるようになり、そしてじきにデスクトップ開発者の間ですばらしく思われるようになることを願っているし、そしておそらく、あらゆるデバイスの万人にも素晴らしく思われるようになるだろう。私はむしろ、我々は発想と主導力を発揮できたことに勝どきをあげるべきだとおもう。

今日、クラウドコンピューティングをみれば、マイクロソフトのIAAS部門は技術的にもすばらしく、UbuntuのようなLinuxゲストを含むすべてのOSをAzure上ですばらしくうまく実行していて、作業を快適にしている。市場の転換の影響だろう。情勢が代わり、目的も応じたのだから、我々もそうするべきだ。

その中で、2004年から以下に多くのことが変わったかを振り返るのはいいことだし、いかに早く変わったかもだ。Ubuntuにとっては、我々の目的は依然としてすばらしい体験を、開発者と、製品インフラの構築者と、あらゆるデバイスのエンドユーザーに提供することだ。我々はこれを10年毎に完全に変化していしまうような環境で行なっている。そのため、我々も、意思決定や作業やツールや関係に対して、大きな変更をする意欲を持たなければならない。このバグの状態を変更するのは、そのほんの小さな一例だ。

というわけで、もはやPCが従来のデスクトップやラップトップ以上に広がったし、オープンソースベースのOSもだいぶ広まったので、状況が変化し、従来のバグは意味をなさなくなり、クローズされることになったのだという。

訳していておもったのだが、どうも2004年のMark Shuttleworthと、2013年のMark Shuttleworthは言葉遣いが変わったように思われる。まず、GNU/Linuxと書かずに、単にLinuxと書いている。また、ProprietaryやDRMという言葉は出てこなくなっている。実際には、iOSやAndroidは、プロプライエタリなドライバーやファームウェアやソフトウェアが満載で、到底自由なソフトウェアと認めることはできない。そして、言い回しも複雑になったように感じられる。以前のように自由を全面的に押し出さなくなり、オープンソースという言葉を使い、またエクスペリエンスのような曖昧としたものを宣伝するようになった。

これはどうも、怪しい心境の変化のように思われる。まるで、これからでUbuntu Phoneではプロプライエタリなドライバーやファームウェアを許容できるような・・・というと、うがった見方だろうか。

実際、このバグは全然修正されていない。マイクロソフトの影響力は相対的に下がったとはいえ、少なくとも日本では、近所のPCショップにいって、プロプライエタリソフトウェアの一切入っていないマシンを購入するのは不可能である。ほとんどのデバイスのファームウェアは依然としてプロプライエタリだからだ。このバグは閉じられるべきではなかった。

真に正しいデジタルデータの保存方法

デジタルデータを数十年、百年と保管するにはどうすればいいのか。

まずは記録媒体を考える。

まずやってはいけないのは、CD-RやDVD-RやBD-Rのような、書き込み可能な光学ディスクに記録することだ。これは非常に劣化しやすい。特に、光学ディスクの規格が新しいほど、耐久性は低下している。BDなどは、表面の僅かな擦り傷だけで読めなくなる、長期記録媒体としては最悪のシロモノである。

プレスしたCD-ROMならば、ある程度の耐久性はあるかもしれない。CD-ROMのプレスは非常に高度な製造技術のため、一般人には手が出せない、というのは冗談で、海外業者に頼めば数万円からプレスしてくれる。しかも数百枚プレスしてくれるので、リスク回避のためにできるだけ多くの箇所に分散して保存することができる。ただし、プレス業者の質に注意しなければならない。

HDDはもってのほかである。HDDは消耗品と考えるべきだ。USBメモリーやSSDのようなフラッシュメモリーは論外だ。こいつらは放置するだけで勝手に消える。

テープは古典的だが、いまでもなお信頼性の高い記録媒体である。ただし、テープ自体は安価なのだが、その読み取り装置が高い。しかも、現代における記録媒体としてのテープは大規模なデータ向けなので、個人ではちょっと手が出せない。

このように、記録媒体自体は劣化して、いずれ読めなくなる。そのため、記録媒体をそのまま保存するならば、劣化しにくい記録媒体を選ばなければならない。プレスしたCD-ROMやテープが、とりあえずは30年ぐらいは保存できると考えていいだろう。そう、たったの30年だ。それ以上を望んではいけない。「保存状態を工夫すれば」などという考えはしてはいけない。30年保存して100個の記録媒体のうちひとつでも劣化して読み込めなくなれば、もはやそんな保存方法では安心できない。

30年。30年。30年。

30年こそが記録媒体をそのまま保管して保存できる限界ギリギリの年数であり、保管できる記録媒体の耐久年数は30年である。

しかも、長期保存できる記録媒体を注意深く選んで、保管場所の環境も注意深く維持しての考慮しての限界ギリギリの年数が、30年だ。

記録媒体もさることながら、もっと重大な問題がある。読み取り装置が30年後も存在するかどうかという深刻な問題だ。

記録媒体は30年劣化しなかったとしても、現代の読み取り装置やその互換品が、30年後もそのまま製造されている保証はない。たとえば、30年前のコンピューターで主に使われていたテープの読み取り装置は、もはや当時の読み取り装置で現存して実働するものを探し出すしかない。もはや、そんなものを製造する商業的理由がないからだ。

したがって、30年後にCDドライブが存在するかどうか、そのへんは非常に怪しい。CDほど有名な記録媒体がと言うなかれ。すでに、光学ディスクドライブは、多くの一般消費者向けのPCからは取り除かれつつある。一般に必要とされないような装置は、もはや製造するだけの商業的価値がなく、製造されない。製造されなくなれば、もはや失われた技術と化す。

したがって、私は30年後にCDドライブが製造されていないという予言をしようと思う。私の予言が的中する確率はかなり高いと思っている。

HDDやSSDを接続する、IDEやSATAといった接続端子などは、もっと信頼できない。今のIDEやSATAは30年後には確実に使えなくなっていると予言する。

最新のテープの読み取り装置は、30年後も存続しているかもしれない。あるいは、提供者が今後何年サポートするという契約を付随させているかもしれない。ただしすでに述べたように、これは大規模な業者向けであり、個人で使うには様々な理由で難しい。

では、30年を超えてデジタルデータを保存するにはどうすればいいのか。方法は一つしかない。

多数の記録媒体の集合で構成され、また個々の記録媒体は任意に追加、交換されるクラスター上に、絶え間なく自動でデータを複数の記録媒体に重複してコピーし続けて冗長性を確保するシステム上に保存することだ。

このシステムならば、記録媒体は数年で劣化するものでもかまわない。絶えず記録媒体の追加交換を続けて、システムが稼働する限り、データは安全である。

もちろん、個人では難しいが、企業や団体ならば可能となるし、このようなシステム上にデータを保存するサービスを提供しているところも多数ある。ほとんどのオンラインストレージ系のサービスはこのような形になっている。個人でどうしても長期保存したいというのであれば、自前での保存もした上で、このようなシステムを使ったサービスを使うべきだ。ただし、一箇所ではダメだ。このようなサービスは現れては消えと興隆が激しいため、その時々で主流のものを複数、できるだけ多く利用するべきだ。

デジタルデータの保存活動をしている団体もある。

たとえば、インターネットを保存する目的で活動を続けているInternet Archiveがある。

Internet Archive: Digital Library of Free Books, Movies, Music & Wayback Machine

また、ネットワーク初期のBBSのログを保存し、それとどんなフロッピーディスクでも保存するから送っておくれと宣言しているWebサイトもある。

T E X T F I L E S D O T C O M

Floppy Disks: It’s Too Late « ASCII by Jason Scott

明らかに、この人物は貴重な当時のデジタルデータの保存を愛してる。どのくらい愛しているかというと、このくらい愛している。

UH OH JASON FOUND THE ARRAY | Flickr - Photo Sharing!

ただし、フロッピーディスクの寿命はたかだか30年ぐらいなので、もう時間切れだそうだ。今ある当時のフロッピーディスクの大半は読み込めない。

もしどうしても長期保存したいデジタルデータが公開できる性質のものであれば、複製、保存しやすい形で公開して、他人も保存できる環境を整えるべきだろう。世の中には物好きがいて、ひょっとしたら保存してくれるかもしれない。より多く複製されるということは、より多くの箇所で保存され、そして将来、発掘される可能性が高まる。

このために、DRM(デジタル制限管理)のような保存のための複製を阻害するような機能は根本的な欠陥であり、存在自体が人道上の罪であり、決して許してはならない。

2013-05-30

panopticlickにより、今のブラウザー環境はユニークだという判定を受けた

ブラウザーは、cookieやlocalStorageのような機能を提供しており、これによりWebサイトは、複数回閲覧したユーザーを、たとえIPアドレスが変わったとしても、個人を識別できる。

このような機能を使わずに、変わりゆくIPアドレスの垣根を超えてユーザーを識別しようとすれば、それは可能だろうか。ブラウザーは多くの情報をサーバーに伝えているため、その情報の組み合わせが十分にユニークであれば、個人が識別できるのではないか。それを実際に検証するWebサイトが、panopticlick.eff.orgだ。

Panopticlick

評価している情報は以下の通り。

ユーザーエージェント
これはブラウザーをサーバーに知らせるための情報だ。大半のとりあえず動く必要があるWebサイトは、ユーザーエージェントに従って、そのブラウザーで動くコンテンツを返す。あまり使われていない文字列の場合、かなりのユニーク性がある。
HTTP_ACCEPTヘッダー
これはブラウザーが受け付けるメディアタイプをサーバーに知らせるための情報だ。サーバーはこれに従って、ブラウザーが受け付けるメディアタイプを返す。
ブラウザープラグインのデータ
利用可能なブラウザープラグインだ。珍しいプラグインを使っていれば、それだけユニーク性が増す。
タイムゾーン
これは、あまりそのWebサイトの閲覧者ではないタイムゾーン設定を使っていれば、ユニーク性が増すだろう。
解像度と色数
そのまんま
システムフォント
これは、Flash PlayerやJava Appletが利用可能な場合、それを利用して利用可能なフォント名を列挙し、その結果を情報として使うということだ。FlashやJavaが利用可能で、かつ、珍しいフォント名が利用可能な場合、かなりのユニーク性が確保できる事になる。
cookieが有効かどうか。
cookie機能が有効かどうかを情報として使う。cookieを使うわけではない。
super cookieが有効かどうか
localStorageのような比較的新しいcookie類似機能が有効かどうかを情報として使う。

これらの情報を組み合わせた結果、私のブラウザーは今までテストした2,934,994件のうちで、ユニークであるという判定を受けた。

でかい情報量は、ユーザーエージェントだ。私はUbuntuのレポジトリにあるChromiumを利用しており、このユーザーエージェントは、相当珍しい。

ただし、最大の情報量は、意外にもHTTP_ACCEPTヘッダーだった。どうもこのChromiumと、私の優先する言語設定が、相当の情報量になっているらしい。言語設定を色々と変えてみたが、やはりタイムゾーンとの兼ね合いか、あるいはUbuntuレポジトリのChromiumのHTTP_ACCEPTヘッダーが相当めずらしいのか、情報量は十分に減らない。

どうもJSTはこのWebサイトでは珍しいらしく、これもバカにならない情報量になる。

結果として、私の環境は、これまでテストした環境の中では相当にユニークであるそうだ。

もちろん、ユニークであることと、匿名性はまた別の話だ。例えばTor経由でアクセスした場合、そもそもTorの出口ノード経由でのアクセスになるのでIPアドレスからして相当にユニークであるが、だからといって匿名性に問題があるわけではない。不特定多数の人間が使うコンピューターは、そのコンピューターから先の人間を特定するのが難しい。ブラウザーの送信する情報量のユニーク性が全てではないが、

Windows要件を満たしたPCで、Microsoftの屈辱的なライセンスに同意せず別OSを使うのが困難な状況

[Phoronix] Windows 8 Hardware Has Another Problem For Linux

mjg59 | Secure Boot isn't the only problem facing Linux on Windows 8 hardware

マイクロソフトの不自由なライセンスへの同意を強要するWindows 8を動作させるハードウェア要件として、セキュアブート(Secure Boot)とファーストブート(Fast Boot)がある。

マザーボードのファームウェアがブートローダーの署名を検証し、ブートローダーはそこから先のOSやらドライバーやらの署名を検証し、未署名のコードが特権モードで実行されないようにするというのが、セキュアブートの仕組みだ。セキュアブート自体は技術的、暗号理論的に正しい設計である。設計的にはSSLと同じだ。DRMのように間違った設計ではない。ただし、マイクロソフトを唯一の認証局とし、マイクロソフトのバイナリ形式しか署名しない。これは各GNU/Linuxベースのディストロ、特に小規模なディストロにとっては、手間と費用がかかり難しい問題だ。

GNU/Linuxでは対応が進み、セキュアブートに関しては、後はディストロ毎で認証局たるマイクロソフトから署名を入手する問題ぐらいしか残っていない。

今回Matthew Garrettが取り上げたもうひとつのWindows要件の問題は、ファーストブート(高速起動)だ。これはGNU/Linuxインストールの技術的な妨げにはならないが、GNU/Linuxをインストールしようとすると、まずMicrosoftのライセンスに同意して、不自由なWindowsを利用しなければならなくなる問題が発生する。その理由については、まずファーストブートについて解説する必要がある。

コンピューターの電源を入れると、まずマザーボードのファームウェア(BIOSやEFIと呼ばれている)が実行され、デバイス(マザーボード内蔵とマザーボードにつながっているデバイス)が初期化される。ただし、この初期化について、明確な標準規格は存在しない。とりあえず実装依存の方法で、実装依存の状態に初期化される。その後、ファームウェアはOSに制御を移す。近代的なOSは、ファームウェアによる初期化を信用しない。そもそも、どのように初期化されているかという規格が存在しないのだから、信用できない。そこで、近代的なOS(Windows、Linuxカーネルも含む)は、自前でハードウェアを再び初期化する。

これをみると、まずマザーボードのファームウェアにより初期化され、そのあとOSにより再初期化されるという二度手間を踏んでいる。これは非効率的である。どうせ近代的なOSは自前で初期化するのだ。ファームウェアはできるだけ初期化をせず、電源投入後、すみやかにOSに処理を引き渡すべきである。ファーストブート要件とは、まさにこれだ。ファームウェアによる初期化をできるだけ回避して、OSにすばやく処理を引き渡すという要件だ。

より正確にいうと、ファーストブートとは、ファームウェアがOSに制御を渡すまでの時間を規定している。この時間はとても短く、ファームウェアは到底、全デバイスを初期化完了するほどの猶予がない。そこで、ファームウェアは時間要件を満たすため、ほとんど初期化をせずにOSに制御を移す実装となる。

ファーストブート自体はいい。この仕組みは、corebootという自由なファームウェアを実装するプロジェクトでも使われている。真に自由なコンピューターを求める人間は、マザーボードがcorebootに対応しているかどうかを調べ、corebootを利用すべきだが、残念ながら、利用者が自力でマザーボードのファームウェアを書き換えるというのは難しい作業であり、ハードルが高い。corebootのようなものは、マザーボードの出荷時にベンダーの手で焼きこまれているべきなのだ。

多くのデバイスの初期化は、ファーストブート要件を満たすよりも長い初期化時間がかかる。USBはもちろんのことだし、マウスとキーボードに使われているPS/2の初期化もすっとばさなければならない。これらのデバイスを利用可能な状態に初期化するには、秒単位の時間がかかるため、ファーストブート要件を満たせない。つまり、ファームウェアはキーボードからの入力を処理しているような時間すら与えられていないのだ。したがって、ファームウェアの設定でブート先を変更するという事はできない。

もちろん、設定によりファームウェアに初期化をさせて、ファームウェア設定画面を表示するモードで起動させることができる。これは、UEFI変数に書き込むことで、次回起動の際にファームウェアに初期化をするよう伝えるのだ。ファームウェアに初期化をさせるようUEFI変数に書き込むためには、ファームウェアが制御を移すOSから行わなければならない。OSとは、例えばMicrosoftの不自由なライセンスへの同意を強要するWindowsだ。

多くのPCは、ベンダー側で、Microsoftの不自由なライセンスに同意しなければ使えないWindowsという不自由OSがあらかじめインストールされた上で、出荷されている。利用者がPCを購入して、初回起動した時、キーボードのどのキーを押し続けようと、USBポートやCD/DVDドライブにGNU/Linuxのインストール用のストレージを突っ込もうと、ファームウェアは反応しない。ファーストブート要件により、ファームウェアには反応するだけの時間的猶予が与えられていないのだ。

そこで不自由なOSであるWindowsが起動する。不自由なWindowsはハードウェアを初期化して起動し、利用者に対して、Microsoftのライセンスに同意するよう求める画面を表示する。ここでの選択肢は、同意するか、電源を落とすかだ。

この画面では、ファームウェアによる初期化を伴う再起動をさせる選択肢が提供されていない。そこで、このような不自由なWindowsインストール済みで出荷されたPCにGNU/Linuxをインストールするには、まずMicrosoft Windowsの不自由なライセンスに同意して、Windowsを操作できる状態にした上で、Windowsからファームウェア初期化を伴う再起動をさせなければならない。

これにより、Windowsインストール済みで出荷されたPCにGNU/Linuxをインストールするには、Microsoftの不自由なライセンスに同意しなければならないという屈辱的な問題が発生する。

もちろん、不自由なOSであるWindowsは最初から必要がないのだから、そのようなOSで汚染されたPCを購入しなければよい。しかし、現実的に、普通の利用者が最も入手しやすいPCが、Windowsインストール済みである以上、そう理想ばかりもいっていられない。

運悪くこのような制限的なWindows汚染されたPCを所有している場合、まずPCを分解して、不自由なWindowsがインストールされたストレージ(HDDあるいはSSD)を取り外して起動するという手がある。そうすれば、ファームウェアは起動すべきOSが存在しないわけだから、エラーを利用者に伝えるためにも初期化を行う。あとは設定を変更して、GNU/Linuxのインストール用ストレージをブートさせるようにすれば良い。

残念ながら、今時の不自由なWindowsがインストール済みの状態で出荷されるPCとは、大抵の場合、薄く小さくするために相当複雑で、このような分解は、メーカー保証を無効にしてしまうほどの作業であることが多い。ましてや、もっと極端に小型化を追い求めたPCの場合、マザーボードに直接SSDをハンダ付けしていたりなどして、分解は極めて難しくなる。

もっと多くの利用者が、私のように各パーツを組み立てる自作PC、あるいは汎用パーツを組み立てて販売されているPC(もちろん不自由なWindows汚染されていない)を利用すべきだと思うのだが、現実はなかなか難しい。

利用者が購入したコンピューター上では、利用者の選択したOSが実行されるべきである。しかし、利用者の選択したOSをインストールするのに、まずMicrosoft WindowsのEULAに同意しなければならないというのは間違っている。

2013-05-28

C++14にやってくる見た目に分かりやすい新機能

C++14のCDも公開され、いよいよC++14も形になってきた。いま書いている本はC++11だが、C++14はGCCとClangといった二大C++コンパイラーで数年のうちに実装されるだろうから、もうすぐ実際に使うことができる。

今回は、詳細な説明は省いて、サンプルコードで新機能を語りたいと思う。以下の新機能は、すでにドラフト入りしており、正式採用はまず間違いない機能である。ちなみに、コンパイルしていないので正しいかどうか検証していない。

2進数リテラル

int bi = 0b11110000 ; // 10進数リテラルでは240

2進数の記述が直感的になる。

自動ストレージ上に確保される動的な長さの配列

void f( std::size_t size )
{
    int buf[size] ; // OK
}

もちろん、クラスの配列も可能だし、コンストラクターやデストラクターも正しく呼ばれる。配列は原始的で範囲外アクセスもチェックしてくれないが、ライブラリによる実装よりも直感的だろう。

汎用ラムダキャプチャー

class X
{
private :
    int member ;

public :

    std::function< int (void) > get_closure() const
    {
        // 非staticデータメンバーをコピーキャプチャー
        return [ member = member ] { return member ; } ;
    }
} ;

int main()
{
    std::function< int (void) > func ;

    {
        X x ;
        func = x.get_closure() ;
    } // xは破棄されている

    func() ; // OK、memberはコピーキャプチャーされている

}

今までは、非staticデータメンバーは個別にキャプチャーする方法がなかった。非staticデータメンバーはthisポインターを経由してアクセスされるため、暗黙にリファレンスキャプチャーされてしまっていた。もしコピーキャプチャーしたければ、明示的にローカル変数を宣言するしかなかったのだ。

std::function< int (void) > get_closure() const
{
    int member = this->member ;
    return [ member ] { return member ; } ;
}

これは面倒だし、非効率的だ。C++14では汎用的なラムダキャプチャー(初期化キャプチャー)が追加されたおかげで、キャプチャーする識別子をどのように初期化するか記述できる。

void f()
{
    int x ;

    [ x = x ] { } ; // xをxとしてコピーキャプチャー
    [ x = x + 1 ] { } ; // xをxとしてコピーキャプチャー、ただし初期化はx+1
    [ y = x ] { } ; // xをyとしてコピーキャプチャー

    [ &x = x ] { } // xをxとしてリファレンスキャプチャー

    [ x = std::move(x) ] { } ; // xをxとしてコピーキャプチャー、ただしムーブコンストラクターが呼ばれる
}

これにより、ムーブしてキャプチャーも可能になる。ムーブによるキャプチャーではなく、ムーブしてキャプチャーなのに注意。

変数テンプレート

// 変数テンプレート
template < typename T >
constexpr T pi = static_cast<T>(3.1415926535) ;

// 明示的特殊化
template < >
constexpr int pi = 3 ;

変数をテンプレート宣言できるように変更。これは新機能ではあるが、文面上の変更は極めて小さい。単に変数はテンプレート宣言できないという従来の制限を緩和するだけだからだ。

変数テンプレートは、上記のように定数の実装に使える。これは従来の関数テンプレートでもできたが、pi<double>()のかわりに、pi<double>と記述できるのが大きい。どうせ引数を取らないのならば、()は冗長だ。

普通の関数でも戻り値の型の推定

// C++14
template < typename T, typename U >
auto f( T const & t, U const & u )
{
    return t + u ;
}

// C++11
template < typename T, typename U >
auto f( T const & t, U const & u ) -> decltype( t + u )
{
    return t + u ;
}

lambda式でできる関数の戻り値の型の推定を、普通の関数にも導入。これによる冗長なコードが省ける。

ジェネリックlambda式

template < typename Func >
void f( Func func )
{
    func( 0 ) ; // int
    func( 0.0 ) ; // double
    func( "hello" ) ; // char const *
}

int main()
{
    f( []( auto x ) { std::cout << x << std::endl ; } ) ;
}

クラスによる関数オブジェクトならば、メンバーテンプレートで実現できていたことを、lambda式でも実現可能にする。

constexpr関数の制限緩和

// C++14版のconstexpr関数による平方根の計算
constexpr double sqrt( double s )
{
    double x = s / 2.0 ;
    double prev = 0.0 ;

    while ( x != prev )
    {
        prev = x ;
        x = (x + s / x ) / 2.0 ;
    }

    return x ;
}


// C++11版のconstexpr関数による平方根の計算
constexpr double sqrt_impl( double s, double x, double prev )
{
    return x != prev ? sqrt_impl( s, ( x + s / x ) / 2.0, x ) : x ;
}

constexpr double sqrt( double s )
{
    return sqrt_impl( s, s/2.0, s ) ;

}

constexpr関数で、ローカル変数の宣言、ローカル変数の変更、ループ文(for, while, do-while)の使用、条件文(if, swtich)の使用を許可する変更。これにより、constexpr関数の記述がまともになる。

さらに詳しい全変更内容を知りたい人は、Editor's Reportを参照。

C++ Editor's Report, May 2013

2013-05-26

C++14のCommittee Draftが公開された

C++14のCommittee Draftが公開されている。

ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee

News 2013-05-24: The CD for the new C++ standard is released

[PDF注意] N3690がCDのようだ。

2013-05-23

デニス・リッチーによって書かれた最初のCコンパイラーがGitHubで公開

mortdeus/legacy-cc · GitHub

デニス・リッチー(1941-2011)によって書かれた発展途中の初期のCコンパイラーのソースコードがGitHubで公開されている。ソースコード自体は、まだデニス・リッチー存命の頃から公開されていたが、この機会に紹介してみる。

ライセンスは許諾的で、このライセンス文を同梱すること、並びに、ソースコードから生成されたバイナリはラインセンス文を出力することとなっている。

追記:ライセンスに関してふと思った。このライセンスは名義が企業で、著作権を盾に同意を求めている。日本では、映画以外の団体の著作権の保護期間は公開後50年である。UNIXと付属するソフトウェアのソースコードは当時から公開されていた。ということは、1973年に制作されたこのCコンパイラーのソースコードは、日本国内では、2024年に著作権が切れるのだろうか。

詳しい経緯は、以下のページに書かれている。

Primeval C: two very early compilers

数年前、Paul VixieとKeith Bosticが、VAXに接続されたDECテープドライブを発見したので、昔のDECテープを読み取ってくれることになった。当時でさえ、もはや考古学的な発掘作業であり、1970年代前半のDECテープに日の光を当てる機会であった。私は喜んで手伝い、いくつかのアーティファクトをここに提供する。残念ながら、現存するテープには、最初期のUNIX OSソースのような興味深いものは入っていなかったものの、展示のための化石は用意できた。

追記:今はBond大学にいるWarren Toomeyが、このうちのひとつのコンパイラー(last1120c、下記参照)を使って、PDP-11用のFirst/Second edition Unixエミュレーター上で、自分自身をコンパイルさせることに成功したそうだ。彼のFTPディレクトリを参照されたし。さらに、The PDP-11 Unix Preservation Societyのページで、ソースとエミュレーターについて解説している。

C歴史論文で書いているように、1972年から1973年にかけては、C言語が形成された年である。この時、型無しのBから、弱い型付けがされたCが生まれ、NB言語[訳注:B言語から派生したNew B言語のこと](ネアンデルタール人か?)の影響を受けて修正され、ソースは現存していないと思われていた。またまさにこの時、UNIXがCで書きなおされた。

これを眺めると、なんとも言えない感情が沸き上がってくる。まだ未発展であまりうまく書かれていない。これを展示するのは恥ずべきことだ。だが同時に、創造的な時代のふたつの瞬間を捉えており、歴史的興味のあるものかもしれない。

ここで公開するのはふたつのテープだ。一つ目は"last1120c"とラベル付けされているもので、二つ目は"prestruct-c"というものだ。昔の記憶から、私にはこれが何を意味するものか知っている。一つ目は、我々がPDP-11/20対応をやめるときに保存されたコンパイラーのコピーだ。PDP-11/20には乗算や除算の命令がなく、別の追加ユニットでそのような操作(それとシフト)を、メモリ場所にオペランドを配置することで行なっていた。このハードウェアを利用する話は、別の場所で語られている。

"prestruct-c"というのは、コンパイラー自身が構造体を使い始める直前に私が保存したコンパイラーのコピーだ。

このコンパイラーの年代を正確に割り出すのは難しい。ただし1972-1973の間であることは確かだ。テープイメージには日付ビットも存在するのだが、この時代、我々は起点時間を何度も変更していたので、年度がずれたようなエラーとなっているし、ファイルも幾度とない利用により、コピーされたか変更されたかしているからだ。

初期の方のコンパイラーは、構造体を知らなかった。構造体("struct")という文字列はどこにもでてこない。二つ目のテープは、構造体を今のような意味で実装したコンパイラーが入っている。宣言文法は、どうも{}ではなく()を使っているようだが、それでも . や -> を使って構造体や構造体のポインターのメンバーを指定する機能は、両方とも存在する。

どちらのコンパイラーも、現代の一般的な宣言文法や、それどころかK&R第一版のような、int **ipp; のような複合的な宣言子文法を扱えない。この当時のコンパイラーは、まだ複合的な型の構築(「関数へのポインターの配列」とかのような)という形を扱うほど進歩していなかったのだ。その機能は、5thか6thのUNIX(1975年あたりだったかな)で出現していて、それから数年後のCマニュアルに(Postscriptで)書かれている。

かわりに、ポインター宣言は int ip[] ; の形で書かれていた。この時代の化石は、現代のCでも生き残っている。この文法は、引数を宣言する際に使われている。ただし、* という文法は使われていないものの、受け付けるようだ(自分自身の言語で書かれている発展中のコンパイラーは、自分自身の最新の機能を使わないように注意を払うものである)

興味深いことに、初期の方のコンパイラーは、"long"キーワードをサポートするためのコメントアウトされた用意が残されている。後期の方のコンパイラーは、その場所が"struct"で占められている。longの実装は、数年後のようだ。

その小さなサイズもさることながら、最も衝撃的なのは、その原始的な構築方法だろう。多くの定数がそこら中に散らばっている。これは、当時プリプロセッサーが存在しなかったためである。

もうひとつ、気づきにくいが、驚くほど特徴的なのは、容量確保だ。一時ストレージは、意図的にプログラムの冒頭を上書きし、容量を節約するために、初期化コードをぶち壊している。ふたつのコンパイラーは、これを扱う方法について違いが観られる。初期の方は、関数に名前をつけることで、冒頭を発見している。後期の方では、冒頭は単に0としている。このことからみるに、初期のコンパイラーはメモリーマッピングが存在する以前のコンピューターで書かれたものであり、プログラムの場所は0からではないが、二つ目のコンパイラーの時代では、我々にはマッピング機能を提供するPDP-11があった。(Unix歴史論文を参照されたし)。ファイル(prestruct-c/c10.c)でも、やっつけ仕事なのは明らかだ。

ソースコードへのリンクは下に並べてある[訳注:原文を参照]。c0?.cという名前のファイルから始まる。これはソースをパースして、中間ファイルとしてのテキストで表現されたシンタックスツリーを出力する。c1?.cファイルは、コードジェネレーターで、ツリーを読み込んで、コードを生成する。フォーマットは単純なテキストだ(行を分割するためにNL文字が使われているが、私の使っているブラウザーは問題なく表示できるようだ)。

コード生成の方法は、命令プロトタイプのテーブルを使っている。パースツリーはテーブルの中のルート演算子と再帰的にマッチされる。型の制約とオペランドの複雑性が表現され、テーブルは最初にマッチするものを見つけるまで線形に探される。各制限指定の次に来るのは、展開していだ。小文字はリテラルであり、大文字はツリーのオペランドで置き換えられる。これはPDO-11コンパイラーへのツアーでより詳しく解説されている。(このリファレンスはtroffソースである。PostscriptやPDFの形式のものが、他の論文とともに、7th Edition Manualのホームページで公開されている)。しかし、このツアーは、このソースコードより数年後のものを解説していることに注意。

4つのテーブルで、式からレジスタへのコンパイル方法、副作用だけの目的でのコンパイル、条件コードの判定だけの目的でのコンパイル、スタックにプッシュする方式でのコンパイル(関数の実引数や一時オブジェクトに使われる)を指定している。これは"last1120c"の方しか残っていない。後期もよく似たものだったはずだ。

last1120cコンパイラーのソースは、各パスに補助的なテーブルがあり、ライブラリにないものとか、.s(アセンブラー言語)ファイルのエンコード方式などを指定している。

最後に、cvoptプログラムというものがある。これはnonce-language expression template tableをアセンブラーに変換するために使われている。多くの手作業での修正を行えば、おそらくは動くlast1120cコンパイラーを構築することが可能ではないか。「動く」というのは、「ソースをPDP-11アセンブラーに変換」という意味である。(ページの上部にある成功例を参照)

最後の方のコンパイラーの説明はかなり怪しいやっつけ翻訳だ。

このブログの数年前のC++0x記事を参考にすべからず

このブログでは、まだC++11がC++0xと呼ばれていたドラフト段階から、C++11を解説してきた。

当時の記事は当時のドラフトに基づいて書かれているため、正式なC++11の仕様ではない。そのため、2011年以前のC++0x記事を参考にならないし、当然参考にしてはいけない。

例えば以下の記事は、2009年当時のドラフトの解釈である。

本の虫: lambdaのちょっと分からない点

正式なC++11規格では、immediate enclosing scopeではなく、lambda式を含む関数の最も外側のブロックスコープをreaching scopeと定義し、たとえlambda式がネストされていた場合でも通過できるようにした。これにより、lambda式をネストしても識別子はreaching scopeからlookupされるので、使うことができる。ただし、外側のlambda式でキャプチャーしたものでなければ、内側のlambda式では使えない。

void f()
{
    int x ;

    // OK
    // 2009年当時のドラフトではエラー
    [=] { [=]{ x ; } ; } ;

    // エラー、外側のlambda式がxをキャプチャーしていない
    [] { [=]{ x ; } ; } ;

}

2013-05-22

XChatの謎とHexChatの始まり

XChatというIRCクライアントがある。このソフトウェアは、UNIX風OSとMAC OS XとWindowsに対応している。

XChatのライセンスはちょっと変わっている。、UNIX風OSとMAC OS X用はGPLv2(ただしOpenSSLリンクの例外条項あり)で、Windows用はプロプライエタリソフトウェアとなっている。

1999年に初めて公開されたこのソフトウェアは、当初無料ソフトだったが、2004年からWindows用のみシェアウェアに移行した。公式な理由によれば、Windows用の開発に必要な技術とビルドに必要なコンピューター資源を捻出するためだという。

ただし、依然としてGPLv2(OpenSSL例外条項)なので、ソースコードは公開されている。そのため、実質は公式のWindows用ビルド済みバイナリがプロプライエタリになったというわけだ。この変更に対して、第三者がWindows用のビルド済みバイナリを提供したり、Windows用にforkして開発したりされた。

そのforkに、HexChatがある。当時はXChat-WDKという名前だった。2010年に始まったこのforkは、当初はWindows用の自由なXChatを目指して、Windows環境でのバグを修正したりなどしていたが、その後、新機能を追加したりなどし始め、そうなってくるとWindows限定というのもどうかということで、UNIX風OS向けにビルドもできるようになった。

さて、ここからが謎なのだが、2010年あたりから、当の本家XChatの開発が停滞してしまったのだ。

XChatのオリジナルの作者であるPeter Zeleznyは、どういうわけか音信不通になってしまった。今のXChatのレポジトリには、たった一人、それもPerlインターフェースのメンテナーだけがコミットしている。Peter Zeleznyは、このPerlインターフェースのメンテナーからの連絡にも一切返信しないでいる。XChatは、事実上開発停止してしまった。

こうなってくると、Hexchatも存在意義が増す。Hexchatの開発者は、HexchatとXChatをマージしてはどうかと本家XChatにもちかけてもみたが、そもそもPeter Zeleznyと連絡が通じない以上、どうしようもない。

Hexchatは、とりあえずxchat.orgのドメイン失効を待ってみたが、なんとドメインは執行しなかった。どうやらPeter Zeleznyは死んだわけでもなく意欲を失ったわけでもないらしい。ちゃんとドメインの更新手続きが行われた。しかし、依然として連絡は通じない。

そういうわけで、XChatと合流するというHexChatの当初の目的は達成できなくなり、結局HexChatは別プロジェクトとして独立することになった。その際、もはやWindows限定でもないのに、名前がWDK(Windows Driver Kit)とはおかしいだろうという事で、HexChatに改名した。現在、リリース体制を整えたり、*nixのメンテナーがパッケージ化してくれるように体裁を整えたりと作業を進めているそうだ。

Announcement - HexChat

XChat - Wikipedia, the free encyclopedia

Ubuntuでは、Hexchatをレポジトリに入れてはどうかということと、そして事実上開発停止したXChatをHexChatで置き換えるようにしてはどうかということが議論されているようだ。

Bug #995018 “[needs-packaging] HexChat” : Bugs : “xchat” package : Ubuntu

二大ゲーム用制限コンピューターのスペックが発表された

【後藤弘茂のWeekly海外ニュース】Microsoftが次世代ゲーム機「Xbox One」のベールを剥いだ
【後藤弘茂のWeekly海外ニュース】次世代ゲーム機「PlayStation 4」をSCEがニューヨークで発表

Sonyの制限コンピューターであるPlaystation 4と、Microsoftの制限コンピューターであるXBox Oneは、どちらとも利用者の自由を不当に制限するコンピューターである。そこで、ここでは制限コンピューターと呼ぶ。汎用コンピューターは、所有者にその詳細を検証し、また動作を改変できる自由を保証していなければならない。さもなくば、そのようなコンピューターは、所有者の意図通りに動かず、コンピューター提供者の意のままに動く、制限コンピューターとなり下がる。

したがって、私はこのような制限コンピューターは一切推奨しないし、読者は当然のことながら所有を拒否すべきである。もっとも、実質所有できないコンピューターに所有拒否というのもおかしな話だが。

さて、ここではふたつの制限コンピューターに対する感想を述べるが、これは技術的な感想であって、推奨ではない。

表にみえるような簡単なスペックは、両者とも似通っている。どちらもAMDのx86-64アーキテクチャを使っていて、メモリを8GB搭載している。前回の両者の制限コンピューターは、CPUにPowerPCを使っていた。後藤弘茂氏が言うには、結局統合プロセッサーを設計、製造できるところは限られているから、両者が似るのは技術上の制約であるとのことだ。

ただし、メモリには、両者とも別の場所で無理をしているようだ。

両者のゲーム用制限コンピューターは、CPUとGPUのメモリを統一する設計になっている。

Sonyの制限コンピューターは、GDDR5の2ギガビット品を32個使って8ギガバイトのメモリ容量を実現している。GDDR5は高価なメモリーであり、本来はもっと少ないメモリー容量を想定していたが、競合のMicrosoftの制限コンピューターが8GBなので、それに負けじと合わせたそうだ。ただ、GDDR5を利用しているので、帯域的には悪くないという。

Microsoftの制限コンピューターは、安価なDDR3を使って8GBの容量を実現している。Microsoftの制限コンピューターは仮想化技術でOS切り替えなども想定しているため、大量のメモリが欲しかったらしい。ただし、そのままではGPUの帯域として心もとないので、32MBという大容量のESRAMをGPU近くに無理にでも配置して低帯域を隠しているそうだ。

汎用コンピューターを不当に制限してどこへ行くのだろうか。

2013-05-21

Doubtful description of wikipedia article: Tsuchinoko

I was reading Japanese article of wikipedia article of ツチノコ today and I thought it might be interesting to see how it is explained in English article.

So, I looked for the English article for Tsuchinoko.

It started innocently:

The Tsuchinoko (ツチノコ or 槌の子?) literally translating to "hammer's spawn," is a legendary snake-like cryptid from Japan.

Although I think it's "snake" rather than "snake-like", but it looks okay.

Until...

According to legend, some tsuchinoko have the ability to speak and a propensity for lying, and is also said to have a taste for alcohol.

What?

I've never heard of this funny story. "ability to speak"?, "propensity for lying"? In what legend?

As usual, there is no citation for this.

In old history book such as Kojiki and Nihon Shoki, there is a god modeled from tsuchinoko. Sure. Gods and Spirits may speak. But since everything(animals, plants, mountains, rivers, rocks and literally everything) has corresponding god in Japanese traditional religion, It's not a special case for the Tsuchinoko.

Though it is said Tsuchinoko likes alcohols.

The later sentence:

Legend records that it will sometimes swallow its own tail so that it can roll like a hoop, similarly to the mythical hoop snake.

It looks like some people said this.

xkcd: Wikipedian Protester

なかなか表に出てこないツチノコとDMM

dmmのエンジニアと話をしてみたいという話 - たごもりすメモ

DMMというWebサイトがあるそうだ。どうもよくわからないのだが、dmm.comの方が一般商品を扱うWebサイトで、dmm.co.jpの方がエロ商品を扱うWebサイトらしい。

[dmm.com]DMM.com DVDレンタル、通販、動画配信、FX等の総合サイト
[dmm.co.jp]動画、DVD通販、オンラインゲーム等の総合サイト - DMM

主に動画とか同人作品などの電子的媒体のダウンロード販売を行なっているらしいが、家電なども、コンピューター周辺機器などへの偏りは観られるものの、幅広く扱っているようだ。

Webサイトは日本語で提供されていて、規模的にはだいぶ大きく、これを支えるには、裏で技術的に興味深いことをしているにも関わらず、DMMの技術者は一切表に出てこないし、日本人技術者のつながりからも外れていて、謎に包まれているらしい。

これだけのことをやっているからには内部のシステムは物凄いことになっているに違いない、きっとその話はありとあらゆる世界の教訓になるに違いない。どんな分野の勉強会に行ってもひっぱりだこだ。

のだが、ありとあらゆる技術系勉強会でdmmの人というのに会ったことがない。これでもそれなりに広い範囲の勉強会に行っていろんな人と話をしたと思うんだが、dmmの人は本当に会ったことがない。誰に聞いてもまったく会ったことがある人がいない。

なんなんだ。どこにいるんだ。ツチノコか。技術的にあらゆる意味で意義があるはずなのに。単独でタイトルにあげて1日カンファレンスやれるレベルのはずなのに。なぜだ。どこだ。出てこい。

参照先の人は、ぜひDMMの技術者と勉強会が開いてみたいらしいのだが、果たしてツチノコは発見できるのだろうか。

2013-05-20

Ubuntuのディスク暗号化のコスト

[Phoronix] The Cost Of Ubuntu Disk Encryption

phoronix.comで、Ubuntuのディスク暗号化のコストを比較している。

Ubuntuはふたつのディスク暗号化のオプションを提供していて、Ubiquityインストーラーから選択することで簡単に使うことができる。

ひとつはeCryptfsを使ったhomeディレクトリの暗号化。もうひとつは、LUKSとLVMを使ったディスク全体の暗号化だ。

phoronixでは、この2つの暗号化を使ってインストールされたものにくわえて、暗号化していない場合のディスク性能のベンチマーク結果を比較している。

最近のIntelやAMDのCPUでは、暗号化復号化を高速に実装できるAES-NI命令が実装されていて、このような暗号化の実装でも、使える環境では使うようになっている。

ベンチマークは、AES-NIをサポートしたCPUであるAMD FX-8350と、SSD、OCZ Vertex 2を使って行われたそうだ。

ベンチマーク結果が面白い。暗号化していない方が速いのは当然だが、eCryptfsによるhomeディレクトリの暗号化より、LVMによるディスク全体の暗号化の方がベンチマークのスコアが良い傾向がみられたという。

phoronixの記事では、暗号化によるコストは許容できるものであり、LVMによるディスク全体の暗号化を、セキュリティと精神安定上の理由から推奨している。

ただし、レンチを持った悪意ある者に注意。

本の虫: xkcd: セキュリティ

2013-05-18

任天堂、YouTubeにアップロードされた自社のゲーム動画を広告ハイジャックする決定を下す

BBC News - Nintendo to profit from user videos posted to YouTube

Nintendo Hijacks Ad Revenue From Fan-Created YouTube Playthroughs - Slashdot

YouTubeに任天堂のゲーム用制限コンピューターで生成された映像をアップロードすると、任天堂がcontent ID match機能により、自動的に広告ハイジャックする。広告によって発生した利益は、動画のアップロード者には配分されず、任天堂が独占する。

なるほど、ゲームは任天堂が著作権を持つわけだから、ゲームから生成された映像も任天堂の著作権であるということなのだろう。

しかし、その映像が生成されるためには、人間による操作が必要になる。そして、人間の操作で生成される映像に違いが出るような場合、人間の操作は著作物ではないのか。これは任天堂による著作権侵害ではないのか。

そもそも、任天堂のゲーム用制限コンピューターは、利用者の自由を不当に制限する邪悪な制限コンピューターであるから、もちろん使ってはならない。

しかし、なぜ比較的最近のものは、やたらと著作権保護の対象になるのだろうか。

たとえば、もし私の全身を撮影した画像をインターネットで公開するとしよう。ただし、撮影された画像の私は服を着ている。さて、この場合、私は服を画像という物に固定して公衆送信することになる。すると、まず服のデザイナーに著作権利用許諾を求めるべきなのだろうか。

私がピアノをひいて録音をインターネットで公開するとしよう。生成されたピアノの音の録音に、ピアノの設計者は著作権は及ばないはずである。

ただし、そのピアノというのが、古典的な弦や空気柱の振動で音を生成するのではなく電子ピアノで、したがって鍵盤は単なる入力装置で、入力に従ってあらかじめ録音された音を順次慣らしていくものだとしよう。この結果生成された音の録音には、電子ピアノの提供者の著作権もかかるのだろうか。

ゲームはどうなのか。

2013-05-17

MPEG RVCからLLVMアセンブリを出力するJADE

[Phoronix] JADE: An LLVM-Based Video Decoder For MPEG RVC

JADE(Just-In-Time Adaptive Decoder Engine)は、MPEG RVCからLLVMアセンブリを出力する。MPEG RVCとは、動画フォーマットのための共通のフレームワークである。

Reconfigurable video coding - Wikipedia, the free encyclopedia

こういうものにもLLVMが使われるようになっているとは。

記録からみるLinus TorvalsのC++観

だいぶ昔の、C++に対するLinus Torvalsの発言をtweetしたところ、結構な関心を集めていたので、気分転換に紹介してみる。

Re: [RFC] Convert builin-mailinfo.c to use The Better String Library. [LWN.net]

これはgitのMLで、なぜgitでC++を使わないのかという質問に対して、Linusの回答。

From:  Linus Torvalds <torvalds-AT-linux-foundation.org>
To:  Dmitry Kakurin <dmitry.kakurin-AT-gmail.com>
Subject:  Re: [RFC] Convert builin-mailinfo.c to use The Better String Library.
Date:  Thu, 6 Sep 2007 18:50:28 +0100 (BST)
Message-ID:  <alpine.LFD.0.999.0709061839510.5626@evo.linux-foundation.org>
Cc:  Matthieu Moy <Matthieu.Moy-AT-imag.fr>, Git <git-AT-vger.kernel.org>
Archive-link:  Article, Thread

On Wed, 5 Sep 2007, Dmitry Kakurin wrote:

>
> Gitのソースコードを始めてみた時、2つのことが頭にひっかかった。
> 1. C++じゃなくて純粋なC。理由は不明。移植性とか言わないでよ。
> クソだ。

クソまみれなのはオメーの方だ。

C++は悲惨な言語だ。しかも、少なからぬ数のプログラマーが使っていて、完全無欠のどうしようもないクソを生成するのがめちゃめちゃ簡単になっているという点で、よけいに悲惨だ。マジで、Cを選択する理由が「何もなかった」としてもだ、C++プログラマー避けになるというだけで、Cを使う大義名分になる。

つまりだ:Cの選択は唯一のまともな選択なんだよ。Miles Baderがふざけて、「いやがらせによる追い返し目的」なんていってたが、実際のところ正しい。俺の出した結論では、プロジェクトにCよりC++を使いたがるプログラマーは、むしろいやがらせして追い返したほうがいい。そうすれば、そんなヤツは俺のプロジェクトにやってきて、ひっかきまわしたりしないからな。

C++を使うとめちゃめちゃクソな設計の選択に追いやられる。必ず、最初は「よさげ」な言語のライブラリ機能、たとえばSTLとかBoostとか他の完全なクソを使い始める、それはプログラムに「役立つ」かもしれない。だがしかし、それによって引き起こされるのは:

  • 動かない場合の無限の苦痛(しかも、STLとか、特にBoostが安定していて移植性があるなんて言うやつはクソまみれだし全然面白くもなんともない)
  • 非効率的な隠匿プログラミングモデル、二年ほど開発を続けて、始めて一部の隠匿設計が非効率的なことに気がつくが、その時点では、もうオマエのコードはよさげなオブジェクトモデルに依存しきっていて、書きなおす以外に修正の方法がない。

つまり、まともで効率的でシステムレベルで移植性のあるC++ってのは、Cで使える機能だけに制限することだ。プロジェクトをCに制限すれば、ぶち壊すヤツはでてこない。それと、多くのプログラマーが低級な問題まで理解できるようになり、理想主義的な「オブジェクトモデル」のクソとやらでぶっ壊したりしない。

そういうわけで、悪いんだが、gitのような、効率を第一の目的としたのには、C++の「利点」とやらは大失敗なんだよ。こういうことが分からない人間を追い返せるというのは、多大な利点でもあるんだ。

C++で書かれたVCSが欲しけりゃ、Monotoneでやればいい。マジで。コイツは「本物のデータベース」を使っている。コイツは「よさげなオブジェクト志向ライブラリ」を使っている。コイツは「よさげなC++隠匿」を使っている。ショージキなところ、その結果として、研究者受けはいいらしいが、結果としては悲惨で保守不可能なゴミだね。

まあでも、お前さんはgitよりは気に入るだろうよ。

Linus

LKML: Linus Torvalds: Re: Compiling C++ kernel module + Makefile

もうひとつ。こちらは、LinuxのカーネルモジュールをC++で書くことの是非についてLinusの返事。もちろん、Linuxカーネルとのやり取りさえC互換で行えば、カーネルモジュールのバイナリがどのように生成されたか知ったこっちゃないが、C++でカーネルモジュールを書くのはなかなか難しい。

DateMon, 19 Jan 2004 22:46:23 -0800 (PST)
FromLinus Torvalds <>
SubjectRe: Compiling C++ kernel module + Makefile

On Tue, 20 Jan 2004, Robin Rosenberg wrote:

>
> これでは、「おれらCOBOLで何の問題もなかったじゃんwwwwww」的な論法じゃないか。

実際のところ、LinuxではC++を試したことがある。1992年のことだった。

結果はクソだった。マジで、カーネルコードをC++で書くのは、ド低脳の考えだ。

実際問題として、今のC++コンパイラーはまともじゃない。1992年当時はもっとひどかったのだが、昔も今も根本的なところは変わってない:

  • C++例外処理全体が根本的にぶっ壊れてる。特にカーネル内ではまともに動かない。
  • メモリー確保のようなものを隠したがるコンパイラーや言語は、カーネル用にふさわしい選択ではない。
  • Cでオブジェクト指向コード(ファイルシステムとかだと有用)を書くのは可能だし、しかもC++のような余計なクソがついてこない。

一般に、カーネルモジュールをC++で設計するやつは、以下のいずれかだ。

(a) 好んで厄介事に巻き込まれたい者
(b) 自分が書いているのは実はCだと気がついていないC++バカ
(c) 授業でそういう課題を与えられた者

(d)を付け加えるなら好きにしてくれ。

Linus

ちなみに、私はCが嫌いだ。

Ubuntu 13.10の噂

Ubuntu 13.10に関する様々な憶測や噂が浮かび上がっている。憶測や噂といっても、Virtual Ubuntu Developer Summitで議論された内容がソースなので、根も葉もないというわけではない。Phoronixが拾い上げているので、いくつか紹介してみる

デフォルトのブラウザーをFirefoxからChromiumに

[Phoronix] Ubuntu To Look At Replacing Firefox With Chromium
[Phoronix] Ubuntu 13.10 Likely Switching To Chromium Browser

Ubuntuのデフォルトのブラウザーは、現在のところ、Firefoxとなっている。これをChromiumに変えてはどうかという意見を、結構な数のUbuntu開発者が持っているそうだ。特に、スマートフォンやタブレット対応の関係で、Unity Nextではwebkitベースのレンダリングエンジン(たぶんwebkitではなくBlink側に行くと思うけど)を使用するので、なおさらChromiumを押す声が強い。もちろん現状でFirefoxもChromiumは両方パッケージ化されて存在している。

Firefoxと比べてChromiumは、対応アーキテクチャが少なく(たとえばPowerPCでは動かない)、Orcaスクリーンリーダーが対応しておらず、組み込みPDFビューワーもない。

個人的な意見では、PowerPCアーキテクチャーは今ではすっかり下火になった。たしかに、現行のゲーム用制限コンピューターの多くはPowerPCだが、次世代の制限コンピューターはx86-64ベースになるらしいので、なおさら使われなくなっていくだろう。

Orcaスクリーンリーダーは、まあ、Ubuntuの視覚障害者に対応しようとする努力は認めなくもないが、残念ながら合成音声の品質が極めて悪く、何を言っているのだかさっぱりわからない。

PDFは、印刷用のフォーマットとしては優秀かもしれないが、Webにはそぐわないので、むしろPDFの方が死滅するべきである。

Mirが実験的オプションとして、ログイン時に選択可能になる

[Phoronix] Unity 8, Mir To Be Experimental Choice In Ubuntu 13.10

Ubuntu 13.10では、実験的オプションとして、Mirをログイン時に選択できるようにしようという意見が出てきている。ただ、このログイン時というのが、通常のシェルのようにLightDMでのログイン時の選択なのか、Grubでのブート時の指定なのか、まだはっきりしていないそうなのだ。

その理由は、おそらくこういうことだろう。

本の虫: KubuntuにおけるMir

つまり、Mirというのは、Unityというシェル専用のディスプレイサーバーなので、もはや既存の別のシェルを動かす互換性が失われてしまう。だから、従来通りのLightDMでのログインを提供するのは不可能ではないかというのがKDE開発者の推測だ。これが正しいとすれば、Grubによるブート時の選択なんて話が出てくるのも分かるわけだ。とりあえずブート時に設定を切り替えるのが、一番楽な対応方法だろうから。

MySQL代替品

[Phoronix] Ubuntu Looks Towards MySQL Alternatives

OracleがSunを買収して、MySQLを所有してからというもの、MySQLに対する評価はどんどん下がっている。これは、MySQLの性能だとか安定性だとか開発速度という点の評価ではなく、自由に対する懸念である。

MySQLの権利がOracleに移ってからというもの、開発が不透明になってきているのだ。例えば、バグトラッカーはOracle社内限定の非公開だったり、脆弱性情報が公開されなかったり、とにかく開発が閉鎖的になっている。特に、脆弱性情報については、データベースソフトウェアという性質上、非常に問題になっている。ディストリビューションはMySQLのような有名なソフトウェアには、独自にパッチを作成したりして、脆弱性だけを潰すといったことをしているからだ。

この開発の閉鎖性に危機感が持たれたせいで、MySQLのforkが発生している。最も有名なforkは、他ならぬMontyによって立ちあげられたMariaDBだろう。

ただ、会議で出た意見としては、Ubuntu開発者がDebianにPercona(会社名にして、MySQLのforkである同名のソフトウェア)をパッケージ化させる手伝いをし、Debianでパッケージ化されたPerconaをUbuntuに引っ張ってこようという話になっている。MySQL vs Percona vs MariaDBでどれを優れているのかという決定は、現時点では行わないらしい。

2013-05-15

Mir上でうごくUnity NextのタブレットUIのデモ

AppleのRetina MacBook Pro(GPUはIntel HD4400)で、Mir上でUnity 8のタブレットUIを動かしている動画が公開されている。デスクトップUIについては、後ほど公開するとしている。

これが正しければ、Mirは開発開始から11ヶ月で、とりあえず動いているわけだ。

Waylandは設計開始からすでに5年になるが、なかなか実用は遠い。もちろん、この動画の程度なら動いているが。というより、Mirはかなりの部分をWaylandから流用しているので、これはWaylandの成果ともいえなくはない。

2013-05-13

KubuntuにおけるMir

Mir in Kubuntu | Martin's Blog

Blue Systems社員でKDE開発者のMartin Gräßlinが、Mirについて書いている。

Jonathanのブログ記事にあるように、Mataro Sessions IIでKubuntuにおけるMirについて議論した。このことに関しては、あまり話したくない。しかし、自由ソフトウェア業界の流れからして、議論しなければならないし、我々の下流(KDEを利用する層)も、なぜ上流(KDE開発の本家)は、Mirを受け入れるのは妥当な選択ではないのかと判断したかについて知る必要がある。

これは、CanonicalがMirで生み出した多大な問題に焦点をあてるものだ。私はMirが選択肢に入らない理由として、単に、「Canonicalは糞だ」[1]と言うわけにはいかない。我々がMirと統合しない理由について、私は正当な技術的反論を打ち立てなければならない。私は違いや利点欠点を調査するために時間を割いた。私にはそのような意見があるので、その意見をブログ記事で共有するのはいいアイディアだと思う。

この議論は、Blue Systems社内で同僚にX11とWaylandに関するプレゼンをしている最中に始まった。私は、まずX11について説明することにした。というのも、X11を理解せずに、Waylandの必要性を理解することはできないと思うからだ。Mirについて議論するつもりはなかったが、どういうわけか、議論がそっちの方向にいってしまい、MirとWaylandの違いや利点についての当然の質問が出てきたからだ。その後に続いたのは、Ubuntuとanonicalに対する罵倒だ[2]。そういうわけでその週の後半に、私は「KubuntuにおけるMir」についてより詳細に議論し、下流に対して疑問に答える努力をした。

イントロダクション

フラストレーションとモチベーション

まず、ひとつ明白にしておくことがある。Canonicalは何を開発しようと勝手だ。現状は別にどうでもいいし、またまた別のディスプレイサーバーだと、独自OSカーネルだとかまたぞろデスクトップシェルだとかを新たに立ちあげようとも、これまたどうでもいいことだ。本当にどうでもいいのだ。CanonicalとMarkのカネなのだから、奴らが思うがままにつぎ込めばいい。プロプライエタリソフトウェアだろうと、私の知ったことではない。

気にする問題とは、虚偽にまみれた技術的意見をもちこみ、Canonicalが一切貢献していないソフトウェアに関して無知な声明を発表し、自由ソフトウェアエコシステムを引っ掻き回したことだ。これは到底許せないことだ。非常にいらだつことであったし、私にとって、Canonicalの信頼は大きく損なわれた。この信頼を取り戻すのは難しいだろう。Canonicalはこれが、普通の企業業界ではなく、自由ソフトウェア業界であることを感謝すべきだ。普通の企業業界ならば、法務が動くような声明だったのだから[3]。また、この事件は私のモチベーションをひどく損ねたし、自由ソフトウェアエコシステムの一員である価値についても疑わせた。お互いに協力するのではなく、エコシステムのメンバーが急に競合相手となり、ソフトウェアスタックを侮辱し始めるのだから。これはとてもいらだたしい事態だ。

Mirを開発する妥当でまともな理由はあるのだろう。残念ながら、彼らはその理由とやらを開示していない。もし理由とやらがあるのであれば、さっさと説明すれば、私や他のプロジェクトはもう少し風当たりも良かっただろうに。そうであれば、疑問がない以上、あの発表に苛立つこともこれほどではなかっただろうし、この議論もなかっただろうに。だがしかし、Canonicalは間違った技術上の理由で説明することにしたようだ。

まだ準備できてない

現在、Mirはまだ準備できてない。これは重要である。あの発表により、我々には現状に対して4つの選択肢がでてきた。

  1. Wayland計画を続行し、Mirは無視する
  2. Mirに切り替え、Waylandは無視する
  3. MirとWaylandをサポートする
  4. Mirが準備できるまで、選択を保留する

Plasma Workspace 2の開発予定とMirの開発予定のタイムラインを描いてみると、お互いに重ならない。Mirが準備できる前に、Waylandをサポートしたい。選択を遅らせるのはあまり良くない選択だ。出戻りになるだけだからだ。つまり、選択肢2も妥当ではない。Mirが準備できるまで遅らせねばならないからだ。そのため、妥当な選択肢は、MirとWaylandの両方をサポートするか、Waylandのみをサポートするかだ。現在、Waylandに加えてMirもサポートするのが妥当なアプローチかどうか判断できる段階までコードが準備できていない。前に私がソースベースを確認した時点では、スタブにいくつもぶつかったので、まだ検証するほどの価値もなかった。そこで、我々は現状の情報だけで判断するしかないが、これはMirにとってはあまりよろしくない。

Wayland vs Mir

MirがWaylandより優れているかも知れないこと

MirとWaylandの違いは少ない。違いのうちの一つは、Mirはバッファをサーバー確保するのに対し、Waylandはクライアントサイドでのバッファー確保を行う。私はこれが利点なのか欠点なのか判じかねる。私はこの件に関しては、KristianとWayland開発者を信じることにする。

他の違いとしては、Mirはテスト駆動開発を行なっていることだ。私としては、開発手法は技術的な論点にはならない。私はユニットテストが行われているが動かないシステムより、ユニットテストが行われていないが動くシステムを使いたい[4]。また、KWinはテスト駆動開発をおこなっていない。もし、私がテスト駆動開発をより優れたものであると考えるならば、まず私は自分のところの開発手法を疑わなければならない。

まあ、この程度だ。現在のところ、Mirの利点となりうるかもしれない違いとして私が発見できたのは、これぐらいだ。もちろん、Mirがサイコーとなりうる利点はある。欠点については、私はもう少し長く書く。

ディストロ独自

現在のところ、Mirはたったひとつのディストリビューション専用である。現在のところ、他のディストリビューションでたとえMirが動くとしても、パッケージ化しようと興味を示しているところは存在しない。残念ながら、私は未来を見通す能力をもってはいないが、過去と現在から、未来を予測することはできる。過去を参照すれば、他にもCanonical独自のもので、他のディストリビューションには提供されていないものが存在する。私はUnityをパッケージ化している他のディストリビューションを知らないし、むしろ、UnityをUbuntu以外のディストリビューションでパッケージするのは不可能だとも聞いている。これを考えれば、Mirも同じ道を行くことはありうる話である。Unity用に設計されているのだから、他のディストロがUnityをパッケージ化しないのであれば、Mirだってパッケージ化する必要性がない。

これはMirの受け入れの可否に相当な影響を与える。KDE Workspace開発者で(K)Ubuntuを使っている者を、私は知らない。一体どういう開発が行われているのかとか、コードのレビューや保守はどうなっているかなど、私は一切わからない。これはつまり、受け入れる際には、ifdefで囲まれ、誰もコンパイルせず、誰も実行しないということになる。これでは朽ちていくのがあらかじめ約束されたようなものだ。そもそも、我々のCIシステムはopenSUSE上で動いているのだから、CIすら問題を検知できないということだ。もちろん、Kubuntuのような下流で開発されて、上流にパッチを送るという考えられるが、Kwinのソースコードを引っ掻き回すのは大事になるので、私はそういうことはしないことを大いに推奨する。また、我々が皆同意するように、下流パッチは邪悪である。我々はもはやそのような下流のユーザーをサポートできなくなるからだ。

アーキテクチャー

MirのアーキテクチャーはUnityを中央に据えている。Mirの仕様書はよくわからないBuzzワードだらけなので、Mirのアーキテクチャーを理解するのはとてもむずかしい[5]。私の分かる限りでいえば、Unity Nextとは、Mir上で実装されるウインドウマネージャとデスクトップシェルだ。これがどのようなものになるのか、私には分からない。とにかく、これはデスクトップシェルとウインドウマネージャを分離するという、我々の設計にはそぐわないし、我々はMirがそのような設計をサポートするかどうか分からない。また、MirがメインのターゲットであるUnity Next以外のデスクトップシェルをサポートするかどうかも分からない。一方Waylandは、複数のコンポジター実装を念頭に設計されている。Kwinをセッションコンポジターとするのは、規格の例にも示されている。

ライセンス

WaylandはXのようにMITライセンスでライセンスされていて、これはディスプレイサーバーとしてふさわしい。私はこれをとてもいいライセンスの選択であると思うし、Wayland開発者がこのライセンスに決めたことを嬉しく思う。MirCLA付きGPLv3のみでライセンスされている。私はこのような部分のスタックにこのようなライセンスを使うのは不適切であり、KDE Plasmaから使うのはリスクに晒すと思う。KWin(とほとんどのKDEソフトウェア)は「GPLv2とそれ以降」なので、これが不可能になり、KWin(とMirサーバーに依存するソフトウェア)はMirの派生物となるので、我々のコードは「GPLv3のみ」にしてしまう。私は「GPLv3のみ」のソフトウェアを我々のアプリケーションスタックのコア部分に依存させるつもりはない。これは将来GPLv3と非互換のGPLv4がでてきたときに深刻な問題を引き起こす。私はCLA[6]が嫌いだ。そのため、ライセンスの点から、Mirは到底受け入れがたい。

Unity専用/プロトコルなし

Waylandにおける重要な点は、プロトコルを拡張できるという事だ。これはXでも重要な機能になっていて、ICCCMやEWMH上で我々の独自拡張を使って、追加の機能を実装している。もちろん、我々のworkspaceにも独自のアイディアがあり、これを興味のあるよそのためにも、「標準化」できることは重要である。これはプロトコル拡張のおかげだ。
Mirには本物のプロトコルがない。「内部コア」は、「プロトコル無保証」と記述されている。我々が使うにあたっては問題になる。我々のアーキテクチャは、上記の通り異なったものであり、デスクトップシェルとコンポジターの間にプロトコルが必要になる。Mirがそのようなプロトコルを提供しないのであれば、独自プロトコルを使うしかない。その独自プロトコルはすでに存在していて、「Wayland」と呼ばれている。とすると、MirをサポートするのにWaylandプロトコルが必要になるのか?!? わけがわからない。必要な機能を得るためにMir上でWaylandを走らせる必要があるというのならば、そもそもMirを走らせる必要があるのか?

なおさら悪いことに、MirサーバーとMirクライアントの間のプロトコルは、安定とはされていない。実際、いずれ互換性を壊すと約束されている。これは重大な問題だ。これは致命的な障害物だ。Canonicalにとってみれば、これは問題ない。Canonicalは全体を支配しているので、QMirのようなプロトコルを使って全体を変更できるからだ。

我々にとっては、全く別だ。プロトコルがいつ何時でも変更されうる上、すべてがUnityのためだけに開発されていることを考えれば、サーバーライブラリにバイナリ互換はなく、サーバーライブラリの古いバージョンは最新版のクライアントライブラリとお話できないということが予測できる。我々は常に不安定で互換性を破壊する土台の上で開発しなければならなくなる。これはとても批判的にみえるかもしれないが、私はあるCanonicalのプロトコルがリリースサイクルの後期になって変更され、Kubuntuの同プロトコルを使うアプリケーションを完全にぶち壊した例を知っている。この経験から、リリース前にプロトコルが変更されてKubuntuが出荷できなくなる事態が起こらないと信頼することなどできやしない。

これはサイコーではなくサイテーだ。KWinはMir上でまともに動くことはない。

この考察で、KDE Plasma workspaceの中でMirを使うのは選択肢に鳴らないという事を示せたと思う。MirがWaylandより優れているということは一切なく、同時に、Mirを統合できず、Waylandとともにサポートするという事もできない障害物が複数ある。不安定プロトコルとライセンス選択は明らかに受け入れられない。

Kubuntuはどうなるのだろうか。

疑問符

CanonicalによるMirへの移行は、Kubuntuに疑問をもたらす。回答できる疑問もある。上流はサポートの興味なし。サポートのためのパッチ受け入れもまずなし。上流がMirを使わない以上、UbuntuがMirに移行した後の、Kubuntuのグラフィックスタックはどうなっているのだろうか。この疑問には今答えることはできないが、おそらくあまり良くはないだろう。

スタックへのパッチ

Ubuntuは常に、自由ソフトウェア界における最悪のグラフィックスタック環境である。バグトラッカーから明らかだ。UbuntuのMesaスタックの品質はとても悪い。MirではUbuntuはMesaスタックをさらに激しくパッチしなければならないだろう。実に見たくない光景だ。しかも、MesaはWaylandサポートを有効にした状態でパッケージ化されなければならない。しかし、Canonicalは継続してそんなことをするのだろうか。もししないとなると、Kubuntu(や他のUbuntuフレーバー)は、独自のMesaスタックをつまなければならなくなるのだろうか。もし、Canonicalによる変更があまりにも大きく、標準MesaスタックがUbuntuスタックの上で動作しなくなったらどうするのか?

Switching Sessions

セッション切り替え

自由ソフトウェアの利点のひとつに、デスクトップ環境をログインマネージャから選択できるという事がある。Mirの世界ではこれが不可能になるのではないか。UnityはMirシステムコンポジターとLightDMの上で動作する。KDEはXサーバーかWaylandシステムコンポジターを必要とする。従って、ログインマネージャから直接、別のシステムコンポジターを使うセッションを立ち上げることが不可能になる。同じシステム上でUnityとKDE Plasmaの両方を使うことがいつまで可能だろうか。UnityとKDE Plasma(あるいはGNOMEやXFCEなど)のセッションを同時に立ち上げることは、不可能になるのではないか。

システムコンポジター

システムコンポジターはシステムのどこまで奥深く潜りこむのだろうか。Mirシステムコンポジターを無効にしてXやWaylandに切り替えることは可能なのだろうか。パッケージがコンフリクトしたらどうするのだろうか。KubuntuとUbuntuを同じッシステム上にインストールすることは、今後も可能なのだろうか。Canonicalがそういうことを気にするだろうか。システムコンポジターとは、いずれGRUBでUbuntuかKubuntuを選択して切り替えるレベルにまで落ちるだろうか。

Packages from Where

どこからパッケージ

現在のところ、XとWaylandとMesaはCanonicalによってパッケージ化されている。しかし、将来はどうなるだろうか。Xのパッケージは存在するのか、Waylandのパッケージは存在するのか。存在しないとしたら、どこから持ってくればいいのか。大方はDebian unstableだろう。しかしDebianは停滞するかもしれない。そもそもUbuntuスタックでXとWaylandのDebianパッケージを使うという事が可能なのだろうか。KDE Plasma[7]の要件を満たすのだろうか。もしCanonicalがWaylandパッケージを提供せず、universeに落としたならば、mainのMesaには依存できない。WaylandサポートのMesaをどうすればいいのだろうか。

未来は未来にならないと分からない

このような疑問には、今答えることができない。MirがUbuntuスタックに統合されるまで待たなければならない。その後に、Kubuntu開発者はスタックがどこまでぶっ壊れるのかを知るであろう。私は、Mirへの移行が完了した後に、Ubuntuフレーバーを提供可能であると楽観的に考えてはいない。CanonicalがUbuntuの上に作られるコミュニティ提供のディストリビューションにそれほど興味を持っているとは思わない。そのような兆候が様々な些細な変更点から察せられる。まあ、いずれ分かるだろう。あるいは、私は批判的すぎるのかもしれない。

[1] CanonicalがWaylandに対する誤った情報を流しつつMirを発表したことを考えれば、この技術を却下するにあたって、これも技術の可否を選択する妥当な手法ではないかと思う。

[2] 我々のバグトラッカーがUbuntuリリースのあとに、また膨れ上がったので、まあUbuntuにはいらついていたのだ。

[3] 実際、KwinがMir上で問題なく動くという声明を出したときは、KDE e.V.(訳注:ドイツのKDE登録協会)に言って、Abmahnung(訳注:ドイツ法における法的要請)を送ってもらおうかとも思っていたのだ。

[4] 実際のところ、私はテスト駆動開発を、その一部には便利なところもあるが、無意味で無価値な手法だと考えている。

[5] 「我々のプロトコルと、プラットフォーム不関与アプローチによって、我々はプラットフォーム群とデバイスフォームファクターにおける一貫して美しいユーザーエクスペリエンスのゴールに到達できる」

[6] もちろん、QtにもCLAはあるし、私も署名している。しかし、QtにはKDE Free Qt Foundation agreementがある。

[7] 先週、KWinに入った機能は、私にはテストも利用もできない。なぜならば、Debian testingのX_serverは古すぎるからだ。

WaylandとMirの流れを追っていない人のために解説しておく。

まず、現在UNIX互換環境で主流のディスプレイサーバーはX11を実装したX.Orgである。しかしX11は大昔に設計されたものであり、色々と時代にそぐわなくなってきている。そこで、全く新しいプロトコルを新規に設計して実装しようという動きがある。それがWaylandで、最近設計され、実装が進んできた。

Canonicalは当初、UbuntuをWaylandに移行させると発表してきたが、突然、秘密裏に独自開発してきたディスプレイサーバーであるMirに移行することを発表した。

この発表で、自由ソフトウェア界は大いに揺れている。

さて、このブログ記事であるが、ブログコメントや、Hacker Newsで議論されている。議論の内容は、部外者でも議論しやすい、テスト駆動開発とライセンスに集中しているようだ。

Martin Gräßlinは、あまりテスト駆動開発を評価していないようだが、テスト駆動開発の信奉者が激しい反論を始めている。また、ライセンスがGPLv3のみで貢献にCLA必須というのも、それほど悪いことかと反論されている。

CLAとは、貢献者が著作権をソフトウェアプロジェクトに譲渡するものだ。ある程度の規模の自由ソフトウェアプロジェクトならばどこもCLAを採用している。その目的は、将来プロジェクトのライセンスを変更する必要が生じた場合、貢献者ひとりひとりに個別に同意を求めるのは不可能だからだ。Martin Gräßlinの主張では、Qtは将来ソフトウェアをLGPLやGPLv3でも提供し続ける約束をしているのでCLAに安心して同意できるとのことだが、あまり変わらないのではないかと思う。

ディスプレイサーバーがGPLv3であることの是非についてだが、GPLは著作権と特許権をもとにしたライセンスである以上、ディスプレイサーバー上で動くクライアントにまで著作権が及ぶはずもなく、クライアントソフトウェアからは問題がないのではないかと思う。クライアントソフトウェアから使うライブラリは、LGPLなどのもう少し制限のゆるいライセンスを使うだろうし。もしディスプレイサーバーがGPLであることが問題だとするならば、カーネルだってGPLが問題になるはずだ。

ただし、KWinはその性質上、Mirを取り込む場合、Mirの派生物になるので、GPLv3のみで、しかもライセンスの選択がCanonicalに握られているのは、問題になるかも知れない。

2013-05-11

VP9の完成が近い

The WebM Open Media Project Blog: VP9 Codec Nears Completion

VP9のビットストリーム仕様を6月17日をもってフリーズして正式版にするそうだ。YouTubeなどでも順次VP9で提供を始めていくらしい。

ビットあたりの画質はともかく、リファレンス実装のエンコード、デコード速度はどうなんだろう。

2013-05 post-Bristol mailingの簡易レビュー

ISO/IEC JTC1/SC22/WG21 - Papers 2013

2013-05 post-Bristol mailingが公開された。

すでに、今回正式にドラフト入りした論文は、本の虫: Bristol会議でC++14ドラフト入りが決まった提案一覧で一部解説している。また、本の虫: C++WG 2013-03-pre-Bristol mailingの簡易レビューでも、ここで出てくる論文の改定前のものを解説している。

今回は採択された論文もあったものの、ドラフトの変更は公開されなかった。

N3624: Core Issue 1512: Pointer comparison vs qualification conversions (revision 3)

すでに何度も紹介したが、ポインターの比較やcv qualifierの変換に変更を加える提案。

この変更によって、以下のコードをill-formedにする。

void f(char * p)
{
  if (p > 0) { ... }
  if (p > nullptr) { ... }
}

以下のコードはwell-formedにする。

void g(int **p1, const int**p2)
{
   if (p1 == p2) { ... }
}

N3625: A URI Library for C++

URIライブラリの提案のN3507からの改訂版。

リファレンス実装はcpp-netlib/uri · GitHubで公開されている。

[不潔なPDF] N3626: Floating-Point Typedefs Having Specified Widths

<cstdint>では、int16_tとかint32_tなどのように、長さが指定された整数型のtypedef名が宣言されている。この提案では、それの浮動小数点数版を提供する。

typedef名は、float16_t, float32_t, float64_t, float128_tとなり、それぞれIEEE浮動小数点数フォーマットにおける、binary16, binary32, binary64, binary128に対応する。

このtypedef名が宣言されるヘッダーであるが、従来の<cstdint>ではなく、新たに<cstdfloat>というヘッダーを設けてそこで定義することが提案されている。

この提案により、移植性の高いビット長を指定した浮動小数点数の利用が可能になる。特に、16bit長や128bit長の浮動小数点数の指定が、移植性の問題なく記述できるというのは大きい。

なお、これらはoptionalであり、このような浮動小数点数がサポートされない環境では定義されない。

N3627: Relaxed switch statement

switch文の制限を緩和して、任意の、整数型に暗黙に変換できず、constexpr operator ==を持つリテラル型を使えるようにする提案。

C++では、JavaScriptなどの他の言語のように、任意の実行時評価される式を使うわけには行かない。なぜならば、operator == が副作用を持つ場合、switch文はマッチングではなく、上から下に順番に比較して一致するものを探すという意味に変わってしまうからだ。constexpr operator ==を要求するのはそのためだ。operator ==は実行時評価することもできるが、constexpr縛りにより、副作用が禁止され、コンパイル時と実行時で評価が変わることがなくなる。

そして、string_refもしくはstring_viewのような標準ライブラリや、標準ライブラリ用のユーザー定義リテラルが採用された暁には、とてもわかり易いコードを書くことができる。

switch (s) {
case "pre"s:
 // do something
case "prefix"s:
 // do more things
 break;
}

とか、

switch (e /* std::complex<double>, or std::array<double, 2> */) {
case { 1.0, 3.0 }:
 break;
}

といったぐらいだ。二番目の例は、ユーザー定義リテラルにより、caseラベルがさらにわかりやすくなる。

switch (e) {
case 1.0+3.0i:
 break;
}

リテラル型で、constexpr operator ==を持ち、暗黙に整数型に変換できないクラス型というかなり限定された条件ではあるものの、かなり便利になる。

ただし、その制限から、普通の人間が使えるような機能ではない。

[不条理なPDF] N3628: C and C++ Compatibility

Bjarne Stroustrupが10年以上前に書いて2002年に公開したCとC++の互換性に関する記事三本をまとめてC++WGの論文として公開。D&Eが好きな人は読んでみるといい。特に、三本目の記事は、2002年当時のBjarne Stroustrupの考え方が現れていて面白い。nullを表すキーワードnullptrはC++11でめでたく採用された。

この文章の執筆から10年以上たっているわけだが、CとC++の溝は深まるばかりだ。

[PDFが許されるのはARM C++までだよねーキモーイ] N3629: Simplifying C++0x Concepts

C++11に入ることが予定されていたFull Conceptと比較して、今提案中のConcept Liteではどのような制限を受けるのかという比較論文。

Concept Liteはテンプレートの実体化元の型が当てはまるかどうかを検証するだけで、テンプレート定義を検証しない。Concept LiteにはConcept Map機能がない。コンセプトのrefinement(コンセプト版派生)がない。axiomがない。コンセプトがデフォルトで暗黙になる。といったところだ。

axiomだけは全然惜しくない。

ところで当時、テンプレートの定義の検証方法について、archetypeという画期的な方法が考案されていたようだ。

A Breakthrough for Concepts « C++Next

単にコンセプトで指定されているだけのことができるクラスを精製して、テンプレートのインスタンス化に成功するかどうかを調べれば良い。こんな裏ワザ的な方法でテンプレート定義のコンセプト検証ができるとは目からウロコだ。

ConceptGCCは糞真面目に検証しようとしてバグだらけの不完全な実装に成り下がっていた。

このarchetype実装では、テンプレートのインスタンス化無失敗保証はできないものの、ほとんどのケースはカバーできるという。何より既存のインスタンス化の仕組みを使うので手軽だ。なんだか、テンプレートの実装方法としてinclusion modelが発明されたのと同じ臭いがする。

このarchetype技法はBoost.ConceptCheckに使われているものと同じらしい。

archetype技法は他のメタプログラミング技法と同じで、変態的な裏ワザだが、面白いことは確かだ。

[PDFは邪道。これは定説] N3630: async, ~future, and ~thread (Revision 1)

基本的に、futureのデストラクターはブロックしないが、std::asyncから返されたfutureのデストラクターだけは特別にブロックする。これは非常に不思議な挙動を引き起こす。

例えば、以下のコードと、

{
    std::async([]{ f() ; } ) ;
    std::async([]{ g() ; } ) ;
}

以下のコードは、

{
    auto f1 = std::async([]{ f() ; } ) ;
    auto f2 = std::async([]{ g() ; } ) ;
}

異なる意味を持つ。前者には同期が発生するが、後者には同期が発生しない。

これは、デストラクターがブロックするため、前者のコードは、もし実装はlaunch:asyncを選んだ場合、二つ目のasyncが実行される前に、一つ目のasyncの終了に同期される。

つまりはこういうことだ。

{
    std::async([]{ f() ; } ) ;
// 一時変数のfutureのデストラクターが実行されるためブロック
    std::async([]{ g() ; } ) ;
}

{
    auto f1 = std::async([]{ f() ; } ) ;
// ブロックしない
    auto f2 = std::async([]{ g() ; } ) ;
// ここで同期
}

さらに、以下の一見ブロックしないようにみえるコード

{
    std::async( std::launch::async, []{ f() ; } ) ;
// ブロック
    std::async( std::launch::async, []{ g() ; } ) ;
}

このようなコードでは、ユーザーは戻り値には興味がなく、単に立ちあげて忘れるという意味で書いたのに、二つ目のstd::asyncを呼び出す前にブロックしてしまう。

さらに難しいのはこのコード

void func()
{
    std::future<int> f = start_some_work() ;

    // その他の処理

    // futureのデストラクターはここでブロックするのかしないのか不明
}

もし、start_some_workの実装が、std::asyncを使っていたならば、futureのですトラクターはブロックする。もし、std::threadを使っていたならばブロックしない。そのため、futureがブロックするかどうか分からない。

このため、既存の挙動を変えて、std::asyncでもブロックしないようにする提案がなされている。

この提案が受け入れられない場合、このことをC++プログラマーに教育しなければならない。しかも、将来は絶対ブロックしない別バージョンのfutureを重複して取り入れることになる。

かわりに、デストラクターでのブロックを保証するlocal_futureを付け加える提案もされている。

また、現在のところ、std::threadのデストラクターは、joinもdetachもされていない場合、std::terminateを呼び出す。一貫性を保つため、std::threadのデストラクターはjoinするようにしてはどうかという提案もされている。やはり、Boostとは違い、C++ではthreadのデストラクターがjoinせずにstd::terminateを呼び出すのは違和感があったので、これはいい変更だと思う。

[クサレPDF] N3631: C11: The New C Standard

Dr. Dobb’sで連載されているC11紹介記事を三本、C++委員に紹介するためにコピー。C++委員以外は本家Webサイトを参照してくれとのこと。

fopen_sって本当にセキュリティだろうか。fopen_sは、uを使わない場合、ファイルを排他的に開く。fopen_sで開かれたファイルは他のプロセスから開くことができない。

Windowsがネイティブに提供しているファイルの排他的なオープンは、Unixの世界ではまれだ。Linuxでは原則として、ファイルロックはadvisoryに行われる。ファイルロックしたい場合openにO_EXCLを指定する。ただし、他のプロセスがO_EXCLを付けずにopenを呼び出すことは阻止できないし、その場合は普通にファイルが開かれる。

ひとつのプロセスに排他的なファイルロックは果たして正しいセキュリティ機能だろうか

一応、Linux独自の実装として、flockでそのようなプロセス排他のファイルロックは実現できるし、他のOSでも、flockやらlockfやらfcntl経由やらで提供されているが、はたしてセキュリティだろうか。

まあ、Cには興味がない。

N3632: Additional std::async Launch Policies

std::asyncに新しいランチポリシーを3つ付け加える提案。

launch::task

これはlaunch::asyncに似ていて非同期だが、スレッドの再利用を許すものである。launch::asyncは、あたかも新しいスレッドで実行されたかのように振る舞うと定義されているが、これはつまり、実際に新しくスレッドを作らなければならない。既存の別のlaunch::async用に作ったスレッドを使いまわすことはできない。新しくスレッドを作ることの利点は、スレッドローカルストレージも新しく確保されるという事で、これはある意味で好ましいかも知れないが、パフォーマンス上問題である。スレッドローカルストレージが以前のものを再利用してもかまわないのであれば、スレッドを使いまわせるlaunch::taskはパフォーマンス上有利である。

launch::sync

これは同期で、しかもstd::asyncの中で実行するランチポリシー。つまり、std::asyncを経由せずその場で直接呼び出すのと何ら変わらない。

これは一見無意味なように思えるが、何らかの目的で同期呼び出しに切り替えたい場合も、別にコードを書くことなく切り替えることができる。たとえば、ポリシーを受け取ってstd::asyncを呼び出すラッパーというのも現実的にありうる。

void routine( std::launch policy, args...)
{
    /* ... */

    std::future<X> fx = std::async( policy, ... );

    /* ... */
}

このようなコードが、もしstd::launch::syncをサポートしていない場合、とても面倒になる。まずstd::launchではなく独自のenumを使わなければならないだろうし、std::asyncを呼び出すか直接呼び出すかの条件分岐も、自前で書かなければならなくなる。

launch::default_

ポリシーを指定しない場合のデフォルトの挙動を明示的に指定するためのポリシー。この値は、sync | async | task | deferredになる。

この提案の結果、デフォルトのポリシーはlaunch::syncも含むことになるが、これは問題ではないだろうか。たとえば

auto f = std::async( []{ /* ブロックする処理 */ } ) ;

このコードは、現行規格では絶対にブロックしない。どちらのlaunch::asyncとlaunch::deferredのどちらのポリシーが選ばれようと、std::async呼び出し自体はブロックしない。しかし、もしN3632が採用されたら、ブロックするかもしれないのだ。

もし、将来の規格が新たに異質なランチポリシーを追加し、デフォルトポリシーが追加された新ポリシーを含むとしたら、デフォルトポリシーを安全に使うことは到底できない。何故こんな明白に危険な提案が出されたのか。

この疑問を著者のPeter Dimovにぶつけてみたところ、

基本的には正しい。しかし、今この時点では、既存のコードへの影響はほぼない。このあとの将来の規格ではデフォルトをいじることはできないだろう

今回、デフォルトを拡張する提案を盛り込んだのは、通る見込みが薄いとしても、今が変更できる最後の機会だからだ。

もちろん、N3632は退けられたので、何の意味もないけど。

とのことだった。たしかに、まだstd::asyncを使った現場で動いている既存のコードは少ないだろう。また、Bristol会議のコンセンサスは、「asyncのランチポリシーを拡張するのではなく、executerライブラリに力を入れるべきだ」とのことだそうだ。

まあ、よくも悪くもstd::asyncはお手軽ライブラリで、柔軟な利用には向いている設計ではない。

N3633: What can signal handlers do? (CWG 1441)

シグナルハンドラーの制限を緩和する提案。シグナルハンドラーの中で普通にローカル変数やアトミックが使えるようになる。

[スカラー電磁波とPDFは人体にとって有害である] N3634: Improvements to std::future<T> and Related APIs

N3558の改訂版。具体的な文面案も盛り込まれた。本の虫: C++WG 2013-03-pre-Bristol mailingの簡易レビューを参照。

[光を放ち今立ち上がる若きPDFに帰依しよう] N3635: Towards restrict-like semantics for C++

restrictをC++でサポートするための考察論文。restrictの利点は疑う余地がないとしながら、C++に導入するのはなかなか難しい。

[もし妻がPDFを使っていた場合、石もて打ち殺さねばならない。申命記 22:13-21] N3636: ~thread should join

N3630からthreadのデストラクターだけに注目した論文。現在、joinもdetachもされていないthreadのオブジェクトのデストラクターが呼ばれた場合、std::terminateが呼ばれる。Boostではjoinが呼ばれたのだが、標準ライブラリに取り入れる際に、明示的にjoinもdetachもされていないスレッドはバグの元だからstd::terminateを呼ぼうという合意に達した。

やっぱり変えようということで、threadのデストラクターはjoinableならjoinを呼び、そうでなければなにもしないようになる。

というかなんで最初からBoostの挙動にしておかなかったのか。

[PDFを信ずる者らを恐怖せしめよ。そのため、彼らの頭を叩き斬り、指をすべて叩き切れ。クルアーン 8:12] N3637: async and ~future (Revision 3)

デストラクターの挙動の違うfutureを追加しようという提案。

既存のfutureとshared_futureは、デストラクターが決してwaitもgetもしないようにする。そして、デストラクターがwaitかgetするwaiting_future/shared_waiting_futureを追加する。

N3638: Return type deduction for normal functions

関数の戻り値の型推定がC++14に入る。まあ、解説の必要もないほど普通の型推論だ。

// auto func() -> int と同じ
auto func()
{
    return 0 ;
}

これはK&R Cにあった暗黙のintのような邪悪な機能ではない。たとえば以下のようなコードは正しくエラーとなる。

// エラー、戻り値の型を型推論できない。
auto func( bool b )
{
    if ( b )
        return 0 ;
    else
        return 0.0 ;
}

再帰も可能だ。

auto power( unsigned int x, unsigned int y )
{
    if ( y == 0 )
        return 1 ;
    else
        return x * power( x, y-1 ) ;
}

再帰の場合も、正しく型推定できるし、すべてのreturn文が同じ型を返せば合法となる。

戻り値の型を指定しない定義ではない関数の宣言もできる。これは、クラスの定義でメンバー関数を宣言だけしたい場合、以下のように書きたいし、

struct A {
  auto f(); // forward declaration
};
auto A::f() { return 42; }

これを許すならば、一貫性を保つため、他の場面でも宣言できるべきであるからだ。

C++14では、推定される戻り値の型に言及しない場合のみ、宣言ができる。

auto f(); // return type is unknown
auto f() { return 42; } // return type is int
auto f(); // redeclaration
int  f(); // error, declares a different function

テンプレートの場合も同様。

template <class T> auto g(T t); // forward declaration
template <class T> auto g(T t) { return t; } // return type is deduced at instantiation time
template <class T> auto g(T t); // redeclaration

もちろん、このような場合に、宣言だけして定義が事前に見えない関数を使うとエラーとなる。

auto f();    // return type is unknown
int i = f(); // error, return type of f is unknown

テンプレートの明示的特殊化や明示的実体化も、元のテンプレートがautoを使っていた場合、autoを使う必要がある。

template <class T> auto f(T t) { return t; } // #1
template auto f(int); // OK
template char f(char); // error, no matching template
template<> auto f(double); // OK, forward declaration with unknown return type

template <class T> T f(T t) { return t; } // OK, not functionally equivalent to #1
template char f(char); // OK, now there is a matching template
template auto f(float); // OK, matches #1

戻り値の推定にテンプレートの実体化が関わってくる関係上、SFINAEかどうかという扱いが気になる。テンプレートの実体化がill-formedの場合は、substitution failureではなく、エラーになる。

auto関数を使うと、lambda式をそのまま返すこともできる。

auto f()
{
    int value = 0 ; 
    return [=]{ return value ; } ;
}

C++11ではクロージャーオブジェクトの型を指定する方法がないため、lambda式によって生成されるクロージャーオブジェクトを直接返すことができなかったのだが、C++14では可能になる。

std::initializer_listを推定することはできない。virtual関数は技術上不可能ではないが、実装がややこしくなるため禁止されている。

N3639: Runtime-sized arrays with automatic storage duration (revision 4)

実行時にサイズを指定できる配列の提案。C99にある機能だ。

N3640: Extending shared_ptr to Support Arrays

shared_ptrを配列に対応させる提案。

N3641: Extending make_shared to Support Arrays

make_sharedを配列に対応させる提案。

[ド低脳PDF] N3642: User-defined Literals for Standard Library Types (part 1 - version 4)

標準ライブラリをユーザー定義リテラルに対応させる提案。std::complexは別論文に分割。

[くそったれPDF] N3643: Range Adaptor for Selecting from Pair or Tuple

pairやtupleを返すイテレーターに対して、何番目かの要素を指定して返すイテレーターアダプターを返すレンジアダプターの提案。

for (auto& i : m)
{
    i.second.foo() ;
    i.second.bar() ;
}

と書く代わりに、

for (auto& i : select<1>(m))
{
    i.foo();
    i.bar();
}

と書くことができる。

[ボケナスPDF] N3644: Null Forward Iterators

要素を刺さず、コンテナーのオブジェクトにも関連付けられていない、nullイテレーターの提案。

[存在時代が冗談みたいなPDF] N3645: Splicing Maps and Sets (Revision 1)

従来のlistで提供されている互換アロケーター同士のlistのオブジェクトで、内部のストレージ上に構築した要素を直接移動するspliceを、mapとsetとunordered_mapとunordered_setにも提供する提案。

mapやsetの特性に合わせた設計になっている。

[わらうべきPDF] N3646: Network byte order conversion

今となっては古典的なバイトオーダー変換ライブラリの提案。テンプレートによるジェネリックな実装の追加の他、互換性維持のために、htonl, htons, ntohl, ntohsも提供する。ヘッダー名<net>が提案されている。

個人的な意見では、この2013年に、ネットワーク越しにバイトオーダーが問題になるようなプロトコルを使うべきではないと思う。UTF-8か、ビット列を使うべきだ。

N3648: Wording Changes for Generalized Lambda-capture

Generalized Lamda-captureの文面案。このgeneralizedとは、汎用ラムダキャプチャー、あるいは一般ラムダキャプチャーなどと訳すべき機能で、ラムダキャプチャーで識別子と初期化子からなる文法を使い、キャプチャーの方法を明示的に指定できる機能だ。

void f()
{
    int x = 1 ;
    // [x] と同じ
    [ x = x ] { return x ;  }() ;
}

汎用ラムダキャプチャーは、例えば変数を別名でキャプチャーすることができる。

void f()
{
    int x = 0 ;
    // xをyという名前でコピーによるキャプチャ
    [ y = x ] { } ;
    // xをyという名前でリファレンスによるキャプチャ
    [ &y = x ] { } ;
}

初期化子は、他の初期化子と何ら変わりなく使える。

void f()
{
    int x = 0 ;
    // xに1を足した値をxという名前でコピーによるキャプチャ
    [ x = x + 1 ] { } ;
    // x == 0
}

汎用ラムダキャプチャーは代入ではないことに注意。あくまでキャプチャーの方法を指定するだけである。

汎用ラムダキャプチャーに難でも書ける初期化子がある最大の理由は、ムーブキャプチャーを書けるようにするためだ。

void f()
{
    std::vector<int> v ;

    // vをvという名前でムーブしてコピーによるキャプチャー
    [ v = std::move(v)] { } ;
// ここでvはムーブされている
}

また、クラスのメンバーをコピーキャプチャーすることもできる。

struct X
{
    int member ;
    void f()
    {
        // エラー、変数名memberは存在しない
        [member] { } ;

        // OK、ただしmemberはthis経由のリファレンスによるキャプチャー
        [=]{ return member ; } ;

        // memberをmemberとしてコピーによるキャプチャー
        [ member{member}] { return member ; } ;
    }
} ;

文法は以下の通り

init_capture:
    identifier initializer
    & identifier initializer

初期化子なので、[x = x]のかわりに、[x{x}]といった記述も可能だ。識別子の前に&がつくのは、ムーブによるキャプチャーだ。

文法上は、init-captureとなっている。初期化キャプチャーとでも呼ぶべきなんだろうか。

Generalized Lamda-captureにより、ラムダキャプチャーを一般的な初期化子として記述できるようになる。

この提案はぜひとも入って欲しい。

N3649 Wording for Auto Generic Lambda Proposal (Bristol 2013)

autoジェネリックlambdaの文面案。ポリモーフィックラムダとも言う。ポリモーフィックといっても、静的なポリモルフィズムである。こっちのジェネリックは、型をパラメーター化する方のジェネリックで、つまりはテンプレートと同じだ。

メンバーテンプレートを使った以下のような関数オブジェクトを、lambda式で書けるようになる。

struct Function_object
{
    template < typename T >
    T operator () const ( T t ) { return t ; }
} ;

この提案による同等のlambda式は以下の通り。

[]( auto t ) { return t ; } ;

はよ入れはよ。

[クソ、またPDFか] N3650: Resumable Functions

レジューム可能な関数の提案。この提案はN3634と対になっている。N3634はライブラリベースの非同期処理の提案で、こちらは非同期処理をコア言語で記述できるようになる提案だ。

なぜライブラリベースではだめなのかというと、ライブラリベースで非同期処理を実装すると、以下のようなコードになるからだ。

future<int> f(shared_ptr<stream> str)
{
    shared_ptr<vector<char>> buf = ...;
    return str->read(512, buf)
        .then([](future<int> op)
        {
        // lambda 1return op.get() + 11;
        });
}


future<void> g()
{
    shared_ptr<stream> s = ...;
    return f(s).then([s](future<int> op)
    {
        s->close();
    });
}

このように、とてつもなく読みづらい。あらゆる非同期処理はクラスのオブジェクトを返し、そのオブジェクトのメンバーthenを呼び出して、処理が終了した後の処理を渡す。これはlambdaで可能だ。こうすることによって、非同期処理がライブラリベースで記述できる。Windows RTの設計もこのようになっていて、ファイルひとつ読み書きするにも非同期処理を要求し、しかもとてつもなく制限された実行環境で、ライブラリを作成して配布ということもできないため、Windows RTのプログラマーは皆、自前でライブラリを作るか、諦めてWindows RTを直接使うかの選択を余儀なくされるという非常にクソなことになっている。

このコードは、コア言語が途中で中断して後で再開可能な関数、すなわちResumable functionを提供していれば、とても読みやすくなる。同等のコードは以下のように書ける。

future<int> f(stream str) async
{
    shared_ptr<vector<char>> buf = ...;
    int count = await str.read(512, buf);
    return count + 11;
}
future<void> g() async
{
    stream s = ...;
    int pls11 = await f(s);
    s.close();
}

わざわざラムダを入れ子にするよりよっぽど読みやすい。futureを返す関数にasyncキーワードを使って、resumable functionであることを指定し、awaitキーワードで、それ以降の処理が非同期に実行されることを指定する。

関数の呼び出し元からみると、awaitキーワードが実行された時点で、関数は処理から戻ったようにみえる。もちろん、実際には実行が中断されているだけだ。結果の戻り値を確認するにはfutureのgetを使わなければならない。futureのgetを使うと、関数の実行が中断された箇所から再開される。実行の再開は、別のスレッドで行うこともできる。

ライブラリベースの非同期処理では、このawait以降に当たる処理を、関数の入れ子にしなければならない。さらに、メモリは動的に確保しなければならない。Resumable関数では、実装がスタックなどのメモリを動的に確保するので、普通の自動変数が使える。

[PDFは死滅せよ] N3651: Variable Templates (Revision 1)

変数テンプレートの提案。変数宣言をテンプレート宣言できるようにしただけで、文面上はそれほど大きな変更ではない。ユーザーが見るコードとしては、相当な変化があるが。

N3652: Relaxing constraints on constexpr functions

constexpr関数の制限を大幅に緩和する提案。議論の結果、以下の制限緩和の合意に至った。

constexpr関数の中での変数宣言。ただし、staticとthread_local、未初期化の変数宣言を除く。

constexpr int ok( int x )
{
    int temp = x ;
    return temp ;
}

constexpr int error()
{
    static int a = 0 ; // エラー
    thread_local int b = 0 ; // エラー
    int c ; // エラー、未初期化

    return 0 ;
}

ifとswitch文の許可(gotoは禁止)

constexpr bool Not( bool b )
{
    if ( b )
        return false ;
    else
        return true ;
}

constexpr bool prime_table( unsigned int value )
{
    switch( value )
    {
        case 2 :
            return true ;
        case 3 :
            return true ;
        case 5 :
            return true ;

        default :
            return false ;
    }
}

これで条件分岐をまともな文として書ける。

寿命が定数式評価時に始まるオブジェクトの変更。

constexpr int f( int x )
{
    int temp = 0 ;
    temp = x * x ;
    return temp ;
}

ループ文をすべて許可:for(Range-based forも含む), while, do-while

constexpr unsigned int power( unsigned int x, unsigned int y )
{
    unsigned int temp = 1 ;
    for ( ; y != 0 ; --y )
    {
        temp *= x ;
    }

    return temp ;
}

これでループを再帰で書かなくてもすむ。

また議論の結果、constexpr非staticメンバー関数は暗黙のconstではなくなった。よくぞ決断した。

N3653: Member initializers and aggregates

メンバー初期化子とaggregate初期化を組み合わせて使えるよう制限を緩和する変更の文面案。

制限緩和の背景について詳しくはN3605: Member initializers and aggregatesを参照。

N3654: "quoted" proposal

区切り文字を含む文字列をそのままストリームで扱うマニピュレーターの提案。

[PDFは絶滅しろ] N3655: TransformationTraits Redux, v2

メタ関数のエイリアステンプレートによるラッパーを追加。いちいちメタ関数の戻り値を得るためにtypeという名前のnested typeを書かなくて良くなる。ラップする名前はmetafunctionという名前のメタ関数に対して、metafunction_tとなる。

[preを利用した実質プレインテキストなHTML] N3656: make_unique (Revision 1)

make_sharedのunique_ptr版であるmake_uniqueの提案。

[[preによる実質プレインテキストなHTML] N3657: Adding heterogeneous comparison lookup to associative containers (rev 4)

この論文は[PDF注意] N3465の改訂版である。

C++11では、Dave Abrahamsの論文、Binary Search with Heterogeneous Comparisonのalgorithmによる実装が採用された。具体的には規格を参照してもらうとして、そのheterogeneous compparisonを連想コンテナにも広げる提案。

N3658: Compile-time integer sequences

テンプレートパラメーターパックで使える連番の整数列を生成するライブラリの提案。議論の結果、名前を変更が行われている。また、効率に対する考察が追加されている。これは本の虫: std::make_integer_seqをO(LogN)にしろという議論でボレロ村上さんが問題提起した結果だろう。

効率の考察

N個の整数のシークエンスにおけるリファレンス実装は、N個テンプレートを再帰的に実体化するので、シークエンスの長さはコンパイラーのインスタンス化の深さの最大長に制限されてしまう。シーケンスの両端から開始して、中央に向かって同時に生成することで、インスタンス化の回数をlog2(N)に低減させることは簡単にできる。

コンパイラーintrinsicを使って、再帰なしで任意長の整数シークエンスを実体化することも可能である。

コア言語機能として、...3を{ 0, 1, 2, 3}のようなパラメーターパックに展開し、この問題を解決する別の方法も提案された。この言語機能はC++14の段階では採用される望みはないため、この問題を解決する方法として本論文の提案の採用を妨げるものではない。

うむ、そのコア言語機能は欲しい。

詳しくは本の虫: C++WG 2013-03-pre-Bristol mailingの簡易レビューのN3554の解説を参照。

N3659: Shared Locking Revision 2

multiple-readers / single-writer locking patternを実装するためのライブラリの提案。

[必ず、かの邪智暴虐のPDFを除かねばならぬと決意した] N3660: User-defined Literals for std::complex, part 2 of UDL for Standard Library Types (version 4)

std::complexをユーザー定義リテラルに対応させる提案。他の標準ライブラリのユーザー定義リテラルを追加する提案とは分割された。

N3661: Digit Separators

数値リテラルを区切り文字を使って読みやすくする提案。

問題なのは、その区切り文字を何にするかという事だ。コンマは明白な理由で使えない。今のところ一番人気なのはアンダースコアだが、これも色々と問題が多い。現行の提案論文では、アンダースコアになっている。

N3662: C++ Dynamic Arrays

実行時に長さを指定できる配列ライブラリDynarrayの提案。コア言語でC99の動的配列をサポートするよりライブラリベースで提供すべきだと主張。

N3663: C++ Sized Deallocation

ストレージのサイズを実引数として取るdeallocation functionのオーバーロードを追加する提案。

N3664: Clarifying Memory Allocation

規格のメモリ確保の文面を厳密に解釈すると確保要求のたびに逐一確保関数を呼びださなければならず、また実行時の前後のメモリ確保の状況で挙動を変えてはいけないようにも読める。そのような無意味な制限の撤廃。

N3665: Uninterleaved String Output Streaming

同期してストリームに出力した際、十分に小さな文字列では、出力が途中で分断されないよう保証する提案。

N3666: C++ Latches and Barriers

処理が完了するまでスレッドをブロックするライブラリ、ラッチとバリアーの提案。

N3667: Drafting for Core 1402

ムーブコンストラクターとムーブ代入演算子があまりに頻繁にdeleted定義されるので、条件の緩和の提案。

N3668: exchange() utility function, revision 3

非アトミック版の関数テンプレートexchange()の提案。

[いかなる時でも自転車が壊れたりPDFがはびこれば自転車修理マンは行く] N3669: Fixing constexpr member functions without const

constexpr非staticメンバー関数を暗黙のconstにしない変更の文面案。

N3670: Wording for Addressing Tuples by Type: Revision 2

tupleで重複しない型の要素に、まるで連想コンテナのように型でアクセスできるよう変更する提案の文面案。

N3671: Making non-modifying sequence operations more robust: Revision 2

ひとつのRangeの結果を、別のイテレーターに書き込むアルゴリズムは、出力用の別のイテレーターは開閉の対で取らない。そのため、些細なプログラミング上のミスにより、Rangeの範囲を超えて書き込むということが起こりうる。

そのような既存のアルゴリズムに、出力用のイテレーターも開閉の対で取るオーバーロードを追加する提案の文面案。

というかこのセキュリティが重要な時代に既存の設計はおかしい。

N3672: A proposal to add a utility class to represent optional objects (Revision 4)

ライブラリstd::optionalの文面案。

N3677: A Proposal to Add additional RAII Wrappers to the Standard Library

そうだよ。こーゆーのがほしかったんだよ。

ほとんどの論文がすでに存在する論文の改訂版や文面案だという会議後の論文の中で、これは珍しく新しい論文。

ジェネリックなRAIIラッパーライブラリを追加する提案。unique_ptrをさらに汎用的にしたものだと言える。

独自の簡単な解放処理が必要なリソースや処理に対して、わざわざ自前でクラスを書くことなく、このライブラリで済ませられる。

スコープから抜ける際に条件を満たすなどすれば登録された処理を行うscoped_function, scoped_resource_unchecked, scoped_resource, unique_resourceを追加する。

これはぜひとも欲しい。

N3678: C++ Stream Guards

ストリームを排他的にロックして操作できるライブラリの提案。

N3679: Async future destructors must wait

すんでのところで採択されかけた危険な変更、std::asyncが返すfutureのデストラクターがブロックするのをやめるという変更が、なぜ問題なのかということを解説した論文。

dangling referenceの問題は通常のlambdaにも存在するが、std::asyncを使うとすでに実行されている分、なおさら悪いという事だ。

N3680: Improving Pair and Tuple

現行規格では、pairやtupleを使った以下のコードが動かない。

std::tuple<int, int> pixel_coordinates() 
{
  return {10, -15};  // Oops: Error
}

struct NonCopyable { NonCopyable(int); NonCopyable(const NonCopyable&) = delete; };

std::pair<NonCopyable, double> pmd{42, 3.14};  // Oops: Error

何でダメなんだよ? おかしいだろ? ジョーシキで考えてフツーに動けよ? という疑問に答えるため、何故これが動かないのかという解説と歴史的経緯の説明、そして解決法を提案している。

詳しい理由は論文を読んでもらうとして、暗黙の型変換による些細なプログラミングミスを検出するために、当時はあえてこのような設計にしたのだという。

解決法は、perfect initializationというテクニックを用いる。ほぼ同じメタ関数でガードした非explicitとexplicitなコンストラクターを宣言すると、なかなか興味深いことに、暗黙の型変換を行うdirect initializationは許可するが、暗黙の型変換を行うcopy initializationは許可しないという挙動になるらしい。

それから、"This function does not participate in overload resolution unless […]"という文面は、SFINAEで除去するのではなく、実際にその条件で明示的特殊化をするが失敗するよう定義してもいいのだという。なるほど、そんな手もあったか。

色々と技法の勉強になる。

N3681: Auto and braced-init-lists

auto指定子がbraced initializerからinitializer listを推定してしまうのは問題が多いから禁止しようという提案。

具体的には、auto指定子がinitializer listを推定しないようにし、また複数の要素をもつbraced initializerをautoで受けるのも禁止する。

これは、互換性をぶち壊す変更だ。

// C++11では、decltype(a)はstd::initializer_list<int>
// N3681では、エラーとなる
auto a = { 1, 2 } ;

ただ、このようなコードはまず書かれないだろうから、おそらく問題はないだろう。

N3685: string_view: a non-owning reference to a string, revision 4

文字列を様々な内部表現へのリファレンスで表現して、共通のインターフェースを提供するstring_viewライブラリとその文面案。

N3686: Traversable arguments for container constructors and methods, wording revision 3

従来、Rangeと呼ばれていたコンセプトの提案。ただし、Rangeという名前は意味が重複しており、誤解を招きやすい。そこで、投票の結果、Traversableという名前に改名することに決定した。

しかし、すでにRange-based forという正式な名称があるのだが、ややこしい。

実装は、Range-based forと同じくADLベースになる。

2013-05-10

Linux Mintのno codec版で取り除かれているパッケージ

Linux Mintでは、ソフトウェア特許やDRMといった悪法のある日本やアメリカ向けに、一部の問題の有りそうなパッケージを削除したno codec版のISOイメージも用意されている。では、一体何が取り除かれているのか。

検索しても、取り除かれたパッケージの一覧が見つからなかった。とりあえず教えられたのが、Linux Mint 13の日本語ISOの時に、本家からのパッケージの差異を列挙したものだ。

[Linuxmint-jp-devel:58] Re: 日本語化されたISOの用意について。

なるほど、ほとんどのパッケージは、Ubuntuにも存在する。それも、Universeに存在するパッケージもある。

コーデックの名前通り、音声、動画フォーマットのエンコーダー、デコーダーが多い。

ただし、ひとつだけUbuntuのレポジトリにはないパッケージがある。w32codecsだ。Ubuntuのコミュニティ派生のMedibuntuにはあるらしい。というか、Linux MintもMedibuntuとはそれなりに関係しているらしい。たぶんMedibuntuがもとになっているのだろう。

さて、このw32codecsというパッケージは何なのか。実はこれ、Windows用の動画フォーマットのvfwデコーダーのDLLファイルなのだ。

なぜWindows用のDLLファイルのバイナリがパッケージ化されているかというと、一部のプロプラ動画フォーマットをまともにデコードできるのが、このバイナリしかないからだ。

しかし、Windows用DLLファイルなんてどうやって使うのか。実は、mplayerにはWineから流用したLoadLibraryの実装が含まれており、同じx86アーキテクチャのLinux環境ならば、自前でWindowsのDLLファイルをロードしてマップして実行できるのだ。このようなvfwデコーダーは、純粋な演算だけでWin32 APIを呼び出すという事もないので、そういう方法で実行できるのだ。

でも、このバイナリって再配布していいのとかどうとか、そのへんが不透明にもほどがある。そもそも、開発元がもはや存続していないところすらあるのではないか。

なるほど、そりゃ取り除くわけだ。

FedoraとUbuntuのLinuxカーネル設定の比較

jwboyer: Fedora and Ubuntu Kernel Config Comparison

Red HatのJosh BoyerがFedoraとUbuntuのLinuxカーネル設定を比較している。

たまに、私は洞穴の中、つまりbugzillaから這い出てあたりを見回し、他のディストロのカーネルスペースがどうなっているのか調べる。今日、私はFedoraとUbuntuのカーネル設定の違いについて興味を持った。私は常々、カーネルは注目されるものの、ディストロの中では最も退屈なパッケージであると考えている。カーネルは動くべきであるし、良く動くべきであるし、それだけだ。ディストロを差別化するために存在するのではない。ディストロを動かすために存在するのだ。さて、私の説は正しいのか、あるいは設定の中に、あるディストロを別のディストロと差別化するための何かが含まれているのだろうか。さて、調べてみよう。

私は一行ごとの逐次比較は行わない。なぜならそれは、1)とてつもなく長いし、2)クソ退屈だからだ。例えば、Ubuntuはあるscsiドライバーを有効にしているがFedoraは無効にしているとか反対にとかいったことは、知らなくてもいいことだ。ここでは、様々な機能の部分の軽く調べる。

カーネル

比較目的として、Ubuntu 13.04パッケージのlinux-image-3.8.0-19-genericと、Fedoraの3.8.11-200.fc18の設定を使った。これは同じupstreamカーネルバージョンをベースとしており、どちらもディストロでも、最新の安定版リリースからのものである。私はx86_64(Ubuntu用語ではamd64)ビルドを使った。現在、これを使うのが最もふさわしいと思ったからだ。開発中のカーネルを使うという事もできたが、変更が甚だしいだろうし、広く利用されているものを比べたほうがいいと思ったのだ。

大観

大半の設定はほぼ同一である。ディストリビューションの設定ならこんなものだ。様々なデバイスやバスに対する広範なサポートがあり、ほとんどが組み込みではなくモジュールで提供されている。これは期待通りだ。というのも、どちらも同じupstreamコードベースであるし、ほとんどの設定オプションには、まともな設定はひとつしかないからだ。

低級オプション

とはいえ、一部の低級オプションは違っている。特に大きいのは、UbuntuはCONFIG_NR_CPUSを256にしているが、Fedoraは128に設定しているということだ。ほとんどの人には、128コアのマシンをブートするなどという事すらやりすぎだろう。しかし、Ubuntuはデスクトップとサーバー用に単一のカーネルを使うよう決定したそうだし(たしか12.04からだったと思う)、Ubuntuには高く設定する理由があるのかも知れない。Fedoraとしては、急に大掛かりなマシンのサポートの需要が浮上すれば、その時考慮するまでだ。私は自分用のミニスーパーコンピューターテストシステムを待ち望んでいる。

その他に違っていることとして、NUMAオプションがある。UbuntuはCONFIG_X86_NUMACHIP, CONFIG_MOVABLE_NODE, CONFIG_MEMORY_HOTPLUG, CONFIG_MEMORY_HOT_REMOVEを有効にしている。CONFIG_NODES_SHIFTの値はUbuntuの方が大きく、より多くのNUMAノードが使えるようになっている。これも、彼らのサーバー用途を考えれば、なにか理由のあることなのかも知れない。Fedoraはそのクラスのマシンには日常的に使われない。

HZ分野にも違いがある。FedoraのデフォルトはHZ_1000で、UbuntuはHZ_250だ。つまり、タイマーのtickはFedoraで秒間1000回なのに対し、Ubuntuでは250回となる。一般に、HZの値が大きいと、反応レスポンスがよくなる。サーバーでは、デスクトップやユーザーとの対話を待つ必要はないので、小さめのHZ設定にすれば、タイマーがプロセスを割り込む頻度が減って多くの処理ができる。もちろん、どちらのディストロもCONFIG_NO_HZを有効にしている。つまり、タイマーはCPUがアイドルのとき、必要に応じて割り込みがかかる。私が思うに、どちらもディストロもいずれは、3.10カーネルのマージウインドウに入っている、新しい完全なticklessオプションを採用するのではないかと思う。

UbuntuはCONFIG_FAST_NO_HZも有効にしているが、Fedoraはしていない。このオプションはRCUコールバック待機中にあるCPUを、grace periodを延長することで動的tick状態(アイドル)に入らせるものだ。これはsynchronize_rcu呼び出しを遅らせるが、CPUをより多くアイドル状態に移行させることができ、省電力性に貢献する。聞こえはいいし、実際いいのだろう。Fedoraはこれを有効にして様々な問題に直面したので、無効にしている。このオプションはupstream入りしてからカーネルリリースを何回か経ている。そろそろ我々も再評価してみるべきかもしれない。

デフォルトの選択

g.

大方、デフォルトの選択は同じだ。違いのある箇所は、デフォルトのI/OスケジューラーとかデフォルトのCPU frequency governorとかだ。Ubuntuはデフォルトでdeadlineスケジューラーを使っていて、FedoraはデフォルトでCFQ(Completely Fair Queueing)を使っている。Ubuntuはperformance governorを使っているが、Fedoraはondemand governorを使っている。言っておくと、どちらのオプションも、両ディストロで提供されている。単にデフォルトの設定が異なっているというだけだ。

LSM

セキュリティスタックは、UbuntuとFedoraで大きく異なっている分野のひとつだろう。FedoraはSELinuxのみを使っている。これはFedoraが有効にしている唯一のLSMであり、当然ながらデフォルトだ。Ubuntuは逆に、SELinuxも含めて全て有効にしている。これは少し以外だった。UbuntuがデフォルトのLSMとして使っているAppArmorしか有効にしていないものと思っていた。これにより、UbuntuがFedoraよりセキュアになるということではない。ただし、セキュリティはMACかDACかということに関して、ユーザーに選択の機会を提供しているとも言える。

モジュールオプション

FedoraとUbuntuはどちらも署名付きモジュールを生成している。Ubuntuはセキュアブート目的には必要ないと声明を出していたので、これは以外だった。おそらく、Ubuntuは別の目的に使っているのだろう。UbuntuがCONFIG_MODULE_SIG_SHA512を使っているところをみると、やはり別の目的だろう。FedoraはUEFIで一般的なハッシュ実装であるCONFIG_MODULE_SIG_SHA256を使っている。

UbuntuはCONFIG_MODVERSIONSも有効にしている。これはエクスポートされたシンボルのプロトタイプのCRCを生成するものだ。モジュールがロードされた時、カーネルのCRCをモジュールのCRCと比較して、一致しなかった場合ロードを失敗させるものだ。これは単純なモジュールのABIチェック機構だ。UbuntuはMODULE_SRCVERSION_ALLも有効にしている。これは"srcversion"フィールドを埋め込む。これは、別のカーネル用にモジュールをビルドして、それを知りながらもロードするという事を可能にする。

昔の時代遅れのクソ

UbuntuはFedoraより昔のものを有効にする傾向にあるようだ。Ubuntuはacorn, atari, ultrix, sysv68パーティションをサポートしている。UbuntuはDECNETとパラレルIDEサポートもビルドしている。ARCNET。まず最近じゃお目にかかることすらないし、この現代に使われることもほとんどない。もちろん、Fedoraもいくつかヘンテコなものをサポートしている。FedoraはまだOSSサウンドスタックを有効にしているが、UbuntuはどうやらOSSは捨てたようだ。

Ubuntuは「組み込み」用のオプションをたくさん有効にしている。full MTDサポートとか、珍しいキーボードドライバーとか、SPI, MFD Regulator, GPIOLIBだ。UbuntuはJFFS2, F2FS VXFSファイルシステムをサポートしている。サウンドとかメディアドライバー用の様々なSoCオプションも有効にしている。これはデスクトップやサーバー向けには不思議だが、Ubuntuカーネルをどっかのx86ベースのSoCでブートしたい場合、可能だということだ。

FedoraはKMSをサポートするDRMドライバーのみと、極少数のフレームバッファードライバーを有効にしている。Ubuntuはほとんどすえて有効にしている。私は我々FedoraのKMSにあらずんば帰れ的アプローチに納得している。不思議なことに、UbuntuはCONFIG_LOGOを有効にしていない。まさかペンギンが嫌いなのか?

最後に、UbuntuはFedoraより相当多くのstagingドライバーを有効にしている。知らない人のために解説すると、stagingとは公式mainlineに入る前の修正中のドライバーが放り込まれるところである。Ubuntuは文字通りカーネルをTAINT_CRAPでtaintしている。Fedoraはこういうことは避けている。UbuntuはunionファイルシステムのAUFSや、クソひどいレビューという前科のある新しいAtherosチップ用のイーサネットドライバーであるALXも持っている。

Summary

まとめ

さて、私の「カーネルは動くべきでありそれだけだ」という自説は維持されただろうか。たぶん維持されていると思う。両ディストリビューションのカーネルに、驚くほどの違いはみられなかった。両者の違いの一部は、両者とも再検討する必要のあるものもありそうだが、最終的には、どのオプションも多大な改善というわけでもない。これはやってよかった実験だと思うが、しばらくは再びやらないだろう。カーネル設定を眺めている間に、すぐbugzillaが興味深くなってくるのだから、なかなか暇がない。

ここまで読んでくれたのなら、ありがとう。

2013-05-09

Ubuntuがまたぞろ新しいパッケージフォーマットを再発明?

[Phoronix] Ubuntu To Get Its Own Package Format, App Installer

App installer design: click packages

メーリングリストubuntu-develで、Ubuntuのための新しいソフトウェアパッケージシステムの必要性が議論されている。

この新しいパッケージシステムは、既存のapt/dpkg/debを置き換えるのではなく、共存するらしい。

Debianから受け継いだ既存パッケージシステムはよくできている。依存関係の設定にも相当な労力が費やされている。UbuntuをDebianの最新版と同期するには、今後もdpkgとaptは使うことに変わりはないし、これを捨てる理由はない。新しいパッケージシステムは既存のパッケージシステムと共存する。

では何故新しいパッケージシステムを再発明するのかというと、ベースとなるシステム以外に依存しないパッケージを作りたいからだという。

つまりこうだ。既存のパッケージシステムは、パッケージがお互いに複雑に依存している。あるソフトウェアはあるライブラリを必要とするので、インストール時には、依存するライブラリもインストールしなければならない。あるソフトウェアは、同じライブラリの別のバージョンを要求する。当然これに対応しなければならない。

debとdpkgとaptはそれなりによくやっているが、依存関係のない独立したバイナリを配布するには向いていない。

そこで、土台となるシステムを定め、その土台システムのみに依存するようなパッケージシステムを作ってはどうか。つまり、debならば細かくパッケージを分割していた場合でも、ひとつのパッケージに全部入れて配布するのだ。これにより、パッケージ同士の依存関係は存在しなくなる。パッケージをそれぞれ別の独立したディレクトリにインストール可能になる。インストールにroot権限を必要としない。

と、そういう目的らしい。主に携帯用途のUbuntu Phoneでの活用を目指しているようだ。

私の考えでは、どうもこれは、不自由なソフトウェアのバイナリのみを配布するのに都合のいいパッケージシステムに思えてならない。そういう細かい依存関係が問題になるのは、不自由なソフトウェアのバイナリだけを配布したい場合だ。バイナリのみで配布する場合、共有ライブラリの差異が問題になるので、結果として依存するライブラリは安全のため、すべて同梱という形になる。

さらに、独立したディレクトリにインストール可能とかroot権限を必要としないということにも引っかかる。まさかUbuntu Phoneは利用者に管理者権限を与えない制限コンピューターに成り下がるのではあるまいな。

ただし、今のパッケージシステムが複雑で分かりにくいという事は確かだ。さらに、今のGNU/Linuxでは、単にそのへんに展開してその場で実行というポータブルなソフトウェアも作りにくい。ただし、やはりソースコードを配布して利用者の環境でビルドさせたほうがいいのではないかと思う。その方が究極の移植性を確保できるし、利用者に自由を保証できるし、そのソフトウェアが便利で知名度が上がれば、誰かが代わりにパッケージ化してくれるだろう。

2013-05-08

各種GNU/Linuxベースのディストロのダウンロードの分かりやすさ調査

このつぶやきにピンときたので、各種GNU/Linuxベースのディストロの公式サイトから、ISOイメージのダウンロードの分かりやすさを主観的に比較してみた。

まずそのまえに、わかりやすいという触れ込みのFirefoxの公式サイトをみてみよう。

Mozilla — Home of the Mozilla Project — mozilla.org

たしかに、これ以上にないというぐらい分かりやすい。上部にダウンロードと書かれており、クリックするとダウンロードが始まる。利用者の環境は自動的に判定し、私の環境の場合、GNU/Linux用のビルド済みのバイナリがダウンロードされた。そのへんに展開してfirefoxというスクリプトを実行するだけでFirefoxが実行できる。これはわかりやすい。ユーザーに一切の入力や選択を強いることがない。マウスさえ使えればダウンロードできる。

思うに、ユーザーになにか選択を強いるような設計は悪なのだろう。大多数のユーザーはバカであり、自分のコンピューターのOSやCPUすら知らないと仮定して設計すべきである。そこで、今回は何もわからないユーザーになりきって、可能な限り懐疑的、批判的に、各種ディストロのISOイメージのダウンロード方法を検証しよう。

さて、GNU/Linuxの各種ディストロだが、DistroWatch.comのディストロ別ページへの過去半年のアクセス数をもとに、知名度の高いディストロについて調べてみた。

Main Page - Linux Mint

まず、最近Ubuntuを押しやってアクセス数ナンバーワンのLinux Mint。公式サイトにDownloadという項目がある。クリックすると、以下のページに飛ぶ。

Download - Linux Mint

これはとても分かりにくい。もちろん、私のようなパワーユーザー(死語)には何の問題もないが、あまりにも選択肢が多すぎる。Mate, Cinnamon, KDE, Xfceというよっつのデスクトップ環境ごとにISOイメージがあり、しかもMateとCinnamonに至っては、特許保護されている可能性のあるコーデックを含む版と含まない版が存在する。さらに難しいことに、32bitと64bitに分かれている。

とりあえず、Mateの64bit版を選んでみる。

Linux Mint 14 "Nadia" - MATE (64-bit) - Linux Mint

何やら呪文のような項目が多数並んでいて、非常に分かりにくい。

どうやら、デフォルトのダウンロード方法はtorrentのようだ。.torrentというファイルがダウンロードされる。ここから目的のISOイメージをダウンロードするには、BitTorrentプロトコルに対応したクライアントが必要であり、とても分かりにくい。現在、bittorrentプロトコルを実装している汎用的なブラウザーはOperaしかない。まったくもって初心者に優しくない。

その下に、直接ダウンロードできるミラーサイトがずらずらと並べられている。ここでまた選択を強いる。非常にわかりづらい。

さて、ダウンロードしたISOイメージはどうすればいいのか。MintではダウンロードのページからユーザーガイドのPDFへのリンクを張っている。ユーザーガイドはISOをDVDに書き込む方法や、インストール方法のそれなりに丁寧な解説が書かれている。各国語に翻訳されているが、わざわざPDFを別に読まなければならず、分かりにくい。

Home of the Mageia project

さて、二番目にアクセス数を集めているのはMegeiaだ。公式サイトでは、中央に、でかでかとFree Downloadと書かれている。これは分かりやすい。早速クリックしてみよう。

Download Mageia 2

クリックすると、予想に反して、別のページに飛ばされた。DVD 32bit, DVD 64bit, CDという三種類のインストール用のISOイメージが並んでいる。しかも、それぞれに直接のダウンロードとBitTorrentプロトコルによるダウンロードが示されている。またしてもユーザーによくわからない選択を強いる設計になっている。

その下にLive CD用のISOイメージが並んでいる。あらかじめ設定されているロケールごとにわかれているし、さらにデスクトップ環境としてGNOMEかKDEかを選ばなければならない。もちろん、直接のダウンロードとBitTorrentプロトコルによるダウンロードという選択肢も存在する。

さて、この.isoとかいうよくわからないファイルはどうすればいいのか。Megeiaではとても小さな字で、Mageia 2 Release Notes - Mageia wikiへのリンクが貼られている。ただし、この内容はとても初心者向けではないし、どこに何が書いてあるのか分かりにくい。

Mageiaのダウンロードはとても分かりにくい。

The world's most popular free OS | Ubuntu

気をとりなして三番目のUbuntuをみてみよう。なんと、公式サイトのタイトルからして、世界一有名な自由OSを謳っている。実際、Ubuntuはかなり使われているし、一時期初心者を取り込むため、CDを無料で郵送するサービスなども行なっていた。果たしてISOイメージのダウンロードも世界一簡単なのだろうか。

上部にDownloadと書かれている他、中央にGet Ubuntu Nowと書かれている。おそらくダウンロードはこれだろう。どちらを選んでも同じページに飛ばされる。

Download Ubuntu | Ubuntu

選択肢がいくつかあるが、Ubuntu Desktopが一番上に配置してある。まずこれを選ぶのだろう。他にもサーバーとかクラウドとか読めない中国語とかが配置されてあるが、まあこれではないだろう。

Download Ubuntu Desktop | Ubuntu

するとまた別のページに飛ぶ。延長サポート用の12.04LTSと、最新のUbuntu 13.04という選択が必要だ。さらに、プルダウンメニューから32bitと64bitの選択もしなければならないが、これはデフォルトで32bitが選択済みである。32bit版ならx86ベースのPCならば確実に動くだろう。

さて、いざダウンロードしようとクリックすると、以下の募金ページに飛ばされる。

Desktop contribute page | Ubuntu

募金は任意であり、払わないという事もできる。募金しない場合、Not now, take me to the downloadをクリックすればダウンロードが始まる。まあ、必要なこととはいえ、ダウンロードの手軽さが遠のいてしまう。

一応、ダウンロードを選択するページから、Alternative downloadsのページに飛ぶことができる。ここでは、種類を選んだり、BitTorrentプロトコル用の.torrentファイルをダウンロードできたり、ミラーサーバーの選択ができたりする。

Alternative downloads | Ubuntu

さて、ダウンロードしたISOイメージはどうすればいいのか。Ubuntuでは、ダウンロードの選択をするところから、インストールガイドに飛べる。インストールガイドは、PDFなどではなくWebサイト上で読むことができる。ISOイメージからブート可能なDVDやUSBメモリを作成する方法が、各OSごとに説明されている。

Fedora Project Homepage

さて、Fedoraはどうか。Fedoraの公式サイトトップページも上部に小さくDownloadと書かれたリンクが存在する。ここまでみてきた他のディストロと違い、分かりやすい「ここをクリックしてダウンロード」のようなボタンや、ボタンのようなテキストや画像が存在しない。トップページは全体的にごちゃごちゃとしたつくりで、Downloadのリンクを探すのに手間取った。Linux Mintのトップページもダウンロードのリンクを強く主張していなかったが、Fedoraほどごちゃごちゃしたデザインになっていなかったので、それほどダウンロードリンクの発見に苦労はしなかった。Fedoraはこの点、非常に劣っている。

Fedora Project - Download Fedora and try it.

なんとかダウンロードへのリンクを見つけ出して、小さい文字リンクに苦労しながらカーソルをあわせて押すと、別のページに飛ぶ。こんどは、Download Now!と勇ましく書かれたボタン風テキストが中央に表示される。選択肢は何もない。これを押すだけでISOイメージがダウンロードできる。これはすばらしい。

ダウンロードページの右サイドにインストールガイドがあり、Webサイト上で読むことができる。

Installation Guide

このインストールガイドは、詳細ですばらしいことは確かだ。普段の私ならば賞賛していただろう。しかし、あまりにも堅苦しく真面目すぎて、とても初心者向けではない。初心者向けの簡易なインストールガイドがあればよかったのだが。

Debian -- The Universal Operating System

さて、古参のDebianはどうか。Debianの公式サイトのトップページは非常にシンプルなテキストベースの作りになっていて好感が持てる。しかし、初心者向けには、どうもテキストが多すぎるような気がする。やはり分かりやすい「ここをクリックすればダウンロード!」なかっこいい画像やボタン風テキストを用意したほうが、初心者受けはいいのではないかと思う。CD ISO Imagesと書かれたところをクリックしてみる。

Debian on CDs

まず最初にあるのが、各国向けのCD-ROM購入サービスへのリンク集だ。なんとインストールディスクを郵送してくれるらしい。インストールディスクの作成方法が分からないようなユーザー向けにはすばらしいサービスではないかと思う。日本向けのサービスも存在する。値段も安い方ではないかと思う。

cart.env-reform.com, 「オープンソース」のお店

さて、ISOイメージをダウンロードには、jigdo経由、BitTorrent経由、HTTP/FTP経由、LiveイメージのHTTP/FTP/BitTorrent経由という選択肢がある。

jigdoというのは、特別なソフトウェアを使い、ミラーサーバーを自動で選択して、debファイルをダウンロードし、ローカルでISOイメージを作成するものだ。Debianはjigdoを将来メインのISOイメージ配布方法と書いているが、理解できない。というのも、このソフトウェアがやっていることは、単にISOイメージが欲しいだけの初心者向けではないからだ。jigdoはむしろ、独自にパッケージを選んだカスタマイズISOイメージを作成するツールである。これは到底初心者向けではないし、メインの配布方法とするのはわけがわからない。それに、大量のディレクトリやファイルをローカルに作成するのはパフォーマンス上よろしくない。普通の利用者が最も高速にISOイメージをダウンロードできるのは、やはりBitTorrentプロトコルではないかと思う。

BitTorrentプロトコルは、jigdoよりは有名だ。自動的なハッシュ検証、分割ダウンロード、レジュームなどの機能を備えていて、とても高速にダウンロードできる。しかし、やはり初心者には難しい。

さて、HTTP/FTPを選ぶと、以下のページに飛ばされる。

Downloading Debian CD/DVD images via HTTP/FTP

これは不親切にもほどがある。とてつもなく分かりにくい。これは初心者向けではないからだろうが。

やはり、初心者向けというのはLiveイメージだろう。これならディスクやUSBメモリからブートして試したり、さらにインストールもできる。これが最後の選択肢なのはとても分かりにくいと思う。

Debian -- Live install images

さて、ダウンロードはあはり分かりにくい。アーキテクチャ名がダウンロードへのリンクになっているのはどうかと思う。それに、アーキテクチャ名をクリックしても、さらに以下のようなFTPサーバーに対するHTTPページのようなページに飛ばされるのだ。

Index of /debian-cd/current-live/amd64/iso-hybrid

一体どれをダウンロードすればいいのかさっぱりわからない。

さらに、ISOイメージをどうすればいいのかという説明も、Frequently Asked Questions about Debian CDsの中に埋もれていて、とても探しにくい。

openSUSE.org

openSUSEはどうか。公式サイトのトップページに、Get it!と分かりやすい画像つきのボタン風リンクがある。これを押すと別のページに飛ぶ。

software.opensuse.org: Download openSUSE 12.3

選択肢がたくさんあるが、デフォルトの選択は、直接のダウンロード、32bit PCである。まあ、ほとんどのユーザーの環境に適合するだろう。そのままDownload DVDをクリックするとダウンロードが始まる。分かりやすい。

さて、どうやってインストールしたらいいのか。openSUSEのインストールガイドは、スクリーンショット付きでわかりやすく、USBメモリに書き込む方法や、インストラーの操作方法を解説している。

Portal:Installation - openSUSE

So cool ice cubes are jealous » PCLinuxOS

PCLinuxOSのトップページも、ごちゃごちゃしていて分かりにくい。上部にGet PCLinuxOSとあるから、これをクリックすれば別のページに飛ぶ。

Get PCLinuxOS » PCLinuxOS

左右にごちゃごちゃとなにかがあるが、選択自体は至って質素なページだ。主な選択はKDE Desktopの32bitか64bitかだ。とりあえずKDE Desktop 64bitを選んでみる。

64bit KDE Desktop » PCLinuxOS

何やら細かい文字でびっしりと書き込んである。かなり下までスクロールしないとダウンロードリンクが見つからない。ようやくISO Downloadという文字を見つけるが、直接のダウンロードは下部にあるどのリンクでも同じだとか書かれているだけ。その次にあるのは.torrentファイルのダウンロードリンクだ。

一番下までスクロールして、ようやく直接のリンクをみつける。各ミラーサイトへのリンクが貼られている。すでに上に書かれていたように、どのリンクでも同じなのだが、やはり選択を強いるのは難しい。

Arch Linux

Arch Linux。どうかんがえても初心者用のディストロではないし、いかに難しかろうと誰も文句は言わないようなユーザー層であるが、一応Distro Watchでは8番目にアクセス数の高いディストロであるので、確かめてみよう。右上にDownloadとある。

Arch Linux - Downloads

テキストを主体としたとても質素なページに飛ばされる。推奨のダウンロード方法はBitTorrentで、しかも.torrentファイルではなくマグネットリンクが先になっている。まあ、ArchユーザーならばBitTorrentクライアントぐらい使いこなせるだろうから問題はないだろう。次にネットワークインストール。そしてHTTP経由の直接ダウンロード。

今回の検証の目的からは外れるが、Archのダウンロードページは、ある点においてすばらしい。まず、ISOイメージのMD5、SHA-1のハッシュ値に、さらにはPGP署名まで提供されていること。さらに、それがHTTPSで提供されているという事だ。ハッシュ値の表示程度なら、すでに紹介した別のディストロのいくつかでも行われていたが、いずれもHTTPプロトコルで提供されていた。つまり、悪意ある者によって途中の経路で改変される攻撃を受けた場合、ISOイメージとハッシュ値が両方改変される恐れがある。その場合、私は悪意ある改変が施されたISOイメージをダウンロードしてしまい、念の為ハッシュ値を確かめても、ハッシュ値も改変されているために、改変に気がつかず、まんまと悪意ある改変版をインストールしてしまう。

その点、ArchのWebサイトはHTTPSで提供されているので、途中の経路による改変を阻止できる。すばらしい。

Archはドキュメントの整備もすばらしい。初心者向けではないにせよ、すばらしいことは確かだ。

Manjaro Linux

Distro Watchで9番目にアクセス数の高いディストロ、Manjaro Linux。上部にGet Manjaroとあるリンクをクリックすると別のページに飛ぶ。

Get Manjaro | Manjaro Linux

XFce, OpenBox, ネットインストールから選ぶことができるようだ。選んでクリックすれば、sourceforge.netに飛んでダウンロードが始まる。選択肢は少ないし、ダウンロードはあっさりとしている。

ダウンロードはあっさりしていていいのだが、どうやってインストールするかというドキュメントが見つけにくい。

Puppy Linux

FTP経由か、FTPのHTTP用ページでのダウンロードになり、とても分かりにくい。ドキュメントも乏しい。

Gentoo Linux -- Gentoo Linux News

番外になるが、一応紹介しておかなければ怖い人に刺されそうなので、Gentooも検証してみる。Get Gentooからダウンロードのページに飛べる。

Gentoo Linux -- Where to Get Gentoo Linux

ダウンロードはFTPのHTTP用ページから行う。ドキュメントも初心者向けではないが整備されている。

とりあえずDistro Watchでこの半年アクセス数の多いディストロ10件+Gentooを調べてみた。結論として、Firefoxほど分かりやすいダウンロードを提供しているGNU/Linuxベースのディストロは存在しなかった。ユーザーに選択を強いるのは難しい。ユーザーはその選択の意味を理解できないからだ。やはりデフォルトの選択を提示し、ユーザーが望めば、必要に応じて選択させるデザインであってほしい。さらに、落としたISOイメージをどうするのかという初心者向けの簡易ドキュメントも重要だ。これがないか、ダウンロードページからわかりやすくリンクの貼られていないWebサイトは難しい。

BitTorrentプロトコルの人気も気になるところだ。たしかに、BitTorrentプロトコルは便利だ。ダウンロードのハッシュ値チェックも自動で行われるし、レジューム機能も標準搭載している。ただし初心者向けではない。

それにしても、8番目にDistro Watchの専用ページへのアクセス数が多いディストロがArchという事自体、まだまだGNU/Linuxの普及が進んでいないという事だろう。

追記:

Debianはトップページの右上にダウンロードのリンクが貼られており、クリックするだけでHTTPプロトコルを使って直接ダウンロードが始まるが、この記事を書いている時、私は気がつかなかった。なぜかというと、私は1920x1200のディスプレイを使っており、デザイン上、右上というのは視界の外にあったからだ。

Fedoraはトップページの画像に分かりやすいダウンロードへのリンクがあるが、この記事を書いている時、私は気がつかなかった。なぜかというと、この画像、JavaScriptを使い、時間経過で自動的に4種類の画像が切り替わるようになっている。私はFedoraの公式Webサイトのトップページを開いた直後に閲覧したのではなかったので、画像が切り替わった後にダウンロードリンクを探した結果、見つからなかったのだ。