2011-03-31

VS2010 SP1に対するWindows SDKのアップデート

Released: Visual C++ 2010 SP1 Compiler Update for the Windows SDK 7.1 - Microsoft Windows SDK Blog - Site Home - MSDN Blogs

VS2010 SP1とWindows SDKを併用すると、コンパイラーが削除されてしまうというバグがあったが、Windows SDKが修正された。

2011-03-30

gcc 4.6のconstexprバグ

gcc 4.6では、以下のコードがエラーになる。

struct X
{
    constexpr X() { }
    constexpr X f( X x ) { return x ; }
} ;

このコードは、well-formedである。なぜならば、クラス型は、クラス定義の内部では不完全型であるが、戻り値や仮引数の型では、完全型であるとみなされるからだ。9.2 Class members [class.mem] paragraph 2

このバグを26日に発見したので、報告したところ、29日に修正された。gcc 2.6.1はこの修正を含むそうだ。

Bug 48296 – [C++0x] constexpr member function cannot use the class type it belongs as parameter type or return type

しかし、何で私が実際に何かコードを書こうとするたびに、コンパイラーのバグに出くわすことになるのか。

constexpr constructorを使った、短いコード例を考えているが、特に思いつかない。関数はともかく、クラスオブジェクトをコンパイル時定数にできるというのは、なにか面白そうな例が思いつきそうなのだが、どうも出てこない。困ったものだ。

2011-03-27

なぜ漫画雑誌は無料で公開するのか

この度の震災によって、物流が滞っている。面白いことに、漫画雑誌は、ネット上に、無料で雑誌を公開し始めた。何故そんなことをするのか。果たして、単なる見せかけのチャリティ(笑)や、宣伝と称する売名行為のためだろうか。

日本における漫画雑誌は、事実上、立ち読みし放題である。漫画雑誌を丁寧にもひもで縛っていたりラップしていたりする書店の方が少数派である。大多数の書店は、漫画雑誌を立ち読み可能な形で、そのまま陳列している。

したがって、漫画雑誌を無料で公開すること自体は、なにも新しい考えではない。もともと、当然の如くに立ち読みされてきたのだから、今更、無料でネット上に公開されたところで、影響はないだろう。

しかし何故、流通が途絶えたからといって、にわかにネット上で公開しだすのか。

この問題を考えていた私は、ある結論に至った。もし、数週間ないしは数ヶ月ほど雑誌を読まなくなると、再び読もうという気がなくなるからである。娯楽品はある種の中毒性を持っていて、頻繁に楽しまない娯楽は、忘れてしまうのだ。

私は高校生になった時から、漫画雑誌をあまり読まなくなってしまった。理由は、様々あるが、高校生に成り立ての頃、色々と忙しく、数週間ほど、漫画雑誌を読む暇がなかったのだ。何しろ、当時の私は、片道10キロメートルほどの道のりを、自転車で通学しなければならなかったのだ。私は田舎に住んでおり、都合のいい電車やバスは通っていなかったのだ。そのような田舎でさえ、毎週、発売日の前日に、漫画雑誌は店頭に並ぶのである。

数週間して、通学にも慣れたのだが、再び漫画雑誌を読む気にはならなかった。漫画雑誌を読まないと、単行本も買う気がしない。そして、私は次第に、漫画から離れていった。

いま、震災によって流通が滞り、数週間、ないしは数ヶ月、漫画雑誌を読まなかったとすると、かつての読者の大半は、漫画雑誌を読むのをやめてしまう。おそらく、出版社が恐れていることはこれだろう。

たとえ普段は立ち読みでも、読んでいる限り、ある程度の金は落としてくれる。しかし、一切読まない者からは、金は落ちないのだ。

しかし、出版社は今ひとつ煮え切らない。聞説、ネット上で公開されている漫画雑誌を閲覧するには、専用のソフトウェアが必要だというではないか。しかも、そのソフトウェアは、MS Windows専用だというではないか。

そのような、本来、技術的に不必要な、環境依存の制限を強いる漫画を読む義理はない。我々は読むのをやめるべきである。なあに、心配はない。漫画中毒は、治療が可能だ。数週間も読まずにおれば、さほどまでに読みたいとは思わなくなる。数ヶ月もすれば、もうすっかり禁断症状も収まり、読もうとも思わなくなるだろう。

そもそも、いまどき書籍程度は電子媒体で提供されているべきなのだ。技術的には何の問題もないのだ。ただ、既存の価値観にとらわれている出版社が拒否しているだけなのだ。我々はそのような不親切なコンテンツを閲覧する必要はない。

gcc 4.7が始まった

世間では、gcc 4.6のリリースに沸いている。しかし、「人と同じことをするのは馬鹿だ」という銘を座右に刻んでいる私は、そのような大衆迎合には応じない。代わりに、gcc 4.7の開発が始まったことを嬉しく思う。

また、llvm 2.9のリリースも、来週に控えている。聞説、LLVM 2.9では、ref-qualifierを実装しているそうだ。ref-qualifierとは、簡単に説明すれば、thisポインターの参照するオブジェクトが、lvalueリファレンスなのかrvalueリファレンスなのかを指定するものである。楽しみだ。

struct X
{
    void f() ; // lvalue
   void g() & ; // lvalue
    void g() && ; // rvalue
} ;

int main()
{
    X x ;
    x.g() ; // lvalue
    std::move(x).g() ; // rvalue

}

キャップが足りない!

asahi.com(朝日新聞社):キャップ不足、ミネラル水の増産ピンチ 工場が被災 - ビジネス・経済

品薄のミネラルウオーターの増産が、ペットボトル容器のキャップ不足で危うくなっている。大手のキャップ工場が東日本大震災で被災し、生産量が激減。キャップの色や形が飲料メーカー各社で違うことも、生産量が上がらない要因になっている。

各社のキャップは、同じ工場で作り分けている。別の社のキャップの生産に切り替える際は、生産ラインをいったん止めるため、作るキャップの種類が増えると、生産効率が落ちる。キャップメーカー幹部は「各社がキャップの色と形を統一してくれれば、もっと作れるのに」と嘆く。

飲料メーカー側も、キャップ不足を心配する。担当者は「工場にはもっと増産する余裕はあるが、キャップが足りず、できない」と明かす。

まるでFalloutの世界だ。水商人が、水を売るためにキャップを要求する。すると、日本でFalloutが起きたら、キャップが貨幣になるのだろう。

なお、なぜFalloutの世界の通貨はキャップなのかという理由については、falloutのwikiが詳しい。

Bottle cap - The Vault, the Fallout wiki - Fallout: New Vegas and more

2011-03-26

C++0xのFDISが可決された

Madrid会議で、とうとうFDISが可決されたそうだ。ドラフトの文面ができあがるまでには、なお数週間を要するが、とにかく、ようやく、FDISが可決された。あとは、各National Bodyからの投票があるだけだ。この投票は、認めるか認めないかという二択だけである。もはや、コメントはない。

ちなみに、range-based forはどうなったかというと、結局#5になるようだ。基本的にはメンバー関数begin/endを呼びだすが、見つからない場合に、ADLにフォールバックする案である。

We Have FDIS! (Trip Report: March 2011 C++ Standards Meeting) « Sutter’s Mill

2011-03-25

Duke Nukem Foreverが発売延期

Duke Nukem Forever gets one last delay | thinq_

まあ、今更驚かないが、5月6日から、6月10日に延期されたらしい。

というわけで、以下の動画でも聞きながら待つといいだろう。

2011-03-22

青空縦書きリーダーを大幅に更新

青空縦書きリーダー - Google Chrome extension gallery

Chrome extensionの青空縦書きリーダーを大幅に更新した。ブラウザーアクションを追加した。

ブラウザーアクションから、任意のサイトを縦書き化可能になりました。ただし、webkitの実装が完全ではないため、色々と不都合があります。

ブラウザーアクションから、ルビ表示の切り替えが可能になりました。

chrome.tabs APIへのアクセスと、任意のサイトへのcontent scriptの注入のため、パーミッションを変更しています。そのため、アップデート後は手動で有効にする必要があります。

Chrome自体のバグのため、ローカルファイルに対して縦書き化やルビ切り替えが効きません。

browser_action on file:/// - Chromium-extensions | Google Groups
Issue 76705 - chromium - file:// not working for "permissions" in extensions, but does work for content scripts. - An open-source browser project to help move the web forward. - Google Project Hosting

2011-03-21

.xxxは言論の自由を脅かす

少々出遅れた感があるが、ICANNが.xxxを可決した。これはインターネット上の言論の自由を脅かす出来事である。

何故ならば、この新しいTLDによって、例えばある国では、アダルトコンテンツと判定されたコンテンツは、すべて.xxxを使わなければならないという法律ができるかもしれない。しかし、何がアダルトコンテンツであるかは、非常に曖昧である。例えば政府に対する批判がアダルトコンテンツだと認定されるかもしれない。そのような不都合な情報に対する不当なレッテル貼りは、過去に数えきれぬほど行われてきた。

ある種のコンテンツが、不当に隅に追いやられ、排除される。言論の自由としんに優れた芸術のために害悪である。

ゆえに、言論の自由と芸術とを重んじる我々は、.xxxをボイコットしなければならない。

Lauren Weinstein's Blog: ICANN Approves .XXX -- Boycott Urged -- ICM Keeps Blowing Smoke
RFC 3675 - .sex Considered Dangerous

織田 作之助

青空縦書きリーダーを作ったので、せっかくだから何か本を読むことにした。やはり、縦書きであるというのは、本を読む気にさせるものだ。

なにか今までに読んだことのない作家の本を読もうと、いくつか眺めていたところ、織田 作之助夜光虫が目についた。これは、よく書けている小説だ。軽い文章が、実に下層階級の描写にあっている。

織田作之助の他の小説も面白そうだ。よい作家をまたひとり知った。

しかし、織田作之助の作品は、その取り扱う分野が低俗なこともあり、しばしば発禁処分の憂き目にあったそうだ。その結果、本来公開されていたはずの素晴らしい文章が、世に行われなかったとすれば、日本人の読書家にとって大いなる損失である。発禁処分の害悪はここで実証されている。

しかし、私の気に入る作家は、何故皆、夭折しているのか。天才は短命なのか。あるいは、近い死を覚悟したからこそ、一流の芸術品が出来上がるのか。

2011-03-20

青空縦書きリーダーを実装しての雑感

今日は本の虫: Chrome extension: 青空縦書きリーダーを作った。

たった数時間程度の作業だったが、実に多くの新しいAPIを学んだ。

Chrome extensionのAPIに限って言えば、エクステンションの設定画面を提供するためのOptions Pageや、localStorageとContent scriptsをつなぐための、Background Pagesなどだ。幸い、ドキュメントがそれなりに用意されているので、簡単だった。

設定を保存するため、Web Storageも使った。これは、簡単だった。

また、mousewheelやkeydownイベントをまともに扱ったのも、初めてだ。しかし、ChromeはDocument Object Model (DOM) Level 3 Events Specificationを実装していないのか、一部のプロパティが使えなかった。その代わりに、規格にはないプロパティがたくさんあった。

scrollToやScrollByによるスクロールも、初めて扱った。これはおそらくChromeのバグなのかもしれないが、writing-mode : vertical-rlを使ったときに興味深い挙動を示した。というのも、(0,0)は右上である。これは、別におかしくはない。おかしいのは、横軸が負数だということだ。左端に動かすには、window.scrollTo( -document.body.scrollWidth, 0 )などというようにしなければならない。なぜか負数でなければならないのだ。この挙動はどうなのだろう。なにかおかしいような気がする。そもそも、scrollTo/scrollBy自体が規格で定義されていないのだが。

とりあえず、座標系が負数になる件は、issueとして投げておいた。仕様だとは思いにくい。

その他、getComputedStyleも使った。Document Object Model CSSで規定されている。

Chrome extension: 青空縦書きリーダー

青空縦書きリーダー - Google Chrome extension gallery

青空文庫 縦書き拡張 - 冬通りに消え行く制服ガールは、夢物語にリアルを求めない。 - subtechをみて、色々と惜しい感じがしたので、自分でも作ってみた。

Google Chromeのエクステンションとして動作する。何か特別なことをする必要はない。青空文庫のXHTML版が、自動的に縦書きになる。

例えば、森鴎外の舞姫とか、夏目漱石の吾輩ハ猫デアル中島敦の山月記などがおすすめだ。

chrome://extensions/のオプションから、フォントの種類や大きさ、マウスホイールの挙動、追加のCSSを変更可能。

ちなみに、この仕組を使えば、青空文庫以外にも、単純なテキストで構成されているサイトなら、縦書き化が可能である。いまは任意のサイトを縦書き化するためのUIを実装していないが、需要があれば実装するつもりだ。

バージョン情報

Version 0.40
パーミッションを変更したため、アップデート後に手動で有効にする必要があります。
ブラウザーアクションを実装。
任意のページを縦書き化が可能。
ただし、Chrome自体のバグのため、ローカルファイルは縦書き化できず。
参考:Issue 76705 - chromium - file:// not working for "permissions" in extensions, but does work for content scripts. - An open-source browser project to help move the web forward. - Google Project Hosting
ルビ表示の切り替えが可能。

Version 0.30
設定の保存方法を変更
以前のバージョンの設定は引き継がれません。

Version 0.21
marginを微調整

Version 0.20
キーボードショートカットのエミュレートをサポート
フォント設定の見直し(複数選択可にした)

Version 0.12
設定をしないと、マウスホイールのエミュレートが効かない問題を修正

webkitにおけるvertical writingは、まだ実装途中であり、正しく動作しません。そのため、このextensionは、将来、互換性を損なう形でアップデートされるか、あるいは放置されているかもしれません。

縦書きtextarea要素

以下は、縦書きのtextarea要素の例である。Windows上のChromeで動く。もちろん、入力できる。是非とも試してもらいたい。

赤いピルを飲むと、不思議の国は続行だ。ウサギの穴がどれだけ深いか見せてやろう。

2011-03-19

Chromeで、CSSによる縦書きとマルチカラムレイアウトの合わせ技を試す

CSS Multi-column Layout Module

CSS3には、マルチカラムレイアウトが規定されている。これは、縦書きと組み合わせることができる。例えば、以下の様なCSSを使うと、

<div style="
    column-width: 15em ;
    column-gap: 2em ;          
    column-rule: thin solid black ;
    -webkit-column-width: 15em ;
    -webkit-column-gap: 2em ;
    -webkit-column-rule: thin solid black ;

    writing-mode : vertical-rl ;
    -webkit-writing-mode : vertical-rl ;
    font-family : '@MS 明朝' ;
    font-size : 16pt ;
    line-height : 2em ;

">
<p>
本分
</p>
</div>

以下のように表示される。

 ちょう邯鄲かんたんの都に住む紀昌きしょうという男が、天下第一の弓の名人になろうと志を立てた。おのれの師とたのむべき人物を物色するに、当今弓矢をとっては、名手・飛衛ひえいおよぶ者があろうとは思われぬ。百歩をへだてて柳葉りゅうようを射るに百発百中するという達人だそうである。紀昌は遥々はるばる飛衛をたずねてその門に入った。
 飛衛は新入の門人に、まずまたたきせざることを学べと命じた。紀昌は家に帰り、妻の機織台はたおりだいの下にもぐんで、そこに仰向あおむけにひっくり返った。とすれすれに機躡まねきが忙しく上下往来するのをじっと瞬かずに見詰みつめていようという工夫くふうである。理由を知らない妻は大いにおどろいた。第一、みょうな姿勢を妙な角度から良人おっとのぞかれては困るという。いやがる妻を紀昌はしかりつけて、無理に機を織り続けさせた。来る日も来る日もかれはこの可笑おかしな恰好かっこうで、瞬きせざる修練を重ねる。二年ののちには、あわただしく往返する牽挺まねき睫毛まつげかすめても、絶えて瞬くことがなくなった。彼はようやく機の下から匍出はいだす。もはや、鋭利えいりきりの先をもってまぶたかれても、まばたきをせぬまでになっていた。不意にが目に飛入ろうとも、目の前に突然とつぜん灰神楽はいかぐらが立とうとも、彼は決して目をパチつかせない。彼の瞼はもはやそれを閉じるべき筋肉の使用法を忘れ果て、夜、熟睡じゅくすいしている時でも、紀昌の目はカッと大きく見開かれたままである。ついに、彼の目の睫毛と睫毛との間に小さな一ぴき蜘蛛くもをかけるに及んで、彼はようやく自信を得て、師の飛衛にこれを告げた。

これも、Windows上のChromeで動作を確認した。これは、私が手動で罫線を挿入したのではない。ブラウザーが自動でマルチカラムレイアウトを計算しているのである。

ただし、現在のwebkitにおけるマルチカラムレイアウトの実装は、かなり不完全である。他のCSSプロパティとの組み合わせがうまく動かないし、ボックスモデルの計算もかなりおかしい。特に、縦書きと組み合わせて、長い文字列を描画させた際に、描画がうまくいかなくなる。そのような未熟な実装だからこそ、まだベンダープレフィクスが必要なのだろう。

CSS3のプロパティ、text-combine

CSS3で規定されている、text-combineは、縦中横を実現するプロパティである。以下のように使う。ただし、例によってwebkitのベンダープレフィクスを使用した。Windows上のChromeで動作を確認している。

<p style="
    writing-mode : vertical-rl ;
    -webkit-writing-mode : vertical-rl ;
    font-family : '@MS 明朝' ;
    height : 10em ;
">
平成<span style="text-combine : horizontal ; -webkit-text-combine : horizontal ;">20</span>年
<span style="text-combine : horizontal ; -webkit-text-combine : horizontal ;">4</span>月
<span style="text-combine : horizontal ; -webkit-text-combine : horizontal ;">16</span>日に
</p>

平成20416日に

text-combineを使わない例は、以下の通り。

平成20416日に

CSS Writing Modes Module Level 3

2011-03-18

EPUBは流行らない

私は、基本的にEPUBに反対である。EPUBは確実に流行らないであろうと考えている。

何故か。

EPUBとは、HTMLやCSS、Javascript、他のリソース(画像や動画など)を、あらかじめ定められた書式に従って、ZIPで固めたフォーマットである。

しかし、それなら何もZIPで固めなくてもいいではないか。普通にHTMLでマークアップして、CSSでスタイルを指定して、Javascriptでスクリプトすればいいではないか。なぜわざわざ共通のZIPの「固め方」の規格が必要になるのか。

なるほど、確かに共通の方式を決めておけば、専用デバイスなどでも読みやすくなるかもしれない。しかし、そもそも専用デバイスなどは必要ないのである。持つべきものは、汎用的なコンピューターである。専用デバイスではない。

配布用に、ひとつのファイルにまとめるのは理にかなっている。その方法にもっとも普及しているZIPを使うのも、悪くはない。さて、そのZIPファイルを、展開するとか、そのままマウントして仮想ファイルシステムとして使うとかは、読者側のやることである。わざわざ共通化するまでもない。

EPUBの問題点は、現時点で広く普及していないということである。EPUBを描画できるソフトウェアが、PCには欠けている。いまだに各ブラウザーはEPUBをネイティブにサポートしていない。最も汎用的なPCの中でも、もっともEPUBと親和性の高いブラウザーでサポートされていない現状では、EPUBは使えないフォーマットである。今、使えないフォーマットは、将来も使えないフォーマットである。技術の世界においては、今使える技術こそが優れているのだ。一年後に使えると宣伝されている技術などは、無価値も同然である。その点では、FlashやPDFにも劣るのである。

もちろん、単にZIPを展開して、内部のファイルを取り出して使うことはできない。EPUBのファイル構造は、展開したものを簡単にブラウザー上でみることができるように構成されてはいない。手動で簡単に編集できない。専用のビューワーが必要なのである。したがって、現行のブラウザーではまともに閲覧することが出来ない。

さて、HTML自体は、インターネットのHTTPプロトコルで、標準のマークアップ言語として、長らく使われてきた。HTMLには、いまだに様々な問題があるものの、広く使われている実績がある。新しいマークアップ言語を設計しようという声は、あまり聞こえない。あるのは、HTMLを、下位互換性をなるべく保ったまま改良しようという意見だけである。したがって、HTMLは電子書籍を記述するのに十分な力を備えていると言える。

HTMLを直接使えばいいのだ。そのようにすれば、専用リーダーは、機能の極端に制限されたものではなく、汎用的なコンピューターにならざるを得ない。これは将来に良い影響を与える。消費者の利益を考えれば、リーダーは汎用的なコンピューターになるべきである。iPadやAmazon Kindleのように、不当に機能を制限されたオモチャに成り下がってはならない。自由を求める我々は、そのようなオモチャに魂を売ってはならない。

現行のCSS3のwriting-modeのドラフト化には、EPUBの規格団体、IDPFによる努力もあっただろう。それは、オープンな規格の受ける恩恵である。EPUBが優れているかどうかは、別の問題である。

追記:コメントに対して

しおり、HTML、CSSなどは、クライアント側で解釈されるものである。標準規格があること自体は望ましいが、クライアント側の解釈を強制させることはできない。

たとえば、あるクライアントは、HTMLに対してある種の変換を行うかもしれないし、また、CSSによるスタイル指定を無視して、ユーザー側にとってより閲覧しやすいスタイルを適用するかもしれない。

どのようにコンテンツを再生するかは、クライアント側の自由である。

もし、HTMLやCSSが、標準団体によって規格準拠を認証された再生装置によってしか再生できないなどと規定していたら、今日の興隆はなかったであろう。

電子署名や暗号化などのいわゆるDRMに関しては、技術的に不可能なことを可能だと見せかけているに過ぎない。第一、名前が誤解を招いている。偽装化とか難読化とか、「コピー防止お願いのフラグ」などという名前に改めるべきである。クライアント側で復号できる以上、改変も再配布も技術的に可能である。クライアントがそれをしないのは、単にクライアントの実装者が規格を準拠して、コピー防止お願いのフラグを尊重するという、いわゆる紳士協定を結んでいるからに過ぎないのだ。

それに、私的利用の範囲内における複製や翻案は、著作権の及ばないところである。EPUBをサポートしていない環境のために、EPUBを別のフォーマットに変換する。これは私的利用の範囲であって、著作権の及ばないところである。

永遠にサポートされる技術などというものはありえない。たとえば将来、HTMLがもはや古臭いフォーマットとして誰からも顧みられることがなくなり、HTTPプロトコルも忘れ去られ、そもそもインターネット自体が絶滅している日がやってくるかもしれない。もちろん、その時には、現代では想像もできないぐらい優れた代わりの技術が使われているのである。今あるコンテンツは、すべてより優れた媒体、フォーマットに変換をしなければならない。

ゆえに、私的利用の範囲における複製や翻案が重要なのだ。

もしこれができないのだとしたら、その規格は消費者の権利を不当に制限しており、また将来的にコンテンツは閲覧できなくなるであろう。そのような規格で配布されるコンテンツはボイコットするべきである。

従来の紙の本にはない制限を、何でわざわざ付け加えるのか。

そもそも人類の記録媒体の歴史を省みるに、石に刻み、木簡や竹簡、羊の皮や木の繊維から作られた紙、そして電磁的記録媒体となった。後の世の事など誰が知っているというのか。

否定疑問文:しませんか? はい、します

「勉強を一緒にしませんか?」、「勉強を一緒にやりませんか?」
「はい、します」

日本語は否定疑問文を論理的に答える言語である。ところが、ある外人から、このような例を提示された。「これは、否定疑問文だが、答えるときには、英語と同じく、非論理的に答えているではないか。やはり日本語の論理性とやらにも例外があると見えるな」云々。

はて、確かにこれは、否定疑問文のように思われる。しかし、答えは非論理的になる。これはどういう事だろう。日本語にも、非論理的な例外が存在するのだろうか。

ひとつ思うのは、私はこの、「しませんか?、やりませんか?」という形の疑問文を、否定疑問文のように認識できない。ただたんに、丁寧な表現であるかのように感じている。だから、非論理的に答えているというより、そもそも否定疑問文だとは認識していないのである。

これがもし、「何でお前は勉強を一緒にしないんだ?」という質問であったならば、「いや、やるよ」という答えになる。これは、論理的な答えである。

あるいは、本の虫: 多くない文で結論したように、「せん?」というのは、たんなる念押しの表現なのか。

Chromeがいつの間にか縦書きを実装し始めていた

注意:ここに示したCSSは、実用的な目的には、まだ使ってはならない。何故ならば、-webkitベンダープレフィクスを使っているからである。。これは、webkitの実装がまだ完全ではないことを意味する。

Chrome(というよりもwebkit)がいつの間にか、縦書きを実装し始めていた。つまり、CSS3のwriting-modeプロパティのvertical-rlとvertical-lrをサポートしているのである。まだ、ベンダープレフィクスが必要なので、完全な実装ではないのかもしれないが、少なくとも、ある程度は動くようだ。

例えば、以下の様なマークアップが、

<p style="
writing-mode : vertical-rl ;
-webkit-writing-mode : vertical-rl ; 
font-family : '@MS 明朝' ;
font-size : 16pt ;
height : 30em ;
">
本分
</p>

 ちょう邯鄲かんたんの都に住む紀昌きしょうという男が、天下第一の弓の名人になろうと志を立てた。おのれの師とたのむべき人物を物色するに、当今弓矢をとっては、名手・飛衛ひえいおよぶ者があろうとは思われぬ。百歩をへだてて柳葉りゅうようを射るに百発百中するという達人だそうである。紀昌は遥々はるばる飛衛をたずねてその門に入った。
 飛衛は新入の門人に、まずまたたきせざることを学べと命じた。紀昌は家に帰り、妻の機織台はたおりだいの下にもぐんで、そこに仰向あおむけにひっくり返った。とすれすれに機躡まねきが忙しく上下往来するのをじっと瞬かずに見詰みつめていようという工夫くふうである。理由を知らない妻は大いにおどろいた。第一、みょうな姿勢を妙な角度から良人おっとのぞかれては困るという。いやがる妻を紀昌はしかりつけて、無理に機を織り続けさせた。来る日も来る日もかれはこの可笑おかしな恰好かっこうで、瞬きせざる修練を重ねる。二年ののちには、あわただしく往返する牽挺まねき睫毛まつげかすめても、絶えて瞬くことがなくなった。彼はようやく機の下から匍出はいだす。もはや、鋭利えいりきりの先をもってまぶたかれても、まばたきをせぬまでになっていた。不意にが目に飛入ろうとも、目の前に突然とつぜん灰神楽はいかぐらが立とうとも、彼は決して目をパチつかせない。彼の瞼はもはやそれを閉じるべき筋肉の使用法を忘れ果て、夜、熟睡じゅくすいしている時でも、紀昌の目はカッと大きく見開かれたままである。ついに、彼の目の睫毛と睫毛との間に小さな一ぴき蜘蛛くもをかけるに及んで、彼はようやく自信を得て、師の飛衛にこれを告げた。

このように、見事な縦書きになる。(Windows上のChromeで動作を確認)

ただし、現状のChromeの実装には、いくつか問題がある。まず、通常の横書きのように、word wrapがきかないという問題だ。そのため、上の例では、仕方なくheight propertyを使用している。また、フォントの問題もある。頭に@のつくフォント名は、実際のフォントではなく、Windows独自の機能である。そのため、このマークアップは、Windows以外では動かないだろう。

また、フォントの描画が、何か微妙におかしい。

禁則処理もされていないので、改行が不自然だ。その他、あらゆる日本語の組版の常識が欠けている。

そのため、この縦書きは、まるで画像を貼り付けたようにみえる。何もかもが固定、環境依存で、あまり使いやすくはない。

追記:ルビのせいで、行間がまばらになるという指摘があったので、とりあえず修正した。行間は、CSSのline-heightプロパティで修正可能である。実用的に行間を調節するには、ルビのrt要素のスタイルも調整する必要がある。ブログのようなサイトにおいて、この調整を記事単位で可能にするために、style要素のscoped属性を、早くサポートしてもらいたいものだ。

追記2:現行のChromeでは何故か、vertical-lrがvertical-rlと同じように動く。まだ不完全である。

追記3:縦書きをマルチカラムレイアウトと組み合わせてみた。本の虫: Chromeで、CSSによる縦書きとマルチカラムレイアウトの合わせ技を試す。この縦書き表示に感動した人は、これを見ると、もっと感動できるはずだ。

追記4: 青空文庫を縦書き化できるChrome extensionを作りました。青空縦書きリーダー - Google Chrome extension gallery

CSS Writing Modes Module Level 3

2011-03-17

予備自衛官補に関する本を書きたい

今回の地震が起こってから、自分に何ができるかを考えていた。私は補上がりの予備自衛官であり、もしかしたら、招集がかかるかもしれない。それに関しては、すでに下着などの必要な荷物をリュックに詰めて準備している。

私が危惧しているのは、今回の地震によって、予備自衛官補という制度に志願する人が急増するのではないかということだ。なぜ危惧しているのかというと、予備自衛官補の教育訓練を修了できる割合が、非常に低いからなのだ。

予備自衛官補は、退職した自衛官以外でも、予備自衛官になれる制度である。予備自衛官補は、3年以内に50日間の教育訓練を修了すれば、予備自衛官になれる。訓練は5日単位で行われる。この5日単位を、課程という。50日間なので、10課程ある。A課程からJ課程である。

予備自衛官補の試験に合格するのは、比較的簡単である。もっとも、今回の地震で、志願者が急増するかもしれないので、倍率は上がるかもしれない。しかし、予備自衛官補になったからといって、訓練を修了できるとは限らないのだ。

私が予備自衛官補の最初の訓練を受けたとき、ある駐屯地の教育部隊には、その年に同じく予備自衛官補の試験に受かった数百人の予備自補がいた。しかし、最終過程にまで残った予備自補は、わずかに数十人。つまり、予備自補の訓練の修了率は、たったの1割なのである。

もちろん、すべての人間が1年以内に訓練を終了するわけではない。確かに、3年以内に50日間の訓練を終了すれば、予備自衛官になれる。しかし、2年、3年かけて訓練を修了した人間は、わずかに数人なのだ。つまり、一年以内に訓練を修了できる確率は1割で、2年、3年かけてに修了できる割合は、数パーセントという割合になる。残りの9割弱の予備自補は、訓練を修了できずに脱落してしまうのだ。

なぜこんなに修了率が低いのか。それには、二つの理由がある。ひとつには、訓練に参加できないという問題である。一年に50日間、しかも一度の訓練につき5日単位の拘束というのは、民間で働いている人間には、なかなか難しい。

もう一つ、訓練が厳しすぎると感じて脱落していくのである。もちろん、「厳しい」というのは現職の自衛官、すなわち自衛官候補生や一般曹候補生、幹部候補生の教育訓練に比べれば、天と地とほどの差がある。現職の厳しい訓練に比べれば、予備自補の訓練は全然厳しくないのだが、それでも9割方の人間は、脱落していく。どれほど強い志を持っていても、自由のない、完全に外界と遮断された、規律のある集団生活に、精神的に耐えられない人間はかなり多い。

それが、予備自衛官補の教育訓練の修了率1割という数字になって現れるのである。

今回の地震によって、予備自衛官補を志願する人が増えることは、予備自衛官の制度の知名度の上昇という点においては、好ましいことであるが、単に試験の手間や訓練の脱落者を増やすだけになるのは、好ましくない。

このため、実際に私の予備自衛官補の教育訓練の体験から、そのような安易な志願を戒めるような本を出版したい。今回の地震をきっかけに、予備自衛官補への志願を煽るような無責任な宣伝は、今後かなり増えるであろうと思う。そのような宣言は、私がするまでもない。私がすべきことは、むしろ、頭を冷やすための宣伝である。「熱に浮かされて予備自補を志願するのはいいが、本当に予備自衛官補の教育訓練を修了できるのか」ということを警告するような本である。予備自補の試験や訓練の内容を、実体験から執筆すれば、安易な志願を思いとどまらせることができるかもしれない。

そもそも、自衛隊の本分は災害派遣ではない。日本の国土の防衛である。災害への対処は、消防や警察のほうが優れている。災害に置いて自衛隊の優れているところがあるとすれば、それは、自衛隊は完結した組織であるということだけだろう。つまり、自衛隊は炊事から道路の整備、橋を架けるなどといった基本的なことも行えるし、目的地に徒歩で到達するような訓練も行っている。もちろん、個々の技術、たとえば道路整備や橋の建築を考えれば、自衛隊は民間より劣っている。これは、自衛隊は長期にわたって実用的な道路や橋を作るのではなく、有事の際に一時的に建設するという、そもそも異なる目的を持っているので、当然である。そのため、自衛隊の災害派遣用の装備も、一人で担いで持ち運べることを基本としている。民間には、もっと優れた機材がある。ただし、一人で持ち運べるとは限らない。自衛隊は一人で持ち運べることを考えて、機材を導入しているのだ。

もちろん、そのような本を実際に出版するのは、色々と難しい。まず、出版社を探さなければならない。また、自衛隊とも連絡を取り、そのような本を出版していいのか、また仮に出版できるとしても、公開してはいけない情報が含まれていないかどうかという確認を行ってもらわなければならない。そのような作業は、まだ現実に災害が続行中である現段階ではできない。一段落してからでなければならない。

実現できるかどうかは分からないが、とにかく私ができることをしようと思う。

2011-03-14

Boost.Type Traitsへの拡張案のレビュー開始

Boost.Type Traitsへの拡張案のレビューが始まっている。これは、has_operator_XXXという一連のメタ関数を付け加えるものである。オペランドの型同士で、演算子をサポートしていれば、trueを返すメタ関数である。

これは、希望的には、以下の様なことをしてほしい。

struct X { } ;
int operator + (int, X) ;

int main()
{
    using namespace boost ;
    has_operator_plus<int, int>::value ; // true
    has_operator_plus<X, int>::value ; // false
    has_operator_plus<int, X>::value ; // Boostの実装では動かない。true, 演算子のオーバーロード
    has_operator_plus<X *, int>::value ; // true, ポインターと整数型の演算
}

ところが、現状の実装では、ここまで柔軟に動いてはくれない。なぜならば、decltypeを使っていないからだ。できるのは、オペランドの方がポインター型や基本型だった場合の、演算適用性の可否である。

ちなみに、decltypeを使えば、正しくジェネリックに動くメタ関数は簡単に書ける。例えば、以下のようになる。

template < typename T1, typename T2 >
struct has_operator_plus_impl
{
private :
    template < typename U1, typename U2 >
    static auto check( U1 u1, U2 u2 ) -> decltype( u1 + u2, std::true_type() ) ;
    template < typename ... Types >
    static std::false_type check( Types ... ) ;
public :
    static const bool value = decltype( check( std::declval<T1>(), std::declval<T2>() ) )::value ;
} ;

template < typename T1, typename T2 >
struct has_operator_plus
    : std::integral_constant< bool, has_operator_plus_impl< T1, T2 >::value >
{ } ;

ただし、このコードが正しく動くコンパイラーは、まだ存在しない。なぜならば、どのコンパイラーも、decltypeを正しく実装していないからだ。workaroundとしては、decltypeを以下のコードように変更すると、gccで動く。

std::common_type< decltype( check( std::declval<T1>(), std::declval<T2>() ) ) >::type::value

結局、Boostが未だにdecltypeを積極的に使わないのは、まだ正しく実装したコンパイラーが存在しないからだろう。

2011-03-11

V 2010 SP1の感想

とりあえず、Windows SDK 7.1はいれてないので、VS 2010 SP1をインストールしてみた。

その前に、この機会にVS2010 Web Developer Expressもみておこうと思い、インストールをしようとした。しかし、英語版のWebインストーラーをダウンロードする方法がわからない。なぜかWeb Developer Expressだけは、言語の選択がなく、Webインストーラーは勝手に日本語を選ぶ。仕方が無いので、Webインストーラーは諦めて、Expressをすべて含むISOイメージを落とすことにした。これは、700MB弱あったが、7MB/secという爆速で落とすことができた。

インストーラーのレイアウトが崩れていて、一部のUIがウインドウのサイズの外側に押しやられていたことを除けば、インストールには問題がなかった。

ただし、とくに何も変わったことはない。ただし、エディタのword-wrapのパフォーマンスは、若干マシになっているような気がした。

参考:本の虫: Visual Studio 2010が救いようのないほどクソだ

相変わらずメモ帳並みとまではいかないが、少なくとも、実用的な一行の長さでは、IMEの変換候補がチカチカするようなことはなくなった。

Web Developerは相変わらず、JavascriptではなくJScript(笑)をサポートしている。また、すでに告知があったように、JScript(笑)のIntellisenseは、DOM Level 2やHTML5をサポートしていない。

2011-03-10

これはひどい

障がい者雇用、ワーストは毎日新聞、共産党、ニチイ学館、トリスタ:MyNewsJapan

普段、障害者や社会的弱者に対する支援を主張する団体が、実は一番、法律で義務付けられた障害者雇用を守っていないという事実。

これは、ironyとsarcasmのどちらに分類されるのだろうか。私は、sarcasmだと思う。

VS2010 SP1が公開されたが、不具合あり

Microsoft Ships Visual Studio 2010 Service Pack 1 - Application Development - News & Reviews - eWeek.com
Microsoft Corporation

MSDN購読者は、購読者用のダウンロードから、そうでない人は、ここから、3月10日以降(おそらく日本時間では明日以降)、SP1をダウンロードできる。

また、Feature packというのも、いくつか公開されるようだ。

しかし、残念なことに、Windows SDK 7.1を同時に使いたい場合、不具合のため、SDK側のコンパイラーが消えてしまうそうだ。

Windows SDK v7.1 with Visual Studio 2010 Service Pack 1 – Potential issue with x64/IA64 Visual C++ Compilers - Microsoft Windows SDK Blog - Site Home - MSDN Blogs

このため、Windows SDKを使っている人は、修正がなされるまで、少し待つべきである由。

また、IE9の正式版が、3月14日から(日本時間では15日から)、公開されるそうだ。

A More Beautiful Web Launches on March 14th

アメリカの特許の認可に深刻な問題あり

Click | Futility Closet
TV control device - Patent 3962748

テレビの制御装置に関する特許。

アメリカの特許の仕組みには深刻な問題がある。

これはひどい

違法配信に関する利用実態調査 【2010年版】

日本レコード協会のアンケート調査集計がひど過ぎる件

なぜか、無料のダウンロードという質問に答えたはずなのに、違法のダウンロードという意味にすり替えられている。

もはや音楽は死んだな。

2011-03-09

ごもっとも

404 Blog Not Found:高校の「情報」の教科書が無駄にすごい無駄な件

www.さとなお.com(さなメモ): 高校の「情報」の教科書がすごい件

彼女はリビングで勉強したがるので何やっているのかわかっちゃうのだが、その中で気になることをやっていた。「フォトショの拡張子は…」とか声を出して暗記しているのだ。そして「お父さん、AVIファイルってデータ量が大きいんだっけ?」とか訊いてくる。

そしたら「情報A」とかいう科目と試験があるらしい。ほぉ。そういえばそんなこと言っていたな。ちょい見せてw

教科書を見せてもらって驚いた。
いやぁ、なるほど。いまどきの高校生ってこういうの体系的に教えてもらっているのね。

Photoshopで使っている拡張子を暗記することに意味はない。AVIコンテナーは古臭い劣ったコンテナーなので、いまどき覚える価値はない。いや、むしろAVIコンテナーを使ってはならない。いや、そもそも、AVIという拡張子を持ったファイルのデータ量が大きいとは何を意味するのだ。

もちろん、体系だって教えることは、効率がいいだろう。しかし、その体系が間違っていては、どうしようもない。

こんな馬鹿げた「情報A」という教育を受けた高校生が世に出てくる数年後は、どうもあまり期待できない。

果たして、こんな馬鹿げた教育でも、ないよりはマシなのだろうか。いや、とてもそうは思わない。

思うのだが、現行の学校教育は、わざと日本人の頭を悪くするために行っているのではないだろうか。少なくとも、私は学校教育では、英語は学べなかっただろう。中学生高校生の時分、私は英語の時間、授業などハナから聞いていなかった。授業は無視して、代わりに、ハリーポッターを読んでいた。今から考えると、あの選択は正しかったと言える。

2011-03-08

グラフィックカードのドライバーをアップデートしない低能達

アメーバピグユーザーが、Flash Playerのアップデートをしない低能であることは、すでに述べた。しかし、この問題は、単にFlash Playerだけにとどまらない。グラフィックカードのドライバーにも当てはまるのだ。

実は、グラフィックカードのドライバーというのは、アップデートの激しいドライバーである。理由は、グラフィックというものが、かなり複雑だからだろう。ましてや、最近のGPUは、どんどん汎用的になってきており、新しい機能に、ドライバーのアップデートで対応できる場合もある。

何故こんな話をするのか。それは、ブラウザーは描画にGPUを使うことが、次第に一般的になりつつあるからだ。ところが現在、かなり難しい問題が持ち上がっている。多くのユーザーは、ドライバーをアップデートしていないのだ。このため、とっくに修正されたバグのある不安定なドライバーを使っているユーザーがー多い。

すでに、ChromeとFirefoxがこの問題をブログに書いている。他のブラウザーも、じきに続くだろう。

Upgrade your graphics drivers! « Benoit Jacob
Chromium Blog: GPU acceleration + old drivers = :(

問題は、現在のブラウザーのコードが、まだ実験的であり、バグを含んでいるということだ。アプリケーションがどのようなおかしなことをしようとも、OSやドライバーはおかしくなるべきではない。しかし、OSやドライバーにも、当然バグはある。それを修正するために、OSやドライバーは、日々アップデートされているのだ。

さて、読者諸君のグラフィックカードのドライバーは最新だろうか。たとえゲームをしていなくても、グラフィックカードのドライバーはアップデートしておくべきである。そもそも、最近はゲーム以外にも、GPUの力に頼る場面は多い。多くのモダンなOSは、通常のUIの描画もGPUに頼り始めた。もはや、ゲームをしなくても、ある程度の性能を持ったGPUを使うのは当然なのだ。

ソフトウェアのアップデートを怠る低能になってはならない。ある者は言う。新しいソフトウェアには、バグが含まれているかもしれない。だから様子をみるのだと。しかし、アップデートがバグフィクスのためならば、今使っているソフトウェアには、確実にバグが含まれているわけである。低能の極みである。

また、ある者はいう。果たしてすべてのPCユーザーが、システム管理者のようなことをしなければならないのかと。当然、すべてのユーザーは、自分の所有物たるPCの管理をすべきである。そのPCはユーザーの所有物であり、管理は当然、ユーザーによってなされるべきだからだ。

たとえば、整備不良の車の責任は、所有者にある。所有者は自分で車を整備するか、あるいは、整備を代行してもらう。そのコストは、所有者が持つものである。雪道では、タイヤにチェーンを付けなければならない。タイヤにチェーンを付けるのは、車の所有者の責任である。タイヤにチェーンを付けずに雪道を走ってスリップした場合の責任は、当然、所有者にある。道路の管理者に文句をいうのはお門違いである。

自分のPCは自分の責任で管理する。もし自分が管理できない場合は、他人に管理を代行してもらえばいい。もちろん、そのコストは、所有者が持たねばならないが。

荒木飛呂彦へのインタビュー

広瀬川インタビュー

杜王町広瀬川による荒木飛呂彦へのインタビューが行われている。素晴らしい。

それにしても、また一段と若返ったような。

CSSでキュウべえ(FULL)を描いてみた

CSSでキュウべえ(FULL)を描いてみた - jsdo.it - Share JavaScript, HTML5 and CSS

これはすごい。

キュウべえというのは、「魔法少女まどか☆マギカ」というアニメに出てくる、白い小さい可愛い小動物である。しかし、この魔法少女まどかマギカというアニメは、閲覧者に暴力的な影響を与える、非常に危険で有害なアニメである。私は実際に観ていないので詳細は不明だが、このアニメを見たものは皆、この白い小さい可愛い小動物であるキュウべえを虐待したいという衝動にかられるらしい。理解に苦しむ現象である。

2011-03-07

確率分布の使い方

C++0xのstd::randomには、様々な分布クラスが存在する。一体どうやって使い分ければいいのか。ここでは、ゲームにたとえて考えてみる。

もっとも簡単な分布は、一様分布(Uniform distributions)である。これは、a ≦ i ≦ b, の範囲の値iを、それぞれ等しい確率で返す分布である。

ゲームでいえば、サイコロやルーレットなどの実装に使えるだろう。

// 六面サイコロの実装
int main()
{
    std::mt19937 rng ;
    // 一様分布
    // 0から5までの数字を等しい確率で返す分布
    std::uniform_int_distribution<> dice(0, 5) ;

    int a[6] = { } ; // 六面サイコロの出た目の回数を記録する配列

    // 600回サイコロを振る
    for ( int i = 0 ; i != 600 ; ++i )
    {
        ++a[dice(rng)] ; // サイコロを振る
    }

    // 600回サイコロを振った結果、どの目も100前後になる
    for ( int i = 0 ; i != 6 ; ++i )
    {
        std::cout << i + 1 << "=" << a[i] << std::endl ;
    }
}

ベルヌーイ分布(Bernoulli distributions)は、ある確率pでtrueを、確率1 - pでfalseを返す分布である。

ゲームでいえば、10%の確率で攻撃が当たるとか、30%の確率でアイテムを落とすなどといった場合に使える。trueの場合はアタリで、falseの場合はハズレである。

// 30%の確率でアイテムを落とすコード
int main()
{
    std::mt19937 rng ;

    // ベルヌーイ分布
    // 30%の確率でtrueを返す分布
    // 30%の確率でアイテムを落とす
    std::bernoulli_distribution drop_rate( 0.3 ) ;


    int n = 0 ;
    for ( int i = 0 ; i != 1000 ; ++i )
    {
        if ( drop_rate(rng) ) // アイテムを落としたかどうか計算
            ++n ;
    }

    // 1000回の可能性のうち、アイテムは、300回前後落とされている
    std::cout << n << std::endl ;
}

ポアソン分布(Poisson distributions)は、単位時間あたりの事象の発生の平均回数が与えられている場合に、確率的に、何回発生したのかを求める分布である。

ゲームでいえば、ストラテジーゲームで、一年で1000人の敵を倒せる武将が、10日で何人の敵を倒せるかという確率を計算するのに使える。

// 一年で1000人の敵を倒せる武将は、10日で何人の敵を倒せるのか確率的に求める
int main()
{
    std::mt19937 rng ;

    // 一年で1000人の敵を倒せる武将が、10日で倒せる人数の平均を求める
    // 1000人 / 365日 * 10日
    double rate = 1000 / 365 * 10 ; 

    // ポアソン分布
    std::poisson_distribution<> score( rate ) ;

    // 最初の十日間で倒した人数
    std::cout << score(rng) << std::endl ;
    // 次の十日間で倒した人数
    std::cout << score(rng) << std::endl ;
    // その次の十日間で倒した人数
    std::cout << score(rng) << std::endl ;
}

正規分布(Normal distributions)は、統計の初歩でも出てくる、だいぶ馴染み深い分布であると思う。

ゲームでいえば、ゲーム内において、大小様々な木々を動的に生成するときに、できるだけ大きさの差を自然にしたいときに使えるだろう。

サンプリング分布(Sampling distributions)はある個数のうちのランダムなサンプルがいくつか与えられている場合に、全体の個数の統計的な情報を得るための分布である。

この分布は、出る目の確率が偏っている、イカサマなサイコロを実装するのに使える。

// イカサマなサイコロの実装
int main()
{
    std::mt19937 rng ;

    // 1の目がでる確率が50%、その他の目のでる確率がそれぞれ10%の、イカサマなサイコロ
    std::discrete_distribution<> cheat_dice = { 0.5, 0.1, 0.1, 0.1, 0.1, 0.1 } ;

    int a[6] = { } ; // 六面サイコロの出た目の回数を記録する配列

    // 600回サイコロを振る
    for ( int i = 0 ; i != 600 ; ++i )
    {
        ++a[cheat_dice(rng)] ; // サイコロを振る
    }

    // 1の目が300前後、その他の目が60前後振られている
    for ( int i = 0 ; i != 6 ; ++i )
    {
        std::cout << i + 1 << "=" << a[i] << std::endl ;
    }
}

ちなみに現実では、第二次世界大戦中、ドイツの戦車の生産台数を割り出すのに使われている。これは本当の話である。当時連合国側は、捕獲したドイツ戦車の連番のシリアルナンバーから、ドイツの戦車の生産台数を割り出したのだ。詳しくは、WikipediaのGerman tank problemを参照。また、以前にこのブログでも取り上げている話題だ。

問題は、これらの分布クラスに、いくつか派生版があるということだ。一体どのように使えるのか、数学の知識のない私には、よく分からない。

一様分布 - Wikipedia
ベルヌーイ分布 - Wikipedia
ポアソン分布 - Wikipedia
正規分布 - Wikipedia
Sampling distribution - Wikipedia, the free encyclopedia

トルコ、GoogleのBloggerを禁止したること

Turkey bans Google's Blogger over soccer piracy - TechSpot

トルコの裁判所は、トルコの衛星放送を違法に中継していたBloggerのため、GoogleのBloggerサービスを遮断せよとの命令を下した。これを受けてGoogleは現在、同国内におけるBloggerサービスを遮断している。

一部の利用者による犯罪のために、サービス全体が遮断されて良いものだろうか。そもそもこの理論で行けば、、Bloggerではなく、トルコのISPを業務停止させるべきではないのだろうか。さすが、EUに成り切れず、かといって中東でもなく、しかしまた、イスラムというドグマを捨てきれない中途半端な国だ。

2011-03-06

How Not To Learn Japanese

I've met many forigners studying Japanese language in the Internet. I admire the effort to learn something completely different language like Japanese. But I concern some people studying the Japanese language in totally wrong way. By using Romaji and remembering Kanjis.

The Romaji is a mapping from Japanese kana to latin alphabet. Some people studying Japanese by using Romaji. That is a really bad idea.

They use Japanese like this.

Watashi ha nihongo ga wakaru.

This is as bad as following.

アイ ノー イングリッシュ(I know English)

No Japanese use Romaji for writing Japanese. Sure, Romaji is a one-to-one mapping to/from Kana. But learning Japanese by Romaji is like learning English by Kana or using Caesar ciphered version of alphabet.

If you really want to use Japanese. You must avoid using Romaji. Forgetting the Romaji is even better.

Remembering Kanjis is also a bad idea. It is true if you want to read Japanese text just like natives, you have to understand a few thousands Kanjis. But still, remembering each Kanjis doesn't improve your real Japanese skill.

Kanjis are mostly used in compound form. Remembering each Kanji meanings doesn't help you understanding the compound words.

For example, 名 may be translated to name and 前 may be translated to front. Then what does 名前 means? It means name. We, Japanese, recognize it a single word. We don't recognize it as "name + front".

Also, avoid remembering Kanji meanings by English translation. 名 means なまえ, not a name. "name" is a translation. You must understand it as it is. Not by translation.

To actually learn Kanjis, one must learn from context. Just remembering individual kanjis doesn't improve your practical Japanese skill.

2011-03-05

新しいビルドシステム、ニンジャ

Chromium Notes: Ninja, a new build system

ChromeをWindowsから移植し始めたとき、我々はSconsを使ってChromeをビルドしようとした。Sconsは、正しく動作して、使い方も簡単であった。しかし、開発を始めてすぐに、Sconsはとても遅いということに気がついた。ソースを実際にビルドし始めるまでに、40秒もかかるのだ。Sconsが全面的に悪いというわけでもない。Chromeのビルドは、たったひとつの実行ファイルのために、WebKitも含めて、30000ものファイルがあるのだ。

結局、私はLinuxビルドのために、単にMakefileを使うことにした。これは、我々のビルドシステムが、メタビルドシステム、すなわち、WindowsやMac用のビルドファイルを生成するビルドシステムだったから可能だったのだ。開発を進めるほどに、私はどんどんビルドのパフォーマンスが気になって仕方がなかった。Windowsビルドで、たったひとつのファイルを変更しただけなのに、リンクするのに8分もかかったことがある。これは、私のプロダクティビティとモラルの為に害悪である。

ビルドのパフォーマンスというものは、様々なファクターが影響する。ビルドシステムは、何をすべきなのかを計算しなければならない。コンパイラーがファイルをコンパイルするのにも時間がかかる。リンカーがリンクするのにも時間がかかる。これらの要素は改良できる、逆順に。Google社員によって書かれたgoldリンカーは、素晴らしく速い。コンパイル時間は、高速なコンパイラー(最近の私のclangにおける活動を参照のこと)と、より良い並列化(私はかなりの時間を、同僚にdistccを布教するのに費やしている)によって、短縮できる。ビルドシステムそのものも改良可能だ。

これらの改良と、注意深く、再帰しないように生成されたmakefileによって、インクリメンタルなビルドは、10秒から20秒程度に抑えることができた。私は特に、Linuxにおけるビルドシステムを開発したことを誇りに思っている。というのも、最初の移植では、開発は進まなかっただろうと思うからだ。他の開発者が使いたいと思うようにならなければ、Chromeの開発は進まない。例えば、多くの(いや全員か?)Chromeエクステンション開発チームは、開発環境にLinuxを使っている。何故といって、デバッガーの質は悪いものの、その他の要素がはるかに優れているからだ。このため、私はGitのサポート要員でもあるのだ。Gitはよりプロダクティブで、Linuxでは爆速である。

しかし、まだ私は、実際のコンパイルが始まるのに20秒かかるということに、満足していない。ディスクキャッシュが効いている状態ならば、そんなに時間がかかるはずはないと思うのだ。

我々のmakefileは、様々な賢いハックを多用している。多くのアイディアは、Linuxカーネルのビルドシステムからパクッてきた。makeが自分ではやってくれないことをやらせるのだ。例えば、ある出力におけるコンパイルフラグが変わった場合、出力ファイルはリビルドしなければならない。これは、すべてのmakefileを、存在しない入力に依存させることによって実現できる。つまり、ルールは常に一致するのだ。その後、ほんとうにリビルドが必要かどうか独自に判断すればよい。また、以前のビルドに使われたコマンドラインも保存しておく必要がある。このような、本来Makeの想定していない使い方こそが、Makeがそれほど早くない原因なのだろう。

我々のビルドをMakeに移植する際に、私は多くのことを学んだ。中には、意外なこともあった。たとえば、これを試してみるといい。

touch foo.c
echo 'foo: foo.c' > Makefile
strace -estat make

GNU makeは、ビルドルールの一環として、RCSとSCCSメタデータを読み込みに行くではないか!(これは大昔のバージョン管理システムで使われていたものである。この挙動は、Makeお-rフラグで変更できる)

これらをすべて踏まえ、週末を使えば、私はとても単純なビルドシステムを作れると考えた。Makeによく似ているが、機能がほとんどないものだ。なぜ単にMakeや他のビルドシステムを改良しないのか。それは、私はこれを娯楽としてやっているからだ。他のものを娯楽でやるつもりはない。さて、私はMakeにはない機能をいくつか実装した。例えば、ビルドコマンドを並行して実行しているときに、すべてのビルドコマンドの出力をバッファーしておくことによって、エラーの出力は、他の出力を妨げることなく、失敗したコマンドの完全なコマンドラインと関連付けることができる。そしてプロファイルの結果、Chromeのビルドを1秒で開始させることができた。

これを他のツール(特にgold)や高速なコンピューターと組み合わせれば、ひとつのファイルを変更したことによるChromeのインクリメンタルビルドを、6秒で終えることができる。私はこの開発の結果であるビルドシステムをオープンソースにする許可を得た。私はこれに、ニンジャ(Ninja)という名前をつけた。これは素早いからだ。githubから入手できる、また、より詳しいことは、マニュアルを読んでほしい

この人の他の記事も面白い。例えば、Clangにおける開発だ。

Chromium Notes: Clang work

Variadic Variadic Templates

テンプレートのおかげで、我々は型をパラメーター化できる。テンプレートは、普通のプログラマーならば、当然使える機能である。


template < typename T >
void f( T ) { }

struct MyType { } ;

int main()
{
    f( 0 ) ;
    f( 0.0 ) ;
    f( MyType() ) ;
}

また、Variadic Templatesのおかげで、我々は任意の型を任意個、パラメーター化できる。Variadic Templatesは、向上心のあるプログラマーなら、当然使える機能である。

template < typename ... Types >
void f( Types ... args ) { }

struct MyType { } ;

int main()
{
    f( ) ;
    f( 1, 2, 3, 4, 5) ;
    f( 0, 0.0, MyType() ) ;
}

果たしてしからば、Variadic TemplatesのVariadic化は可能だろうか。つまり、Variadic Variadic Templatesである。

何故そんなものが必要なのか。例えば、任意の型の関数ポインタ―を任意個とる場合を考えてみる。


template < typename ... Types >
void pack( Types ... args ) { }

void f( int ) { }
void g( int, int ) { }
void h( float, double ) { }

int main()
{
    f( &f, &g, &h ) ;
}

これはもちろん動くが、面倒である。それに、この方法では、関数ポインタ―以外にのあらゆる型も、実引数として渡せてしまう。これを何とかしたい。

これは、できるC++プログラマーなら、たやすいことだ。単に型を制限してやればいいのだ。

template < typename ... Types, typename ... ParamTypes >
void pack( Types (* ... args)( ParamTypes ... ) )
{ }

しかし、これには問題がある。これは、同じ仮引数リストと任意の戻り値の型の関数ポインタ―を任意個とる関数である。

void f( int ) { }
void g( int, int ) { }
void h( float, double ) { }

int main()
{
    pack( &f, &g, &h ) ; // エラー
}

関数ポインタ―の、仮引数リストの型が違っていれば、この関数には渡すことができない。

つまり、ここで必要なのは、Variadic Variadic Templatesである。残念ながら、C++0xには、そのような機能はない。

機能がなければ、ユーザーコードでなんとかするしかない。それがC++の精神である。そういうわけで、ちょっと頭のいいC++プログラマーならば、以下の様なコードは簡単に書ける。

template
<
    typename Type0, typename ... ParamTypes0,
    typename Type1, typename ... ParamTypes1,
    typename Type2, typename ... ParamTypes2
>
void pack
(
    Type0 ( * arg0 )( ParamTypes0 ... ),
    Type1 ( * arg1 )( ParamTypes1 ... ),
    Type1 ( * arg2 )( ParamTypes2 ... )
)
{ }

さらに頭のいいメタプログラマーは、このコードに規則性を見出す。規則性のあるコードは、自動で生成することが可能である。とすれば、以下の様なコードが頭に浮かぶのは、メタプログラマーとして当然である。

#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/enum.hpp>

#define EZOE_PP_PARAM_MAX 10

#define EZOE_PP_TEMPLATE_PARAMETER( z, n, data ) \
typename BOOST_PP_CAT( Type, n ), typename ... BOOST_PP_CAT( ParamTypes, n )


#define EZOE_PP_PARAMETER( z, n, data ) \
BOOST_PP_CAT( Type, n ) (* BOOST_PP_CAT( arg, n ) ) ( BOOST_PP_CAT( ParamTypes, n ) ... )


template
<
    BOOST_PP_ENUM( EZOE_PP_PARAM_MAX, EZOE_PP_TEMPLATE_PARAMETER, ~ )
>
void pack( BOOST_PP_ENUM( EZOE_PP_PARAM_MAX, EZOE_PP_PARAMETER, ~ ) )
{
    
}

#undef EZOE_PP_TEMPLATE_PARAMETER
#undef EZOE_PP_PARAMETER

メタコードによって、仮引数の数もコンパイル時に調整できる。しかし、このコードには根本的な問題がある。必ず10個の関数ポインタ―を実引数として渡さなければならないのだ。

デフォルト実引数は使えない。なぜならば、パラメーターパックにデフォルト実引数は使えないからだ。

何ということだ。プログラマーの中でも最上級のメタプログラマーは、ここで敗北せねばならぬのか。

真のプログラマーは、もうそろそろ気がついているであろう。こんな馬鹿げたコードは、もとより必要ないのだ。まず、関数ポインターかどうかのチェックは、static_assertを使えば、こんなに簡単に書ける

template < typename T >
struct is_function_pointer
    : std::conditional<
        std::is_pointer<T>::value &&
        std::is_function< typename std::remove_pointer<T>::type >::value
        , std::true_type, std::false_type >::type
{ } ;

constexpr bool check( bool b )
{
    return b ; 
}
template < typename ... Types >
constexpr bool check( bool b, Types ... rest )
{
    return b && check( rest... ) ;
}


template < typename ... Types >
void pack( Types ... args )
{
    static_assert( check( is_function_pointer<Types>::value... ), "all argument shall be a type of function pointer" ) ; 
} 

void f( int ) { }
void g( int, int, int ) { }
void h( double, float ) { }


int main()
{
    pack( &f, &g, &h ) ; // OK
    pack( &f, &g, &h, 0 ) ; // static_assertによるコンパイルエラー、intは関数ポインターではない
}

また、仮引数の型を知る方法としても、メタプログラミングが使える。ただし、この実装はつまらない規則性のあるコードの羅列になってしまうので、自分で実装する必要はない。Boostの実装を使えばよい。Boostの実装には、is_function_pointerもあるので、これまた自分で実装する必要はない。

Boost.FunctionTypes

教訓としては、真に優れたプログラマーとは、車輪の再発明をしないプログラマーのことである。ましてや、その再発明された車輪は、往々にして輪ではなかったりするのだ。

Scarborough Fair

Scarborough Fairという歌がある。理不尽に不可能なことを要求し、その要求を満たした場合、結婚しようという内容の歌だ。Simon & Garfunkelがカバーしている。

いい歌だ。

ところで、この歌詞、二重否定が強い否定の意味で使われているのではないか。

Tell her to make me a cambric shirt
Parsley, sage, rosemary, and thyme
Without no seams nor needlework

"without no seams nor needlework"となっている。

2011-03-04

Boost候補のXIntが残念だ

The Extended Integer (XInt) Library: The Extended Integer (XInt) Library

いまどきCOWはないだろう。ましてや、もうそろそろC++0xもでる。コピーは単に参照を共有するというのは、shared_ptrのような、ごく限られた用途にのみ使うべきだ。

C++/CLIのインテリセンスについて

C++/CLI IntelliSense in Visual Studio vNext - Visual C++ Team Blog - Site Home - MSDN Blogs

VS2010 SP1にも間に合わないが、次のVSのバージョンでは、提供できるそうだ。

それよりも規格準拠度を高めて欲しいのだが。

値段のつけ方

たとえば、100円で売りたい商品があるとする。多くの店は、100円で売ることはない。98円で売る。同様にして、1000円の商品は、980円で売られる。これは、どの店でもやっていることである。

この、あまり正直ではない値段の付け方は、日本だけではなく、世界中で行われている。ただし、国ごとに事情が異なるので、微妙に値段の付け方も異なっている。

たとえば、アメリカでは、$10の商品に、$9.99の値段を付ける。日本では、999円ということは、あまり行われていない。大抵は、980円である。これは、歴史や文化の違いであろう。

フィンランドになると、€9.95になる。なぜならば、フィンランドのユーロ硬貨の最小単位が、5セントだからだ。

また、アメリカにおける、ガソリンの値段の付け方が面白い。たとえば、「2.99 9/10」などという値段を付ける。この9/10は、10分の9セント、すなわち、0.9セントであり、0.009ドルである。米ドル硬貨の最小単位は、1セントなのに、なぜこのような値段をつけるのか。それは、このガソリンの値段は、1ガロンあたりの値段だからだ。たとえば、2.99 9/10という値段で10ガロンいれるのならば、値段は29ドル99セントになる。

基本的な考え方は同じだが、事情が異なるので、微妙に値段の付け方も異なっているのだ。

これはひどい

山本弘のSF秘密基地BLOG:【入試問題投稿事件】TBSから変なメールが来た

つまり、ここまで読解力のない人間が、普段テレビで流れているニュースの取材をしているわけだ。むべなるかな。

アメーバピグ、低能ユーザーによって大炎上中

アメーバピグという、Flashベースのチャットサイトがある。最近、Flash Player10.1以降を要求するようになったそうだ。

【ピグ】推奨利用環境の変更について|スタッフブログ

しかしなんと、あまりにユーザー層の知能が低過ぎるので、Flashをアップデートできず、クレームが殺到している。

968 ■ハ?利用者にやめろってヵ?
いつも、アメピグ楽しくやってた。
アメGだって、招待で
ケータイのパケ代かかってた。
アメーバさぁ、なにが都合悪くなったヵ
知らんヶドさ、もどしてくれん?
ウチんとこのPCもしかしたら
対応してないヵも知れん。
↑できないんだったら、
FlashPlayerと変な取り引きでも
してるの?
してないんだったら、
前の状態に
戻してくれん?
ameba軽く詐欺じゃん
マヂなんなわけ?

ウチゎケータイのパケでしヵ
金使ってないヶド
フツーにアメG大量
購入したヒトの気持ちにも
なってみたら?
amebaみたいに
気遣いできないんだったら、
会社とヵ.つぶれるんじゃない?
お願いだから戻して。

これに対して運営は、Flash Playerのアップデート方法を、スクリーンショット付きで説明するものの、

【ピグ】FlashPlayerのバージョンアップについて|スタッフブログ

361 ■無題
これらの競合するアプリケーションを閉じると、インストーラーは自動的に続行されます。
とでてきたのですが、ピグができません><
どうしたらいいですか?

362 ■無題
めんどくさ

373■ふざけてんじゃねぇよ!
まったくやり方が初心者の人にわからない説明だな
もっと正しくしろ
大体本アカは10.2だが、発言が相手に届かないエラーばかり出るんだよ いい加減にしてくれないか?
ここは初心者が多いんだぞ 上級者の多いところだと思ってたのか? サイバーエージェント

などと、問題解決には程遠いようだ。

初めて、この手のFlashベースのサイトに同情してしまった。これは悪夢のような事態だ。そもそも、アメーバ側に問題はないのだから、どうしようもない。

基本的に、このユーザー層は、ソフトウェアのアップデートをしないし、エラーメッセージも読まない種類の人種なのだ。どう説明したところで、分かってもらえまい。一体どう解決するのだろう。

ちなみに、この機会に手持ちのPCにインストールされているFlashのバージョンを調べたら、10.2.152.26だった。おっと、これは危ない。現時点での最新バージョンは10.2.152.32なのだ。最近は、FlashはZero Punctuationをみるのにしか使っていないので、気がつかなかった。そもそも、メインで使っているブラウザーであるChromeでは、Flashを無効にしているのだ。

2011-03-03

Windows 1.0からWindows 7までアップグレードしてみた

Chain of Fools: a video experiment to upgrade every version of Windows – istartedsomething

Windows 1.0から、Windows 7までを、延々とアップグレードしていく試み。

これはすごい。なにより、ちゃんと動くのがすごい。

2011-03-02

Bloggerの日本語コメントのスパム判定が結構ひどい

ふと気がついたら、日本語コメントがほとんどSPAM判定を受けていた。BloggerのコメントにSPAMフィルターが導入されたのは、昨年の8月だ。これはひどい。

とりあえず、溜まっていたコメントで、SPAMではないものをすべて表示させた。

何故か、SPAM解除したコメントは、2件のコメントとカウントされている。不思議だ。いや、ひょっとしたら、消したSPAMまで、表示はされないものの、コメントされたとしてカウントされているのか。

問題は、このSPAMフィルターを無効にする方法がないし、通常のコメントとSPAM判定を受けたコメントが、別画面に分離されているので、分かりにくいということだ。

2011-03-01

GMail、テープから復旧中

Gmail back soon for everyone - Official Gmail Blog

やはり、いまだにテープは強いか。たしか、高校生ぐらいの時に、天文台の観測データの保存にテープを使っているという記事を読んだ記憶がある。テープの入れ替えまで全自動なのだとか。テープを使う理由は、もちろん容量である。ペタバイト単位のデータを保存するには、HDDではコストが掛かり過ぎるのだとか。テラバイト単位のHDDが安価になった今は、どうなっているのだろう。

core language active issuesを読破

一週間かけて、C++ Standard Core Language Active IssuesのReadyとTentatively Readyを読破した。

前々から、いずれはやらなければならないことだと思っていたのだが、なかなか踏ん切りがつかなかったのだ。FDISがでるまで、C++参考書の執筆を積極的に進めることができない今、思い切ってacitve issueを読破することにした。その結果、FDISで変更されるかもしれない箇所を把握できた。

また、これからは、差分だけ追いかけていけばいいのだ。もっと以前に読破しておくべきだった。

ちょうど、Pre-Madrid mailingが公開されているので、新しいissueもいくつか追加されている。さっそく読むことにした。

なんと、今回追加された20件のissueの中に、SubmitterがRyou Ezoeになっているissueが3件もあるではないか。たしかに、ここ最近、クラス周りにいくつか問題のある文面を発見して、そのつど指摘していたが、まさかissueに載るとは思わなかった。この調子で粗探しを進めるとしよう。

pre-Madrid mailingの簡易レビュー

Pre-Madrid mailingが公開された。

最新のドラフトは、N3242となった。N3225からの大きな変更はない。typoの修正などにとどまっている。

N3233: Decltype and Call Expressions

decltypeの型は完全型でなければならないが、これは不必要にきつい制限であるとのこと。例えば、以下のコードはエラーになる。

struct S ;
S void f() ;

using type = decltype( f() ) ; // ill-formed.

このため、decltypeの式が関数呼び出しであり、戻り値の型が不完全型である場合を許可するという提案。

N3234: Remove explicit from class-head

クラスのメンバーの明示的なチェックを強制するexplicitを廃止する提案。現時点では、まだ時期尚早である。

N2335: Generalized pointer casts

ライブラリでは、static_castを用いた、異なるポインター型の間での型変換という要求があるが、これは、ポインターのようにふるまうクラスでは、難しい物がある。そこで、pointer_traitsを新たに定義し、static_castの代わりに用いることにする提案。

N3241: Moved-from state

ムーブされた後のオブジェクトの状態を規定する提案。標準ライブラリに渡すオブジェクトは、ムーブされた後も、指定された要求を正しく行わなければならない。例えば、代入可能なことを要求している型の場合、ムーブした後のオブジェクトに代入した場合、ちゃんと動作するように実装しなければならない。

N3248: noexcept Prevents Library Validation

noexcept指定された関数から例外がthrowされた場合の挙動を、terminateから未定義動作に変更する提案。

理由は、デバッグのためである。デバッグ用に、STLでクラスの内部状態をチェックして、不正な場合に、エラーを出すという手法は、一般的である。たとえば、イテレーターが参照された場合、本当に妥当な要素を参照しているのかどうかをチェックするような機能である。

noexceptを、規格制定のかなり遅い段階で取り入れたことにより、また、noexceptが実際に有用であることにより、ライブラリWGは、既存の関数を、noexcept指定すべきかどうか、洗いざらいに検証した。しかし、noexcept指定された関数からは、例外を投げられないので、デバッグ版ライブラリの実装、また安全なライブラリの実装は、できなくなってしまう。

現実の実装では、コンパイルにはモードを付けるべきだろう。ひとつはテストモードであり、noexcept指定された関数からの例外のthrowを、通常通りサポートする。もうひとつは、プロダクションモードであり、こちらは、terminate()を呼び出す。

もちろん、モードというものは、規格では言及されていないし、また、現時点では行うべきではない。そのため、noexcept指定された関数から例外が投げられた場合の挙動は、このような実装を可能にするため、未定義動作にすべきである。

N3250: US-18: Removing User-Defined Literals

ユーザー定義リテラルを取り除く提案。ユーザー定義リテラルには実装経験がない。実装がないために使用経験もない。C99の16進数浮動小数点数リテラルの文法と衝突する。ユーザー定義リテラルを規格から取り除くためのコストは低い。何故ならば、ユーザー定義リテラルを使っている、他のコード、文面、標準ライブラリはないからである。

これは当然だろう。ユーザー定義リテラルは取り除くべきだ。

N3258: US-65: Removing Inheriting Constructors

継承コンストラクターを取り除く提案。継承コンストラクターには実装経験がない。実装がないために使用経験もない。継承コンストラクターはVariadic Templatesでエミュレート可能である。継承コンストラクターを規格から取り除くためのコストは低い。何故ならば、継承コンストラクターを使っている、他のコード、文面、標準ライブラリはないからである。

継承コンストラクターの廃止は惜しいが、確かに、コンストラクターのデリゲートに比べれば、あまり魅力的ではない。廃止されても仕方がないだろう。

N3253: A Proposal to Tweak Certain C++ Contextual Conversions

ifやwhileなどでは、式がある型、たとえばbool型に変換可能であることを要求している。現行の文面は、変換先の型以外には、全く同じことを、それぞれ微妙に異なる文面で定義している。このような定義はまとめるべきである。

この提案は、ある型へ変換可能であるという意味の、contextually convertedという用語を定義し、他の文面では、単にbe contextually convertedという言葉を用いるように変更する。

N3254: Proposed resolution for US104: Allocator-aware regular expressions (rev 2)

正規表現ライブラリをアロケーターに対応させる提案。

N3255: C++ Decay Copy

std::forwardの戻り値の型を、std::decayを適用した型にした、std::decay_copyを追加する提案。単純だが、標準ライブラリにあるべきヘルパー関数である。ちなみに、実装は以下の通り

template <class T>
typename decay<T>::type decay_copy(T&& v)
{ return std::forward<T>(v) ; }

N3257: Range-based for statements and ADL

この問題については、本の虫: range-based forに対する意見求むで解説した。私は案4を推している。

C++0xとC++03の比較

2ch.netのC++0xスレのために書いたコードを、試しに、C++03に移植してみた。

まずは、C++0x版から。

#include <iostream>
#include <vector>

// range_traits案の実装
namespace std
{
 
template<class T>
struct range_traits
{
    static auto begin( T & t ) -> decltype( t.begin() ) { return t.begin() ; }
    static auto end( T & t ) -> decltype( t.end() ) { return t.end() ; }
    static auto begin( T const & t ) -> decltype( t.begin() ) { return t.begin() ; }
    static auto end( T const & t ) -> decltype( t.end() ) { return t.end() ; }
} ;
 
}
 
// 使用方法
template < typename Container >
void print( Container && c )
{
    using traits = std::range_traits< typename std::decay< Container >::type > ;
    for ( auto iter = traits::begin( c ), end = traits::end( c ) ; iter != end ; ++iter )
    { std::cout << *iter << std::endl ; }
}
 
int main()
{
    std::vector< int > v = { 1, 2, 3, 4, 5 } ;
    print( v ) ;
}

このコードは、なかなか簡潔だ。しかもすばらしくジェネリックである。

C++03は非常に劣った言語で、autoもdecltypeもrvalueリファレンスも新しい関数記法もエイリアス宣言も初期化リストもない。となると、上記のコードは、大幅に書きなおさなければならない。

#include <iostream>
#include <vector>

// range_traitsの実装
namespace std
{
 
template<class T>
struct range_traits
{
    static typename T::iterator begin( T & t ) { return t.begin() ; }
    static typename T::iterator end( T & t ) { return t.end() ; }
    static typename T::const_iterator begin( T const & t ) { return t.begin() ; }
    static typename T::const_iterator end( T const & t ) { return t.end() ; }
} ;
 
}
 
// 使用方法
template < typename Container >
void print( Container const & c )
{
    typedef std::range_traits< Container > traits ;
    typedef typename Container::const_iterator iterator ;
    for ( iterator iter = traits::begin( c ), end = traits::end( c ) ; iter != end ; ++iter )
    { std::cout << *iter << std::endl ; }
}
 
int main()
{
    std::vector< int > v ;
    v.push_back( 1 ) ;
    v.push_back( 2 ) ; 
    v.push_back( 3 ) ;
    v.push_back( 4 ) ;
    v.push_back( 5 ) ;

    print( v ) ;
}

だいぶ、ジェネリック度が下がっている。それに、この場合はconstなlvalueリファレンスでもいいのだが、何かもっと大胆なことをしようとすると、やはりrvalueリファレンスが欲しいところだ。typedef指定子の文法は分かりづらい。

ちなみに、range-based forのために、range_traitsが採用されることは、まず確実にないと考えている。かなり意見が割れているので、規格の制定を遅らせないために、もしかしたら、現状維持かもしれない。しかし、やはりADLに頼るのはやめてほしいのだが。

C++0xの非常に分かりにくい宣言

非常に分かりにくいC++0xの宣言を考えてみた。もちろん、識別子やインデントによって、C++のコードを読みにくくすることは可能だ。ここでは、そのような難読化ではなく、文法上、こう書かなければならないものだ。

namespace NS
{

    template < typename T >
    struct X
    {
        template < typename U >
        void Y(U) { }
    } ;
} 

template < > template < > void NS::X<int>::Y<int>(int) { } ;

これは、C++0xの新機能をふたつも使った、非常に分かりにくい宣言だ。C++では、テンプレートを宣言した名前空間スコープの外側で、テンプレートの特殊化や部分的特殊化を宣言できる。その際には、名前の修飾が必要である。また、関数は特殊化できる。

template < > // explicit-specialization for template class NS::X
template < > // explicit-specialization for template function NS::X::Y
void // return type of specializations of template function NS::X::Y
NS:: // namespace qualification
X<int>:: // specialization for template class NS::X
Y<int>(int) // function declaration
{ } // function body
;

もちろん、通常のプログラマーは、このようなコードを理解する必要はない。