Suicaの力

Suicaに蓄えられている料金は、プリペイド…とかそういうのではなく、あれは、Suica Force(Suicaの力)と、呼ばれるいわばエーテルのようなものであり、Suicaによる支払いは、このSuica Forceを消費することで行われている。
これは、Suicaを利用したときに、「SF利用」(SF = Suica Force)と表示されることからも確認できる。

プログラミングのための線形代数

最近本積みすぎ。
いつだか覚えてないくらいの昔にさかいさんとこで勧められてたような気がしてて(気のせいだったらすいません)ずっと、頭の片隅に残ってたのだけど、なんか図書館で見かけたのでパラパラ読んでみた。


なるほどー。けっこう面白い。
数学の人モドキの人(どんな人?)とか、数学あんまり好きじゃないけど、なんか必要になってしまった人向けなのかなー。「ややこしい定義はいいから、結局行列ってなんやねん」っていうような人向け。
本屋で見かけたら、「はじめに」と、「総まとめ」(最初にある)を読んでみて、肌にあいそうだったら読んでみるとよいのではないかと思う。本物の数学のひとからみたらこういうのは冗長なのかもしれんね。


「プログラミングのための」と、題名に入ってるけど、プログラミングはほとんど…というか、表示用にちょろっと使ってるだけで、説明には全く出てこないのだけど、いったいどういう事情でタイトルに「プログラミング」って入ったんだろうか謎。

あなたのほしいものはオブジェクト指向ですか?それとも…

最近Linux気味、といっても、Linuxをよく使ってるとかではなくて、なんか、勉強してる範囲にポータビリティが無いとか、そういう方向でLinux気味。


そういえば、kvm(カーネル仮想マシンのアレね)がなんかできないかなー、とか考える。あれって要するに、ユーザ空間MMUが使えるっていうことだよなー。
ここで謎が。カーネルと、ユーザプロセスと、ユーザプロセスの上で動く仮想マシンとかあって、カーネルと、仮想マシンではMMUが使えるのに、どうして真ん中のユーザプロセスはMMUを使えないのでしょうか?いや、まあ、ファイルのマッピングとか駆使すれば、MMUみたいなことはできるけど。
ハードウェア支援の仮想化(VTとかのアレね)機能ってつまり、二段MMUってことでいいのかなー。つーか、一段MMUでも一応仮想化してあると言ってもよいのではないだろうか。VTとかのアレが搭載されたことで仮想化を実現とかいうのは変で、アレは、「多段仮想化」とでもいうべきなんではなかろうか。


まあ、それはいいか。kvmとかはあんまり関係ないのだけど、最近の自分トレンドは、ラッパ使わずに、いかにレレイヤを薄くして書けるかどうか、というようなところで、最近Linuxよりになってるのだった。
なんか、まあ、そういう話。オブジェクト指向を捨てられるか模索中とかの話。(まだできてないけど)


ふつう、何かいろんなものを抽象化をする、といった場合、

  1. ある「何か」が持ってるインターフェースは何かを調査
  2. よく似たインターフェースのやつを同じものとみなす
  3. 同じものとみなしたオブジェクトのインターフェースに対して処理を行う
  4. いろいろなものが同じように処理できました!万歳!

というような手順をたどると思う。
今回は、この手順を「オブジェクト指向的な抽象化」とでも呼んでおこうか。略して「オ抽化」(それはない)。
オブジェクト指向っつーと、まあ、「みんな(言うことが)違って、みんないい」、なんだけど、ここでも、「オレオレオブジェクト指向」を持ち出し、「共通のインターフェースを持つものを同一視する」というやりかたをオブジェクト指向的なやりかたとする!するったらする!


で、まあそういうオブジェクト指向なんだけど、昔っからどうも、このやりかたには、なんともいえない気持ち悪さを感じていた。というのは、2.の「同じものとみなす」という部分で、切り捨てているものがあるからだ。
オブジェクト指向的なやりかたでは、インターフェースは、最小公倍数的なものになってしまう。「AがインターフェースXとY、BがインターフェースYとZを持っている」と、いうような状況の場合、AとBで処理を共通化するには、「インターフェースYを持ってるクラスC」というのを考えて、「A is a C」「B is a C」となる。けど、ここでインターフェースXとインターフェースZはどこへ行ってしまうのん?


このことは、実際に問題を起こすこともあると思う。たとえば、「ハードウェアアクセラレーション転送付きヴィデオカード」と「ただのフレームバッファだけのびでおかーど」があったとしよう。これを同一視することができますか?
おそらく、「ハード転送付き」のほうは、フレームバッファ機能も付いてるだろうから(いや、そういうもんだとして)ここで、「フレームバッファを持ってるものをビデオカードとする」とすればよい?良いの?そんな、せっかくハード転送を実装したハード屋さんと、大量に詰め込まれたマスクパターンの運命やいかに!?彼らの努力は無駄になってしまったのでした。


彼らの努力を無駄にしないためにもハード転送は生かしてあげるべきでしょう。そこで、「ハードBitBltが付いてるのをビデオカードとする」って、そんなんあかんよ!そんなことしたら、フレームバッファだけのビデオカードビデオカードとみなされないやん?このように、「AはAでない」というのを、「is not a関係」と呼び、ここでは、「Video card is not a video card」という、哲学的な問題になるのだった。(そういえばさっきアルコール摂取したのを思い出した)


よーするに、「共通のインターフェースを持つものを同一視する」というやりかたでは、「性能の劣化」か「is not a関係」を生じさせる。あなたの手元にある「ポータブル」を謳っているライブラリはどこで「性能の劣化」を発生させているだろうか?どこで、「is not a関係」を生じさせているだろうか?
たとえば、Linuxのfutexには、「ファイルディスクリプタを取り出して、selectとかepollとかで待機」できる、という機能がある。ネットワークの到着とか、デバイスの完了と一緒に、mutexの空きを監視することができる、スレッドの数を減らしたいときには有効な場合もあるかもしれない。


しかし、pthreadのmutexにはそんな機能はありませんね。さて、この「ファイルディスクリプタを取り出して」という機能はどこへ行ってしまったのでしょう?pthreadのmutexはfutexで実装されているのに?(このへんが前回書きたかった話その1)


まあ、要するになんだかんだ。じゃあ、低レベルなAPIをがしがし使っていけばよいのかというと、そんなことしてたら、移植性もへったくれも無いわけで、じゃあ、どうすればよいんだよ。
低レベルな処理っていうのは、低レベルな部分と一番ユーザに近い部分とで必要になってる感がある。
低レベルな部分は当たり前として、ユーザに近い部分、は、

  • 効率とかの問題
  • UIの統一とかの問題
  • そもそも処理が低レベル(管理ツールとか、Windowsだと、シェル拡張とか)

とか、そういう理由で、OS依存の機能が必要になる場面があるような感じ。


ポータブルなライブラリだと、そういうのができない。無理やり合わせると、ライブラリ自体の移植性が下がってしまう。重要なのは、バランス感覚…なのだろうか?


これの問題は、「似たようなインターフェースのものを同一視する」というところから来てるように思われる。同じインターフェースを持った瞬間に、同じものとみなされる。そして、同じものと見なさないといけない。
だがちょっと待ってほしい、「同じものとみなす」必要があるのだろうか?「同一のインターフェースを持っている」という制限だけで十分で、別に「is a関係」を持つ必要は無いはず。そこらへんできっとおかしいことが起こってるはずだ。


考え方を変えよう!「同じインターフェースを持つ」ということは、「同じものである」ということではない!全く別の物がたまたま同じインターフェースを持っているだけ、ということは十分ありうる!
オブジェクト指向的世界では、関心ごとは、次のように分かれた。

  • アルゴリズムがどういうインターフェースを必要とするか
  • オブジェクトはどういうインターフェースを持ってるか

しかし、この考え方を変えよう!「同じインターフェースを持つ」ことが「同じものである」ということを意味しない世界では、関心ごとは次のように分かれる。

  • アルゴリズムがどういうインターフェースを必要とするか
  • 構造はどんなふうになってるか
  • 構造があるインターフェースを持つというのはどういうことか(ある操作が可能である、とは、どういうことか)

なんかうまく文章にできないな…まあ、伝わって!「構造」「アルゴリズム」「構造とインターフェースのマップ」の三つに分かれるの!


これは言語の機能としては、Haskellでいう型クラス、C++のテンプレートでも頑張ればできる、あと前聞いた話だと、C++0xの新機能がまさに、そういう機能だったはず(id:Cryoliteさん、その節はどうもありがとうございました。大変参考になりました(四ヶ月越しで礼を述べる奴))。
とはいってもまだ上のスタイルでちゃんとしたコード書いてないので、ほんとにうまくいくのかどうか実験中なのだけど。次回、アルコール摂取したときに続く。(多分。続かないかも)
(前回のnaname.tar.gzとか、その前のrr.tar.gzとかが実験中のコードです)