2007-04-27
Boost 1.34.0 Beta was released
車の話
2007-04-21
酒を飲んだ話
2007-04-16
チラシの裏
2007-04-12
feed pigeons
2007-04-06
定額定額定額
2007-04-02
niconico video
2007-03-28
ネオジム磁石のブレスレット
先日紹介した、ネオジム磁石のブレスレットが、やっと届いた。さっそく装備する。
そういえば、昔は防具屋の近くに意味ありげなオヤジがいて、「ぼうぐは そうびしないと いみが ないぞ」などと教えてくれたものだ。近頃、こういう親切な人が耐えて久しい。
さて、今日はクエストがある。トム爺さんを押すのではなく、三流ホテルの皿洗いのクエストだ。さっそくいくと、パーティメンバーの、職業おばはんの人から、次のように言われた。
おばはん曰く、「へぇ~それ強い磁石なんだ。もぅ~すごい波動が出てるんじゃない」
我、答えて曰く、「科学の名において、有神論者に災いあれ」
まあ、つづめて言うと、ネオジム磁石の面白いブレスレットを身に付けてバイトに行くと、磁石が健康にいいと信じているおばはんが、波動がでていると宣ったわけだ。
一体波動とはなんだろうか。確かに間違いではない。電磁波(もちろん可視光も含む)を、一般に波動というのだろうが、このおばはんの口にする波動という言葉は、どこかオカルトじみていた。このおばはんは、本当にこの手の似非科学がすきなのだ。サプリメント愛用者であり、バイト中の水分補給に酸素水を愛飲している。サプリメントなんて、緊急に何かを摂取しないといけないときぐらいしか使う必要がないし、酸素水は愚の骨頂、そもそも酸素は水にほとんど溶けないのだ。ペットボトル一本飲み干しても、一呼吸分の酸素に相当するかどうかも怪しいものだ。第一、水に溶けた酸素をどうやって吸収するというのか? 我々は、何十平方メートルもある肺胞で酸素を取り入れるのだ。この面積はどうしても必要なのだ。皮膚呼吸などというものが、いかに馬鹿げているか分かるだろう。
本当に、「水商売」は昔からなくならない。
そして、磁石の健康への影響も、統計的には、存在しないと結論できる。しかし、何故人はこの手の似非科学に惹かれるのだろうか。
2007-03-27
what's wrong with Trackback
トラックバックという機能を知ったときは、面白いとは思ったが、さほど興味を抱かなかった。なにしろ私には、「どうぞ私にスパムを送りつけてください」と宣言しているように感じられたからだ。
こちらへリンクを自動的に貼ってもらうという仕組みは、当然スパムに利用されるに決まっている。案の定、もはやトラックバックはスパムだらけである。このスパムに対して、各社とも知恵を絞っている。単純な単語やIPなどのフィルタから、トラックバック元に、こちらへのリンクがなければ無効にするという機能、あるいは、同一のリモートホストから、自社のブログサービスへ、一度に大量のトラックバックが送られた場合、スパムとみなすなどである。これらの努力はすばらしいが、しかし、そこまでしてトラックバックを使いたいものかと疑問になる。
ところで、bloggerには、バックリンクという仕組みがある。これは、自分へリンクしている所へ、こちらからリンクをはる機能だ。そもそもトラックバックは、Movable Typeが始めたもので、ある記事にたいするリンクである。自分の記事にリンクしているサイトは、明らかに関連のある事柄を扱っているに違いない。では、こちらからもリンクしてやろうというわけだ。この仕組みは、なかなか面白い。このバックリンクへスパムを使用とするならば、Googleにクロールされる形で、スパム先へのリンクを提供し続けなければならないからだ。
とはいっても、バックリンクを提供できるのは、大手検索サイトぐらいなものだろう。特にGoogleだ。
2007-03-25
リアル砂の女(主人公は女)
2007-03-24
いい加減にしろ、黄昏フロンティア
2007-03-22
I don't like Automatic Transmission.
2007-03-19
2007-03-18
Does VC8 optimize quick sort?
バイナリサーチは末尾再帰で書けるので、最適化できる。では、末尾再帰ではない再帰は、どのようなコードが生成されるのか。たとえば、クイックソートだ。
template < typename Iterator >
void quick_sort(Iterator first, Iterator last)
{
if ( std::distance(first, last) < 3 )
{ return ; } // 末尾
Iterator left(first), right(last) ;
++left ;
--right ;
while ( left < right )
{
while ( left <= right && *left <= *first )
{ ++left ; }
while ( left <= right && *right > *first )
{ --right ; }
if (left < right )
{ std::iter_swap(left, right) ; }
}
std::iter_swap(first, right) ;
quick_sort(first, right) ;
quick_sort(++right, last) ; //末尾
}
どうもスマートに書くのは難しいが、とりあえず実験の用には足りるだろう。これはどう見ても末尾再帰ではない。これをVC8でコンパイルしてみると、二つ目の再帰呼び出しは、最適化されてループになっていた。なるほど、そういうこともできるのか。
2007-03-16
Does VC8 optimize Tail Recursion?
2007-03-15
Why Japanese translation of south park is gay
2007-03-13
how to write Merge sort?
insertion sort
the best learning site ever and never
2007-03-11
glad im japanese
2007-03-09
Some funny videos
Great YouTube video : CAUTION! You probably lose your money.
私は、首飾りや指輪、腕輪などといった装身具に興味を持たない人間である。私はよくいる、外見に一切気を使わない人間の一人であり、服にも一切こだわっていない。にもかかわらず、このすばらしいYouTubeの動画は、この私にブレスレットを売りつけてしまった。これを一回見ただけで、もうどうしようもなくこのブレスレットが欲しくなってしまったのだ。この動画は危険である。あなたから50ドルを奪ってしまう。
この商品は、Bandoleer Braceletだ。購入も、ここから行える。価格40ドルで、海外への送料が10ドルだ。ちなみに、この商品を注文すると、つぎのようなメールが送られてきた。
Your order at Dynomighty has been received. Due to significant response from our YouTube video, we currently have delays in order fulfillment. We are making every effort to ensure your order is shipped ASAP. Estimated delivery is currently 10 days.
Dynomightyへの注文を受け付けました。ただいま、YouTube動画への反響がとても大きいために、商品の発送が遅れております。なるべくはやく商品をお届けするよう、努めています。発想までには10日ほどかかると思われます。
これは大変そうだ。
What THE FUCKING great japan is!
Expression Template
C++ Templatesに載っているExpression Templateの実装は、嫌いだった。物凄く面倒なのだ。これを実装するぐらいだったら、自前でループを書いたほうが、まだましだろう。
ところで、C++ Template Metaprogrammingを読んでいると、より分かりやすい方法が見つかった。C++ Templatesに載っている方法は、各種演算のための参照でラップするクラスと、演算子をオーバーロードするテンプレート関数があったのだが、C++ Template Metaprogrammingのサンプルでは、この演算方法を、テンプレートパラメータとしていた。
struct plus
{
static float apply(float a, float b)
{ return a + b ; }
} ;
struct minus
{
static float apply(float a, float b)
{ return a - b ; }
} ;
template < typename L, typename OpTag, typename R >
struct Expression
{
Expression(L const & l, R const & l)
: l(l), r(r) { }
float operator[](unsigned index) const
{ return OpTag::apply(l[index], r[index]) ; }
L const & l ;
R const & r ;
} ;
template < typename L, typename R >
Expression<L, plus, R> operator + (L const & l, R const & r)
{
return Expression<L. plus, R>(l, r) ;
}
なんて分かりやすいんだろう。C++ Templatesの実装では、Expression_Addとか、Expression_Subなどをそれぞれ用意しなければならないが、こうすると、かなり分かりやすくなる。なぜ今まで思いつかなかったのだろう。分かってしまうと単純なのに、自力で発見することはできない。コロンブスの卵というやつだろうか。
2007-03-07
Concepts Extending C++ Templates For Generic Programming
この情報は恐ろしく昔のもので、現在のドラフト規格とまったくあっておりません。検索で飛んでこられた方は、この情報を信用せず、ご自分で規格をご確認ください。
これは最高にためになる動画だ。
コンセプトとは、C++のパラダイムのひとつ、ジェネリックプログラミングを、もっと分かりやすくするための文法だ。
前半の5分ほどは、ジェネリックプログラミングはなんであるかを解説している。
The reason we think that we can make it simpler is that many of the way people use template now are... tricks! There're complelcated tricks. You can't even read in the book in many faces. You have to dig for newsgroup to see how they work recall look at boost C++ library to see what those guys did.
今のテンプレートは、複雑なトリックを多用しすぎている。多くのトリックは、本にも載っていない。Boost C++ライブラリを書いている連中が何をやっているのかを知るためには、ニュースグループを調べなければならない。(原文が正しい自信がない)
conceptには三つの機能がある。Concept Difinitions
ある型にたいする要求を定義する。たとえば、ある型TはT:func()というメンバ関数を持っていなければならないとか、T::value_typeという型が定義されていなければならないなどだ。
Where Clauses
テンプレートパラメータに必要なコンセプトを明示的に指定できる。
Concept Map
既存の型を、どのようにコンセプトの要求どおりに使うかを指定できる。個人的な感想は、恐ろしく賢いマクロか、恐ろしく便利なシンタックスシュガー。
この例では、型Tは、less than演算子を持っていなければならないというコンセプトが示されている。たとえば、比較演算子としてgreater than演算子(>)を使った場合は、コンパイラがエラーを出す。less than演算子で比較できない型を渡した場合も、コンパイラはエラーをだす。しかも、コンパイラが吐くエラーは、「LessThanComparableの要求を満たしていません」等といった、人間に分かりやすいエラーだ。従来の、インスタンシエイトの過程を追っていくような、人間にとって暗号に近いエラーメッセージではない。
それでは、LessThanComparableというconceptはどうやって定義するのか。
文法的な要求と、意味的な要求を定義できる。講演では、axiomについては詳しく述べていない。しかし、この機能はどうやって実現するのか疑問だ。本当に、これをコンパイル時にチェックできるのだろうか。ここでの、syntactic requirementは、T型の引数を二つ取り、bool型を返す、less than演算子がなければならないというものだ。もちろん、現在のテンプレートパラメータのように、複数指定できる。Why not?
他にも、value_typeという型を持っていなければならない要求や、それらの型に対するコンセプトをネストして指定できる機能など。
where clauseは、次のように指定できる。
ここで質問がある。InputIterator<Iter>::value_typeには、typenameの指定はいらないのかというものだ。もちろんここは型を指定すると決まっているので、必要がない。コンパイラは適切に判断できる。 たとえば次のようにすれば、conceptをサポートしていないコンパイラに対する、下位互換性も保てるだろう。
さて、28分あたりから、いよいよ、超強力なconcept_mapの解説に入る。先ほどのfindという関数は、イテレータに対しては問題なく対処できた。でも、int型の配列に対してはどうだろう。int型の配列の先頭要素へのポインタは、十分にイテレータとして通用する。しかし、組み込み型であるので、value_typeやdifference_type等を持っていない。そこで、Concept Mapを使い、どうやってコンセプトに合うようにするか、いわばマップを行う。 Concept Mapとは、How(如何にして)conceptの要求を満たすかを定義する。たとえば、int型のポインタに、value_typeとdifference_typeが必要というのであれば、定義してやるだけだ。
とはいっても、組み込み型だけでも、かなりの数がある。いちいちひとつずつやっていくのは面倒だ。ここは、テンプレートを使うべきだ。Why not?
これで、すべてのポインタは、InputIteratorのコンセプトを満たすようになった。
コンセプトは、階層構造にすることができる。Concept Refinementという。
every random access iterator is a bidirectional iterator is a input iterator
ランダムアクセスイテレータは、バイディレクショナルイテレータであり、インプットイテレータである。 このヒエラルキーは、Overload Resolutionに絡めることができるらしい。たとえば、イテレータを、指定された個数分進めるadvanceであるが、
この例では、where clauseがないが、これは簡便なショートカットシンタックスである。意味も分かりやすい。ワーオ!
まず、最初のadvance関数は、非常にジェネリックで、どんなイテレータでも使うことが出来る。しかし、ランダムアクセスイテレータの場合、これは無駄が多すぎる。そこで、RandomeAccessIteratorのコンセプトを使ってやる。コンパイラは、ベストマッチを探してくれる。ご存知の通り、Bidirectional Iteratorは、Input Iterator 「である」ので、最初の関数にマッチする。それにしても、タダでさえOverload Resolutionはややこしいというのに、さらに複雑になるのだろうか。現状では、テンプレートは、インスタンシエイトされてから、Overload Resolutionにかけられる。これだけでもややこしいというのに……。
さて、さらにConcept Mapの話は続く。こんどは、あるコンテナの全要素をイテレートするというものだ。いわばfor-each loopだが、これをどうするか。もちろん自分でやってもいいのだが、全要素をループさせるというのは、よくある操作なので、楽をしたい。他の言語はどのようにしているかというと。
Pythonは、イテレータとコンテナのプロトコルを定義している(ある決まった形でなければならない)
Perlは、ユーザ定義型を無視する(ハァ? 組み込み型以外は知ったこっちゃないね)
C#は、IEnumerableインターフェースを使う(既存の俺様コンテナは知ったこっちゃないね)
C++0xは、concept mapを使う。
次のForコンセプトを満たす必要がある。
つまり、次のコードが、
何の解説もないが、原文のbracket parentheseの間に空白がないのは、意識してやっているのだろうか。これをできるようにしようという提案がされているのだが。もうひとつ、こんな風にコンセプトを明示的に使うことも出来るのだろうか。解説がないが。
たとえば、int型の配列に対しては、次のようにする。
これを使えば、STLとは微妙に違う、俺様コンテナであっても、コンセプトに合わせるようにしてやれば、俺様コンテナ自身を変更することなく、for-each loopに書けることができる。これはいい。既存の、既に問題なく動いているコードや、共通のフレームワークなどを変更せずにすむからだ。 質問があるが、コンセプトはnamespaceの中に入る。これは当然だ。
ところで、STLのmultisetには、equal_rangeというメンバ関数がある。これは、引数として指定した値の範囲のイテレータを、pairで返す。コンテナではないが、for-each loopに必要な情報は、すべてそろっている。ではどうやってForコンセプトに合わせるのか。
恐ろしや恐ろしや。
しかし、ひとつひとつ、これを定義していくのは、面倒である。我々はすでに、Containerというコンセプトを定義した。これを使えばよい。
これで、Containerコンセプトを満たす型は、すべてforループにかけられる。とてもとても汎用的だ。
テンプレートがらみのエラーメッセージに辟易としない人はいないはずだ。コンパイラは、インスタンシエイトの過程を追っていくので、エラーメッセージは膨大になり、人間が簡単に読めるものではなくなってしまう。しかも、内部の実装の詳細の識別子などがでてくるので、まずわけが分からない。
上記のコードの、VC8のエラーメッセージは次の通りである。
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3112) : error C2784: 'reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : テンプレート 引数を 'const std::reverse_iterator<_RanIt> &' に対して 'std::list<_Ty>::_Iterator<_Secure_validation>' から減少できませんでした
with
[
_Ty=int,
_Secure_validation=true
]
D:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1856) : 'std::operator -' の宣言を確認してください。
.\test01.cpp(10) : コンパイルされたクラスの テンプレート のインスタンス化 'void std::sort<std::list<_Ty>::_Iterator<_Secure_validation>>(_RanIt,_RanIt)' の参照を確認してください
with
[
_Ty=int,
_Secure_validation=true,
_RanIt=std::list<int>::_Iterator<true>
]
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3112) : error C2784: 'reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : テンプレート 引数を 'const std::reverse_iterator<_RanIt> &' に対して 'std::list<_Ty>::_Iterator<_Secure_validation>' から減少できませんでした
with
[
_Ty=int,
_Secure_validation=true
]
D:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1856) : 'std::operator -' の宣言を確認してください。
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3112) : error C2784: 'reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : テンプレート 引数を 'const std::reverse_iterator<_RanIt> &' に対して 'std::list<_Ty>::_Iterator<_Secure_validation>' から減少できませんでした
with
[
_Ty=int,
_Secure_validation=true
]
D:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1856) : 'std::operator -' の宣言を確認してください。
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3112) : error C2784: 'reverse_iterator<_RanIt>::difference_type std::operator -(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : テンプレート 引数を 'const std::reverse_iterator<_RanIt> &' に対して 'std::list<_Ty>::_Iterator<_Secure_validation>' から減少できませんでした
with
[
_Ty=int,
_Secure_validation=true
]
D:\Program Files\Microsoft Visual Studio 8\VC\include\xutility(1856) : 'std::operator -' の宣言を確認してください。
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3112) : error C2676: 二項演算子 '-' : 'std::list<_Ty>::_Iterator<_Secure_validation>' は、この演算子または定義済の演算子に適切な型への変換の定義を行いません。(新しい動作; ヘルプを参照)
with
[
_Ty=int,
_Secure_validation=true
]
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3112) : error C2780: 'void std::_Sort(_RanIt,_RanIt,_Diff,_Pr)' : 4 引数が必要です - 3 が設定されます。
D:\Program Files\Microsoft Visual Studio 8\VC\include\algorithm(3231) : 'std::_Sort' の宣言を確認してください。
これをまともに読める人間は、まずいないだろう。次のようになれば、読みやすいのではないかと思う。
「std::list
他にも、インスタンシエイトされる前に、テンプレートのコードが、コンセプトにあったものかを、コンパイラがチェックすることができる。たとえば動画の例では、InputIteratorは、less than演算子を使うことが出来ない。
最後の質問でも出ているのだが、これらの機能にはコストがかかる。Boostのライブラリをふんだんに使ったコードのコンパイルには、かなりの時間がかかるが、コンセプトもテンプレートと同じく、かなり多くの処理を行わなければならない。どうなることやら。
しかし、仕様が確定するのが2009年で、ISOの認可がおりるのが、2010年、それから主要なコンパイルベンダーが実装するのに、数年はかかるだろうから、案外楽観視していいのかもしれない。ムーアの法則が続いていればの話だが。
FAITH OF THE FALLEN by Terry Goodkind
2007-03-04
ビル・Gからの手紙
「ビル・Gからの手紙」は週間アスキーで連載されていたコラムである。某巨大企業のビル・Gと名乗る人物から送られてきた手紙を、コモエスタ坂本が翻訳するという形をとっている。たとえば、次のようなで出しだ。
第17便
毎日毎日ラッシュ・アワーの電車でもみくちゃにされ、通勤地獄に悩まされている日本人の皆さん。私はポルシェで快適に通勤する、ビル・Gである。第21便
家から遠く離れた会社に通勤するために、ニワトリより早く目覚めなければならない日本人の皆さん。私はワシントン湖のほとりに集う小鳥たちのさえずりと、やわらかな朝日と、そして愛する妻リンダの優しい声で一日をスタートさせるビル・Gである。
第31便
たった6枚のタタミ・マットの上で日々を過ごしている、親愛なる日本人の皆さん。私は最近完成された豪邸に引っ越したばかりのメディア王、ビル・Gである。
このビル・Gにかかると、Unicodeも、いまだに絵文字でコミュニケートする第三世界の野蛮人への配慮ということになってしまうし、クリントン元大統領も、ビル・Gのクローン人間ということになる。
ISBN4-7561-1855-0と、ISBN4-7561-3151-4の二冊である。