2011-02-28

はてなブックマークの奇妙な挙動

とりあえずはてなブックマークの問題を解決した。ふしぎなことに、コールバック関数の名前が問題だったようだ。

はてなブックマークのAPIは、JSONPが使える。この時のコールバック関数名は、perlの正規表現、/^\$?[a-zA-Z0-9\[\]\.\_]+$/に一致しなければならないとされている。わたしは、コールバック関数として、hatebu_callbackという名前の関数を使っていた。ところが、どうもこの名前では動かないようだ。確実にブックマークされているURLであっても、hatebu_callback(null)が帰ってきてしまう。色々と試してみたが、hatebu_callbackというコールバック関数名のときだけ、この問題が起こるようだ。なぜだろう。とりあえず、コールバック関数の名前を変更しておいた。

なお、この問題は、すべてのURLで起こるわけではない。その辺も謎だ。どうも2月23日にブックマークされた以降のURLにおこるのではないかと思っている。

しかし、正規表現によるURLのパースは、あまり良い実装とは言えないと思うのだが。

2011-02-27

range-based forに対する意見求む

現在、range-based forに対して、改良を加えられるチャンスがある。これはまだ議論中であり、次のFDISに入るかどうか分からないが、未来のC++0xユーザー候補が、今知るべきことだと思うので、ここで説明する。意見がほしい。

問題は、あるクラスを、どのようにrange-based forに対応させるかというものである。現行ドラフトを簡単に説明すると、以下のようになっている。

range-based forに渡した式を引数に取り、イテレーターを返す、begin(expr)、end(expr)を、ADLにより探す。

// Cの構造体による既存のコード
struct Container
{
    int * ptr ;
    std::size_t size ;
} ;

int * begin( Container & c ) { return ptr ; }
int * end( Container & c ) { return ptr + size ; }
// 同様のconst版

これは、同じ名前空間スコープにbegin、endという名前の関数を書けばいいだけなので、初心者にも簡単といえるだろう。また、クラス定義を変更する必要がない。

また、range-based forのADLには、std名前空間が特別にassociated namespaceとして付け加えられる。std名前空間には、クラスのbegin/endという名前のメンバー関数を呼び出す関数があるので、これを利用することでも、クラスをrange-based forに対応させられる。

つまり、クラス内で、イテレーターを返すbegin/endという名前のメンバー関数を定義する。

// 標準ライブラリのコード
namespace std
{
template <class C> auto begin(C& c) -> decltype(c.begin());
template <class C> auto begin(const C& c) -> decltype(c.begin())
template <class C> auto end(C& c) -> decltype(c.end());
template <class C> auto end(const C& c) -> decltype(c.end());
}

// Containerのためのイテレータークラス
// もちろん、ポインターによる実装も可能
class Iterator ;
class Container
{
    Iterator begin( ) ;
    Iterator end( ) ;
// 同様のconst版
} ;

この対応は、クラス定義が変更できる場合に、使うことができる。しかし、既存のクラス定義は、様々な理由で、自由に変更できない可能性がある。例えば、Cコードの構造体や、外部のライブラリであり、変更できないという状況は、現実のプログラミングでは、大いにありうる。

しかし、多くの中級者以上のC++プログラマーが知るように、ADLは根本的に邪悪である。今、range-based forに対して、最後の変更を行うチャンスがある。

案1は、現状を維持する。変更は行わない。

案2は、traitsベースの実装に変更する。つまり、range-based forにおけるイテレーターの取得を、テンプレートクラスを通じて行うようになる。

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(); }
 // 同様のconst版など
} ;

}

クラスをrange-based forに対応させるには、range_traitsの特殊化を行う。

// C++0xの新機能、別の名前空間スコープにおけるテンプレートの特殊化
template < >
struct std::range_traits<Container>
{
    int * begin( Container & c ) { return c.ptr ; }
    int * end( Container & c ) { return c.ptr + c.size ; }
// 同様のconst版など
} ;

しかしこれでは、ユーザーはテンプレートの特殊化、しかも、STLのテンプレートの特殊化(規格上許可されている)という、かなり上級者向けのコードを書かなければならない。

案3は、案2に加えて、ADLフォールバック機能がつくものである。すなわち、range_traitsによるイテレーターの取得ができなければ、現行のADLベースの実装を使うというものである。これは、range_traitsによる優れた実装を提供しながら、ADLによる泥臭い実装も提供するという意味である。

案4は、イテレーターの取得方法には、メンバー関数、begin/endを使うというものである。つまり、traitsによる対応もできないし、クラス外での関数による対応もできない。ただし、クラス定義を変更せずにrange-based forに対応させる方法はある。アダプターである。

// 既存のCの構造体のような使い方をするクラス
struct Container
{
    int * ptr ;
    std::size_t size ;
} ;

class Adaptor
{
private :
    Container & ref ;
public :
    explicit Adaptor( Container & ref )
    : ref(ref)
    { }

    int * begin() const { return ref.ptr ; }
    int * end() const { return ref.ptr + ref.size ; }
} ;


int main()
{
    Container c = { new int[10], 10 } ;

    for ( auto & value : Adaptor(c) )
    {
        value = 123 ;
    }

    delete[] c.ptr ;
}

つまり、言語側の機能は最小限にして、ユーザーコードで対処しようというものである。このようなアダプタークラスは簡単に書けるし、パフォーマンス上の問題もない。また、make_adaptorなどといったヘルパー関数のテクニックを使えば、テンプレート化もできる。

案5は、案4に加えて、メンバー関数が見つからなかった場合に、ADLへのフォールバック機能を付け加えるというものである。案2に対する案3と同じである。つまり、ADLによる泥臭い機能は残される。案5は、現状維持とさほど変わらない。ただ、順番が変わっただけである。ADLの前に、メンバー関数を探しにいくようになるのだ。

私は、案4が最適だと考えている。ADLを利用してはならない。ましてや、range-based forは、将来のC++にコンセプトが入った場合、コンセプトを使った実装に書き換えられるはずなのだ。いま、ADLという穴を作るわけにはいかない。これは、range-based forからADLを外せる、最後のチャンスである。今、ADLを許可すると、一生ADLをサポートしなければならない。

ちなみに、案4のアダプターは、完全にユーザーレベル、ライブラリレベルでの対応なので、どの案を選んだとしても、行うことができる。むしろ、アダプターパターンは非常に一般的なので、C++プログラマーならば、アダプターという手法は、関数を書くことのように、空気を吸って吐くことのように、HBの鉛筆をベキッとヘシ折れるように、できて当然である。アダプターパターンにパフォーマンス上の欠点はない。

意見求む。

追記:配列について

配列は、現行ドラフトですでに、特別に処理されるようになっている。この問題は、配列以外の型に対する実装である。どの案を選んでも、配列に対してrange-based forが使えなくなるということはない。

2011-02-26

はてなブックマークのAPIが動いていない

不思議なことに、2月23日から、はてなブックマークのAPIが動いていない。

厳密にいうと、JSON形式で情報は取得できるのだが、JSONP、すなわち、コールバック関数を指定すると動かなくなる。なぜかコールバック関数の引数がnullになってしまうのだ。どうしたことだろう。

2011-02-25

日本では絶対にプログラミングしてはならない

"Librahack"共同声明に関する詳細情報

あれだけ馬鹿げたことをして、いまだに被害届の取り下げが行われないのか。何故か。前例がないからか? 被害届の提出に対する萎縮か? 意味が分からない。

日本は、Winnyの開発者を逮捕して、P2P技術の合法利用という道を塞いだ。ナップスターの例にみられるように、合法利用に転換する道はあったはずなのだ。Winnyプロトコルは、たしかに違法目的にしか利用できなかったが、管理サーバーのない、純粋なP2Pによるネットワークによって、実用的なファイル共有を実装した最初の例として、Winnyはソフトウェアの歴史に名が残るはずだ。また、BitTorrentプロトコルは、LinuxのISOイメージの配布、ゲームのアップデートパッチの配布、さらには、合法的なゲームの販売における配布そのものにすら、使われている。その道を日本国自ら閉ざしてしまうとは情けない。検索エンジンは著作権法にひっかかり、日本にサーバーを設置できない。最近、ようやく著作権法が修正されたものの、すでに時遅く、日本はもはや、検索エンジンではどうあがいても勝ちようがない。ましてや、ユーザーの機器を代理設置することによる、テレビの海外転送サービスまで、著作権上、違反という判例がでている。これにより、インターネット上のホスティングサービス(インターネットのほとんどのサーバーが該当する)をまともに提供することは不可能だ。

ソフトウェア特許はいうまでもない。私は生涯、パナソニック系列の製品を買わないと決めている。

日本は法整備の点ではるかに遅れをとっており、もはやソフトウェア産業に期待することはできない。いずれ滅びるだろう。その時最も役に立つのは、英語力である。プログラマーに英語は必須である。字が読めなければ、プログラミングを学べるわけがない。プログラミングに関する情報は、ほとんどが英語である。好むと好まざるとにかかわらず、英語が必須である。

しかし、今私は英語を読めない人間のために、C++0xの参考書を書いているわけだ。おそらく、むしろ書かないほうが日本人のためなのかもしれない。つまり、日本語の参考書など書かなければ、日本人がプログラミングを学ぶには英語を学ばなければならず、必然的に、日本に固執する必要がなくなるため、国外に出ていく。その方が、いま日本に住んでいる子供、すなわち未来の本物のプログラマーのためである。

しかし実際、私はプログラミングをする。しかし、その結果を日本国内で公表することは決してない。何故ならば、日本国内において、どんな内容であれ、プログラムを公開するということは、すでに何度も実例があるように、高い逮捕のリスクがある。もちろん、公開しなくても、結局はリスクがあることに変わりないのだが、逮捕の可能性を大幅に下げることが可能だ。

何故ならば、ひとたび逮捕されるや、事実上、起訴されるまでに十分な時間、拘留され、保釈は認められない。起訴されるも、相変わらず拘留され、保釈は認められない。恐ろしいことに、論理的、技術的に反論すればするほど、犯罪の理解と意図があったとみなされ、ますます保釈が認められなくなるし、罪も重くなる。

日本の取り調べは密室であり、被疑者の権利が十分に保証されていない。記録も残らず、ありもしない作文への署名を強要される。ほぼすべての人間は、圧迫的な取り調べに数日と耐えられず、一刻も早く逃れたいがために、また、早く自白すれば罪が軽くなるという、日本には存在しない司法取引に騙され、ありもしない自白をし、作文に署名する。裁判は形だけ行われ、取り調べでの強制的な自白や書名は、すべて正しいものとして扱われる。そこに希望はない。逮捕されれば、すべて終わりである。自分だけはその魔女裁判のような取り調べに耐えられると考えるのはうぬぼれである。人間の精神は、そのような非現実的な環境に耐えられるほど強くはない。裁判で無罪を証明できたとしても、拘留された何ヶ月、何年もの時間は、取り戻しようがない。ゆえに、そのような論理と正しい技術理解の通用しないリスクは、もとより避けるべきである。

ゆえに、日本でプログラミングをしないということは、リスクを最小限にするという点で、もっとも理にかなった戦略だと言える。ソフトウェアの価値を正しく評価しない日本ならではの最善手である。

テンプレートとオーバーロードと暗黙の特別なメンバー関数

注意:この記事は、現行のドラフトの先を見据えて書いている。この記事を読む前に、core issue 535と、core issue 1080を参照されたし。

次のFDISで大幅な変更が来るので、現行のN3225が一切信用できない。そこでこの一ヶ月は、執筆を急ぐより、規格のテンプレートとオーバーロードの文面をじっくり読む期間にあてることにする。

テンプレートとオーバーロードと暗黙の特別なメンバー関数が関係する場合、非常に分かりにくい挙動になる。もちろん、規格を厳密に解釈すれば、何も恐れることはないのだが、それでも、やはり難しい場合は存在する。

たとえば以下のコードだ。

struct X
{
    X() { }

    template < typename T >
    X( T const & ) ;
    template < typename T >
    X & operator = ( T const & ) ;
} ;

int main()
{
    X a ;
    X b(a) ; // use implicit copy constructor
    b = a ; // use implicit copy assignment operator
}

テンプレートコンストラクターとテンプレート代入演算子は、コピーコンストラクターやコピー代入演算子ではない。ただし、コピーコンストラクターやコピー代入演算子と同じ方法で呼び出されるし、オーバーロード解決の候補にも上がる。

ただし、テンプレートコンストラクターはコピーコンストラクターではないということは、暗黙のコピーコンストラクターの生成を妨げないということである。つまり、上記のコードでは、暗黙のコピーコンストラクターは、依然として生成される。オーバーロード解決で、型の順位が同じであった場合、非テンプレート関数はテンプレート関数より良しとされるので、非テンプレート関数である、暗黙のコピーコンストラクターが選ばれる。代入演算子も同じ。

したがって、上記の場合で、テンプレート版のコンストラクターや代入演算子を使いたい場合は、暗黙の特別なメンバー関数を、deleted定義しなければならない。

struct X
{
    X() { }

    X( X const & ) = delete ;
    template < typename T >
    X( T const & ) ;
    X & operator = ( X const & ) = delete ;
    template < typename T >
    X & operator = ( T const & ) ;
} ;

int main()
{
    X a ;
    X b(a) ; // use template constructor
    b = a ; // use template assignment operator
}

では、以下の場合はどうだろうか。

struct X
{
    X() { }

    template < typename T >
    X( T && ) ;
    template < typename T >
    X & operator = ( T && ) ;
} ;

int main()
{
    X a ;
    X b(a) ; // use template constructor
    b = a ; // use template assignment operator
}

この場合、テンプレート版のコンストラクターや代入演算子を使う。何故だろうか。これには、非常にややこしいわけがある。

テンプレート仮引数に対するrvalueリファレンスが仮引数で、実引数がlvalueの場合、テンプレート仮引数はlvalueリファレンスとなり、rvalueリファレンスは無視されるというルールがある。

template < typename T >
void f( T && ) ;

int main()
{
    int x = 0 ;
    f( x ) ; // f<int &>(int &)
}

これと同じことが、テンプレートのコンストラクターや代入演算子でも起こっている。ではなぜ、非テンプレートよりテンプレートの方が優先されるのか。それは、const修飾子を付け加えるというのも、標準型変換の一種だからだ。テンプレート版は、型を一切変換する必要がないので当然、非テンプレート版より順位が高い。そのため、テンプレート版が選ばれる。

とにかく、現行のN3225は一切信用できない。はやく3月末になってほしいものだ。

2011-02-24

カダフィがギレンに思えてくる件

【リビア騒乱】右腕も離反 カダフィ大佐四面楚歌 残るは一族のみ… - MSN産経ニュース

「アブドルファッターフ・ユーニス(オベイディ公安相)はどこにいる? 裏切り者(反体制派)に殺されてしまったのだ!」

カダフィ氏は22日の演説で何度か、1969年のクーデターで政権を奪取した当時からの腹心であるオベイディ氏に言及した。

そのオベイディ氏は数時間後、北東部ベンガジからの声明で、「私は生きている」と反論。中東の衛星テレビ局アルアラビーヤとの電話インタビューでは、カダフィ氏が自分を暗殺しようとし、間一髪で命拾いしたとも明らかにした。

この暗殺未遂が起きたとされるのはカダフィ氏の演説の前後。カダフィ氏はその忠誠を疑ったオベイディ氏を暗殺し、その責任を反体制派になすりつけようとしたとみられる。

なんというか、あの演説を思い出すというか。

我々は一人の英雄を失った。これは敗北を意味するのか?否!始まりなのだ!
列強に比べ我がリビアの国力は30分の1以下である。にも関わらず今日まで戦い抜いてこられたのは何故か!諸君!我がリビアの戦争目的が正しいからだ!
一握りのエリートがアフリカにまで膨れ上がった植民地を支配して42年、宇宙に住む我々が自由を要求して、何度列強に踏みにじられたかを思い起こすがいい。大リビアの掲げる、人類一人一人の自由のための戦いを、神が見捨てる訳は無い。
私の右腕、諸君らが愛してくれたオベイディは死んだ、何故だ!

オベイディ「ワシャまだ死んどらん」

2011-02-23

不完全型と暗黙のインスタンス化

以下のコードはwell-formedである。

template < typename T >
struct A
{
    T member ;
} ;

struct B
{
    A<B> * ptr ;
} ;

int main()
{
    B b ;
    b.ptr->member ;
}

クラスBの定義内では、Bは不完全型である。したがって、A<B>型は不完全型である。もし、クラスBの定義内で、インスタンス化が起こるのならば、このコードはill-formedである。しかし、このコードは、実際にはwell-formedである。何故か。

暗黙のインスタンス化は、完全なオブジェクトの型が必要になった地点で行われる。完全なオブジェクトの型でなくても、プログラムに影響を与えない場合は、インスタンス化は行われない。では、上記のコードにおけるA<B>のインスタンス化を発動させる行はどこだろうか。当ててみてほしい。

// Point of Instantiationを答えなさい
template < typename T >
struct A
{
    T member ;
} ;

struct B
{
    A<B> * ptr ; // #1
} ;

int main()
{
    B b ; // #2
    b.ptr ; // #3
    b.ptr->member ; // #4
}

答えは、#4である。何故ならば、ある型へのポインターは、ある型が完全型でなくてもかまわないからだ。したがって、#1はA<B>のPoint of Instantiationではない。また、#2、#3も、A<B>の中身を参照していないので、Point of Instantiationではない。インスタンス化の発動は、実際に完全型が必要な、#4の時点で行われる。

テンプレートのインスタンス化が起こらなければ、不完全型であっても構わない。テンプレートのインスタンス化が起こる地点で、完全型になっていればいいのだ。

rubyに中二のコミッタが誕生

Rubyのコミッタになりました | cod.note

私は、「現在は過去よりも進歩しており、未来は現在よりも進歩している」と考えている。コンピューターが筆、鉛筆などと同じく、リテラシー(読み書き能力)として認識されている現代においては、中学生や小学生で、このような活動をすることは、別段驚きでもない。とはいえ、誰にでもできるわけではない。

私が中学生の頃は何をしていたか。私は当時、コンピューターを持っていなかった。そこで、私は紙媒体のコンピューター雑誌やプログラミングの参考書をひたすら読みふけっていた。私は脳内でプログラミング言語を理解し、脳内でソースコードを書き、脳内でコンパイルしていたのである。

後に、高校生の夏休みの期間をすべてバイトにあて、初めてコンピューターを買った。私は脳内ソースコードを実際に入力してコンパイルを試みた。コードは私の理解通り、正しく動いた。

このような経緯があるからこそ、今の私があるのだろう。もし、中学生当時にコンピューターを所有していれば、私は厳密な規格の理解ではなく、何か実際に動くプログラムの開発を重視していたかもしれない。

これはひどい

GALAXY Tab を買いましたが、買ってはいけません | nekohacks blog

最悪だな。

私はこの手のデバイスや、携帯電話には興味がない。もし金が入ったら、USB接続のデータ通信カードと、普通のラップトップを買うつもりである。今や、電話を所有する意味はないのだ。ボイスチャットならば、Skypeなどでやればいい。

クラスはいつ完全型になるか

クラスは、クラス定義が終わった時点で、完全型になる。これはつまり、}の後である。

struct X
{
    X x ; // エラー、Xは不完全型
} // Xは完全型
;

X x ; OK

しかし、9.2 Class members [class.mem] paragraph 2には、クラス定義内でもクラス名が完全型として扱われる特別な場合について、言及している。例えば、関数の本体だ。

struct X
{
    X x ; // エラー、Xは不完全型
    void f()
    {
        X x ; // OK、Xは完全型
    }
} ;

この仕様は、特に知らなくても問題はない。C++の規格は、プログラマーにとって自然になるように設計されているからだ。必要のない限り、知らなくてもいいことである。

しかし、ここにひとつ重要な場所が抜けているように思われる、メンバー関数の仮引数宣言だ。関数宣言が定義であるとき、仮引数宣言も定義である。しかし、クラス定義内でメンバー関数を定義した場合、クラスはまだ不完全型である。しかし、9.2 paragraph 2は、仮引数宣言については言及していない。これはどうなっているのか。以下のコードはill-formedなのか?

struct X
{
    void f( X x ) { } // エラー?
    void g( X x ) ; // OK、宣言
} ;

そもそも、仮引数宣言は定義なのだろうか。3.1 Declarations and definitions [basic.def ]では、定義ではない宣言の例として挙げられていない。とすれば、すべての仮引数宣言は定義である。はて、以下のコードでも定義なのだろうか。

void f( int x ) ; // 関数の宣言

これは、xを定義しているのだろうか。しかし、コード例では、定義ではない関数宣言では、何も定義されないとしている。これはどうなっているのか。

規格を読んでも、さらに特別な仕様を規定する文面は見つからない。仕方がないので、久しぶりに人に訊ねた。一瞬で答えが得られた。聞くは一時のなんとやら。

実は、さらに特別な仕様を規定する文面はある。8.3.5 Functions [dcl.fct] paragraph 9である。

また、定義ではない関数宣言の仮引数宣言は、宣言であるが、現在の文面では、3.1 Declarations and definitions [basic.def]に挙げられていない。その他にも、テンプレートパラメーターや、エイリアス宣言が欠けている。

これは、core issue 758で解決される予定である。たぶんFDISには入るのではないだろうか。

2011-02-22

美麗印刷付き高級板ダンボール

Amazon.co.jp で日本語電子書籍をおまけとして配布します - コトリコ

ある人が、アマゾンで美麗印刷付き高級板ダンボールを委託販売するらしい。ダンボールは大変便利な紙製の板であり、期待が持てる。

結局この辺のインフラが整っていないのが、いまだに日本で電子媒体が本格的に始まっていない理由なのだろう。

Unicode 6.0が制定された

Unicode 6.0.0 is [actually] released! - Sorting it all Out - Site Home - MSDN Blogs

今回は、新たに2088文字が追加された。そのうち1000文字以上が、(日本の)携帯の絵文字である。

2011-02-21

多くない文

ある日本語を学んでいる外人から、こんな質問を受けた。

本当に日本語は常に否定疑問文を論理的に答えるのか? 例えば、「多くない?」って聞かれたときはどう答えるんだ。

はて、これはどうしたことか。私は今まで、日本語は常に否定疑問文を論理的に答えると考えていた。しかし、「多くない?」という疑問文に対しては、目的物が多くなかった場合、

うん、多くないね。
いや、多くないよ。

と、両方答えることが可能であるし、目的物が、多い場合にも、やはり同様に、二種類の答え方が可能だ。

はて、これはどうしたことだろう。常日頃、「英語はなんて非論理的な言語だ。日本語を見よ」と笑っていたのが、急に恥ずかしくなってきた。

ところが、どうも思うに、「多くない?」という文章は、私の感覚からすると、肯定疑問文にも、否定疑問文にも、受け取れるのだ。事実、英語のように非論理的に答える場合、私は肯定疑問文だと解釈している。とすれば、日本語の否定疑問文における論理性は崩れないことになる。

しかし、なぜ肯定否定の両方の解釈が可能なのだろうか。「多くない!」と言う場合、これは確実に否定である。しかし、疑問文に使ったときは、肯定とも否定とも取れる不思議な印象を受ける。

少し考えた結果、これは、「多く + 無い」ではなく、「多く + な + い」という文法なのではないかと考えた。日本語の文法規則には、色々と諸説あって難しいが、とりあえず手持ちの学研国文法(初版が昭和39年という、かなり古い本である)を引いてみると、果たして、な、い、という助詞が載っていた。

助詞「な」には、三種類あるが、感動、驚嘆の意をあらわす種類であろう。

助詞「い」は、念を押す意を表すとされている。

君の頭は確かかい。

夏目漱石「それから」

父さんが来たを思って、好い気になって泣くない。

島崎藤村「嵐」

島崎藤村の例は、最近は使わないし、どうも今問題の文法とは違うような気がするが、とりあえず、助詞「な + い」という形はあり得る。

つまり、「多くない?」とは、通常の文をイントネーションを上げ調子にして疑問文にする、「多く + 無い ?」と、2個の助詞によって構成される、「多く + ない + い ?」と、両方の解釈が可能であり、それによって、肯定とも否定とも取れる印象をあたえるのだろうと考えた。

しかし、また外人の曰く、「でも、助詞「い」は、単に念を押す程度の意味しか持たないから、省略しても意味が通じるようになるんじゃないか。「多くな」だけで、本当に意味を成すのか?」

そう言われてみれば、どうもこの解釈は怪しい。「多くな?」という文は成立しない事もないだろうが(それってどんな感じ? 例えば多くな?)、やはり、どうも難しい。

どうにもうまい解釈が出てこない。

追記:だいぶ前から一方的にGoogle Readerで購読していた人が、この問題を考えてくれた。

多くない? - M59の記録

「ない」という言葉は、打ち消し、もしくは念押しのどちらの意味にもとれるので、結果として、文章が肯定なのか否定なのか、どちらにも解釈できるという説である。この解釈の方がよさそうだ。

2011-02-20

こういう発想ができるようになりたい

「※この発言は個人の見解であり、所属する組織の公式見解ではありません」をリリースしました - 床のトルストイ、ゲイとするとのこと

相変わらずこの人の発想は面白い。もっとも、Twitterでの発言を見ると、似たようなことを考えた人が、他にいるようだが。

Twitterには、どのクライアントで投稿したかが表示されるそうだが、そのクライアント名を意味のある名前にしてみようという試み。Twitter自体が140文字しか投稿できないのだから、これは追加の情報を付加できることになる。

もっとも、Twitterは使うべきではない。検索しづらいTwitterはやめて、ブログを使うべきである。ブログには140文字などという、思想的な文字数制限はない。あるのは、技術的な制限だけである。

中学生、高校生のカースト

Togetter - 「中学生・高校生のリアル」

アメリカの学校のカーストは、結構わかりやすく、チアリーダーとアメフトだったりする。まあ、社会にでると逆転が起きるのだが。日本のカーストも、なかなかしょうもない。

2011-02-19

Native Client SDKがリリースされた

Chromium Blog: Native Client: Getting Ready for Takeoff

Native Clientとは、ブラウザ上でネイティブコードを安全に実行するためのフレームワークである。ネイティブコードの利点は、もちろん速度だ。

しかし、やはり私は、Webにはネイティブコードは相応しくないと考えている。それどころか、JVMやCILのようなバイトコードも、相応しくないと考えている。やはり、Javascriptで行くべきだ。

2011-02-18

clangの発展速度に驚く

clangの目覚しい開発速度には驚くばかりだ。今日、ふと、clangはどのくらい向上しているだろうかと調べたところ、なんともはや、C++03ならば、かなり実用的なコンパイラーになっていた。いまは、C++0xの実装に注力しているらしい。恐ろしい開発速度だ。去年のはじめ頃は、まだまだ開発段階だなと思っていたのに、もう実用的になっている。

残念ながら、C++の参考書の執筆中に、clangのC++0xの実装が、gcc以上に進むことはないだろうが、将来に期待できるプロジェクトだ。

現在、C++0xの新機能をもっとも多く実装しているのは、gccのtrunkだろう。ただし、まだバグや未実装部分も多く、全く信頼できない。もちろん、いまC++0xの参考書を執筆するということは、コンパイラーに頼らず、規格と厳密に照らし合わせてコーディングしなければならない。とはいえ、gccはないよりマシだ。少なくとも、うっかりtypoぐらいは発見してくれる。

2011-02-17

oldnewthingネタを二つ

Don't mention the war. I mentioned it once, but I think I got away with it all right (Episode 2) - The Old New Thing - Site Home - MSDN Blogs

イギリス人が他国人をどのように見ているかという記事へのリンク。ちなみに、タイトルは、Fawlty Towersが元ネタである。

John Cleeseは最高だ。

What is the difference between a directory and a folder? - The Old New Thing - Site Home - MSDN Blogs

フォルダーとディレクトリーの違い。ディレクトリーとは、ファイスシステム上に存在する物理的な位置を著す。フォルダはもっと高級な概念であり、コントロールパネルなどの仮想的な存在も含む。

2011-02-15

Googleの検索結果をブロックするextension

Google Chrome Blog: New Chrome extension: block sites from Google’s web search results

Googleの検索結果に出てくる、価値のないサイトをブロック出来るextension。Google自身から出ている。また、Googleはこのブロック情報を収集して、サイトのランク付けの参考にするのだという。

コンストラクターのデリゲート

C++0xにおけるコンストラクターのデリゲートのメモ。

class X
{
public :
    X()
    {
        // 共通の初期化処理
    }

    X( int value ) 
    {
        // 共通の初期化処理
        // 引数を使った追加の処理
    }
} ;

この例では、どちらのコンストラクターも、初期化処理は共通している。同じコードが重複するのは、バグの下である。こういう場合、C++03では、共通の処理をメンバー関数に移すことができる。

class X
{
private :
    void init() ;
public :
    X()
    {
        init() ;
    }

    X( int value ) 
    {
        init() ;
        // 引数を使った追加の処理
    }
} ;

しかし、この方法では、非staticデータメンバーをコンストラクター初期化子で初期化することはできない。それに、結局init関数を呼び出さなければならないことにはかわりない。

class X
{
private :
    int member ;
    void init() ;
public :
    X()
        : member(123) // 重複
    {
        init() ;
    }

    X( int value )
        : member(123) // 重複
    {
        init() ;
        // 引数を使った追加の処理
    }
} ;

コンストラクターを、別のコンストラクターに渡すことができればいいのだが・・・

C++0xでは、コンストラクターのデリゲートが提供されている。以下のように使う。

class X
{
private :
    int member ;
public :
    X()
        : member(123)
    {
        // 初期化処理
    }

    X( int value )
        : X() // コンストラクターのデリゲート
    {
        // 引数を使った追加の処理
    }
} ;

このとき、X::X(int)を、delegating constructorという。デリゲートするコンストラクターは、デリゲート先のコンストラクターを実行してから、コンストラクター本体の実行に移る。コンストラクターをデリゲートする際には、コンストラクター初期化子には、他のメンバーやクラス名を書くことはできない。

もちろん、デリゲートは何度でも行える。

class X
{
public :
    X() : X( 1 ) { std::cout << 1 ; }
    X( int a ) : X( a, 2 ) { std::cout << 2 ; }
    X( int a, int b ) : X( a, b, 3 ) { std::cout << 3 ; }
    X( int a, int b, int c ) { std::cout << 4 ; }
} ;

int main()
{
   X x ;
}

この例では、デフォルトコンストラクターはX::X(int)にデリゲートし、さらに、X::X(int,int)にデリゲートし、さらにX::X(int,int,int)にデリゲートされる。出力は、4321となる。

コンストラクターは、直接的、間接的に、自分自身に対して、デリゲートすることはできない。

class X
{
public :
    X() : X() { } // エラー、直接的な自分自身へのデリゲート

    // エラー、間接的な自分自身へのデリゲート
    X( int ) : X( 0.0 ) { }
    X( double ) : X( 0 ) { } 
} ;

残念ながら現時点で、コンストラクターのデリゲートを実装しているコンパイラーは存在しない。コンストラクターの継承と合わせて、是非とも欲しい機能だ。この機能がなくてはコーディングが困難な現実の問題があるというわけではないが、このような簡単な機能こそ、是非とも普及して欲しい。

2011-02-13

Carole Lieberman曰く、暴力ゲームがレイプを誘発する

Playing the Rape Card: ‘Media Psychiatrist’ Ratchets Up Anti-Videogame Rhetoric | GameLife | Wired.com

暴力ゲームはレイプを誘発させていると主張している。しかし、FBIの統計によると、1993年以降、強姦件数は激減しているというのに。

それに、レイプゲームが公然と売られている日本は最悪の国になっているはずだ。この女が日本のゲーム売り場に来たら卒倒するんじゃないだろうか。

しかし、名前がたまたまLiebermanだ。Postal 2でネタにされた、Joe Liebermanが思い起こされてならない。

2011-02-12

面白い英語

English pronunciation test

異なる発音なのに同じスペリング、または反対に、同じ発音なのに異なるスペリングの単語を組み込んだ英語の詩である。

これはなかなか面白い。この英語を正しく発音できるようになれば、かなり英語ができるようになったと実感できるだろう。まだ無理だ。

時代の流れには乗るしかないのだろうか

とうとう、このブログにTweetボタンを付けてしまった。Twitterによって提供されているAPIは非常に分かりやすく、すぐに実装できた。Twitterを使っていないため、テストしていないが、多分動くだろう。

相変わらず、Twitterを使う気はないが、ともかく、時代の流れには乗っておこうと思う。

何が時代の流れなのか。URLに対する評価方法である。歴史を振り返ってみよう。かつて、人気のURLを得る方法は、特定の個人や団体によって運営されているサイトを見るか、機械的に評価された順位を返す検索エンジンであった。当時は、ひたすらリンクを集めた個人の日記サイトが、大流行したものだ。その後、Googleが現れた。

近頃は、ソーシャルな評価方法が盛んだ。とくに、そのものズバリの目的に特化したサービスは、オンラインブックマークだ。おそらく最大手はDiggだろう。日本では、はてなブックマークになる。多くの人間に、手動でブックマークされるサイトは、何らかの理由で、価値が高いといえる。

しかし、最近、オンラインブックマークサービスが明らかに衰えてきている。かわりに盛り上がっているのは、Twitterに代表される、Micro Bloggingサービスによるリンクである。特に、Twitterへのポストの中に含まれるURLが、オンラインブックマークを駆逐しつつあるのだ。

私はどうしたわけか、オンラインブックマークにも、Twitterにも心ひかれるものがなかった。そのため、いまだにこの手のサービスを使ってはいない。ただし、利用はしている。はてなブックマークの注目エントリーを、RSSリーダーで購読すれば、今話題のURLの一覧が得られる。Twitterは、公式にはそのようなサービスがないものの、サードパーティによるサービスはある。Twitterの投稿からURLを抜き出して、各URLに対するリンク数を集計し、短期間で被リンクを大量に得たURLを教えてくれる。その人気のURLの一覧を一瞥して、タイトルと最初の数十文字を読めば、その記事が自分にとっても価値があるかどうか、すぐにわかる。これは、自分で価値のあるサイトを、何時間もかけて探し出す必要がないという点で、実に優れている。

もちろん、この方法により、一昔前の、怪しい輝きを放つ、当時のインターネットの魅力は失われてしまった。リンクをどんどんたどっていく楽しみは、もはや存在しない。現在は確実に昔より進歩しており、また、未来は現在よりさらに優れたものになると確信しており、実際に優れたものになっているのだが、やはり、当時を知る身としては、どこか寂しさも覚えるものだ。

思うに、私には、新しいもの好きの気質があるのではないかと思う。それも、ただ新しいだけではなく、今までにない新しさを好む。大衆化してしまったものには、あまり興味を示さない。

そこでだ。現在、私の食指の動く「何か」が見当たらない。動画サイトもはや大衆化してしまったし、生放送でストリーミングできるということも、所詮は動画サイトの延長線上にあるに過ぎない。ゲームはすっかり大規模化してしまって、逆につまらない。オンラインゲームは、もはや死んだコンテンツである。無料モバイルゲーム? 笑わせるな。小説はつまらないし、漫画も、ムダヅモ無き改革、角刈りすずめなどの一部を除けば、てんでダメだ。アニメなどは見る価値もない。

何かこれまでにない、既存の枠組みを超えた、新しい仕組みが欲しい。

自分で作るというのは、どうも面白くない。私は物事を学ぶのは好きだが、実際にその知識を活用して、何か革新的なものを創りだそうという意欲に欠ける。第一、革新的な物を発明するにしたって、その労力の大部分は、単調な実装作業に費やされるのだ。私はクリエイターではなく、オブザーバーになりたいのだ。

追記:ところで、いま注目しているものは、実はある。電子書籍だ。日本では、版組の複雑さから、若干の遅れがあるかもしれないが、いずれ、紙の本は駆逐されるだろうと考えている。今執筆中のC++0xの参考書も、いろいろと思うところがある次第である。

2011-02-11

左右対称の顔

人間の顔は、左右非対称である。ではもし、型側を反転させて、左右対称の顔を作ったらどうなるのか。

Echoism Faces | Crack Two

なかなか興味深い。

C++の雑学

C++の、特に知らなくても問題ない知識。

virtual関数のデストラクターをもつクラスの、deallocation functionがdeleted定義されていたり、名前が曖昧である場合、エラーとなる。

struct X
{
    virtual ~X() { } // OK、グローバルスコープのoperator deleteが発見される
} ;

struct Y
{
    virtual ~Y() { } // エラー、operator deleteはdeleted定義されている。
    void operator delete( void * ptr ) = delete ;
} ;

これは、クラスYのvirtualなデストラクターを定義した時点でエラーになる。たとえ、クラスYのオブジェクトをnew、deleteしていなくても、ましてや、プログラム中でクラスYのオブジェクトを使っていなかったとしても、関係はない。デストラクタの定義の時点でのエラーである。

これは、デストラクターがvirtual関数である動的な型をもつオブジェクトは、かならず、delete式に渡せるということを保証するための仕様である。

メンバー関数としてのoperator deleteのオーバーロード関数は、staticメンバー関数である。つまり、virtual関数にはできない。ただし、デストラクターがvirtual関数の場合、operator deleteも動的に呼び出される。

struct Base
{
    // staticメンバー関数
    void * operator new( std::size_t size ) { return ::operator new(size) ; }
    void operator delete( void * ptr ) { ::operator delete( ptr ) ;}
} ;

struct Derived : Base
{
    // Baseのメンバーを隠す
    void * operator new( std::size_t size ) { return ::operator new(size) ; }
    void operator delete( void * ptr ) { ::operator delete( ptr ) ; }
} ; 

int main()
{
    Base * ptr = new Derived() ;
    delete ptr ; // Base::operator deleteが呼ばれる
} 

なぜならば、呼び出すべきoperator deleteは静的に決定されるからだ。

もし、クラスがvirtual関数のデストラクターを持っていた場合、delete式では、動的な方に応じて、deallocation functionが実行時に選ばれる。

struct Base
{
    // staticメンバー関数
    void * operator new( std::size_t size ) { return ::operator new(size) ; }
    void operator delete( void * ptr ) { ::operator delete( ptr ) ; }
    virtual ~Base() { }
} ;

struct Derived : Base
{
    // Baseのメンバーを隠す
    void * operator new( std::size_t size ) { return ::operator new(size) ; }
    void operator delete( void * ptr ) { ::operator delete( ptr ) ; }

    // 暗黙のデストラクターはvirtual関数になる
} ; 

int main()
{
    Base * ptr = new Derived() ;
    delete ptr ; // Derived::operator deleteが呼ばれる
} 

ブロックスコープ内の宣言は、外側のスコープの名前を隠す。これは、関数にも適用される。

void f(int) { }

int main()
{
    void f() ; // ブロックスコープ内の関数の前方宣言、void f(int)を隠す

    f( 0 ) ; // エラー、void f(int)は見つからない
}

void f() { }

ブロックスコープでは、関数宣言を行わないほうがいいだろう。もっとも、ブロックスコープで関数宣言ができるということを知っているC++ユーザーの方が少数派かもしれないが。

2011-02-10

カタンを3D印刷するのは合法か?

Is it legal to print Settlers of Catan tiles on a 3D printer? - Boing Boing
3D game pieces by Sublime - Thingiverse

Settlers of Catan(カタン)というドイツ産のボードゲームがある。Klaus Teuberというドイツ人によって考案された。興味深いことに、面白いボードゲームやカードゲームはたいてい、ドイツ製である。ドイツには、何かこのような遊びを生み出す土壌があるのかもしれない。

それはさておき、Thingiverse - Digital Designs for Physical Objectsというサイトで、Sublimeというユーザーが、カタンのボード、タイル、チップ一式の3Dデータを公開している。目的としては、3Dプリンターで成型するためである。

さて、これは合法であろうか、というのが問題だ。

カタンは著作権によって守られている。ただし、カタン全体が著作権の対象になるわけではない。タイルの上に印刷されている画像には、著作権がある。画像は著作権保護の対象になるので、これは当然だ。では、タイルやチップの造形は、著作権保護されているのだろうか。もし仮に著作権があったとしても、かなり制限されたものになるだろう。カタンのチップの造形は、あまりにも汎用的すぎる。例えば、道は単なる直方体だし、家の形も、あまりにも単純だ。

著作権は、タイルの造形に適用されない。また、ゲームのルールは、著作権保護の対象にならない。著作権はアイディアには適用されない。著作権は表現に適用される。

してみれば、3Dプリンターでカタンのボード、タイル、チップを造形するのは、合法であると言える。

2011-02-09

牛乳の値段

日本では、低脂肪乳の値段が安い。脂肪を減らしていない通常の牛乳は、結構高い。価格差は、倍ぐらいあると思われる。

ところが、海外では事情が異なるらしい。牛乳と低脂肪乳の値段はほとんど同じか、むしろ低脂肪乳の方が高くなることすらあるのだとか。

たまたま、クリーム (食品) - Wikipediaを読んで知った次第。ためしに外人に聞いてみると、確かに日本に来て、牛乳と低脂肪乳の価格差に驚いたとのこと。ドイツでは、低脂肪乳の方が安いといえば安いが、11円ぐらいしか違わないということであった。

2011-02-08

Haskellを学ぼう

Haskellを学ぼうと真剣にかんがえている。クイックソートの例がすばらしい。

2011-02-07

学校で習う減算記号は左結合か

(-)はassociativityを満たさないのにa-b-cみたいに括弧を省略して書いちゃうのが習慣になってるのはどうなんだろう。小学校の頃から今まで宿題やテストやレポートの中でも指摘されたことが無い気がする。

Twitter / 梶本裕介

左結合だと仮定してると言われたことも無い気がする。忘れてるだけかもしれないけど。

Twitter / 梶本裕介

そういえばそうだ。減算記号は、結合法則(Associativity)と交換法則(Commutativity)を満たさない。しかし、私は小学校の算数で引き算を習うとき、左結合(Left-associative)かつAnticommutativityであると習った覚えはない。

しかし調べてみると、結合法則、交換法則、分配法則(Distributivity)は、小4か小5で習うらしい。うーむ、たしかに私は数学が苦手な方ではあったが、交換法則と分配法則は習った記憶がある。しかし、結合法則だけは、しっかり習った覚えがないし、プログラミングを始めるまで、演算子の結合法則を気にしたことがない。「左から右に計算するんだよー」と言われたことがあっただろうか。例えあったにしても、やはり、交換法則や分配法則ほど、しっかりと汎用的に教わった覚えがない。

ともかく、コレをきっかけに、CommutativityとDistributivityという英単語を学ぶことができた。

2011-02-05

ドナルド・マクドナルド、誘拐さる

フィンランドで、ドナルドが誘拐されたらしい。犯行声明がYouTubeに上がっている。

どうやら、ハンバーガー信者の仕業らしい。質問に答えなければ、ドナルドを処刑すると言っている。誠意を持って答えたならば、より多くのバーガーを買ってやるのだとか。

フィンランド人は理解出来ない。

unique_ptrの実装は意外と面倒だ

朝早く目が覚めてしまったので、朝飯前に何かコーディングすることにした。何をコーディングするか。できればメタプログラミングがしたい。そうだ、unique_ptrはどうだろう。たしか、unique_ptrのnested typeであるpointerは、メタプログラミングが必須だったはずだ。

というわけで、さっそく、unique_ptrの実装にとりかかった。しかし、unique_ptrの実装は、意外と面倒だった。

pointerは簡単なのだが、面倒なのは、ポインターとデリーターの両方を仮引数に取るコンストラクターだ。これは、難しいというわけではないが、相当に面倒だ。

しかし、わざわざここまでして、lvalueリファレンス型のデリーターをサポートする必要があるのだろうか。デリーターは、どう考えても初心者がたやすく使いこなせるとは思えない。

2011-02-04

メガネがないと不便だ

この前、メガネを亡くしてしまった。警察とタクシー会社に連絡してみたものの、やはり出てきそうにない。

裸眼でも、日常生活に問題はないのだが、画面の字が読みづらいのだけは困る。

しかし、まともなメガネをつくろうとすると、3万はかかる。やれやれ、何につけても金か。

C++の参考書も、あまり大胆に進められない。Madrid会議で、また大幅な変更が来そうだからだ。特に、range-based forにおけるイテレーターの取得方法が、ADLベースではなく、traitsベースになる予定なので、半分以上書き直しになるだろう。去年の参考書の執筆は、新しいドラフトが出るたびに修正する必要があるので、3歩進んで2歩下がるような状態だった。

一応、次のMadrid会議で、変更は最後になるはずだ。その後は、typoの修正ぐらいしか行われないはずだ。予定通りならばだ。さすがに、もうこれ以上引き伸ばして欲しくはない。

MSがChrome用にH.264再生プラグインを提供

Greater Interoperability for Windows Customers With HTML5 Video - Interoperability @ Microsoft - Site Home - MSDN Blogs

もはや政治だな。動画圧縮規格の統一は、いまだにできていないのだから、おそらくまだ当分はできないだろう。

ちなみに、現在主流の画像の規格は、あまりにも古臭い。例えば、H.264のイントラフレームは、jpegよりも高性能である。ただし、いまさら画像のサイズが半分ぐらいになったところで、誰も喜ばないし、新たなフォーマットのサポートは面倒なので、誰もやろうとしないだけだ。Googleが、VP8のイントラフレームを、新しい画像圧縮規格として提案していたが、多分流行らないだろうと思う。

2011-02-03

最高に面白いゲーム

Duty Calls

Duty Calls公式サイトから無料で落とせる。Bulletstormの広告用に作られたゲームだ。So Real.

2011-02-01

Intelの最新チップセットに深刻な不具合

Intel Identifies Chipset Design Error, Implementing Solution

Sandy Bridge用の、Intelの最新チップセットの設計に不具合が発見された。具体的な問題は公開されていないが、SATAが影響を受け、時間経過とともに、HDDやSSDなどの速度低下、使用不可などが起こるらしい。BIOS(今はEFIか?)のアップデートでは対応できないらしく、交換しなければならないらしい。

おそらく、今、日本にいるSandy Bridgeユーザーは、軒並み該当するのではないかと思う。マザーボードの交換が必要になるというのは、非常に面倒だ。