2010-01-31

articleとplural

日本人にとって、article(冠詞)とplural(複数形)は難しい。

たとえば、かわいい猫がいたとする。さて、この猫の可愛さを、どう表現したらいいのだろうか。

The cat is cute.
(This particular cat IS cute. not others.)

Cats are cute.
(All cats are cute, obviously.)

It's Caturday! I has cheezburgar lol
(The cat is the cutest animal in the world.)

そもそも、猫が一匹なのか、複数入るのかどうかというのは、日本語から考えれば、どうでもいいことなのだ。

英語を使う際は、当然、英語で考えているのだが、やはり日本語ネィティブとしては、articleとpluralだけは、落としてしまう。

その結果、私のチャットの発言は、だいぶ不自然な英語になっているのである。

何とかしないといけないなぁ。結局、私は、全く文法を学んでいないためなのだろう。

追記:意味の違いは、理解しているのだが、英語を使う際に、自然に頭から出てこない。

VS2010のヘルプビューワー、LightWeight

Microsoft Help Viewer - New Help System in Visual Studio 2010 | kmcgrath | Channel 9

Get Microsoft Silverlight

dexplorerベースのclassicヘルプビューワーから、ローカル上のhttp鯖形式のLightWeightヘルプビューワーに変更したようだ。ヘルプは、自分の使っているブラウザ上からアクセスできる。

ヘルプビューワーを、Visual Studioから切り離したので、Visual Studioとは独立してアップデートを提供できる。現時点では、半年おきにアップデートすることを考えているらしい。

また、コンテンツの追加、削除も、非常に簡単に行える。

コンテンツのアップデートは、月例を考えているようだ。

また、ローカル上のヘルプコンテンツと、オンラインとを、切り替えることができる。オンラインは常に最新になっているが、インターネットを介するので、当然、ローカルよりは遅延がある。しかし、全く同じUIを提供している。

この新ヘルプビューワーは、現状では、従来のクラシックヘルプビューワーにあった、コンテンツのツリー形式の目次がなくなっている。これは、ある意味すっきりとするのだが、目次をたどって機能を調べたい人間から、不満が出ているらしい。ただし、このLightWeightは、Visual Studioのリリースとは独立できるので、後からアップデートして追加ということも、考えているらしい。

ちなみに、この新しいヘルプビューワーは、今すぐ体験できる。オンライン上のMSDN Libraryから、LightWeight Betaを選択すればよい。一度切り替えると、元に戻すには、右下のSwitch Viewから選択しなければならないので、注意されたい。

これはよい変更点だと思う。このようなドキュメントは、ローカル鯖からブラウザを介して見れたら分かりやすい。なにしろ、自分が使い慣れたブラウザを使えるのだから。

2010-01-30

思うこと

先日、x264の開発者であるDark_Shikariとチャットをしていたら、彼が面白いリンクをくれた。何でも、オーストラリアでは、貧乳が禁止されたらしい。とても面白かったので、元ソースの、オーストラリアセックス協会なども調べて、概要を翻訳して、ブログを書いた。28日のことである。

このネタを翻訳して日本に持ち込んだのは、知る限りでは、私が一番乗りである。

29日、このネタは受けたらしい。各所からリンクされ、一気にアクセス数が上がった。

さて30日の今日、あのザイーガからリンクが張られた。ザイーガは、公平に言って、人気のブログであると思う。おそらく、日々のアクセス数も、かなり高いと思われる。その内容は、主にエロとグロと猫である。私は、主に猫の理由で、あのザイーガをGoogle Readerに入れていた。そう、猫のためである。ホントだ。信じてくれ。私が猫好きである証拠に、あの、I Can Has Cheezburger?も、Google Readerに放りこんでいる。

驚くべき速さである。たしかに、このネタは面白いと思う。しかし、たかが数千アクセス程度で、アクセス数が極端に上がったと言えるブログである。それほど有名にはなっていまい。盛り上がったのは29日、その次の日の30日に、このネタを見つけてリンクを貼れるとは、いったいどういう人間なのだろう。

有名ブログには、有名ブログなりの理由があるのだろう。それに、これだけではない。流行のネタを、いちはやく見つけて記事にしなければ、人気は保てない。

ちなみに、私はこのブログには、広告を貼っていないし、別に、特にアクセス数を伸ばそうという野心があるわけでもない。ただ、このブログの記事を見て、誰か一人にでも、何らかの利益を与えたならば、それでいいと思っている。このようにヒットするのは、年に数回である。

ちなみに、このネタが大いに受けたということを、Dark_Shikariに報告したところ、EUでは形の悪い野菜が、法律によって禁止されていたということも教えてもらった。面白かったので、これも簡単にまとめて記事にした。

こんな会話があった(極端に意訳している)

私:形の悪い野菜が法律で禁止? ガイジンは理解できねぇな。
Dark_Shikari:節子、それガイジンやない、政治家や。

まあ、どちらのネタも、記事を書くのにかかる時間にして、せいぜい数十分である。気分転換に丁度良い。

思えば、私も英語力が上がったものだ。

EUのヘンテコな形の野菜を禁止する法、撤回さる

Long live knobbly carrots: ban on ugly fruit and vegetables is scrapped - Times Online

自然のありのままに育った、ヘンテコな形の野菜や果物を、今日から(訳注:2009年7月の時点)、スーパーで売れるようになった。形のいい野菜より、四割は安い。

曲がったキュウリ、枝分かれしたニンジン、シワだらけのさくらんぼは、欧州委員会の制定した法律によって、禁止されていた。この二十年前の法律は、今日、ようやく撤回された。

しかし、曲がったバナナは別である。果物の規格は、大周委員会でも、また別のルールで管理されている。ある欧州委員会の公務員は、バナナはキュウリと違って、曲がっているべきだと言っている。

ミニチュア野菜はかわいいので、今後、もっともっと普及していくだろう。今日から、11センチメートル以下のカリフラワーや、8グラム以下ニンジンを売ることは、違法ではなくなるのだ。

ヨーロッパでは長らく、野菜の形が不揃いだと違法だったらしい。だから、曲がったキュウリや枝分かれしたニンジン、あまりに小さすぎる野菜を売ることができなかったらしい。この法律は、なんと二十年前から効力を持っていたというから驚きだ。この馬鹿げた法律は、ようやく、2009年の7月をもって、撤回されたそうだ。

Google日本語入力の技術講演会

Google日本語入力の、公式技術講演会に行ってきた。その次第を書きたいと思う。

今回の会場は、なんと大阪である。そのため、私のように関西圏に住んでいる人間には、参加しやすい。

まず、京都から大阪へ行く。いつも思うのだが、大阪の都市部は、まるでダンジョンだ。地上と歩道橋と地下道があって、一体どこを進んでいいのやらさっぱりわからない。大阪の立体構造を再現して、ゲームとして売り出せば、案外ヒットするのではなかろうか。

さて、受付の始まる時間になったので、会場に向かう。なんと、すでに長蛇の列であった。早くも失敗したか。もっと早くから来ていれば、前の方に座れたかもしれない。軽く失望しつつ受付を済ませると、なんと、一番前の席が、二席だけ開いているではないか。知っての通り、私はそういう性格なので、迷わず一番前に座った。ちなみに、隣の席は空いていたが、何故か誰も座ろうとしなかった。こういうのは、だいぶ性格が出るらしい。前に座った方が、スライドも見やすいし、講演者とも近い。前に座ったことで、損をすることはない。とすれば、最前列に座るのが最善であるはずだ。にもかかわらず、私が部屋に入ったときは、もうほとんど埋まっていたのだが、それでも、前の席が空いていた。

このような講演会に来るほどは積極的で、しかも最前列に座るほど積極的ではないというのは、どういうものなのだろうか。それはさておき。

肝心の内容だが、それほど目新しい情報はなかった。多くの事は、すでに技術系サイトのインタビューなどで、断片的に公開されている内容であった。それでも、実際に講演を聞くのは、得るところが多かったと思う。

特に何も言われていないので、興味のある人のために、講演会の概要をここに書いておく。また、すでに技術系サイトのインタビューなどで、既出となっている情報もあるが、特に示さない。

まず、IMEというものについて説明があった。

IMEは、ブラウザやOSにすら匹敵する、非常に大規模なシステムである。

IMEには、二つの問題がある。絶対にクラッシュできないという事と、強いセキュリティが要求されるという事だ。

もちろん、ソフトウェアは、なるべくクラッシュするべきではない。とくにIMEは、辞書などのファイル操作を伴なう。クラッシュすることによって、ファイルの書き込みが不完全になってしまうと、IMEの挙動がおかしくなってしまうかもしれない。これは、クラッシュしてはならない理由の、IME側の都合である。その他にも、クラッシュしてはならない理由がある。

Windows環境では、IMEはDLLの形で提供する。このDLLは、かな漢字変換を利用する全アプリのプロセスにロードされる。もし、IMEのDLLがクラッシュしたならば、その読み込み元のプロセス、すなわち、他人のアプリを巻き込んでしまう。したがって、IMEのDLLは、クラッシュしてはならない。

残念ながら、IMEのDLLは、実際にクラッシュする。これは、IME側の理由だけではない。もし、IM DLLを利用するアプリがクラッシュすれば、当然、そのプロセスのDLLも巻き添えを食らう。

ファイル書き込みなど、IME自体もクラッシュしてはならない理由はすでに述べた。しかし、IME側だけではどうにもならない、アプリ側のクラッシュには、一体どう対処すればいいのか。

セキュリティの問題もある。IM DLLは、アプリのプロセスに読み込まれる。つまり、IMEは、利用されるアプリと同じ権限を持つということである。つまり、管理者権限で実行されるアプリにロードされたIMEもまた、管理者権限を持つのである。たとえば、レジストリエディタだ。たとえば、ログオンプロセスだ。したがって、IMEは、絶対にセキュリティ上のヘマをしてはならない。

たとえば、IMEの変換候補ウインドウから、ブラウザを立ち上げてググれたら、便利な機能かもしれない。しかし、IMEはログイン画面で実行されることもあるということを考えれば、ブラウザを立ち上げるような、安易な行動はできないのである。ログイン画面で、ログインもせずに、管理者権限のプロセスであるIMEからブラウザを立ち上げられるような環境は、セキュリティ上、非常にまずい。

従来のIMEの実装は、DLLで、ユーザーの入力やら、かな漢字変換やら、結果の表示やらを、すべてやっていた。その結果、DLLは非常に肥大化した。巨大になるということは、それだけクラッシュする要因が増えるということである。

Google日本語入力は、既存の価値観に縛られない、斬新な発想で設計された。

Chromeでもおなじみの、マルチプロセスとsandboxである、

Google日本語入力を、大別すると、以下のようになる。

IM DLL(GoogleIMEJaTIP32.dll)
全プロセスに読み込まれるDLL。従来のIMEは、主にこれを指す。Google日本語入力では、IM DLLは、ユーザーからの入力を受け取り、Converterに渡し、結果を表示するだけの処理をする。
Converter(GoogleIMEJaConverter.exe)
変換エンジン。IM DLLから、ユーザーの入力を受け取り、かな漢字変換の処理を行い、結果をIM DLLに返す。
Renderer(GoogleIMEJaRenderer.exe)
変換の候補ウインドウを表示する。

IM DLLは、最小限の処理しかしない。ユーザーの入力を受け取り、変換エンジンに丸投げし、結果を表示するのである。IMEの肝心要の、かな漢字変換機能は、Converterが処理する。

ConverterやRendererは、必要最低限の権限しか持たない。Windowsでは、プロセスの持つ権限を制限することもできる。Chromeでもおなじみの手法である。

このように、プロセスで分けることによって、クラッシュ耐性とセキュリティを確保している。IM DLLがクラッシュしても、Converterには被害が及ばないし、逆に、Converterがクラッシュしても、IM DLLには被害が及ばない。

また、移植性(portability)も確保できる。たとえば、64bit版は、わずか一日で移植された。テストに十日かかった。わずか一日で移植できた理由は、マルチプロセス、プロセス間通信という設計なので、アプリに読み込まれるIM DLLさえ64bitコードに移植すれば、ConverterやRendererは、32bitプロセスでも、問題はないからであった。

Converterは、クラッシュしても全く問題ないようになっている。ためしに、タスクマネージャからConverterのプロセスを強制終了しても、全く問題がない。Converterプロセスが終了したことを検知し、自動的に再起動される。

デモでは、4秒おきに、Converterプロセスを強制終了する、極悪なスクリプトを走らせた状態においても、IMEが全く問題なく使えるということを実演していた。

しかし、ユーザーの入力中に、Converterが終了したら、どうするのか。たとえ、Converterプロセスを再起動できたとしても、また変換の確定していない、入力中の文字列は、一体どうすればいいのか。

これも、問題ない設計になっている。IM DLLは、ユーザーの一連のキーシーケンスを保持している。Converterプロセスが不意に終了した場合、このキーシーケンスを再び送り返すことによって、元の状態に戻すことができる。だから、4秒おきにConverterが強制終了するというような、極悪な環境下でも、ユーザーはまったく気にせず、入力ができるのである。

一連のキーシーケンスとは何か。これは、Enterキーを押して、変換を確定するまでを指す。

ちなみに、4秒ごとにConverterを殺すデモでは、全員、無反応であった。というのも、あまりに普通に動きすぎて、ユーザー側からみると、Converterが4秒おきに殺されているなんて、全く分からなかったからだ。「ここは、驚くところなんですけどね」という講演者の声が、むなしく響いた。それぐらい、あまりにも普通に動きすぎていた。

また、この機能は、デバッグにも役立つ。たとえば、あるキーシーケンスでConverterがクラッシュする場合を、容易に補足できるし、また、問題の再現が簡単である。自動テストでは、様々なキーシーケンスを、非常に過酷な状況(CPUが遅い、メモリが不足している)で流し込み、延々と走らせ、クラッシュする場合を探している。

さて、では肝心の、かな漢字変換は、どうなのか。これは、具体的なアルゴリズムは公開できないものの、教科書に乗っているぐらい、基本的なものを使用しているとのことであった。

辞書について。語彙は重要だが、多ければ多いほどいいというわけではない。英文のスペルチェックでも、既存の辞書のすべての単語を、スペルチェックの辞書に詰め込むと、普段使わないような文字の組み合わせでも、妥当な単語として認識されてしまう。

しかし、豊富な語彙は必要である。しかし、あまりに多すぎると、メモリを大量に消費してしまう。第一、辞書ファイルの破損の問題もある。一体どうすればいいのか。

まず、辞書のデータ構造だが、これはTRIEと呼ばれているツリーのような構造を用いている。これは、決して高速なデータ構造ではないが、辞書サイズの圧縮に役だつ。また、かな漢字変換の単語検索には、完全一致(exact match)ではなく、たとえば、「あ」なら、あに続く単語(亜、愛、愛子、アイス等)も必要になる。この要求も満たしている。

さらに、このTRIEというデータ構造を、LOUDSという手法で実装して、データ量を圧縮している。ハフマン符号で、さらに圧縮をしている。別になにか特別な改良版アルゴリズムを使っているということはなくて、基本的には、教科書通りのハフマンらしい。

データ構造の圧縮と最適化については、タバタさんという職人気質なGoogle社員が、20%ルールでやっているそうである。タバタ・メソッドと呼ばれているとか、いないとか。

LOUDSで、辞書を70MBまで圧縮し、ハフマンで35MBまで圧縮しているらしい。

たったの数十MB程度のファイルサイズだが、語彙は膨大なものになるらしい。語彙がどのくらいあるのかということは、公開できないとのことだ。

辞書はどうやって生成するのか。これは、Web上からのデータから、自動的に生成している。人力ではない。ただし、ある程度の基本的な単語(食べる、歩く等)は、自動生成ではない辞書を持っている。

辞書のデータをどのように保持するのか。これは、辞書ファイルというものがあるのではなく、実行形式のバイナリに、そのまま埋め込んでいる。つまり、Converterに埋め込んでいる。

この設計の利点は、辞書をstatelessにできるということだ。辞書への書き込みが行われないので、辞書ファイルの破損ということはなくなる。何らかの理由で辞書が破損した場合(HDDが壊れたなど)、Converter自体が動かなくなる。つまり、破損した辞書ファイルのまま、中途半端に動くということがなくなる。

また、自分でメモリ管理をしなくていいという利点もある。なぜなら、Windowsでは、実行ファイルは、メモリ上にマップされる。メモリ管理は、OSが自動でやってくれるのである。

このため、OSのメモリ管理の戦略がヘボいと、IMEのパフォーマンスも落ちてしまう。具体的には、Windows XPだ。Vista以降なら、メモリ管理のアルゴリズムも賢くなっている。まあ、XPの欠点は、すでによく知られた話だが。この問題は、昼休みから帰ってくると、メモリがスワップアウトしていて動作がモッサリになるので、そのような名前をつけられていた気がする。

また、辞書のデータ構造の互換性に悩まされなくてもよいという利点もある。データ構造を改良した結果、下位互換性がなくなったとしても、辞書は、Converterそのものなので、Converterを差し替えればよい。すでに述べたように、Converterが不意に終了しても、全く問題ない設計になっているので、アップデートも、簡単にできる。最も、アップデートの際は、IMEがONになった時点とか、比較的安全な、都合のいい時を選ぶらしいが。

Google日本語入力は、「もしかして」機能から始まった。もしかして機能の利用結果を調べたところ、既存のIMEの誤変換によるものと思われる入力間違いが、非常に多かった。そして、もしかして機能は、正しい結果を返すことができていたのである。とすると、これはIMEにも利用出来るのではないかと考えた。

Googleには、有名な20%ルールがある。これは、「20%の時間を使ってもいいよ」という権利ではなくて、「20%は別のことをしなさい」という要求であるらしい。実際、何もしていないと、「何でお前は何もしていないんだ」と文句がくるらしい。Google日本語入力は、当初、20%ルールとして発足した。今は、本プロジェクトになっている。

Google社内には、日本語処理や、IMEの開発に携わっていたプログラマが、何人もいた。そういう人達が集まって、IMEの設計のディスカッションをし始めた。IMEの設計はどうあるべきなのか。

IMEは膨大である。当初は、ただひたすらディスカッションだけに、半年もの時間が費やされた。ある日、「誰もコードを書いていないではないか!」、ということに気がついた。それからは、週に一度、集中的にコードを書く日を設けることにした。

出来上がったデモ版は、はじめからかなり精度が高かった。これならイケるということで、社内でdogfooding(自社製品を社員が率先して使うという意味のMS用語)が始まった。多くのフィードバックが得られたが、特に多かったのが、「俺の使っている、既存の某IMEにある、この便利な機能がないぞ」というものであった。既存のシステムからの移行を用意にするため、既存のIMEのキーバインドや、メジャーな機能を、なるべく提供するようにした。Google日本語入力独自の売りは、サジェスト機能と語彙である。

あとはひたすらテスト、テスト、テスト。

テストが通らず、やむなく落としている機能も、二、三あるという話である。どのような機能かは公開できないが、いずれ、公にする日が来るだろうとのことであった。

Google日本語入力は、斬新な設計である。クラッシュを前提にした、クラッシュしても問題のない設計。そのためのマルチプロセスを利用したsandbox化。Web上から自動的に辞書を生成。辞書の圧縮と、辞書をプログラムのバイナリに含めること。

興味深い質疑応答を取り上げると。

今後のリリース期間はどうなるのか。定期的なバージョンアップなどはあるのかという質問に対しては、まだプロジェクトが始まったばかりなので、決まっていないが、できれば常に最新版を提供して行きたいとの答えであった。

Web上のデータは、信頼性の高いデータと、あまり文法的に正しくない文章の使われている可能性の高い、信頼性の低いデータが混在している。Web上から辞書を自動生成する際に、データごとの重み付けをおこなっているのかという質問に対しては、そのような重み付けは行っていないとの答えであった。

Web上のデータからの辞書生成には、品詞を推定してつけている。完璧とは言わないが、ある程度は動いている。

ユーザーの実行環境は様々である。一体、何が最も、パフォーマンス上のボトルネックになるのかという質問に対しては、メモリとの答えであった。Windows XPのメモリ管理の戦略が、相当ひどいらしい。Vista移行なら問題ない。これは元々質問だったが、興味深かったので、上でも言及した。

コマンドプロンプトではGoogle日本語入力を使えないが何故かという質問に対しては、Vista以降なら使える。XPはTSSのサポートがまだ不十分なのだ。Vista以降を使えば問題ないという答えであった。

Web上のデータは、偏りすぎているのではないか。普通の文章が書きにくいのではないか。ユーザーの特性を判定して、単語のランクを変えるというのはどうかという質問に対しては、いい意見だとの答えであった。

放送禁止用語はどうするのか。他のとあるIMEは、放送禁止用語を省いていることを、「機能」だと謳っているそうである。現在のGoogle日本語入力には、放送禁止用語が多数含まれている。これを自主規制することは考えていないのかという質問に対しては、Googleはあくまで、Web上の単語のランクに基づいて辞書を生成し、人の手を加えることがないようにするのが、基本理念なので、そういうことはしないとのことであった。

個人的な意見では、自主規制は、すべきではない。だいたい、身体障害者を意味する、片輪だって、本来は、湾曲表現だったのだ。最近、とある政治家が、障害者ですら差別的に聞こえるから、障がい者としようなどと行っているらしいが、これとて本来は、障碍者だったのである。また、そもそも障害者という言い方をやめて、フィジカリー・チャレンジド・ピーポー(Physically Challenged People:肉体的に、神から試練を与えられた人々)にしようなどとたわけた事を抜かす政治家もいるようだが、アホらしすぎてまともに反論する気さえない。

こうなってくると、私には、Political Correctnessを、「政治的に正しい」と訳すのは、妥当な翻訳であると思えてしまう。実際、その正しくなさが、自己言及的に正しいと思う。

話がそれた。私信を終わる。

一体、どうやってIMEで利益を出すのかという質問に関しては、現時点では、IMEで直接利益を上げることは考えていないとのことであった。IMEを使うことによって、プログラマやユーザーがより便利になれば、間接的に、Googleの利益にもなるだろうという旨のことを答えていた。

Linux版は、本当に出してくれないのかという質問に関しては、Linux版はださないという答えであった。ただし、Chrome OS関連で、オープンソース化されるので、Linuxに移植したい人がいれば、ご自由にどうぞというスタンスらしい。

他の言語、たとえば英語とか、アラビア語とかのIMEを統合して、開発する予定はないのかという質問に対しては、そのような予定はないとの答えであった。ただし、Googleは中国語版のIMEを開発していて、すでにリリースされているらしい。

私は、ユーザー辞書について質問したいと考えていたのだが、それは何人も質問していた。そこで、前々から気になっていた事を質問することにした。

それは、学習機能である。多くのIMEは、ユーザーの入力から学習して、文節の区切りや単語のランクを変更する。ところが、この学習が愚直で、大昔にただ一度だけ入力した変な変換結果を、そのまますべての変換に適用し、その結果、学習すればするほど、おバカになっていくということが、ままある。これを改善できないのかと質問した。まったく具体的な技術とは関係ない、単なる要望である。

答えは、それは、IME各社とも、非常に悩んでいる問題である。改善したいとは思っているとのことであった。

その後、Googleの新卒採用と、採用試験の方法についての説明があった。とくに真新しい情報はなかった。中途採用も年中募集中らしい。

なんだか、Googleで働きたくなってしまった。しかし、今私が最優先すべきなのは、C++の参考書の執筆である。働きながら執筆というわけにはいかない。私がGoogleにレジュメを送るとしたら、前回のC++WG会議で、一生さんに語ったあのネタを、本気で実行するしかない。

さて、Googleの講演会なので、いくつかのGoogleグッズをもらった。

Googleのロゴ入りボールペン。残念ながら、私は、万年筆を使っているので、ボールペンを使うことはないのだが、なかなかカッコいい。

Googleのロゴ入り携帯ストラップ。これもシンプルでカッコいい。

Googleのロゴ入り手提げバッグ。単なる安物の買い物袋である。Googleのロゴが入っているのでカッコいい。

Googleのロゴ入りTシャツ。質問をした人、全員に配られた。前に円を主体とした幾何学模様、後ろの首の部分に、Googleのロゴが入っている。カッコいい。

講演会は非常に楽しかった。終わってから、「やあ、本はどうですか」と声を書けられた。誰かと思えば、redboltz氏である。氏もこの講演会に参加していたとは、全く気がつかなかった。しかも、質問までしたというではないか。いやはや。

氏とC++0xの本について話しながら、大阪駅まで歩いた。相変わらず、大阪のマップはダンジョンである。幸い、氏が先達となってくれたので、私は無事に、迷路のような地下道を脱出して、大阪駅にたどり着くことができた。

氏に、「君はGoogleに向いているのではないか」と言われた。英語はともかく、その他はどうだろうか。最近の私は、言語仕様専門なのだ。アルゴリズムといえば、入門書に乗っているような基礎的なものしかしらない。しかも、主に考えることは、このアルゴリズムを、C++でジェネリックに実装したらどうなるか、ということである。それに、今の最優先事項は、C++0x本の執筆である。C++0x本の執筆に、時間が必要である。フルタイムの時間が必要である。

本の執筆には、金がいる。海外で行われる標準化委員会のmeetingに出席したいし、なにより私は、生活していかなければならないのだ。しかし、執筆以外の仕事に時間をとられているわけにはいかない。あの理想主義者のネタしかしないのか。

まあ、レジュメを送ってみるか。

追記:氏はTwitterを使っているが、私のGoogle Readerからは漏れていた。フィードに放り込んでおけば、あらかじめ、気がつけたかもしれない。私はすでに、10人以上ものTwitterアカウントを、Google Reader経由で閲覧している。結局のところこれが、Twitterに賛同できない私の、最低限の落しどころである。Twitterよりブログの方が楽だと思うのだが。

2010-01-29

C++0x本:文(Stattements)

文、ステートメント、これらは比較的、簡単だ。簡単というのは、目次作成が簡単だという意味である。

ユーザーが個別の機能としてみている文と、規格上の文は、それほど違わない。式文や、宣言文など、普段、あまり文として意識しない文もあるにはあるが、基本的には、それほどユーザーの認識と乖離していない。

ところで、以下の文がコンパイルできないということを、前に述べた。

decltype(0)(0) ;

このコードはコンパイルできない。そもそも、このコードはなんなのかというと、実は、関数記法の型変換ではないのだ。このコードは、変数の宣言なのだ。

// int x と同じ
decltype(0)(x) ;

// int
std::cout << typeid(x).name() << std::endl ;

なぜ、変数の宣言になるのか。それは、関数記法の型変換と、宣言文とで、文法上、曖昧になるケースが存在する。その場合は、すべて、宣言文として解釈する(たとえ、意味上のエラーになるとしても)というルールがある。そのため、宣言文になってしまう。

それを防ぐためには、括弧が必要である。

// int(0) と同じ。
(decltype(0))(0) ;

C++0x本:式(Expression)

ようやく式まで目次が進んだ。式である。我々がよく、「演算子」と呼んでいるものも、そうでないものも、一括りに、式というカテゴリに入る。

目次の名前が難しい。たとえば。Static castだ。一体どのような目次にすればいいのだろうか。

そのまま使うのか。

Static cast

あるいは、訳すのか。

静的キャスト(Static cast)

あるいは、キーワードにしてしまうのか。

static_cast

キーワードの使用は、あまりよいとは思われない。Static castは、訳さず、このまま目次にした方がいいのではないかと思う。

規格に忠実に考えると、インクリメントとデクリメントは、二種類あって、それぞれ別々の章に分けなければならない。前置と後置である。前置は、前置式のカテゴリに入るし、後置は、単項式のカテゴリに収まる。

もっと難しいのが、四則演算子だ。減算演算子というものは、存在しない。Additive operators(加算的演算子)というのがあって、その配下に、+, -がある。

同様に、除算演算子とか、剰余演算子などといったものもない。すべて、Multiplicative operators(乗算的演算子)というのがあって、その配下に、*, /, %がある。

まあこの辺は、そのカテゴリの下で、一括して説明すればいいかもしれない。

細かいところでは、配列の添字を取る演算子、operator [] はなんと呼ぶのが一般的なのだろうか。英語では、subscriptingという。添字演算子、配列演算子。どうもしっくりこないな。

C++0x本:言葉は難しい

Standard Conversionまで終了

たとえば、Floating point conversionsだ。これは、普通に日本語に訳すと、たとえば「浮動小数点数型変換」となる。これでは読みにくい。浮動小数点数を浮動小数点とか、浮動小数などと、小手先の最適化をしたとしても、やはり、読みにくいことにはかわりない。

長い単語だから読みにくいと感じるのか。しかし、元の英単語も、それなりに長い単語である。一体、なぜ英単語では、特に読みにくいとは思わないのに、日本語にした瞬間に、読みにくいと感じるのであろうか。私はこれでも、日本語ネイティブである。ひょっとして、私はバカなのだろうか。

ひょっとしたら、日本語にはセパレーターがないから、読みにくいと感じるのかもしれない。英語では、単語ごとに、空白文字というセパレーターを用いる。しかし、日本語には、そのようなセパレーターはない。句読点は、あくまで補助的な区切りに過ぎないし、どのように、句読点を、打っても、かまわない、わけだ。特に、ルールは、決まって、いない。

そこで私は、セパレーターを用いることにした。

浮動小数点数 型変換

あまりよろしくない。だいいち、空白文字のセパレーターというのは、日本語には馴染みがない。たとえ、数百年後には、一般的になったとしても、この2010年の時点で、そんな大胆な言語を使うことはできない。私は小説を書いているのではないのだ。

一般的に、・が使われている。

浮動小数点数・型変換

これもダメだ。読みにくい。ならばいっそ。

フローティング・ポイント・コンバーション
フローティング ポイント コンバーション

ダメだ。ますます分かりにくい。floatの型変換としたほうがまだましだ。まてよ、日本語として自然な区切り文字があるではないか。

浮動小数点数の型変換

これだ。まだマシだ。区切り文字として働いてくれる。

しかし、floating pointの訳語は、浮動小数点数でなければならぬのか。これはかなり漢字が多くて読みにくいのではないか。浮動小数ではだめなのか。ましてやこれに型をつけると、浮動小数点数型、浮動小数型。浮動小数でも通じるんじゃないだろうか。

浮動小数の型変換

この方がすっきりしていいと思う。

そもそも、文字的には、floating pointなのだから、浮動点とか、浮点などと訳されるべきである。しかし、このような訳語は、一般的ではない。浮動小数点数にしておくべきなのか。

ともかく、日本語には、何らかのジェネリックなセパレーター(区切り文字)が必要だと思う。

なぜ日本語には、セパレーターの概念がないのか。我々には、ひらがな、カタカナ、漢字がある。これらを組み合わせれば、セパレーターなしでも、それなりに単語の区切りが分かるからだろうか。では、中国はどうだ。あれは漢字しかないではないか。なぜ中国にセパレーターの概念が生まれなかったのか。

所謂、カギ括弧(「」)とか、句読点という、非ジェネリックなセパレーターはある。かなと漢字と、この非ジェネリックなセパレーターがあったから、欧米のように、ジェネリックなセパレーターは発明されなかったのか。

Google日本語入力が更新された

GoogleJapaneseInput-0.8.186.0が、GoogleJapaneseInput-0.9.248.0になった。

主な変更点は以下の通り。

Google Japan Blog: Google 日本語入力がアップデートされました。

英単語への変換がサポートされたらしい。いくつか試してみた。

アンビリーバブル
変換できない
ビリーブ、ビリーヴ
Believe
アコモデーション
accommodation
ガンダム
GUNDAM
ジャパン
JAPAN
ジャップ
JAP
オーストラリア
Australia
オーストリア
Austria
オーストリー
変換できない
サウスパーク
South Park
エリック カートマン
Eric 変換できない
スタン マーシュ
Stan Marsh
カイル ブロフロスキ
変換できない
ケニー
Kenny
ケネス マコーミック
Kenneth McCormick
ゴジラ
godzilla
サラリーマン
変換できない
サラリー
salary
マン
man
ウルトラマン
ULTRAMAN
マニフェスト
manifest
グーグル
Google
メタプログラミング
変換できない
プリプロセッサ
変換できない
ブレイン ファック
BRAIN FUCK
ミサ
Misa
ハスケル
Haskell
リスプ
Lisp
スキーム
Scheme
ジャバ
Java
スモールトーク
Smalltalk
ベーシック
BASIC
パスカル
PASCAL
シー
C
シー プラス プラス
シー 変換できない 変換できない
プラス
変換できない
あでぃしょん
変換できない
サブトラクション
変換できない
まるちぷりけーしょん
変換できない
ディヴィジョン
Division
スマート
Smart
トランスレート
変換できない
トランスレーター
Translator

アンビリーバブルってそんなにマイナーなカタカナ化だろうか。

カートマンと、カイルは変換できない。ただし、スタンとケニーは変換できる。このことから、Google日本語入力は思想が偏っていると言える。 :P

プログラミング言語に関しては、それほど偏りはない。まさか、プログラミング言語 Misaまで変換できるとは驚きだ。:P

変換精度の向上については、これは一ヶ月は使ってみないと分からない。

PS3がハックされたらしい

On the PlayStation 3: Here's your silver platter
PS3: Hacked | DigitalFoundry
How the PS3 hypervisor was hacked « root labs rdist

PS3がハックされたようだ。ハックの結果、システムの全メモリにアクセスできるようになった。すなわち、hypervisorと同等になったということらしい。

方法としては、なんとも地味というか、地道というか。ようするに、まず取っ掛かりが必要なのだが、そのために、バス上にパルスを流しこんでやって、誤作動を引き起こすところから始めるらしい。興味深い話だ。

しかし、この手のハックをやる意味がわからない。自由にプログラミングできないハードウェアなど、そもそも使う価値がないので、わざわざこんな労力を書ける意味がないと思うのだが。なぜ、いまだにゲーミングコンソールが流行るのか理解できない。

2010-01-28

C++0xの機能ふたつ

auto({1}).size()で行けない?

autoは、5.2.3 Explicit type conversion (functional notation) [expr.type.conv]には使えない。たしかに、Explicit type conversionの方には、simple-type-specifierが使えると書いてある。ただし、7.1.6.4 p3 auto specifier [dcl.spec.auto]に、以下のように書いてある。

This use of auto is allowed when declaring objects in a block (6.3), in namespace scope (3.3.6), and in a for-init-statement (6.5.3).

というわけで、以下のようなコードは書けない。

// ill-formed
auto x = auto(0) ;

decltypeには、このような制限は見当たらなかったので、以下のように書けるはずだ。

// well-formed?
auto x = decltype(0)(0) ;

が、VC10ではエラーがでる。さて、どうなのか。どこかに規格の見落としがあるのだろうか。さらに調べなければ。

これなら通った。

auto x = (decltype(0))(0) ;

優先順位の問題なのか?

#include <cstdio>

template <class t_any>
void check(const t_any &val)
{
std::puts("this is const left value.");
}

template <class t_any>
void check(t_any &&val)
{
std::puts("this is right value.");
}

int main(void)
{
check(100);

int x = 200;

check(x);

return 0;
}

GCC4.4.1で両方右辺値になるんだけどなんで?

おそらく、GCCのバグである。Overload Resolutionは、Argument Deductionの後に行われる。そして、テンプレート引数のrvalue referenceに対しては、lvalue referenceもdeduceされる。その場合、&&は、単に無視される。

さて、argument Deductionの後の関数は、どちらも同じ程度にマッチする「候補」である。すると、このコードは、どちらのオーバーロード関数を呼び出せばいいのか、曖昧である。したがって、コンパイルエラーになるべきである。

ちなみに、lvalueは、left-hand-valueの略ではないし、rvalueはright hand valueではない。いまだに古臭いC言語の世界に生きているのなら、使ってもいい。

C++0x本:御免

C++0xには、説明を省いてもいいのではないかと思う機能も、いくつか存在する。

たとえば、registerやinlineは、もはやまともに使われてはいない。モダンなコンパイラは、ことごとく無視する。今や、この手の最適化に関しては、コンパイラの方が人間より賢いのである。

exportは、まともに実装しているコンパイラがない。

asmは、完全に無視されている。インラインアセンブリをサポートしているコンパイラでも、結局、独自の文法を使っているのである。

しかし、これらの理想主義を広げていくと、危険である。

long longはC99とかいう時代遅れの言語から取った機能だ。使うべきではないし、そもそも規格に入れるべきではなかったので解説しない。

volatileは何の役にもたたないので解説しない。

これらは、ある意味正しいのだが、long longやvolatileは、実際に型として認識される。これを解説しないのは問題がある。

extern "C"はどうか。私は、これも気にいっていない。単にC言語との互換性以外に、別言語と会話する場合に必要だという意見もあるかもしれない。しかし、現実はさらにややこしい。レジスタをどう使うか。スタックに引数をどのように積むか、などといった呼び出し規約は、規格外である。そもそも、レジスタやスタックなど、規格では規定されていないのである。純粋にextern "C"だけ説明しても、何の役にもたたない。

ページ数が足りないから割愛するならともかく、気に入らないから割愛、役に立たないから割愛というのは果たしてどうだろうか。しかし、具体的な環境がなければ意味をなさないこれらの機能を、ただ言語上の定義から解説しても、無意味である。

ここに挙げた以外にも、規格の上では定義されているが、実際何の役にも立たない機能は多数存在する。その機能の多くは、相当の年季の入ったC++プログラマも知らないのである。たとえば、テンプレートのデフォルト引数がマージされるような機能は、誰も知らないだろうし、知っていても、使いたいとは思わないだろう。関数ポインタの宣言時に、デフォルト引数を指定できるという機能は、C++0xで禁止された。

Safe for Work: オーストラリア、貧乳を禁止す

Australia bans small breasts - Somebody Think Of The Children
The Strange Politics Of “Obscene” Bodily Fluids

オーストラリア セックス党(Australian Sex Party)が水曜日に発表した話によると、オーストラリア レーティング評議会(Australian Classification Board、日本でいう、映倫やビデ倫)は、アダルトビデオ及び映画における、貧乳の女性を禁止すると決定した。オーガズムの際の潮吹きを禁止し、捜査対象になるとの決定から、わずか一週間後の発表である。

オーストラリア セックス協会のWebサイトでの発表によると、二十代後半の女性の出演する、多くのアダルトビデオが、女優のバストサイズがAカップであるとの理由で、削除されはじめているとのことである。

なぜこんなことになっているかというと、児童ポルノだ。オーストラリアの法では、18歳未満は、児童ポルノである。ところが、オーストラリアはどうも極端というか、18歳未満に見える者も禁止しようとしたらしい。その結果、貧乳を全面的に禁止することになったとか。

ポルノのレーティング評価が拒否されるということは、まともに表だった市場で売れないということである。

ちなみに、オーストラリアでは、潮吹きも禁止されている。これは、あまりにも演出臭いとの理由かららしい。

日本でも、一時期バガボンドが自主回収されたりなどと、馬鹿げた話があったが、これはさらに上をゆく。

ヰタ・セクスアリスや、チャタレイ夫人の恋人を発禁処分にするような馬鹿げた言論統制は、今なお行われているのである。

ちなみに、二次元はどうかというと、オーストラリアは最高に言論統制が激しい。実写よりひどい。

追記:どうも、Australian Sex Partyは、政治結社らしいで、partyは、協会ではなく、党と訳した方が良さそうだ。

すばらしいゲーム

ユウラボ無料ゲーム | オムニバスRPG | アラスジクエスト完全版 - Synopsis Quest -

このゲームはすばらしい。

ちなみに、私はノーヒントで全クリした。

C++0x本:前人未到

C++を日本語で相当深く解説するなどということは、誰もやった事がない。ということは、定着した訳語がないということである。

unqualified name lookupを、非修飾名前検索と訳すのは、どうも気に入らない。では、qualified name lookupは、修飾名前検索かというと、これがまた違和感を覚えるのである。

ましてや、name hidingの如きは、どう訳していいものやら。名前隠匿なんて、センスがないにも程がある。

一体、先人たちは、どのようにこの問題を解決してきたのか。彼らは、技術者であって、詩人ではなかった。そこで、つとめて辞書的な訳語をつけようとした。addressを番地といったり、delegateを委譲というなど、センスのかけらもない、それだけでは意味がわからない、日本語らしからぬ訳語を、たくさん作り出してきた。

辞書的な訳語の利点は、誤訳するよりマシだということである。逆に、日本語から英語に直す場合でも、英和辞書で、「番地」や「委譲」をひけば、addressやdelegateが出てくる。つまり、可逆なのである。

可逆といえば、losslessという単語に対し、可逆という言葉を割り当てたのは、果たしてどうであろうか。losslessは、ロスがないという意味であるのに対し、可逆とは、元に戻せるという意味である。また、lossyに対しては、非可逆という言葉が用いられている。

可逆というのは、明らかに聞き慣れない言葉ではあるが、losslessの訳語として、十分定着した感がある。これには、救いがある。つまり、最適な訳語でなくても、十分にユニークであれば、定着するのだ。

和訳、音訳、英語表記の間で、妥当な線を探らなければならない。

CookieもIPもなしで、ユーザーをトラックできるか

Panopticlick

異なるサイト間でユーザーを識別できる利点というのは、いくらでもある。たとえば広告だ。ユーザーが閲覧するサイトの傾向から、効果的な広告を表示させることができる。

プライバシーの問題はさておき、実際に利益になるなら、誰かがやる。

ユーザーをトラックングするにはどうすればいいか。これは、一般的には、CookieやIPアドレスが用いられる。これはつまり、そのユーザーであることを示す、十分にユニークなIDがあればいいのだ。

しかし、多くのユーザーのIPアドレスは、変動する。ユーザーはCookieを無効にしているかもしれないし、すぐに消すかもしれない。これらの古典的な方法以外に、ユーザーを特定する方法はないだろうか。

ブラウザは、実に多くの情報を送っている。たとえばユーザーエージェントだ。ユーザーエージェントは、もちろん完全にユニークなIDではない。しかし、同じユーザーエージェントを使っているユーザーが十分に少なければ、実用的なユニークIDとして機能するのではないか。

そのほかにも、ブラウザが送る情報の中に、IDとして使えそうなものは、たくさんある。一体、これらは実用的に使えるだろうか。

これを研究したのが、Panopticlickだ。アクセスすると、自分のブラウザが送っている情報の中で、とくにユーザーごとに変化する情報のエントロピーを推測してくれる。

ユーザーエージェント以外にも、実に様々な、ユーザーごとに変化する情報がある。たとえば、HTTP_ACCEPT ヘッダーだ。あるいは、ブラウザのプラグイン情報、タイムゾーン、スクリーンの解像度と色数。Flashを使えば、システムにインストールしているフォントまで調べることができる。

これだけの、ユーザーごとに変化する情報を組み合わせれば、たとえCookieを無効にしていて、IPをころころ変えるユーザーであっても、短期間の間ならば、トラックするのは可能かもしれない。

日々の日記

どうやら、GoogleのGoogle日本語入力に関する技術講演会に応募したところ、受かった。30日は大阪に行くことになる。こういうものを近場でやってくれるとはありがたい。

しかし、主に学生向けと書かれていたから、ある程度は予想していたものの、連絡のメールが、露骨にも新卒採用事務局である。大方は、Googleに興味のある新卒に、求人をかけるのが主目的なのだろう。

Googleで働くのは、面白そうではあるが、要求されるスキルはさておき、今はC++0x本の執筆に時間が必要だ。

もう十分に相談をしたと判断したので、いよいよ、C++0x本の目次案の作成をしだした。総合的な解説をしないということを決定したので、規格から、コンパイラ屋に必要な部分を削ぎ落した形になる。

ExpressionsとかStatementsあたりは、そのままの目次でもいいのだが、宣言がややこしい。宣言(Declarations)と宣言子(Declarators)を、たんに「宣言と定義」という章でひとくくりにできれば、ある程度は分かりやすくなるのかもしれない。しかし、Declarationsとは、名前が何であるかを宣言するのに対し、Declaratorsとは、もっと具体的な、オブジェクトや関数や型を宣言するのである。場合によっては、定義や初期化も伴う。やはり、これらは分けるべきであると思う。

しかし、たとえばStorage class specifiersとか、Function specifiers単体で説明されて、分かりやすいかというと、それも疑問だ。しかし、では一緒くたに説明するかとなると、それは総合的な解説になってしまう。それぞれ別の機能なのだと実感できなくなってしまう。難しいものだ。

2010-01-27

C++0x本:そろそろ構想を固めなければならない

ここ数日、いろいろと相談しながら考えていたが、やはり、総合的な解説というのはやめようと思う。

総合的な解説というのは、たとえばポインタなら、宣言と初期化、その他の演算などを、ひとつの章で解説するということである。同時に、関数も、宣言と定義とその他のspecifierまで、一箇所で解説することはしない。

ポインタの使い方とか、関数の書き方なら、すでにいくらでも、本は出ている。車輪の再発明をしても仕方がない。

やはり、言語としてどう定義されているかということを考えた目次にするべきだ。この本は、初心者向けの入門書ではないので、それでもいいだろう。

言語として深く解説するというのは、果たして受け入れられるだろうか。

本を書くにあたって、既存のC++の参考書を、あらかた流し読みしてみた。

たとえばconstなメンバ関数だ。既存のC++の参考書では、たいてい、「メンバ関数はconstにできる。これは、そのメンバ関数が、メンバ変数を変更しないという意味である」などと説明している。これは、表面的には正しい。constを指定したメンバ関数は、実際に、メンバ変数を変更することはできない。しかし、言語的には間違っている。もし私が解説するとしたならば、

そもそも、メンバ関数に指定できるのは、constだけではなく、volatileもある。これらはまとめて、cv-qualiferと呼ばれている。では、何がconstやvolatileなのか。*thisである。

thisの型は、そのクラスのポインタである。

struct Foo
{
    void f()
    {
        typedef decltype(this) type ;
    }
} ;

ここで、typeの型は、Foo *である。

そもそも、なぜ非staticなメンバ関数で、thisが使えるのか。それは、メンバ関数に、見えない引数として、クラスのオブジェクトを渡しているからだ。

class Foo
{
public :
    void f(/* Foo & this_ref */)
    {
    // Foo * this = &this_ref ;
    }

} ;

このコードは、厳密に正しいわけではないが、このようになっていると想像すれば、分かりやすい。メンバ関数にconstをつけるということは、この隠された引数にconstをつけるのと同じ意味である。だからこそ、Overload resolutionの際にも、考慮される。

struct Foo
{
    void f() & ; // #1
    void f() const & ; // #2
    void f() volatile & ; // #3
    void f() const volatile & ; // #4

    void f() && ; // #5
    void f() const && ; // #6
    void f() volatile && ; // #7
    void f() const volatile && ; // #8
} ;

int main()
{
    Foo foo ;
    Foo const c_foo ;
    Foo volatile v_foo ;
    Foo const volatile cv_foo ;

    foo.f() ; // #1 
    c_foo.f() ; // #2
    v_foo.f() ; // #3
    cv_foo.f() ; // #4

    std::move(foo).f() ; // #5
    std::move(c_foo).f() ; // #6
    std::move(v_foo).f() ; // #7
    std::move(cv_foo).f() ; // #8
}

こういう説明が一番わかりやすいと思うのだが、一般大衆は、ただ「メンバ変数が変更できない」という説明だけで、この意味が分かるのだろうか。なぜ、以下のコードがエラーになるのか、分かるのだろうか。

struct Foo
{
    void f() {}
} ;

void f( Foo const & foo )
{
    foo.f() ;//Error
}

これを、「メンバ関数にconstをつけてないから、変更される恐れがあるので呼べない」などという解釈で、納得出来るのだろうか。Overload Resolutionのルールの説明なしに理解できるのだろうか。

2010-01-25

C++0xの定数式について

以下のコードはwell-formedなC++0xのコードである。

int f()
{ return 0 ; }

template < int x >
struct Foo {} ;

Foo< true ? 0 : f() > foo ;

constexpr int x = true ? 0 : f() ;

f()は定数式ではないが、この場合、評価されない。つまり、この初期化式は、定数式である。falseの場合は、コンパイルエラーである。

これはC++0xの変更点である。C++03では、trueでもエラーになる。

このルールは、Conditinal operatorの他にも、logical AND operator, logical OR operatorにも適用される。

C++0xの字句について

以下のコードは、完全にwell-formedなC++0xのコードである。

// 変数(U+5909, U+6570)
int \u5909\u6570 = 0 ;

C++0xでは、universal-character-nameが追加されている。Unicodeのコードポイントを、直接記述できるのだ。これは、なんと識別子にも使える。したがって、上記のコードは、well-formedなC++0xのコードであり、いやしくもC++0x完全準拠を謳うコンパイラならば、必ずコンパイルが通るべきコードである。

また、以下のコードはimplementation-dependantである。

int 変数 = 0 ;

ただし、ill-formedとは規定されていない。また、実装がこのような実装依存の文字をサポートしている場合の挙動が規定されている。したがって、実装によっては、このコードは通る。

もちろん、これはプリプロセッサのトークンにも適用される

#define λ []

std::vector<int> v ;
std::for_each(v.begin(), v.end(),
    λ(int value){ std::cout << value << std::endl ; } ) ;

まあ、流行るとは思えないが、参考までに。

C++0x本:目次案について考える

やはり、規格に沿った目次でもいいのではないか。もちろん、規格通りでは分かりにくいので、順番を変えるのは当然だ。また、ユーザーとして、あまり知っていても役に立たない部分は、割愛してもいいだろう。

つまりこれは、機能を総合的に解説することをあきらめるということになる。たとえば、「ポインタ」ならば、宣言と定義、初期化、ポインタに対する演算は、別々の場所で説明することになる。果たして、そんな本が受け入れられるだろうか。

しかし、この本は、初心者向けの入門書ではない。私の想定では、本書の読者は、すでに、変数や関数の書き方、ポインタの使い方、クラスの書き方、などを、少なくとも、表面的に知っている。とすれば、いまさら総合的な解説などいるだろうか。ポインタについて総合的に解説する章は、必要だろうか。それよりは、たとえば読者が加算式について知りたくなった場合、目次から飛べば、基本型(Fundamental Type)に対する加算も、ポインタに対する加算も、両方調べることができる。そんな本のほうが喜ばれるのではないだろうか。

表面的なC++の書き方を説明する入門書ならば、すでにいくらでもあるし、また、C++0x版の入門書も、いずれ出版されるだろう。私の本はむしろ、リファレンス的な役割を果たしたい。

総合的な解説をやめるというのは、本を最初のページから順番に呼んで行くことができなくなるということを意味する。難しいものだ。

C++0xのすべてを解説する必要があるとは思っていない。たとえば、No Diagnostic Requiredのごときは、省いても誰も文句を言わないだろう。他にも、registorやasmやexportの類は、そういう予約語があるということだけ説明しておけばいいし、TrigraphやAlternative tokenも、説明しなくてもいいだろう。

2010-01-23

Google日本語入力についての講演があるらしい

Google Japan Blog: Tech Talk in 関西: Google 日本語入力を支える情報処理技術 (学生向け)のお知らせ (1 月 30 日)

大阪なら近いので行ってみたいが、どうも、主に学生向けの様子だ。しかも、私はこの辺のアルゴリズムはまったく分からないときている。一応、応募だけしてみようか。

しかし、今の自分の職業って何だ?

それ、C++0xでできるよ!

コンセプトなしでテンプラ引数が、特定のメンバ関数を持ってるか調べられるの?

SFINAEでできるよ!

// Overload Resolutionと併用する場合。
class has_xxx {

        typedef char yes_type ;
        typedef struct { char c[8]; } no_type ;

        // Unified Function Syntaxが入れば、autoではなく[]になる。
        template< typename U >
        static auto check( void ) -> decltype( std::value<U>.xxx(), yes_type);

        template< typename U >
        static no_type check( void ) ;

public:
        static bool const value = std::is_same< decltype(check<T>()), yes_type >::value ;
} ;
// SFINAEのみでやる場合
template < typename T, typename U = void >
struct has_xxx_impl
{
    static const bool value = false ;
} ;

template < typename T >
struct has_xxx_impl<T, decltype( std::value<T>.xxx() ) >
{
    static const bool value = true ;
} ;

template < typename T >
struct has_xxx : public has_xxx_impl< T >
{ } ;

なぜならば、C++0xでは、SFINAEの定義の仕方が変更されているからだ。これまでは、SFINAEになる場合を列挙していたが、これからは、規格で規定されている場合以外は、すべてSFINAEになる。また、sizeofやdecltypeの中身は、SFINAEの際に考慮される。

ちなみに、C++03でも、SFINAEを変態的に使えばできたりする。

本の虫: has_xxxの実装方法

最初に学んだ言語

この前、C++WG会議の後の酒の席で、面白い話題が出たので、書いておこうと思う。話題というのは、一番最初に学んだプログラミング言語は何か、という事である。

ほとんどの者は、BASICを挙げた。N88-BASICにしろ、VBにしろ、BASICには、実装の数ほど方言があるが、BASICである。

もちろん、これは世代による。昔は、コンピューターといえば、N88-BASICが走る箱であったという。その席にいた人たちは、大抵が、人生の比較的早い時期にプログラミングを始めた種類の人間である。とすれば、BASICが共通言語になっているのは、別に不思議ではない。

現代では、プログラミング言語は世にあふれている。多くの言語は、開発ツールがほぼ無償で手に入る。これは、数十年前からすれば、夢のような学習環境である。一体、今を生きる未来の天才プログラマは、どの言語を使って、プログラミングを学ぶのだろうか。

ちなみに、ひとりだけ、最初からC++でプログラミングを学び、printfではなくiostreamを使ってhello worldを書いたというツワモノがいたが、それは例外的な存在である。

では私はどうかというと、これがまた、相当変わっているのだ。

私は幼稚園の頃から、コンピューターを使っていたが、せいぜい、ゲームで遊ぶ程度であり、プログラミングをしようとは考えたことがなかった。ただし、プログラミングというものがどういうものかは知っていた。こうかくと、「何を当たり前のことを」といわれるかもしれないが、世の中の大多数の一般大衆は、今もって、プログラミングという概念自体を知らないのである。私はいつも、そういう種類の人に、「プログラミングするというのは、そもそも何であるのか?」と訊ねられて、説明に窮している。彼らは携帯やパソコンを使う。しかもプログラミングの何たるかを解さないのである。

この難題に対する、私の回答は、たいてい次のようなものである。

「MS OfficeやWindowsといったOS、あるいは携帯やゲームなども、所詮はソフトウェアに過ぎない。プログラミングは、そういったソフトウェアを作ることをいう。そういうソフトウェアを作るには、何をどうするかという、具体的な手順を指示する必要がある。その手順を記述するのが、プログラミング言語である。プログラミングするというのは、たいてい、この言語を書くことをいう」

この説明は、残念ながら、全く理解されない。難しいものだ。

ともかく、私は幼い頃から、プログラミングという概念を理解していた。しかし、私は生来の読書好きなので、小学校時代は、ただひたすら本を読んでいて、プログラミングをしようとは思わなかった。

中学生になって、私は無性に、プログラミングがしたくなった。しかし、私はその当時、パソコンを持っていなかったし、手に入れる手段もなかった。

この問題に対して、私の取ったworkaroundは、実に変わっていた。私は、ひたすら脳内で学んだのである。図書館でPC雑誌を積み上げ、過去のバックナンバー十数年分に渡って読みふけったり、様々なプログラミング言語の参考書を読みふけった。その当時、実に様々なプログラミング言語の参考書を読んだが、一番印象に残ったのは、C言語であった。C++の参考書も読んでいたが、やはりC言語に強く引かれた。Javaが最新で最強のプログラミング言語だと称する参考書もあったが、私はJavaの何がいいのか、さっぱり分からなかったし、今持って、分かっていない。当時の私は、参考書のサンプルコードを読み、脳内でコードを書き、脳内で解釈し、実行していた。おそらくは、これが今の私を形成したのであろう。

また、プログラミングには、英語が読めなくてはならぬと考え、英語を学んだ。私の英語の学び方も、また変わっていた。学校の英語教育は、実に役に立たなかった。私の初期の英語教育は、まったくNHKのラジオ英語講座に負うところが大きい。また、ひたすら洋書を読んだし、映画やcartoonを英語で観た。

高校生になり、バイトをして、パソコンを買った。自作も考えたのだが、当時は田舎に住んでいて、近所にPCショップもなかったし、面倒だったので、BTOでパーツを指定して買った。

プログラミングを学ぶにあたって、私が最初に選んだ言語は、HSPであった。HSPは、決して良い言語とは言えなかった。しかし、HSPの最大の魅力は、その手軽さにあった。何も書かなくても、最初からGUIのウインドウが表示されるし、たったの一行書くだけで、ウインドウに文字列や画像を描画できたし、Windowsのコモンコントロールウインドウも配置できた。

私が最も、実際に動くコードを書いたのは、あるいはこの時期だったかもしれない。

しかし、私はすぐに、壁に突き当たった。HSPの文法は、非常に貧弱だった。制御構文が、実に洗練されていなかった。それゆえ、ifとgotoを組み合わせたコードを書かなければならないことも、しばしばだった。

一年後、もうこれ以上、HSPで学ぶことはないと判断した私は、いよいよC言語に手をだすことにした。このため、私はVisual Studio.NET(無印)のアカデミック版を買いに走った。高かった。たしか、三万円ぐらいしたと記憶している。その翌年、VS7.1のアカデミック版が、1500円程度で売られ始めた。私は泣きたくなった。

そういうわけで、私はHSPという、贅沢で高級なGUIプログラミングから、C言語でCUIという、非常に低級な言語に、学習の環境を移した。すでに、何年もおよそ書店で売られている参考書は読み尽くしてきたので、習得に、さほど時間はかからなかった。私はポインタにつまづくこともなかったし、標準入力から任意のバイト数を読み込んで、動的にrealloc()でサイズが変更されるメモリ上に書き込むコードを書くこともできたし、双方向リスト構造も、バイナリツリーも書けた。また、私はバブルソートとクイックソートとマージソートを書くこともできた。

並行して、私はWin32 APIを使ったGUIプログラミングも学び始めた。MSDN Libraryを読むのに、英語は役に立った。すぐに、私はC言語で、HSPの表現力に迫りつつあった。

しかし、実際にC言語で書くのは、ひどく苦痛だった。たとえばメモリの動的確保だ。メモリ上に保持しなければならないデータのサイズが、実行時にしか分からない場合、また、実行時にデータがどんどん増えてゆく場合、malloc()とrealloc()を使って、メモリを動的に確保しなければならない。それ自体は、別に問題ない。私はポインタを恐れることはないし、正しいコードを書くことができる。しかし、わざわざ毎回そんなことをやっていては、甚だ面倒である。

私はメモリの動的確保のコードを、関数という単位に移したが、それでもやはり、満足できなかった。その関数を、それほどジェネリックに書くことができなかったのだ。それゆえ、私は、構造体ごとに、それぞれ別のメモリ確保の関数を書かなければならなかった。しかし、その関数内に書いている、実際のメモリ確保のコードは、あまり違わないのである。なんという労力の無駄遣いだろうか。

私はC++の世界に入門した。C++は使いやすかった。私はクラスを、構造体に関数を関連付ける機能として認識した。その他にも、コンストラクタ、デストラクタ、仮想関数など、ベンリな機能は様々あるが、言語として、構造体と関数を関連付けられるというのは、実に便利であった。C言語でも、双方向リストやバイナリツリーといったデータ構造を実装するときは、ある構造体専用の関数というものを書いていたが、言語の文法としてサポートされているのは、実に便利だった。

私は、オブジェクト指向(笑)という称する概念が理解できなかった。ましてや、デザインパターン(笑)だの、クラス設計(笑)だのUML(笑)だのと称するものに、何の価値があるのか、さっぱり分からなかった。デザインパターンなど、単なるプログラミング上のテクニックでしかないものを、何をもったいぶった名称を使わねばならぬのか。オブジェクト指向というものに対する私の認識は、「言語の機能や文法として、このような記述ができるというだけの話であって、その機能を使ってどのように記述しようが、それはプログラマの自由である」というものだった。私にとっては、デザインパターン、オブジェクト指向、クラス設計などという呼称は、思考、考え方、発想、アイディアなどと呼ばれるものを制限しているようにしか見えなかった。おそらく、私がJavaに抱く嫌悪感は、ここから来ているものと思われる。

また、C++の標準ライブラリは、実に便利だった。私はもはや、データ構造やアルゴリズムを自前実装しなくてもいいのだ。STLのコンテナに任せておけば、メモリは勝手に確保、解放してくれるし、リストやツリーの構造は、勝手に構築してくれるし、ソートも、要素同士の大小を比較する方法さえ提供しておけばいいのだ。しかも、このコンテナやアルゴリズムというやつは、自分の定義したあらゆる構造体に対して使えるのである。なんと便利なんだ。

しかし、STLのコンテナやアルゴリズムに対して疑問が沸いた。一体どのようにして、こんなクラスや関数を書けばいいのだろうか。「どのようにして」というのは、データ構造やアルゴリズムの問題ではなく、コードとしてコンテナやアルゴリズムを実装する方法である。どうやらテンプレートというものを使うらしいが、その使い方が、いまいちよく分からなかった。

私はさっそく参考書やWebをあさった。テンプレートの表面的な書き方は、いくらでも見つかったが、それだけでは、何か違和感がある。なにか本質的な理解が欠けているのではないのかと、私の生来の本能が告げていた。

とうとう私は、C++ Templatesを買った。この本には、まさに知りたい情報が載っていた。ちなみに、近々、この本が翻訳されるらしいが、今更感がただよう。この本を読むほどの気力のある、真のC++プログラマは、すでに読んでいるし、また、この本の存在を知らないズボラなユーザーは、日本語だろうと読むはずがない。だいたい、この本を正しく翻訳できる日本人が存在するとは思えない。この本は原書で読むべきである。

この時点で、私のプログラミングへの理解は、かなり向上していた。私はMSDN Libraryを読んだだけで、今まで知らないWin 32 APIでも、問題なく使えるようになっていた。今までは、MSDNを読み、ネット上で他人の書いたサンプルを探し、さらに自分で試行錯誤して書いて、ようやく動くという次第だった。しかし今や、MSDNを読み、コードを書き、コンパイラが告げるtypoを直せば、そのまま動くようになってしまった。プログラミング言語に対する理解が深まった今、必要なのは、ライブラリやAPIのドキュメントを読むだけなのである。

私はこれを、つまらないと感じた。これでは、私はただ、ライブラリやAPI、言語を使っているだけではないか。ゲームをつくるというのは、面白いかもしれない。しかし、そのゲームを作るために、こんな単調作業を続けなければならないとしたら、そんなのは面白いはずがない。

私は人に自分の性格を説明するとき、よく、「熱しやすく冷めやすい」という表現を用いる。ただし、飽きっぽいと言われると、それは違うのである。私は、苦労が好きなのである。最初は、何も分からないので、難しく感じるが、学習すると、次第に楽になって行く。ところが、楽になりすぎると、私はつまらないと感じてしまい、それ以上、継続する意欲がなくなってしまう。その場合の私は、何かまた別の、難しい事を探すのである。私は、同じゲームを数カ月以上続けて遊べた例はないし、同じジャンルの本を、数ヶ月以上読むということもしたことがない。次第に楽になって行くので、やる気がなくなるのである。

ただし私は、無駄な努力が嫌いである。たとえば、コピペして一部だけ変えればすむような、同じようなコードを何度も書くであるとかいう類である。

プログラミング言語はだいたい理解した。環境依存のAPIの使い方も、大体理解した。では、これより難しいこととは何か。

ここで、多くのプログラマは、OSやコンパイラを実装し始めるのだと思う。しかし、私の考えでは、それとて、すでに確立されたアルゴリズム、現実のハードウェア仕様などを学ぶだけである。もちろん、自分で斬新なアルゴリズムを考えだすことも可能である。ただし、それは相当難しい。

OSやコンパイラの実装は、まず土台に立てる基礎力をつけるだけで、相当難しい。ましてや一流になるのは、至難の業である。Rubyはあまり好きではないが、Matzは相当のやり手である。

私の進んだ方向は、C++の言語仕様を深く理解することであった。そのため、私は、C++0xのドラフトやペーパーに目を通した。そうして、今に至る。今から考えると、私は言語が好きだったのではないかと思う。たとえそれが、自然言語にせよ、人工言語にせよ。

思えば、私は相当の変人である。

まあ、自衛隊だし

幻影随想: SPA!のトンデモ記事および池田一等陸佐の免疫学に対する無知を切る

馬鹿だから自衛隊員になるのか、自衛隊に入るから馬鹿になるのか、その辺はよく分からない。ただ、予備自補の精神教育で、「日本人の文化はDNAに刻み込まれている」などという文面を使ったスライドを見せる中隊長が入るぐらいだから、まあ、これも、さほど驚くに値しないだろう。

そういえば、元寇に関する教育で、当時動員された人員が、元側の兵力十数万人、日本側の兵力数万人とあったのが、これも、どうにも疑わしい。

2010-01-22

帰宅

最後の予備自補の訓練より帰宅。いつも、予備自補の訓練から変えると、非常に疲れる。訓練中は、それほど疲れている気はしないのだが、娑婆世界に帰ると、気が緩むのだろう。

予備自補の訓練をやり終えて思ったことは、やはり私は、自衛隊には向いていないのだろうということだ。

しかし、疲れている暇はない。明日から、本格的に、C++0x本の執筆にとりかからなければならない。やることが沢山ある。何とかしなければなるまい。

まず、目次案の作成だ。

2010-01-17

五日間留守にします

帰ったら、いよいよC++0x本にとりかからなくては。

文字列リテラルのconst性について

C++0xでは、文字列リテラルから非constなポインタへの変換はできない

私は、このような汚いworkaround的な仕様がC++から、またひとつ減ったことを非常に喜んでいる。

しかしこれは、既存のC++の参考書を、軒並みdeprecatedにしてしまうのではなかろうか。なぜならば、私の記憶する限り、既存のC++の参考書のかなりが、文字列リテラルを、非constなポインタに代入していたからだ。そのような参考書のサンプルコードは、C++0x準拠のコンパイラでは、コンパイルすらできないのである。

いったい、そのような参考書は、責められるべきなのだろうか。

歴史をみてみよう。文字列リテラルは要素数nのconst charの配列(array of n const char)だというのは、そもそも、n0389で提案されている。これは、1993年にリリースされたペーパーだ。文字列リテラルをconstにし、互換性のため、暗黙的にconstを消し去ることを許可しようというものだ。

ということは、これ以降に出版されたC++の本は、言い訳できないはずだ。1993年のn0389リリース以降、すでにドラフト規格は、文字列リテラルはconstであると規定していた。少なくとも、1994年以降のC++本で、何も説明せずに、文字列リテラルを非constなポインタに代入している参考書は、規格を知らない浅はかな人間によって書かれた参考書である。

さて、手元にあるC++の参考書を見ると、どれも、確実に1994年以降に書かれているにも関わらず、痛々しく失敗している。

その中で、唯一、Nicolai Josuttisによって書かれた、Object-Oriented Programming in C++だけは、constなポインタに代入している。しかも、文字列リテラルがconstであり、古いCのコードとの互換性から、非constなポインタに変換できるということまで、解説しているのである。

この本は、全くの初心者にもおすすめできる入門書である。しかも文字列リテラルはconstであるということまで解説している。さすがである。

最も、これは当然だとも言える。なぜならば、Nicolai Josuttisは、非常に有名なC++標準化委員会のメンバーだからだ。彼の所属は、Library Working Groupである。

この本のまえがきは、引用する価値がある。

It took a long, long time to produce this book, but now it is done.

この本を書くには、とても、とても長い時間がかかった。しかし、やり遂げた。

しかも、この本のページ数は、わずかに600ページ。そしてこの品質。これでは、C++0x本を書くのに、たったの800ページでは、ページ数が足りないなどと嘆くのは、言い訳にしかならぬ。なんという事だ。

C++0xでは、文字列リテラルから非constなポインタへの変換はできない

75 :デフォルトの名無しさん:2010/01/15(金) 19:30:19
char *p = "hello world!";

このクソ変換N3000で無くなったんだな
良いことだ

C++0x 8の>>75

はて、そうだっただろうか。気になったので調べてみた。

たしか、n3000では、Compatibility Featuresから、Implicit conversion from const stringsが削除されていた。私はこれだけを見て、やはりdeprecatedにするのは無理があったのでやめたのか、と思っていた。

ところが、Standard Conversionsを見ると、Array-to-pointer conversionの項目から、文字列リテラルは非constなポインタに変換できるという項目が、ばっさり削除されているではないか。なるほど、もはやdeprecatedにすらしないというわけか。

すると、このようになる。

    // well-formed
    // Array-to-pointer conversionが行われる。
    char const * ptr = "superior C++0x programmers" ;

    // ill-formed
    // Array-to-pointer conversionは行われるものの、
    // cv-qualiferを消すことはできない。
    char * ptr = "Silly C idiots" ;

    // ill-formed
    // static_castとreinterpret_castでは、
    // Array-to-pointer conversionは行われるものの、
    // cv-qualiferを消すことはできない
    char * ptr = static_cast< char * >("another idiots") ;
    char * ptr = reinterpret_cast< char * >("Yet another idiots") ;


    // well-formed
    // const_castでは、Array-to-pointer conversionが行われる。
    // const_castは、cv-qualiferを消すことができる。
    // 悪用厳禁、自己責任。
    char * ptr = const_cast< char * >("Real C++0x programmers who is at least understands C++0x well.") ;

最高だ。

日記

一月十四日

また例のごとく、3980円の夜行バスで東京へ行く。しかし、今回のバスには、違和感があった。

違和感というのは他でもない、バス自体だ。私は毎回、同じ夜行バスを利用しているのだが、いつもとは、バスが違ったのだ。どう違うのかというと、実は、バスが夜行バスではなく、観光バスだったのだ。

夜行バスというのは、普通、車内の照明をつけずに走る。ところが、このバスのカーテンは、非常に薄いので、遮光性がまるでない。また、普通は、フロントガラスからの光を遮るため、前にもカーテン等があるはずだが、これもない。これではまぶしくて寝られたものではない。

そもそも、なぜバスにあの独特のブラウン管がついているのだ。また、車体を夜行バスの名前でラッピングしているのだが、、「何々観光バス」という文字がある。明らかに観光バスである。

また、スタッフもおかしい。普通、夜行バスのスタッフは二人いる。運転手と、その他の雑務を行うスタッフである。今回も、スタッフは二名いるのだが、明らかに、二人とも運転手である。

思うに、今回の不況のあおりを受けて、観光バス会社の仕事がへり、そこに目をつけたこの夜行バス業者が、バスと運転手を、そのまま引き受けたか、あるいは委託したか、そんなところではないだろうか。

バスの質は最悪だったが、今回の移動は楽だった。何しろ、たまたま隣に人が座っていなかったのだ。私は二席を占有することができた。

一月十五日

6時に新宿に着いた。いつもは、東京駅で降りて、そのまま神保町で古本をあさり、然る後にC++WG会議に出席するのが、通例となっている。しかし今回は、C++0x本の打ち合わせのため、技術評論社に行かねばならない。新宿で降りて、市ヶ谷へ向かう。なんと今回は、電車を間違えることがなかった。そろそろ東京の複雑怪奇な路線にも、慣れてきたのだろうか。

市ヶ谷に着いた。まだ朝早い。たしか駅前にマクドがあったはずだと思って、行ってみると、マクドとモスが並んでいた。モスに入った。

モスで三時間ほど、D&Eを読んで過ごした。今回C++0x本を書くということで、数年ぶりにD&Eを読んでいるのだが、やはりこの本は、不朽の名著だ。C++成立の時代背景と設計思想が、実に分かりやすく書かれている。

10時になったので、技術評論社で、C++0x本の打ち合わせをした。本が出版されるまでの流れ、印税の計算方法など。ページ数は、せいぜい800ページが限界のようだ。余白は、製本の精度の都合上、あまり狭くできないらしい。

C++WG会議に出席。私はn2951: forwardのレビューをした。

一生さんのレビューしたn2998: Reaching Scope of Lambda Expressionsの印刷で、非常に素敵なフォントを使っていた。一体、なんというフォントなのか知りたかったが、遺憾ながら聞き漏らした。やや丸みのある文字だ。メイリオではないと思う。ヒラギノ角ゴだろうか。これほどの品質のフォントが、フリーフォントとは思えない。

redboltzさんが、2009-10-19/24 Santa Cruz meetingにゲストとして出席したというので、その話を聞いた。面白そうだ。私も出席してみたいものだ。カネさえあれば。

聞説、Googleが人を大募集しているという。興味はあるが、私が、Googleが求めるだけの能力を満たすかどうか。当面の生活費を確保したいが、問題は、今仕事をしていては、本を書く時間がない。

会議後、飲みに行くことになった。C++0x本に関して、なぜある機能が、今の仕様になったのかという、歴史が知りたいという意見があった。たしかに、そのようなコンセプトで書かれたD&Eは名著であるし、興味深いのだが、なにぶん、ページ数にも限りがあるし、今の本のコンセプトは、「C++の歴史」ではない。機会があれば、そういう本も書いてみたいと思う。

私の思想は、高校数学の域を出ていないという話があった。曰く、「高校までの数学は、あらかじめ決められたルールの枠内で考えるものである。一方、大学の数学は、あるルールに対して、本質的に欠くべからざる最小限の定義を考えるのである。だから、C++はどうなっているのかではなく、C++はどうあるべきなのか、ということを書くべきである」云々。

C++の本来の面目を考えるのは、もちろん標準化委員会のメンバーとしては重要だが、普通のC++ユーザーにとっては、現実のC++でwell-formedなコードの方が重要だと思う。

残念ながら、帰りのバスの時間があるので、九時過ぎに抜けた。

帰りのバスも、行きと同じ観光バスであった。帰りは、最後列の窓際の席だった。最後列は唯一、脚がのばせる席である。しかも、シートを倒しても後ろに迷惑がかからない。そのため、今回の夜行バスは、往復とも、比較的ラクだったと言える。観光バスだと、こういう事もあるのだろう。

さて、明日から、予備自補の最後の訓練がある。戻ってきたら、執筆に取り掛かろう。まず行わなければならないのは、目次案の作成だ。Expression, Statements, Declarations, Declaratorsには、人間がひとかたまりの機能だと認識している機能が、点々と定義されていてわかりにくい。この四章で規定されている機能のうち、変数、配列、ポインタ、リファレンス、関数は、総合的に解説した方がいいだろう。他に、総合的に解説した方がいいものはあるだろうか。

2010-01-14

named lambdaが必要な理由

末尾再帰の最適化のため

lambdaは再帰できる。が、末尾再帰を最適化できない。

std::function< void () > func ;
func = [&]{ func() ; } ;

このコードは、残念ながら、ループにすることはできない。

autoは使えない。なぜなら、autoの名前は、その初期化式の中では、使えないからだ。

// Error
auto func = [&]{ func() ; } ;

lambda式の末尾再帰を最適化できるようにするためには、named lambdaが必要になる。

[]func(){ func() ; } ;

C++0x本:説明したくない事

説明したくない事。以下のコードがコンパイルできること。

template<class T1, class T2 = int> class A;
template<class T1 = int, class T2> class A {};

// デフォルト引数を後で指定できる。
void f(int) ;
void f(int = 0) {};

int main()
{
    // A<int, int>
    //複数のdeclarationにおける、テンプレート引数のデフォルト引数はマージされる。
    A<> a ;

    // 関数から関数ポインタへのキャスト
    // アンパサンドを省略できる。
    void(*p)(int) = f ;

    // 初期化しなくてもいい。
    int x ;

    // sizeofには括弧がいらない。
    sizeof x ;

    // C99互換のuglyにも程がある整数型。
   // <cstdint>を使うべき。
    long long int y ;
}

これらは、ほんの一例である。かなり原理主義な部分もある。

しかし、テンプレート引数のデフォルト引数のマージを除いて、実際にこれらは使われている。解説しないわけにはいかない。

追記:文字列リテラルを非constなポインタに、暗黙的に変換することはできなくなった。

C++0x本:鼻から悪魔

unspecified behaviorと、undefined behaviorとは、明確に使い分けなければならない。では、用語をどうするか。unspecifiedは、未規定、undefinedは、未定義とするのが一般的だろう。

これはいい。問題は、ill-formedとwell-formedはどうすればいいのか。違法、合法では、何か違う。英単語のまま使いたいが。

// ill-formed
void main() { }

あえて何か訳語を作るべきなのだろうか。あるいは、単純に、「エラー」としておいた方が分かりやすいか。

conditionally-supportedやdiagnostic messageなど、適当な単語が思いつかない。

ところで、鼻から悪魔の元ネタは、これらしい。

Why is this legal? - comp.std.c | Google Groups

Nasal Demonとも言われているらしい。文字通り、鼻悪魔。

2010-01-13

C++0x本:規格の目次は無理がある

規格をにらみながら考えたが、やはりどうも、規格通りの目次というのは無理がある。あまりにも説明している単位が細かすぎて、とてもじゃないが解説書の体をなさない。

となると、人間が普通にひとつの機能だと認識するものごとに解説しなければならない。以下、メモ。

基本編と詳細編に分けるのが、もっとも分かりやすいのかもしれない。

とりあえず考えたが、まず、GeneralとLexical Convensitonsは、そのまま解説してもいいと思う。ただし、preprocessing tokensは、プリプロセッサと一緒に、総合的に解説すべきだろう。Alternative tokensは、微妙。

Basic conceptsは、分ける必要がある。

Standard conversionsは、そのまま解説していいだろう。

Expressions, Statements, Declarations, Declaratorsは、これが難しい。このまま別々に解説したのでは、実に分かりにくい。ポインタ、リファレンス、関数、などといった単位に分ける必要がある。また、The friend specifierは、当然ながら、Classesへ持っていった方がいいだろう。

Basic conceptsが難しい。これは解説しなければならないのだが、一体どこに持ってきたものやら。やはり、詳細編というのをつくってまとめるべきか。

そして、ライブラリまで一冊に収まる気がしない。

また中国か

Official Google Blog: A new approach to China

Good for them. show 'em the real world.

これはインターネット史に残る。

まだプルタブ(笑)なんて集めてたのかw

私の通っていた小学校でも、プロタブを集めて車椅子を買おうと計画していた。しかし、あんなものはいくら集めても、目方が軽すぎる。たしか十年以上続けても、目標の目方に全く届かなかったはずである。

そこへ、ある熱血教師がやってきた。この熱血教師は、大真面目に、車椅子を買うという前提のもとに行動した。熱血教師は、車椅子の値段と、回収業者が提示するアルミニウムの値段を調べた。その結果、プルタブでは、この先何十年かけても車椅子が買えないと結論した。当然である。プルタブごときがいくらにもならないのは、子供ですら薄々分かっていたのである。ただ、誰も言わなかっただけの話だ。

そこで、熱血教師は、アルミ缶そのものを集めることにした。しかも、これには相当の気合が入っていた。多くの生徒が、家庭ゴミとしての空き缶を、ごみの日に捨てるかわりに、毎日学校に持ってきた。また、生徒の中に酒屋を経営しているものがいて、これが好意で、うちの酒屋で出る空き缶を持っていってもいいということであったので、生徒を引き連れて、空き缶の回収に向かった。

プルタブ集めなど、所詮は「おれ社会奉仕してる」という気分を味わうための、自己満足にすぎないのである。目的を達成するためには、何をどれほど行えばいいのかを、明確にすることが、まず第一である。ホームレスはプルタブを集めているか? 否、空き缶そのものを集めているのである。

熱血教師の努力の結果、わずか数年で、車椅子を買うことができた。実際に車椅子の現物を買えたということが、生徒の心に火をつけたのか、二台目は、もっと早く買うことができた。

あの教師こそ、本物の教師である。今はどうしているだろうか。

2010-01-11

C++0x本:とりあえず今のところの構想

日本語で書く。さすがに、functionとか、typeといった単語を英語で記述するのは無理がある。とりあえず、その用語を解説するときに、英語を併記する。C++WG JPのメンバーからでさえ、「専門用語は全部、英単語だとか、そんな日本語の本は読みたくない」と言われているのだ。全部、英単語にするのは無理がある。

言語を、相当深く解説するときのみ、英単語を使う。例:ADL, SFINAE等

章をどのように分けるかというのは、未だに迷っている。規格の目次のように分けるのが、取りこぼしがなくて完璧だと思う。しかしその場合、人間がひとかたまりの機能だと認識している機能群が、バラバラに説明されてしまい、分かりにくいという懸念がある。また、move semanticsなどを、どこで説明していいのか分からない。

ひとまとめに説明するのと、個々に説明するのと、両方いれるべきか。あるいは、基本編と詳細編に分けるべきなのか。

何にせよ、恐ろしくページ数がかさむ。言語仕様だけでも、一冊に収まるかどうか分からない。どうすればいいのか。

C++0x本:懸念事項

いま抱いているC++0x本の構想には、恐れがある。それは、純粋に言語を解説しようとした挙句、あまりにもマニアックすぎて、極少数の人にしか読まれないのではないかという懸念だ。すでに刊行されている他のパーフェクトシリーズは、私の構想ほど、言語仕様を厳密に解説してはいない。C#やJavaならそれでいいのかもしれないが、C++の場合は、厳密に解説しなければ、本当の意味で理解することは出来ない。

C++は、実に複雑で難しい文法となっている。その理由は、Cの上に付け加えたからで、このcontext-sensitiveな文法の責任は半分以上、Cにある。

たとえば、宣言文である。宣言文は非常に難しい。よく、ポインタが分からないと言われているが、その理由の半分は、宣言文にある。

なぜ、宣言文が難しいのかというと、const、volatileや、ポインタは、前置するが、配列や関数などは、後置するからだ。

例えば、以下のコードで、typeの型は何なのかを考えてもらいたい。

// int
typedef int type ;

// intへのポインタ
typedef int * type ;

// intの配列
typedef int type[10] ;

// intの配列へのポインタ?
// intへのポインタの配列?
// 正解は、intへのポインタの配列
typedef int * type[10] ;

// intの配列へのポインタ
typedef int (*type)[10] ;

// ハァ?
typedef int (*(*type)(int (*)(int [])))(int []) ;

このように、前置と後置が組み合わさっているために、非常にわかりづらい文法になっている。ちなみに、最後の例を、人力で解釈しようとしてはならない。これは、int ( int [] )という関数へのポインタを引数に取り、int ( int [] )という関数へのポインタを戻り値として返す関数へのポインタである。

もちろん私は、最後の例を脳内で構築したわけではない。チートを使った。

typedef int func_type( int [] ) ;
typedef func_type * func_type2( func_type * ) ;
typedef func_type2 * type ;

std::cout << typeid(type).name() << std::endl ;

typedef相当のものを持つ言語というのは、C/C++以外には、あまり見られない。C/C++では、typedefは絶対に必要な機能である。あるいは、他の言語では、別に必要になるほど、宣言文がややこしくなることがないのだろうか。

たとえば文字列リテラルである。文字列リテラルの方は、char const []である。

// char const [13]
// (null文字を含む)
auto type = "hello world!" ;

配列は、ポインタに変換できる。これ自体は、邪悪だが、仕方がない機能である。

// 配列はポインタに変換できる
char const * ptr = "hello world!" ;

// あるいは、クソ真面目に書くと
char const * ptr = &"hello world!"[0] ;

わざわざ文字列程度に、添字とアンパサンドを書きたくはない。したがって、配列から先頭要素へのポインタに変換できる文法は、邪悪だが、仕方がない。ところが、const性まで消し去ってしまうのはいかがなものか。

// いいの?
char * ptr = "hello world!" ;

// これらは間違い
// じゃあなんで暗黙のうちにconstを消しされるのさ?
ptr[0] = 'x' ;
"hello world"[0] = 'x' ;

これは、歴史的な理由である。そもそもCには、constなどというものはなかった。現在のCにはあるが、これはC++から借りてきたのである。Bjarne Stroustrupは、Cのこのような側面を嫌っていた。

Cはこの他にも、かなりの危険な型変換を、明示的なキャストなしに、暗黙のうちに行うことができる。非常に邪悪な言語である。こんな邪悪な言語を土台にしたら、C++が邪悪になるのは当然の話だ。

じゃあ、なんでCなんか土台に選んだのだという批判は、場違いである。Cを土台にしたからこそ、組み込みからデスクトップまで、C++が広く使われているのだ。現代からみて、過去を批判するのは簡単だ。なぜ最初から、文字列にはUnicodeと同等の規格を制定して使わなかったのか。文字が7bitで足りるわけがない。なぜ最初から、CPUのアドレスを64bitにしておかなかったのか。32bitアドレッシングで足りるわけがない。

この手の論者は、数十年後に、自分が批判されるだけである。「なぜ、2010年の時点で、CPUのアドレスを128bitにしておかなかったのか。64bitアドレッシングで足りるわけがない」

C++全部を詳細に解説する本というのは、今までに見たことがないし、洋書でも知らない。C++ Templatesは、Template専門だが、かなり詳しく解説している。最も私の理想とする本に近い。

C++ Templatesのように書くとするならば、まず「どのように」書くかという基本編と、「なぜ」こう書かなければならないのかという、詳細編に分けることができる。その方が分かりやすいだろうか。

C++0x本:バラバラな解説

C++という言語を詳細に、取りこぼしのないよう解説するのがとても難しい。安易に、規格通りの目次で解説していけば良いのではないかと思ったが、これもまた、問題がある。

たとえばポインタだ。規格通りの目次でいくと、ポインタの宣言、ポインタの参照、ポインタに対する加減算は、別々の場所で説明されることになる。

演算子というものをすべて、expression(式)の章で説明するのは、問題がないと思う。しかし、Additive operators(加減算演算子)の項目で、整数に対する演算と、ポインタに対する演算を説明したものだろうか。ポインタなら、ポインタで、ひとまとめにして説明したい。

あるいは、内容が重複してもいいというのならば、個々に解説したあと、まとめて解説するという方法もある。このように、バラバラに説明されると分かりにくい項目というのは、それほど多くはない。ポインタ、リファレンス、関数等々、これらを総合的に解説する章というものを設けてもいいかもしれない。

さらに、純粋に、規格として定義されている言語仕様を解説すると、人間にとっての自然な文法とは、だいぶ違ったものになる。たとえば、=(イコール記号)だ。

int x = 0 ; // #1
x = 0 ; // #2

このふたつのイコール記号の使い方は、どちらも代入演算子だと考えている人が多いのではないだろうか。じつは違う。まず用語だ。言語的には、代入演算子ではなく、assignment-expression(代入式)という名称がついている。式の中に、さらに式を入れることができるから、このような名称になっているのだ。その代入式の中に、代入演算子が存在する。上のコードで、代入式とは、#2のことである。では、#1は何か。これはinitializer(初期化子)である。宣言文に=記号を使った場合、初期化子となる。見た目が同じだからと言って、同じ文法とは限らないのだ。

initializerの右辺には、assignment-expressionを取ることができる。つまり、0とは、assignment-expressionである。#1のイコール記号は、そもそも、演算子ではない。

しかし、言語学者でない、普通のプログラマが、このコードを見れば、「どっちも代入演算子じゃん」と思うはずである。「うむ、これらは明確に別の文法じゃ。大方、初期化子と代入式とか呼ばれとるもんじゃろうて」とは思わないはずである

どこまで言語仕様に忠実に説明するかというのは、非常に難しい問題だ。果たして、初期化子と代入式の違いまで、説明するべきだろうか。さらに、expression(式)とoperator(演算子)の違いも、説明するべきだろうか。読者はどこまで詳しく解説することを求めているのだろう。

iPhoneも勝手に機種のユニークIDを送信するらしい

制御不能な機種固有情報 - ろばの穴

iPhoneに最初から入っているSafariなどは送信しないが、iPhoneにも、個体ごとにユニークIDがある。iPhoneのアプリは、このユニークIDを、自由に取得できるらしい。もちろん、勝手に送信してくれやがる。

アプリがユニークIDを取得しようとしたら、OS側で、ユーザーへ同意を求める程度の機能を、なぜ実装しないのか。「ガイドライン」だけで、プログラマが従うとでも思っているのだろうか。

スマートフォンは欲しいが、ますますiPhoneという選択肢はなくなってしまった。Nexus Oneはどうだろう。

ユニークIDなどという安易なことをせず、ちゃんと普通のWebと同じように、cookieなどを使ってセッション管理すべきなのに。日本はガラパゴス。

C++0x本:単語

単語は難しい。もし、英単語を使わずに、日本語に訳せというのならば、"Argument Dependant Name Lookup"は、「引数依存名前解決」とすべきなのか。とすると、"Two Phase Name Lookup"は、「二段階名前解決」と訳すことができる。"Substitution Failure Is Not An Error"の如きは、「非過失不能置換(ちかんするあたはざりしはかしつにあらず)」とか、「非過失置換的失敗(ちかんのしっぱいはかしつにあらず)」などと訳すべきなのだろうか。これはどう考えてもやりすぎだ。特に、SFINAEの訳語は、漢文の知識がなければ読めない。

もちろん、この訳語は、半ば冗談だが、翻訳というのは難しいものだ。

ひどいデジャブを見た

15歳の君たちに告ぐ、海外へ脱出せよ - Rails で行こう!

戦中に満州に渡った日本人、戦後に南米に渡った日本人も、この手の扇動を聞いていたに違いない。果たして彼らは幸せになれたのだろうか。

そういえば、伝次郎君は、大学は希望者全員を受け入れて教えるべきだという主張をしていた。今や、希望者全員が大学に行けるようになったのだが、果たして伝次郎君の予想通りの現状なのか、その辺は甚だ疑問である。まあ、共産主義を信奉していたぐらいだから、先が見えないのは当然なのだが。

結局、金之助君の言う通り、人でなしの世に行くしかないが、人でなしの世が、人の世より住みやすいとは思えない。

そもそも、言っていることは、完全に個人の都合で、当然、個人の自由のはずだ。「就活」が無駄なら、やらなければいいだけの話だし、「新卒」が無意味なら、学位をとらなければいいだけの話ではないのか。その辺は無学の私にはよく分からない。

2010-01-09

C++0x本:実験

名詞を英単語で書くと、以下のようになる。

constexpr specifierは、functionのtypeとしては認識されない。

つまり、constexprかどうかで、functionのoverloadはできない。

ただし、non-static member functionにconstexpr specifierを指定した場合、const specifierを指定したのと、同じ効果がある。

これ以外では、functionのtypeに影響を与えることはない。

うーん、やりすぎという感じもする。

constexpr修飾は、関数の型ではない

constexpr specifierは、関数の型としては認識されない。

constexpr int bar(int x, int y) // OK
{ return x + y + x*y; }
// ...
int bar(int x, int y) // error: barを再定義している。
{ return x * 2 + 3 * y; }

つまり、constexprかどうかで、関数のオーバーロードはできない。

ただし、non-static なメンバ関数にconstexpr specifierを指定した場合、const specifierを指定したのと、同じ効果がある。

class Foo
{
    int value_ ;

public :
    explicit constexpr Foo(int value) : value_(value) {}
    constexpr int get() { return value_ ; }
} ;

constexpr Foo foo(123) ; // OK
int const x = foo.get() ;// OK

これ以外では、関数の型に影響を与えることはない。

また、constexpr specifierの付いた関数は、{ return expression ; }の形でなければならない。つまり、ifとかswitchとか、forとかwhileとか、gotoなんてものは使えない。ただし、三項演算子が使えるし、再帰もできるので、最低限の分岐やループは実装できる。

例えば、以下は階乗の計算をする関数である。ご覧のように、三項演算子と再帰を使って、条件分岐とループを実現出来ている。

constexpr int factorial(int x)
{
    return x == 0 ? 1 :  x * factorial(x - 1) ;
}


int main()
{
    int const x = factorial(5) ; // 120
    int const y = factorial(10) ; // 3628800
}

2010-01-08

JOJO勉強会

第一回 チキチキ エンジニアの為の JOJO 勉強会(ネタバレあり注意!) : ATND

ゴゴゴゴゴゴゴゴ
ドドドドドドドドドドドドドドドド

22日、用事があって行けない。第一、行けたとしても、東京までこのために行くのは疲れる。

C++0x本:分かりやすい文章はどんなものか

一日一日、規格書を読んで過ごしている。これを何とかして、分かりやすい文章で説明しなければならない。

一体、分かりやすい文章というものはどういうものだろう。世の中には、分かりにくい文章が腐るほどある。

文章を高尚にしようと試みたあげく、読みにくいどころか、高尚にすらなっていない論文が、数多くある。特に、理系の学者に多いが、古文漢文の素養がないのに、わざと難しい言い回しを使いたがるという例が多い。

どうやって難しい言い回しを避けるかというのは難しいが、ひとつの目安として、漢語の多用を避けるべきだと思う。漢語は便利だ。ついつい使いたくなる。しかし例えば、

このようなコードを書けば、より速くなる。

とすれば良いところを、

このようなコードを記述すれば、より高速に動作する。

などと書いても、意味は全く変わらない。言い回しが無駄に難しくなるだけだ。

また、あまりに長いセンテンスを書くのは、慎むべきだ。

なぜこんなことを考えるかというと、私は今回のC++0x本で、かなり長い文章を書かなければならないからだ。General、Lexical conventions、Basic concepts、Standard conversionsあたりを説明するには、どうしても長い文章がいる。

漢語を使う際には、どうしても漢語でなければならぬのかと、考え直すようにしよう

C++プログラマの読むべき文書

Techniques for Scienti c C++

これはすごい。それにしても、Cryoliteさんはいろんな文書を知っている。

誰がブラウザのオートスクロール機能を必要としているんだ?

多くのブラウザには、マウスのミドルボタンでドラッグしたとき、ドラックを開始した地点からの、マウスの移動量に応じて、激しくスクロールする機能が備わっている。これをオートスクロールと呼ぶ。一体誰が使っているのだろう。

ミドルボタンは、多くのブラウザで、リンク先を新しいタブでひらくという意味で使える。ところが、このオートスクロール機能への誤爆が激しい。なんとかならぬものか。

Firefoxは、この機能を無効にするオプションを提供している。Chrome, IE, Opera, Safariには、無効にするオプションが見当たらない。

ちなみに、Chromeでは、「オートスクロールを無効にするオプションを追加すべきだ」というバグ報告が、頻繁に上がるが、つねに、"Won't fix"にされている。いったい、誰がオートスクロール機能をほしがるというのだろう。私にとっては、邪魔でしかないのだが。

ミドルクリック中はマウスの動きを捨てる、不思議なマウスドライバでも使えというのだろうか。

プロセスにアタッチされているデバッガを変更する方法

The Old New Thing : How to change the debugger attached to a process

アプリケーションがクラッシュして、デバッガXが、自動的にアタッチされたとしよう。なぜなら、システムの設定がそうなっているからだ。しかし、急にデバッガYを使いたくなった。デバッガYをインストールはしてみたが、どうやって、現にアタッチされているプロセスのデバッガ、XからYに変更すればいいのだろうか。デバッガYでアタッチを試みても、STATUS_PORT_ALREADY_SETエラーコードが返るだけである。なぜならば、あるプロセスにアタッチできるデバッガは、ひとつだけだからだ。しかし、前のデバッガをデタッチしてしまうと、アプリケーションは消えてしまう。このCatch-22問題はどうやって解決すればいいのだろうか。

こうすればいい。

  • ntsdデバッガを、non-invasive モードでアタッチする。これには、-pの代わりに、-pvオプションを使って、プロセスIDを指定する。
  • ntsdデバッガは、プロセス内のスレッドをすべてサスペンドさせる。
  • ここで、デバッガXに、プロセスをレジュームさせ、デタッチする。もし、デバッガX自体がntsdならば、コマンドはpdである。
  • 次に、デバッガYをプロセスにアタッチさせる。
  • 最後に、non-invasiveモードでアタッチした、ntsdデバッガを、qdコマンドでデタッチさせる。

non-invasiveモードとは、デバッガをプロセスに、実際にはアタッチしないのだ。単に、プロセス内のすべてのスレッドをサスペンドし、メモリを覗き見るだけなのだ。そのため、元のデバッガをデタッチして、アプリケーションの実行を再開しても、アプリケーションは、実行を再開しない。なぜならば、non-invasiveモードのntsdデバッガが、まだアタッチされていて、プロセスをサスペンドさせているからだ。そこで、新しいデバッガをプロセスにアタッチすれば、デバッグが再開できる。

いうなれば、non-invasiveモードのntsdデバッガは、橋渡しの役割を果たす。つまり、デバッガを交換する間、プロセスを止めておけるのだ。

この情報は、誰かの役に立つはず。

ちなみに、Catch-22とは、同名の小説に由来するパラドックスである。小説内に出てくる、ジョン ヨサリアンという人物は、パイロットの軍務から免除されることを願っていた。「免除」されるには、軍医の診察を受けて、「飛行に不適」と診断されなければならない。

「不適」と診断されるには、パイロットが自ら志願して飛びたいと願えばよい。なぜならば、自ら身を危険に晒したいと考えるのは、「狂人」だからである。

しかし、「問題」は、「不適」と診断されるためには、まず自分から、「軍医の診察を受けたい」と申請しなければならない。自分から診察を願うぐらいなら、まだ「まとも」な精神状態である。この条件を考えると、「不適」と診断されるのは、不可能である。

2010-01-07

メイリオはアップデートできる

実はメイリオまだ進化中! 誕生秘話を河野氏に聞いた - @IT

Windows Vistaのメイリオが、実はまだ中途半端なできて、Windows 7では、改良されているというのは聞いていた、また、メイリオUIという、従来のMS UI ゴシックにサイズを合わせたようなフォントが、新しく出来ているというのも聞いていた。

気になっていたが、残念ながら、私はVistaを使っている。たとえ、Vista同梱のメイリオが中途半端だったとしても、そうかそうかと、どこからから、ごにょごにょげふんげふんして、フォントをダウンロードしてくることはできない。

でも、アップデートがあったらしい。

ダウンロードの詳細 : メイリオフォント アップデート

知らなかった。さっそく入れてみた。

これはMeiryo UIフォントによる文字。薔薇檸檬憂鬱御璽

これはメイリオフォントによる文字。薔薇檸檬憂鬱御璽

なるほど、この記事では、Meiryo UIを使ってみよう。

しかし、この人、電話帳を節約するために、かなり斬新なことをしている。製本のことはよく知らないが、余白というのはあれだけ広く必要なのだろうか。

しかし思うのだが、やはり、メイリオは、普通のメイリオの方がいい。

「UIゴシックというのがありますよね。ひらがなやカタカナを70%にコンデンス(細く)したものです。これはこれで非常に見にくいんですが、メイリオでもそれをやれと言うんですね。ひどいことになっています。一応コンデンスされたメイリオもWindows 7に入っていますが、本当に読みやすいものにするなら90%とか85%ぐらいまでなら我慢できるかもしれませんが……。あるいは、ひらがなの『り』のような文字は両脇に白いスペースがたくさんできますので、英語のように、それぞれの文字の幅を変えてプロポーショナルにできるはずです。これはまた時間がかかる話ですけど、いずれやっていかなきゃいけない問題だと思っています」

そういえば、偶然だが、私はC++0x本の余白について考えていた。他のパーフェクトシリーズは、かなり広い余白がある。これは無駄ではないか。詰められないのだろうか。

これは面白い

なぜ私たちはいつも締め切りに追われるのか

面白い。

松尾ぐみの論文の書き方 | 松尾 豊

これも参考になる。

「~において」「~については」などは極力使わないようにしましょう。 また、「前述の」「後述するように」「~節で述べた」などの指示詞も極力使わない方がよいです。 これらの語は、読者の注意を特定の部分に向ける語ですが、 よい文章は、こういう語を使わなくても、注意の対象を読者が自然に意識できるものです。 文章というのは、複雑な思考の直線化(linearization)ですから、 ポインタをたくさん使わないといけないというのは、直線化がうまくないということです。

2010-01-06

C++0x本:文体について

文体について考えてみる。人間である限り、文体という、文章の個性は、当然でてくる。問題は、その個性をどこまで主張するかということだ。

たとえば、ですます調だ。ざっと見た限りでは、日本語の技術書は、ですます調を使っている方が多いと思う。しかし、私はですます調が嫌いなので、使おうとは思わない。

語尾をです、ますから、だ、であるに変える程度なら、別にそれほど問題でもない。それ以外の文章の個性はどうだろう。

例えば、このブログの文章には、かなり「遊び」を入れている。といっても、あまり意図的に入れているわけではない。長い文章を書こうとすると、自然に入ってしまうのだ。この遊びがないと、長い文章がかけない。つまり、文章が単調だと、読むだけでなく、書くのもつまらないのだろう。

とはいえ、これから書くのは本である。個人のブログではない。私は、本には、「よろしく~すべし」とか、「まさに~せんとす」、とか、「~をして~せしむ」などといった表現、あるいは、聞説、所謂、就中、不斜、などといった漢文表現をいれるつもりはない。これは、私が漢文を好きだから、たまに使っているのであって、さすがに、プログラマに漢文の素養を求めるのは、間違っている。したがって、使わない。

それ以外の、差し障りのない遊びをいれるかどうか。あまり入れるべきではない。しかし思うのだが、単調な文章というのは、読んでいてつまらない。ましてや、今回は言語を解説する本である。私は、規格の、Generalとか、Lexical conventionsとか、Basic concepts、あるいは、Standard conversionsなども、すべて解説するつもりでいる。これは、知っていても、直接役に立つというわけではない。しかし、C++を理解するためには、知っておかなければならない。よく、C++が理解できないといわれるのは、文法が理解出来ないのではなくて、この辺を解説している参考書がないからなのだ。

世間には、やる夫で学ぶシリーズや、マンガで分かるシリーズ、萌えるシリーズなどの、参考書が存在する。これも、一種の文体とみなしていいのではなかろうか。これらは、遊びの部分が大きすぎるので、問題もあるのだが、つまらないから学ばないのと、遊びの部分が多くて詳細を解説していないが学べるのとでは、どちらがマシだろうか。

私の母親は、教員免許を持っていて、昔は塾の講師をしていたらしいが、授業する秘訣に、笑いを入れるというのがあったらしい。塾の授業は、何時間もある。単調に学んでいただけでは、集中力が続かない。定期的に、笑いを入れた方が、効果的だったという話である。

これを考えると、文章に、差し支えない範囲で、遊びを入れて、読みやすくするのは可である。

問題は、私の笑いのツボは、少しく世間と乖離しているという懸念がある。例えば、私は、Windows 7のBeep ドライバってどうなったのさ?という記事は、かなり気合を入れて書いた。しかし、たったの2はてブしか得ていない。一方、Windows 7にGod Mode、発見さるという記事は、かなり投げやりに書いた。ところが、こちらは20はてブも得ているではないか。

これはどう考えても解せない。絶対にBeepの方が面白いはずである。こんな面白い記事には、今頃100はてブはされていてしかるべきだ。解せん。

と、このように、私は遊びを入れたがるのである。まあ当然、一般大衆にも分かりやすいのは、フォルダにある特定の名前をつけただけで使える、Windowsの隠し機能の方だろうが。

すげー

HTML Slidy (1)

いい加減、WordとかPowerPointの類のソフトウェアは、死滅するべきだ。XHTMLとCSSとJavascriptがあれば、なんでもできる。

Debug Interface Access SDK

Visual C++ Team Blog : DIA based Stack Walking
Debug Interface Access SDK

Windowsプログラムのデバッグ用のSDK

私の専門ではないけれど、興味深かったので紹介。このブログを読んでいる人で、興味深いと感じる人はいるはず。

C++0x本:正規表現を解説すべきか

C++0xには、正規表現ライブラリが入る。正規表現がいかに便利であるかは、いまさらここで言うまでもないだろう。問題は、正規表現の文法を解説すべきかということだ。

実際、紙面の都合上、ライブラリをすべて解説できるかどうかはわからない。コア言語と、言語サポート・ライブラリだけで、かなりページを消費すると思う。出版社側は、どうも一冊にこだわっているらしく、その場合、ライブラリは広く浅くといった紹介にならざるを得ない。

もし仮に、ページ数を考えずに、深く解説できたとしても、果たして正規表現の文法自体を解説すべきだろうか。

私は、正規表現を語れるほどには、詳しくない。もちろん便利なので、たまに自分でも正規表現を書くが、文法を覚えていないので、文法書を見ながら書く。

私は、一応、規格書を読むだけの読解力には恵まれているので、正規表現の文法一覧のようなものを書くことはできるだろうと思う。しかし、そんな本は、すでに山ほど出ているのである。しかも、どの本も、私より正規表現を理解している者の手によって書かれているのである。

さらに、C++の規格では、正規表現を定義していない。どのように定義しているのかというと、別の規格を参照している。

さらに、C++で使える正規表現は、一種類ではない。たくさん種類がある。std::regex_constants::syntax_option_type定数で、正規表現の文法を切り替えることができる。case sensitivityとか、最適化などの細かいオプションを除けば、以下のような方言が使える。

ECMAScript
ECMA-262で規定されている正規表現、ただし一部変更あり
basic
POSIXで規定されている、basic 正規表現。
extended
POSIXで規定されている、extended 正規表現。
awk
POSIXのユーティリティである、awkの正規表現。
grep
POSIXのユーティリティである、grepの正規表現。
egrep
POSIXのユーティリティである、grepに-Eオプションを渡した場合の正規表現。

現時点では、私はどれがどれぐらい違うのかということを論ずるだけの知識を持っていない。これだけ種類があって、選べるということが、正規表現オタクを喜ばせるのか、あるいは、これでもまだ少ないと不満がらせるのか、それすら分からない。

ECMA-262に対する変更は、本当に細かい。どうも読んだ限りでは、POSIXのClassAtomExClass, ClassAtomCollatingElement and ClassAtomEquivalenceに相当する機能を付け加えるような文面になっている。

それより気になるのは、文面では、ECMA-262とだけ言っている事だ。何番目の規格とは、明示していない。正規表現が正式に入ったのは3rdだというので、少なくとも、それ以降である。規格書を読むと、3rdと5thでは、微妙に文法定義の方法が違っているのだが、表面的には変わらないのだろうか。単にECMA-262と言っているということは、将来、規格改訂で、文法が変わった場合、それに追随するということだろうか。

とにかく、C++独自の正規表現を定義しているのではなくて、いずれも、すでに十分実績のある、他の規格を参照するようになっている。これらの正規表現自体を学ぶのであれば、すでに本が、洋書和書を問わず、山ほど出ているので、わざわざ解説するまでもないだろう。

2010-01-05

Windows 7のBeep ドライバってどうなったのさ?

Larry Osterman's WebLog : What’s up with the Beep driver in Windows 7?

今朝早く、ある人が僕に、「なんで64bit版のWindowsは、PCの内部beepスピーカーをサポートしてないんだい」と訊ねてきた。その答えは、すこしばかり複雑なんだ。また、PCを取り巻く環境とも関係していて、なかなか面白い問題だ。

まず、当時[1]のbeepハードウェアが、どのように機能しているかということについて説明するね。元々、IBM PCは、Intel 8254 プログラマブル・インターバル・タイマー・チップを搭載して、システムクロックを作り出していたんだ。IBMのエンジニアは当時、PCは音を鳴らす必要がある(高音質とまではいかないけれど)と考えたから、8254を、矩形波生成器として使うことにした。このために、エンジニア達は、チップの第三タイマーを使って、矩形波モードを操作できるようにし、好きな出力周波数をカウントできるようにしたんだ。このため、Out2ラインは、クロックが0になるたびに、highからlowへとトグルする。ハードウェアの設計者は、チップのOut2ラインをBeepスピーカーにつなげた。するとほーら、クロック・チップを使って、Beepスピーカーにノイズを鳴らすよう、プログラムできるようになったじゃないか(それほど良い音じゃないけど、まあノイズには違いない)

Beep() Win32 APIは、基本的に、この8254 PIC機能の、薄いラッパーに過ぎない。Beep() APIを呼ぶということは、8254をプログラムしてBeepスピーカーから音を鳴らすということなんだ。

25年もの月日は、飛ぶように早く流れた。PC業界は大きく変わり、PCのアーキテクチャも変わっていった。この時点で、もはや8254を、プログラマブルな割り込みコントローラとしては使わなくなってしまったのだけれど、まだまだ新型PCにも搭載されている。というのも、8254は、いまだに現役でBeepスピーカーを操作するのに使われているからなんだ。

他に、25年のうちに起こった出来事といえば、パソコンはもっともっといろんなことができるようになった。今や、パソコンは奇妙で斬新な新型ハード・ディスク・ドライブを搭載しているっていうじゃないか。僕はよく分からないんだけど、中には30メガバイト以上もの容量をもつヤツがあるっていう話じゃないか。(でも、そんな大容量のハードディスクなんて、誰が欲しがるんだろうね。僕には分からないや)。それに、サーバーじゃないパソコンはみんな、サウンドカードを搭載してる。そんなわけで、今売られているパソコンは、音を鳴らす方法が二つある。サウンドカードと、昔ながらの、内部Beepスピーカーにつながってる8254とだ。(あるいは、サウンドカードの専用入力とか、これは後で説明するけど)

この25年のうちに起こったことは、まだまだある。パソコンは家電になった。パソコンメーカーは、厳しいコストカットを余儀なくされることになったんだ。メーカー各社は、8254に目をつけて、言った。「なんでコレを取り除けないんだ?」と。

でも、それは無理な相談だった。なんでかっていうのが、ものすごく期待はずれの変な理由なんだ。障害を持つアメリカ人法(ADA)のせいなのさ。

ADAだって?ADAとパソコンのBeepと、何の関係があるっていうんだい? それがねぇ、この25年間のどこかで、Win32 Beep()は、障害者補助の技術として使われてたらしいんだよ。StickyKeysみたいな、障害者補助技術は、Beep() APIを使って、一連の音を鳴らしていたんだよ。Windowsには、六つの障害者補助技術(AT)音が、組み込まれて、その実装は、win32k.sysの奥深くに入り込んでいるんだ。

でも、なんでそれが問題になるのさ? それがねぇ、多くの業界団体(政府と民間企業の両方)では、障害者補助技術のない製品は買わないっていう決まりがあるらしくて、つまり、メーカー各社は、beepハードウェアがないパソコンを、そういう業界団体に売ることができないってわけなんだ。

この問題に、最初に気がついたのは、マイクロソフトが64bit版のWindowsを開発していたときなんだ。というのも、最初の64bit版Windowsは、サーバー用途だったから、64bit機が想定する環境として、8254のサポートなんてなかったんだ(障害者補助技術の決まりごとは、サーバーに対しては、すこし緩められたらしい)。でも、一般ユーザー向けの64bit OSを開発しだしたら、問題に直面してしまった。一般ユーザー向けのOSは、障害者補助技術をサポートしなければならなかったんだ。そんなわけで、何とかしてbeepをサポートしなくちゃいけなかったんだ。そもそも、beepハードウェアがないパソコンばかりなのにね。

Windows XPでは、winlogonに、ソレ用のコードを書いて、この問題に対処した。一応動いたんだけど、ちょっと複雑だった(この話には直接関係ないけどね)。Windows Vistaでは、僕は設計をやりなおして、障害者補助のbeepの仕組みを、新しい「ユーザー・モード・システム・サウンド・エージェント」に移した。

この問題のあるパソコンというのは、64bit機だけだから、この機能は64bit版Windows限定の話だよ。

これはつまり、パソコンメーカーは、まだまだ8254というハードウェアをサポートし続けなくちゃならないってことなんだ。そもそも、ユーザーが32bit版のOSを買った場合、もしかしたら、障害者補助機能を使いたがるかもしれないからね。

Windows 7では、この問題を完全に解決した。Beep.sysにあった機能もぜんぶ、ユーザー・モード・システム・サウンド・エージェントに移したんだ。これで、Beep() APIを呼んでも、8254チップを操作するかわりに、実際の音を再生するユーザー・モード・エージェントに丸投げできるって寸法さ。

この計画では、思わぬ利点もあったんだ。8254出力ラインは、サウンドカードの専用入力につながってるって、さっき言ったよね? このサウンドカードへの入力のせいで、サウンドハードウェアは、つねにフルパワーで電源供給されてなきゃならないんだ。だって、アプリケーションがいつ、Beepを呼んで、8254を叩くか、分からないからね。(電源管理機構では、8254は操作できないんだ。だから誰かが8254の第三タイマーをプログラムした時だけ、サウンドハードウェアを起こすなんてことはできないんだ)。Beep呼び出しを、システム・オーディオ・ハードウェアにリダイレクトすることで、サウンド・ハードウェアは、必要になるまで、スリープさせておけるようになったんだ。

このリダイレクトで、また思わぬ利点があったんだ。それも複数。たとえば、間違って、0x07文字を含むファイルをtype、あるいはgrepしたとき(たとえば.objファイルとかね)、あのイヤーなノイズを消すことができるようになったんだ。beepはもう、パソコンのスピーカーから再生されているわけだから、パソコンのミュートボタンで、ささっと消すことができるってわけさ。また、beepのボリュームを操作することもできるようになったよ。

また、思いがけない発見もあったよ。一番傑作なのは、アプリケーションがBeep()を使っていたということに、みんな気がついたってことだね。みんな、パソコンをかなり離して置いていたり、あるいは、周りの音が大きすぎたりして、パソコンがbeepを鳴らしていることに、気がつかなかったんだね。それが、いきなり手元のスピーカーから鳴り出したんだからね。

[1] というわけで、僕がいまだに1980年ものの、昔のIntelの部品データ・カタログを捨ててないのは、正しい選択だったってわけさ。

Larry Ostermanは、このブログでも、何度か取り上げているが、Raymond Chenに次ぐ、有名なマイクロソフトの古参プログラマのブロガーである。Raymond Chenほど頻繁ではないが、たまに、Windowsの昔話を疲労してくれる。彼はWindowsのオーディオ周りを担当している。

ちなみに、Larry Osterman本人は、かなりのヒゲモジャなので、この翻訳の文体は、少し見かけに合わないかもしれない。

むかし、16bit DOSからアセンブリで直接8254を叩いて、音を鳴らして遊んでいたのを思い出した。

それにしても、最近は翻訳文が、流れるようにスラスラ出てくるから気持ちがいい。翻訳の仕事でもしたいものだ。

C++0x本:言語とライブラリの分離

どうしても、言語とライブラリを一緒に解説しなければならない部分がある。

たとえば、Move Semanticsだ。あるいは、Initializer listsだ。メモリ周りも、言語と完全に切り離すことができない。

実際、Move Semanticsというのは、言語でもライブラリでもなくて、プログラミングのテクニックに属する。しかし、これを解説しないわけにもいかない。というのは、規格書には、Move Semanticsという言葉自体は出てきているからだ。具体的な解説はないものの。

一体どうすればいいのだろう。どうしても、言語とライブラリを明確に切り離せないものも存在する。個々に詳しく解説した上で、言語にもライブラリにも属さない章を作り、そこで、組み合わせて使う場合を解説すればいいのだろうか。

C++0x本:内容は重複してもいいのではないか

本の解説は、重複してもいいのではないかと考えている。

たとえば、lvalueとrvalueの違いと、C++0xの二種類のreferenceだ。lvalueとrvalueの違いは詳しく解説するとして、referenceの章でも、多少解説を加えてもいいのではないか。差し当たって、最低限必要なことだけ触れて、「より詳しく知りたければ、X章を参照されたし」などと書くのはどうか。

referenceと、templateのargument deductionもそうだ。argument deductionは、それ単体で、詳しく解説する必要がある、しかし、referenceの解説や、std::forwardの解説の部分でも、触りだけ取り上げてもいいのではないか。このブログでC++を解説するときも、この機能については、別に解説しているので、ここでは一再解説しない、などという書き方はしなかった。

C++という言語には、それ単体で使える機能というものは、あまり存在しない。ある機能Xは、機能Yを知っていなければ使いこなせない。ところが、機能Yも、機能Xの存在を前提に定義されている。といった類の言語機能が、数多くある。

そして、人間の頭というのは、コンパイラのように働かない。ある機能について学びたくて、参考書の章を読んだとする。「この機能を使いこなすためには、他の機能X, Y, Zを知っていることが前提である。まず、それぞれの章を参照されたし」となっていた場合、果たして、その本は人間にとって便利と言えるだろうか。デジタルデータですら、そんな記述をしていては読みにくいのに、いわんや紙に書かれたアナログデータをや。

内容の重複は、ある程度はしかたないのではないか。

Windows 7にGod Mode、発見さる

Understanding Windows 7's 'GodMode' | Beyond Binary - CNET News

Windows 7にGod Modeが発見されたようだ。

  • どこにでもいいからフォルダを作成
  • 名前を、"GodMode.{ED7BA470-8E54-465E-825C-99712043E01C}" に変更
  • フォルダを開く

Windowsの設定変更の一覧が表示される。コントロールパネルより詳しい。

Vistaでも動くそうだが、64bit版は、クラッシュするとの声もある。実際に、手元のVista 32bitでは、動いた。

別にフォルダ名は、GodModeでなくてもいいのだが。

静的型付け言語は時代遅れなのか?

2010-01-04 - きしだのはてな

たしかに、Webサイトを構築する上では、強い静的型付けは、じゃまになるのかもしれない。

ところで、

さて、これからは、JavaScriptが高速化したりHTML5が出たりで、ブラウザ側で処理を行うアプリケーションが多くなっていく。ユーザーインタフェースに対する要求の高まりへのJavaScriptでの対応の難しさから、Flexなどの出番も増えると思う。

これ以上、Flashだけで構築されたサイトが増えてたまるものか。動画だけ再生できてりゃいいのだ。

2010-01-04

C++0x本:執筆に必要なもの

C++0x本を執筆するにあたって必要なものがある。人と金と時間だ。

人が必要である。規格を読んで文章を書くのは、一人でできるとしても、自分の文章を自分でデバッグすることはできない。こう書くと無責任なように聞こえるかもしれないが、プログラマなら誰しも、「自分の書いたコードのバグを、自分で見つけるのは難しい」という考えは、理解してもらえると思う。これは能力の問題ではない。単に、自分の中で、正しいと信じているから、バグを見つけられないのである。かえって他人の方が、バグを見つけやすい。自分のバグを見つけることまで含めて能力だといえば、たしかにそれはそうかも知れない。しかし、OSやブラウザといった、一流のプログラマによって書かれた一流のソフトウェアにすら、バグは山ほどある。とすれば、誰もそんな能力を有していないのである。

よって、査読者が必要である。それも、大勢必要である。確率などというものを言いたくはないが、より多くの人に確認してもらった方が、誤りを発見出来る確立は上がる。査読者は必要だが、残念ながら、対価をはらうということはできない。私は、払いたくても、金がないのだ。

こう書くと、すぐに出てくる発想は、「C++0xを学ぶためなら、査読してくれるボランティアもいるだろう。執筆途中の原稿を、どこかにアップロードして、広く公開すればいいのではないか。誰か読んでくれるだろう」というものである。確かに、より多くの人に見てもらうという点では、最も優れている。しかし、それでどの程度、結果が得られるだろうか。

私が必要としているのは、批評や提案である。「これは良かった、悪かった」という一般的な感想ではない。「この部分の記述は間違っている、なぜならば……」とか、「この部分は文章に問題があり、理解できない。改善するためには……」という類の意見が欲しい。

とすると、希望者のみの登録制にしてもよさそうである。そのためには、MLのような仕組みが必要である。できれば、数MB程度のファイルをアップロードできるとなおよい。わざわざそんなインフラを自前で構築するリソースはない。すると、どこかのWebサービスを使うというのが、最も手軽だと思う。

さて、では、どこのサービスを使うかという問題だが、 Google Groups がなかなかよさそうだ。チャットが必要なら、Google Talkが使えるではないか。メールはGmailが便利だ。関係ないが、私はGoogle Readerなしのインターネットというのは考えられないし、ブラウザはChromeだし、検索はGoogleを使う。そもそも、ブログは、もちろんGoogle傘下のBloggerである。

思えば、私はかなりGoogleに依存している気がする。Googleひいきというわけではないのだが、便利なものは便利だ。

話がそれた。MLなどのWebサービスは、問題ではない。本当の問題は、どうやってボランタリーな査読者を集めるかということだ。広い分野から集めたい。とくに、意欲ある学生を集められないものか。結局のところ、プログラミングというのは、学生のうちに学んだ影響が大きい。とすれば、その学生の意見を聞きたいものだ。

金と時間は両立できない。本を書くためには金がいる。時間がなくては本がかけない。どうするか。

2010-01-03

Not the Messiah

BBC iPlayer Console - Not the Messiah

You know... Eric Idle is always a nice chap. Bloody nice.

How to tweet in Hatoyama way

鳩山首相:ブログとツイッター開始 - 毎日jp(毎日新聞)

鳩山由紀夫首相は1日、インターネット上に自身のブログ「鳩cafe」を開設し、ネット上に短文を発信・表示するサービス「Twitter(ツイッター)」の利用も昨年12月31日から始めた。ブログは週1回程度、ツイッターは1日1回の更新を目指す。現役首相のブログやツイッターの利用は初めて。

ブログには「みなさんと政治の距離を少しでも近づけ、一緒にこの国を変えたい」と抱負を記した。2日のツイッターでは「本当に本人か」との質問に「基本的に私が書き、メールで秘書官付(職員)に送り、ツイッターへの送信はその人がやってくれる」と答えた。

好きに書かせると失言だらけになりそうだからだろうか。

2010-01-02

C++規格におけるoperatorの優先順位の定義方法

ふと、C/C++の規格上は、どのようにoperatorの優先順位が定義されているのかということが気になった。そこで、調べてみた。

operatorはすべて、Expressionの下に配置されているが、どうやら、優先順位を示す表や、文章は見当たらない。しかし、何らかの方法で優先順位を定義しているはずである。

いくら探しても見当たらなかったので、何気なくふと、Grammar summaryを見たところ、なんと、Sytax Notationの形で、優先順位が定義してあった。

たとえば、

expression:
    assignment-expression
    expression , assignment-expression

となっている。では、assignment-expressionの定義はどうか。

assignment-expression:
    conditional-expression
    logical-or-expression assignment-operator initializer-clause
    throw-expression

なるほど、ではlogical-or-expressionはいかに。

logical-or-expression:
    logical-and-expression
    logical-or-expression || logical-and-expression

このように定義されているのである。ちなみに、primary-expressionは、( expression )となっている。これで、括弧も定義されている。

なるほど、面白い定義のしかただ。

この方法は厳密だが、人間にとっては分かりにくい。C++0x本では、分かりやすく表にしようと思う。

ちなみに、この定義を見て始めて、Nicolai Josuttisの、Object-Orientend Programming in C++での、operatorの優先順位の表の意味が分かった。表が、濃い線と薄い線を使い分けているのは、そういう意味だったのか。ちなみに、この本は、C++の入門書として最適である。日本語に訳されていないのだが。

C++0x本では、規格に書いてあるSyntax Notationを用いようと思っている。他のパーフェクトシリーズは、【】なども駆使した、独自のSyntax Notationを編み出しているようだが、私は、規格に従おうと思う。ただし、規格にあるすべてのSyntax Notationは出さない。あくまで、個々の文法を説明するだけに留める。

吹いたwww

パソコンの環境設定

大阪府の電子入札や電子申請に使う端末には、「Internet Explorer 6 SP3」「Internet Explorer 7(以下 IE7)」「Internet Explorer 8(以下 IE8)」並びに「Windows XP SP3」「Windows Vista(以下 Vista)」「Windows 7」を使用しないでください。

何を使えというんだ、何を。

しかも、ある特定のバージョンのJAVAに依存しているらしい。セキュリティーホールがあるバージョンだ。

しかし、JAVAってバージョン間の互換性の問題を度々引き起こしている気がする。JAVAの規格が悪いのか、Sum Microsystemsの実装が悪いのか、プログラマが悪いのか。

そもそも、JAVAの理念というのは、ハードウェアを意識しないで実行出来ることではなかったのだろうか。Javaアプレットは、あんまりいい話を聞かない。

各ブラウザのvideo対応が出揃った

Opera Core Concerns - (re-)Introducing <video>

Operaもvideo要素の実装に本腰を入れ始めたようだ。Operaの実装は、GStreamerを使う。

ただし、Windows版のOperaは、GStreamerを独自に改変したものを使っている。これは、Ogg/TheoraとWAVE PCMしかサポートしていない。彼らは、オープンなOgg/TheoraこそがWebの標準であるべきだという意見らしい。

さて、これで、各ブラウザの<video>対応が、出揃った。

FirefoxとOperaは、Ogg/Theoraをサポートする。Firefoxも、GStreamerを使うという話がある。

Safariは、QuickTimeを使って、動画を再生する。ただし、QuickTimeは、皆知っているように、最悪だ。

Chromeは、ffmpegのコードを使っている。これは、かなり広範な動画をサポートできる可能性がある。

video要素なら、Chromeを使うべきである。

しかし、Ogg/Theoraという、画質の最悪な動画が、Webの標準になろうとしているのは、あまりいいことではない。これではFlashやSilverlightに勝てない。

C++0x本:図と表について

本の品質を良くするために、どうか意見をコメントしてもらいたい。

すでに発行されているパーフェクトC#やパーフェクトJavaを見ると、図や表がふんだんに使われている。実に贅沢な本である。まさかこの本の原稿は、MicrosoftのExcelで書いたのではあるまいか。

一体、図や表は、それほど分かりやすいだろうか。私は、表に細かい文字でびっしりなにやら書いてあるのを見るのが嫌いである。見ているうちに、行や列を見間違えてしまうこともよくある。確かに、図や表は一見してかっこいいし、分かった気になれるが、実は全然理解していないのである。

たしかに、pointerを解説するとなれば、objectを参照するpointerの図のようなものがあった方が、分かりやすいとは思う。また、C++0xとは直接関係ないが、双方向リストというデータ構造がある。双方向リストを解説するには、やはりそのような図が欲しい。とはいえ、演算子をすべて表でならべるというのは分からない。かりに優先順位などを表現したいとしても、たとえば優先順位の高い順番に解説していくという方法もあるではないか。

図や表を使えば、紙面の削減になるのかもしれない。しかし、仮にそうだとしても、理解しづらい方法でページ数を多少削減するなどということは、断じて許容できない。

一体、ニッポン人の図表好きはなぜなのだろう。私は、ソフトウェアの仕様書を、すべてExcelで書いている製品という話を聞いたことがある。一体、何が彼らを図表へと駆り立てるのであろうか。

有名な洋書の参考書をみても、図表をこれほどふんだんに用いているのはまれである。だいいち、そんなに高度な印刷技術を使っていない。もし、日本のパーフェクトシリーズを、海外で出そうとしたら、本の値段は、一桁高くなるはずである。それぐらい、日本の製本技術は優れている。

私は、図表の乱用はやめようと思っている。どうしても必要な場合に限り使うことにしようと思う。結果として、私の本には、図表はあまり出てこないと思う。どう思うだろうか?

本の品質を良くするために、どうか意見をコメントしてもらいたい。

C++0x本:実装依存について

本の品質を良くするために、どうか意見をコメントしてもらいたい。

私の書く予定のC++0x本は、言語仕様を解説する本である。特定の実装(例えばVC++やgccなどのコンパイラ)や環境(WindowsやLinux、組み込み系など)について解説するものではない。

ところが、世の中には、どうしても書かなければならない、デファクトスタンダードとなっている事項が存在する。

たとえば、registerやinlineは、ほとんどのコンパイラで、無視される。しかし、この機能が実装されていないわけではない。この手の仕事は、コンパイラの方が、人間より優秀なので、無視するだけなのだ。C++が設計された当時は、まだコンパイラの技術が貧弱だったので、こういう機能が役に立ったこともある。無論、これは規格の範囲外である。

ところが、もしこれを解説しない場合、「そうか! registerやinlineを使えば早くなるのか! さっそくどんどん使おう」などと、早合点するものが現れないとも限らない。no-opだから、実質は問題ないともいえるが、このような誤解を生むような本は書きたくない。

たとえば、exportは、ほとんどのコンパイラが実装していない。実際、標準化委員会でも、多くの者が、exportは失敗だったと考えている。これはあくまで、個人個人の考えである。標準化委員会としての意見ではない。結局、exportは、inclusion modelとseparation modelの両方をサポートしようとしたために、規格に入ったのだ。

exportについても、このことを、言及しておかなければならない。

たとえば、整数のオーバーフローは実装依存である。しかし、現実のコンピューターのアーキテクチャが、ほぼすべて、2の補数表現を用いている現状を知らなければ、「なぜ整数のオーバーフローが実装依存であることに注意しなければならないのか」ということが、理解できない。(ちなみに、atomic型の整数は、2の補数表現であることが規格で保証されている)

つまり、規格書の目次にそって解説するといえども、規格書の翻訳ではないので、実装依存の事を、完全に無視するわけにも行かないのである。ではどうするか。

思うに、必要最小限の、実装依存の事で、規格を理解する上で、特に知っておくべき事は、書くべきだと思う。ただし、それが実装依存の話であると分かるように、枠線で囲むだとか、インデントするだとか、印刷の際に、表現を変えて、通常のドキュメントとは違う文章であることを、明らかに分かるようにすべきだと思う。

どう思うだろうか?

本の品質を良くするために、どうか意見をコメントしてもらいたい。

2010-01-01

conversion functionの謎

template < typename T >
void f(T x)
{
    x = 1 ;// Error at VC
} ;

int main()
{
    int x = 0 ;
    f(std::ref(x)) ;
}

あれ? これってVCだけかな。

規格を読んだが、どうもこのコードが通るような記述は載っていない。ということは、エラーが正しいのか。

ということはだ、C++0xのstd::refって、使えないんじゃないか。関数オブジェクト限定か?

C++0x本:C++03からの差分をどうするか

本の品質を良くするために、どうか意見をコメントしてもらいたい。

私の執筆する予定のC++0x本は、一体どのように記述すべきだろうか。というのは、既存のC++03ユーザーを考慮するべきか、それとも、あくまで言語として解説すべきか

たとえば、referenceである。referenceの説明は、どちらがいいだろうか。

案1:referenceには、lvalue referenceと、rvalue referenceがある。この二種類のreferenceは、ほぼ同じものである。

案2:C++0xには、rvalue referenceが付け加えられた。従来のreferenceは、lvalue referenceと呼ばれる。この二種類のreferenceは、ほぼ同じものである。

私の本の対象読者は、C++03をある程度知っている者である。とすれば、C++03からの差分で説明すれば、わかりやすい。

しかし、今はそれでいいとしても、C++0x規格が発行されてから数年たてば、新しくC++を学ぶ者が現れるはずである。そのとき、大昔のC++03の差分で説明されても、意味がわからないに違いない。

それに、純粋に言語を解説するとなると、C++03からの差分というのは、どうもよろしくない。

ゆえに、私は、このような差分を使った説明を書かないことにしたい。

どう思うだろうか?

また、ためしに専門用語の名詞を英単語で書いてみた。もちろん、あくまで日本語なので、「二種類のreferences」とはならない。referenceでいい。

あけおめ、ことよろ

私は言語が好きである。日本人なら誰でも、「あけおめ、ことよろ」の意味が分かる。これは実に興味深い。

結局、私の興味は、言語にあるのだろう。それが自然言語であろうと人工言語であろうと、

今年、私はC++0x本の執筆に取り掛かる予定だ。入門書ではない。言語仕様を厳密詳細に解説する本だ。今年中に完成するかどうかは、分からない。おそらくは、今年中には完成しまい。しかし、私は急ぐつもりはない。私は真に優れた本を世に行いたいのだ。

どうかコメントが欲しい。このブログを読んでいて、C++0xの本を待ち望んでいる者は、どうか、本の執筆案の記事に、意見をコメントして欲しい。

さて、年越しそばを食べようと準備をしたのだが、うっかり寝てしまった。目がさめたので、そばをゆでた。とり肉とニシンが両方入った、不思議なそばができあがった。うまい。

今年は私にとって、やりがいのある年になるだろう。私の生活がどうなるかは、依然として分からぬが、そんな私事はどうでもいい。二旬にして九食らうのみだとしても、気にしない。まあ、適度な運動はするつもりなので、最低限、飯だけはしっかり食べる予定だが。第一、飯を喰わなければ頭も働かない。

子思立節

子思居於衛、縕袍無表、二旬而九食、田子方聞之、使人遣狐白之裘、恐其不受、因謂之曰、吾仮人遂忘之、吾与人也如棄之、子思辞而不受、子方曰、我有子無、何故不受、子思曰、伋聞之、妄与不如遺棄物於溝壑、伋雖貧也、不忍以身為溝壑、是以不敢当也。

この漢文通りに生きていけたら高潔だが、でも、誰か狐白の裘を送ってくれないかな。現実問題として、生きていくには、些少の金が入る。優れた小説には奴隷制度が必要不可欠というのは、村上春樹の言だか、さらにネタ元があるのかは知らないが、そのとおりだと思う。奴隷制度の倫理上の問題はさておき、日常の労働から免除されて、あるひとつの学問を専修する人間がいてしかるべきだ。奴隷というのは、無論、現代の倫理にそぐわないので、パトロンというのはどうか。

まあ、理想だが。

縕袍無表といえば、文字通り、一番分厚い外套のファスナーが壊れて、防寒着として意味をなさなくなってしまったのだった。