2012年12月22日土曜日

LispでOSを書く

(このエントリは、Lisp Advent Calendar 2012 の22日目である)

ELIS復活祭のとき、ELISのTCP/IPプロトコルスタックを書いたという方とお話する機会があった。ELISのプロトコルスタックはもちろんLispで書かれていた。その方がおっしゃるには、「C言語はよい。BSDからソースコードを持ってくればいいのだから。しかし、Lispで書かれたプロトコルスタックなどなかった。自分で書くしかなかった」ということだった。それにしても、LispでOSを書くというのは、いったいどんな感じなのだろう?

OS記述言語としてのLisp

UnixがCで書かれて以来、OSは、伝統的にCとその派生言語で書かれることになった。BSDやLinuxを含むUnix-likeなシステムはもちろんCで書かれている。Windows NTはC++を使っている。BeOSもC++で書いたし、MacOS XはObjective-Cを使っているのかもしれない。もしかすると、IBMのメインフレームなどでは事情が異なるのかもしれない。

Cとその仲間たちは、いわゆる高級言語の中でも抽象化のスペクトルのだいぶ下の方に位置している。つまり、ビットを操作するような処理が得意なのだ。だから、デバイスのレジスタを直接叩くような処理はCの得意とするところだ。

OSを構成するサブシステムの中でも、プロトコルスタックやファイルシステムは、デバイスを叩くというよりは、ある種のロジックを実装するものだ。80年代から90年代にかけて研究されたマイクロカーネルでは、これらのサブシステムはユーザプロセスとして実現されていた。

ソフトウェア工学の言葉を使うなら、OSのコア(マイクロカーネル)はデバイスへアクセスする「メカニズム」を提供する。上位のサブシステムは、そのデバイスをどのように使うか(例えば、ファイルシステムをどう構成するか)という「ポリシー」を実装する。

複雑なロジックを実装するためには、できるだけ抽象化のレベルの高い言語を使うべきだ。そして、もっとも抽象化のレベルの高い言語(のひとつ)はLispである。したがって、OSのサブシステムも、ある部分はELISのようにLispで書いてもいいはずだ。

FUSE + libfuse + Gauche + c-wrapper

LispでOSのサブシステムを書くというのがどんな感じなのか、試してみる方法をご紹介したい。私はCommon LispよりもSchemeの方が慣れているので、Gaucheを使うことにしよう。

1から新しいOSを設計するのは、楽しいかもしれないが時間もかかる。Linuxには、FUSE(Filesystem in Userspace)という、ファイルシステムをユーザ空間で実装するための仕組みがある。この仕組みを使って、Gaucheでファイルシステムを書いてみたい。

FUSEにつて簡単に説明しよう。Linuxカーネルは複数のファイルシステムを持っている。ext3, ext4, btrfsなどなどだ。それぞれのファイルシステムの開発者のために、カーネルとファイルシステムとの間に標準的なインタフェースが決まっている。このインタフェースをユーザ空間からアクセスできるようにする仕組みがFUSEだ。

最近のLinuxカーネルなら、FUSEは標準で組み込まれている。/dev/fuseがカーネルへのインタフェースだ。基本的には、普通のファイルアクセスのシステムコールを使って/dev/fuseを操作すればよいのだが、これをもう少し簡単に行うためのライブラリとして、libfuseがある。

libfuseはCのライブラリだ。libfuseをGaucheで使うにはCへのバインディングを書けばよいのだが、もっと簡単な方法は…そう、魔法のc-wrapperである。

hellofs (The Hello Filesystem)

ストレージを操作する本物のファイルシステムではなく(これは大仕事だ)、偽物のファイルシステム(Pseudo Filesystem)を実装してみる。これは、/procや/sysの一種と考えてよい。このファイルシステムは、FUSEのサンプルプログラムをほぼそのままSchemeで書きなおしたものだ(若干の手抜きをしたので、あまりいい例ではないかもしれない)。
#!/usr/bin/env gosh
# hellofs.scm (The Hello Filesystem)

(use gauche.uvector)
(use c-wrapper)

(c-load "fuse.h"
        :cppflags "-DFUSE_USE_VERSION=26"
        :cppflags-cmd "pkg-config --cflags fuse"
        :import '(fuse_operations
                  fuse_main_compat2
                  fuse_main
                  NULL)
        )
(c-load "stdio.h")
(c-load "string.h")
(c-load "errno.h")
(c-load "fcntl.h")
(c-load-library "libfuse")

(define hello-path "/hello")
(define hello-str "Hello world!\n")

(define (hello-getattr path stbuf)
  (memset stbuf 0 (c-sizeof (c-struct 'stat)))
  (cond ((string=? (cast  path) "/")
         (set! (ref stbuf 'st_mode) (logior S_IFDIR #o755))
         (set! (ref stbuf 'st_nlink) 2)
         0)
        ((string=? (cast  path) hello-path)
         (set! (ref stbuf 'st_mode) (logior S_IFREG #o444))
         (set! (ref stbuf 'st_nlink) 1)
         (set! (ref stbuf 'st_size) (string-length hello-str))
         0)
        (else (- ENOENT))))

(define (hello-readdir path buf filler offset fi)
  (if (not (string=? (cast  path) "/"))
      (- ENOENT)
      (begin (filler buf "." NULL 0)
             (filler buf ".." NULL 0)
             (filler buf ((#/^\/(.*)$/ hello-path) 1) NULL 0)
             0)))
      
(define (hello-open path fi)
  (if (not (string=? (cast  path) hello-path))
      (- ENOENT)
      (if (not (= (logand (ref fi 'flags) 3) O_RDONLY))
          (- EACCESS)
          0)))

(define (hello-read path buf size offset fi)
  (memcpy buf hello-str (string-length hello-str))
  (string-length hello-str))

(define hello-operators (make (c-struct 'fuse_operations)))

(set! (ref hello-operators 'getattr) hello-getattr)
(set! (ref hello-operators 'readdir) hello-readdir)
(set! (ref hello-operators 'open) hello-open)
(set! (ref hello-operators 'read) hello-read)

(define (main args)
  (fuse_main (length args)
             args
             (ptr hello-operators)
             NULL
             ))
マウントすると、マウントポイントにhelloというファイルが現れる。このファイルにはお馴染みの文字列が格納されている。
# mkdir /tmp/hello
# ./hellofs.scm /tmp/hello -d -s
...
# ls /tmp/hello
hello
# cat /tmp/hello/hello
Hello world!
マウントするときに、シングルスレッドモード(-sオプション)を指定することに注意して欲しい。libfuseは、その中で新たなスレッドを生成する。このスレッドはGaucheのスレッドではないので、この中からSchemeの関数をコールバックすることはできない。

FUSEを使ってストレージを操作するようなファイルシステムを作りたいのなら、デバイスノードを読み書きすればよい。また、ユーザ空間でできることは何でもできる。例えば、EvernoteやGoogle Driveにアクセスするようなファイルシステムを作ることもできるはずだ。

* * * 

OSのカーネルはますます大きく複雑になっている。Unixの第6版のソースコードは、印刷したものをブリーフケースで楽に持ち歩くことができるほど小さかった。今日のLinuxのソースコードを印刷して持ち歩くことは、不可能ではないが紙の無駄である。

 Unix第6版の時代からプログラミング言語の世界は大きく進歩した(もちろんLispはUnix第6版の時代から存在したのだが)。ところが、今日のOS開発者は、これら進歩的プログラミング言語の恩恵に与っていない。 

そろそろ、OS開発にも、次の世代のプログラミング言語を使ってもよいのではないかと思う。ELISは商業的には成功しなかった。しかし、ELISの開発過程で多くの知識が蓄積されたはずだ。(非常に失礼な言い方だが)ELISの開発者がまだ生きている今こそ、そのチャンスである(失礼しました)。

2012年12月15日土曜日

豊かな社会

私の母校は、工学部のみの小さな単科大学だ。工学部のみの大学であっても、いわゆる一般教養の授業がある。そのための常勤の教員もいる。特に人文社会系の講義のことを、私たちは単に「社会系」と呼んでいた。

私たちにとって、「社会系」の授業は悩みの種だった。これらの単位が、進級のための条件になっていたからだ。私たちは、エンジニアリングを学ぶために大学へ入った。そのために授業料も払った。確かに西洋思想史は興味深いかもしれないが、エンジニアリングとの接点を見出すことはできなかった。

大人になってから、「あの時もっと勉強しておけばよかった」と思わない人はいない。私もその例に漏れない。30歳を過ぎて思うには、もっと真面目に「社会系」の勉強をしておけばよかったのである。

実は、エンジニアリングと「社会系」は密接に関係していた。なぜなら、エンジニアリングとは、社会を豊かにする方法だからだ。学生時代の私は、エンジニアリングの方法論にばかり捕らわれ、その目的が見えていなかった。

19世紀の経済学者は未来を悲観した。保守主義者もマルクス主義者も、産業革命の行き着く先はユートピアではないという点では意見が一致していた。しかるに、二つの世界大戦を挟み、ヨーロッパ、アメリカ、日本を含む国々には、豊かな社会が誕生した。これらの国々の共通点は、エンジニアがたくさん住んでいるということだ。

失われた10年だか20年だか知らないが、日本企業が不調である。パナソニックが赤字という。シャープも赤字という。任天堂でさえ赤字という。日本の製造業は軒並み「オワコン」と言われる。どうしてしまったか?

日本の製造業も、学生時代の私と同様、方法論にばかり捕らわれ、社会を豊かにするという当たり前の目的が見えなくなっているように思う。私も、ついこの間まで日本の製造業に身をおいていたのでよくわかる。もっとも、彼らが捕らわれている方法論は、経営学のそれであるようだ。

何をもって社会の豊かさとするかは難しい。今年のはじめに、ロボット掃除機のルンバを買った。まるでSFの世界にいるようだった。ハインラインの『夏への扉』に出てくる家事ロボットのようだった。私の生活は豊かになった。

今年ももう終わりだ。毎年、その年のテーマを設定することにしている。来年のテーマは「社会系」にしようと思っている。今年のうちに、古本屋行きを免れた教科書を発掘しなければならない。

2012年12月13日木曜日

『オペレーティングシステム 設計と実装 第3版』を読んだ

1953年、ワトソンとクリックによりDNAの二重らせん構造が発見されたとき、生命には神がかり的なものは何もないことが明らかとなった。以来、生命をめぐる神学上の諸々の問題は、科学とエンジニアリングの問題となった。本書を読めば、読者は、オペレーティングシステムのカーネルについて同じ発見をすることになる。

本書は、私の家の積読本コーナーにもう長いこと置かれていた。本書の原書が出版されたのが2005年。本書は、その翻訳として2007年に出版された。翻訳が出版されてすぐに手に入れたのだが、ずっと読めずにいた。何度か読もうと挑戦したものの、途中で挫折してしまっていた。読書会にも参加したが、途中で脱落してしまった。

今回、何度目かの挑戦で、ようやく読み終えることができた。実は、この本を読むのには、少々コツがあったのだ。本書は、1000ページを超える大著である上、本の後ろ半分がソースコードという、かなり特殊な本である。

本書では、カーネル、デバイスドライバ、メモリ管理、ファイルシステムのそれぞれのオペレーティングシステムのコンポーネントについて、それぞれひとつの章が割り当てられている。それぞれの章は、以下の順番で構成されている:
  1. オペレーティングシステム理論
  2. MINIXによる実装の概要
  3. MINIXのソースコード解説
  4. ソースコード
ただし、ソースコードは、すべてまとめて本の後ろ半分に付録となっている。1と2は普通に(つまりシーケンシャルに)読むことができる。問題は、3と4を如何に読むかである。

今まで私がどうやって読もうとしていたかというと、3と4を逐一対応付けながら読もうとしていた。つまり、ソースコードをちょっと読んで、該当する解説を読み、そしてまたソースコードに戻るという具合だ。

この読み方は、非常にしんどい。本文とソースコードとを、頻繁に行ったり来たりしなければならないからだ。すなわち、コンテキストスイッチのオーバーヘッドが大きい。

コツは、ソースコードを先に読むことだ。解説を読まずに、まず、ソースコードを読めるところまで読む。多少わからないところがあっても、本文で解説されていることを期待して、どんどん読み進む。ソースコードをある程度まとまった量(私には1ファイル分くらいが丁度よかった)読んだら、解説に目を通す。すると、自分の理解が正しかったり、あるいは間違っていたことがわかる。

本書は、Linux誕生のきっかけとなった事で有名だ。しかし、オペレーティングシステムの教科書としても非常によい本である。本書の、オペレーティングシステムのソースコードを読むことで学ぶというアプローチは、オペレーティングシステムの真の姿を明らかにする。

著者のTanenbaumは述べている:
実際のOSの真の姿は、知性的な興奮に満ちたものとは程遠く、マイナーな雑用を行うコードの集まりである。しかし、このようなコードこそシステムの可用性を向上するためには非常に重要なのである。(p.637)
また、その少しあとで、こうも述べている:
優れたシステムと平凡なシステムの違いは、スケジューリングアルゴリズムのすばらしさではなく、細部まで正確に仕上げる配慮にあるのである。(p.637)
私自身の学生時代を思い返してみると、オペレーティングシステムの授業では、スケジューリングやページングのアルゴリズムばかりが印象に残っている。そして、オペレーティングシステムとは、普通のプログラムとはどこか異なる、摩訶不思議な、何か神がかったものという印象を持ってしまっていた。

ワトソンとクリック以来、生命は単なる有機化合物の塊となった。本書が明らかにしたように、オペレーティングシステムも、単なるCプログラムの塊に過ぎないのだ。

2012年11月17日土曜日

Unixの自由

TechLION vol.10に行ってきた。村井純さんのお話を聞いてきた。村井純さんといえば、Unixとインターネットを創った男だ。もう古い本だが、村井純さんは、Bachの『UNIXカーネルの設計』の翻訳者でもある。この本は、私が初めて読んだカーネルの本だ。この本でOSとは何かを学び、Unixとは何かを学んだ。今、私がLinuxの仕事をしているのも、この本のおかげだ。

今や、Unixだらけだ。Linuxであり、BSDである。Solarisであり、MacOS Xである。WndowsですらPOSIX APIを備えている。IBMのメインフレームでもLinuxを使う顧客がいるという。スーパーコンピュータもそうだ。Androidもそうだ。どうしてこうなってしまったか?

村井純さんが学生の頃、最初に教授に指示された仕事が、DECのPDP-11用OSであるRSX-11の逆アセンブルであったという。もちろん手作業である。村井純さんは、この作業でOSを学んだという。

その後しばらくしてUnixが登場する。Unixの特徴には、ファイルによる抽象化がある。一見奇妙なfork/execモデルも特徴と言える。しかし、一番の特徴は、Cで書かれていること、そしてそのソースコードを読むことができるということだ。

村井純さんがおっしゃるには、Cで書かれたUnixは遅かったという。ハードウェアベンダーがカリカリにチューンしたOSにはとてもかなわなかったという。しかし、それでもUnixを選んだ。なぜなら、Unixには自由があったからだという。

あるソフトウェアが自由とはどういうことか? もっと単純で物質的な道具について、その自由を表明したら少し奇妙な印象を受けるだろう。例えば、「ハサミは自由である」と言ってみたらどうか?

もちろん、ハサミは自由だ。アナタは、ハサミを使って自由に紙を切ってよい。封筒を開けるのに使ってよい。お菓子の袋を開けるのにも使ってよい。ハサミの使用目的は「切る」ことだ。ハサミが自由であるとは、アナタは何を切ってもよいということだ。もちろん、夜道で人を切りつけてはダメだ。犯罪行為は、道具に関わる自由の例外である。

ソフトウェアも道具だ。Unixにもハサミと同様の自由を認めてよいはずだ。つまり、Unixの使用目的について、アナタは自由である。問題は、Unixの使用目的とは何かということだ。UnixはOSなので、OS一般の使用目的と言い換えてもよい。

OSの教科書をめくると、OSには2つの機能があると書いてある。リソースの管理と、APIの提供だ。これらの機能は、アプリケーションプログラムを書きやすくするためにある。ナマのハードウェアを触るのはしんどい。

したがって、OSの使用目的とは、その上でアプリケーションプログラムを書いて動作させることと言っていいだろう。つまり、アナタは、そのOSで、自由にアプリケーションを書いたり動作させてよい。

どこかで何かを間違ったのだろうか? RSX-11上でアプリケーションプログラムを書いたり動作させることに関して、DECは自由を制限していたのだろうか? そんなはずはないと思う。村井純さんはどの自由のことを言ったのだろう?

帰りの電車の中で、思うところがあってRaymondの『The Art of Unix Programming』を読み始めた(こういうときSafari Books Onlineは最高!!)。この本の、あるセクションのタイトルが目に止まった。それこそ、Unixに固有に認められる自由だった。すなわち、Raymondが言うことには、「Unix Is Fun to Hack」である。

Unixには、アプリケーションプログラムを書いたり動作させたりするというOS一般に認められる自由の他に、ハックする自由がある。ハックの対象は、Unixのカーネルの内部まで及ぶ。つまり、Unixは中身を調べて、場合によっては改造してもいいということだ。そのためには、高級言語で書かれていたほうがいい。

アプリケーションプログラマの中には、RSX-11を好む人もいただろう。Unixは遅いし、誰かのハックのおかげでクラッシュするかもしれない。しかし、多分ハッカーはUnixを好む。誰だって、RSX-11を逆アセンブルしたくはないだろうし、逆アセンブルしたとしてもRSX-11のハックは地下でやるしかない。

道具に関する自由というコンセプトは、アメリカの銃規制の問題を思い起こさせる。アメリカでは合法的に銃を所持することができる。しかし、銃は犯罪にも使われるため、アメリカ人の中には銃を規制したほうがよいと考える人もいる。

銃の使用目的は、何かを撃つことだ。つまり、銃の自由とは、アナタはその銃で何かを撃ってもよいということだ。もちろん、人を撃ったらダメだ。ハサミで人を切りつけては行けないのと同じだ。

銃規制に反対する人は、単に銃を奪われることだけでなく、自由を奪われることを恐れているのではないかと思う。逆に賛成派は、多少の不自由を受け入れればよりより社会になるよ、と言っている。

ハックする自由。なんだか当たり前の結論に至った。Richard Stallmanなんかが一生懸命主張しているのも、つまるところはハックする自由なのだろう。Linuxをはじめ、オープンソースのソフトウェアが普及したのもハックする自由があったからだ。結局みんなUnixの仲間なのだ。

2012年5月6日日曜日

リアルタイム・コンピューティングとカント主義

ミラクル・リナックスに入社してちょうど3ヶ月が経った。試用期間が終わり、正式(?)に採用となった。散々遅刻したのにクビにならなかったので、ほっとしている。これからはフレックスタイムが使えるので、大いに寝坊できるとうものだ。

4月末に、「実績レビュー」なるものがあった。社長以下各セクションのトップを集め、プレゼンを行い、この3ヶ月の仕事を見てもらって、継続して雇うかどうかを判断してもらおうというわけだ。これが、1時間も時間がとってあった。長い。

困ってしまった。私のプレゼンのスタイルは、「瞬発力で勝負」というものであって、せいぜい15分がいいところ。そもそも、1時間もしゃべる話題がない。うっかり口を滑らせて、「Linuxでリアルタイム・コンピューティングをやりたい」と言ってしまったところ、思いの外盛り上がった。

コンピューティングの世界で、「リアルタイム・コンピューティング」ほど誤解されている概念は無い。単に「レスポンスタイムが短い」という意味でリアルタイム・コンピューティングと言う人もいるし、「計算機内部の時間の流れと外部の時間の流れが同期している」という意味で言う人もいる。

私が思うに、「処理のデッドラインが設定されている」というのが、リアルタイム・コンピューティングの定義だ。デッドラインとは、その間に処理が終わって欲しいという時間である。デッドラインを過ぎる(デッドラインミス)と、計算結果の意味が失われる。リアルタイム・コンピューティング技術とは、いかにしてデッドラインを守るかという技術だ。

デッドラインミスが起きたときに何が起きるかはシステムによる。例えば、画像の乱れなど、一時的なパフォーマンスの低下として無視できる場合もある。飛行機の墜落や100億円の人工衛星が失われるなど、「大惨事」が起きるかも知れない。現実には、ほとんどのリアルタイム・システムは前者のグループに属する。ほとんどの場合、デッドラインミスは、単に無視できるか、上位のプロトコルでリカバリーできる。

一般的に、コンピューティングの世界では、パフォーマンスとは「速さ」だ。一方、リアルタイム・コンピューティングの世界では、パフォーマンスとは、あくまでも「デッドラインの尊守」である。計算が速いこととデッドラインの尊守は矛盾する概念ではない。しかし、イコールではない。

一般的なコンピューティングの世界にいる人には、この点をなかなか理解してもらえない。「リアルタイムだろうが何だろうが、速ければ文句ないだろう?」というわけだ。確かに文句はないのだが、それだけでは何か大事なものを見落としているような気がするのだ。

そこで、ひとつうまい説明を思いついた。すなわち、一般的なコンピューティングは、ベンサムの「功利主義」の世界である。一方、リアルタイム・コンピューティングは、「カント主義」の世界である。

功利主義やカント主義というのは、政治哲学の概念である。どうしてこんな比喩を思いついたかというと最近サンデル教授の本を読んだからなのだが、この喩えは、一般的なコンピューティングとリアルタイム・コンピューティングの違いをよく現していると思う。

時代的にはベンサムのほうが古い。ベンサムの功利主義は、最大多数の最大幸福とも呼ばれる。幸福最大原理である。ベンサムは、よりよい社会のためには、「効用」を最大化せよと説いた。効用とは、社会のすべての快楽を合計し、それから社会のすべての苦痛を引き算することで得られる。

ベンサムの視点でコンピューティングの世界を見てみよう。効用の定義は単純だ。効用とは「速さ」だ。すべての処理時間を合計し、それが最も短くなるようにすればよい。

コンピューティングにおける功利主義的技術の例として、キャッシュメモリがある。キャッシュメモリを使用すれば、全体の処理時間を短縮できる。しかし、個々のメモリアクセスに注目するならば、キャッシュミスが発生した場合、そのメモリアクセスの処理時間はわずかに延びる。すなわち、まずキャッシュを見にいき、そこに目的とするデータが無いならば、キャッシュを無効にし、さらにメインメモリを見にいく。この一連の処理の後、レジスタにデータがロードされる。しかし、全体としては、効用(速さ)は最大化(最小化)される。

さて、功利主義への批判は2つある。第1に、少数の意見が無視されることだ。第2に、そもそも論として、快楽や苦痛など人それぞれなのだから、それを「効用」なるある種のスカラー量に押しこむことができるのかということだ。

カントは、「人は皆尊敬されなければならない」とした。少数の意見を無視したり、人によってバラバラの価値観をひとつの尺度に押しこむことは、人々を尊敬しないことだとした。

カントの考えは難しい。尊敬とは何か? 尊敬を「デッドラインの尊守」と考えるならば、カント主義はリアルタイム・コンピューティングと似ているような気がする。少数の処理であれ、デッドラインは尊守されなければならない。プロセッサのパワーに対してタイトなデッドラインを設定する処理もあれば、余裕のあるデッドラインを設定する処理もある。いずれにせよ、デッドラインは尊守せねばならない。

再びキャッシュメモリについて考える。リアルタイム・コンピューティングにおいては、キャッシュミスによってキャッシュメモリの恩恵を受けられない処理があることは、それ自体では問題としない。問題は、キャッシュミスの予測が非常に難しいため、キャッシュミスを考慮した設計ができないことだ。予期せぬキャッシュミスは、予期せぬデッドラインミスを招くかも知れない。カントの目には、キャッシュメモリは非常にリスキーだ。

ベンサムもカントも理論家だ。しかし、多くの政治家は実務家である。現実の社会では、功利主義もカント主義も、どちらが優れているとは一概には言えない。実務家である政治家は、これらをうまく組み合わせ、最適のところでバランスするのである。

我々プログラマも実務家である。リアルタイム・コンピューティングをやっているからといって、例えばキャッシュメモリを排除してしまうのは惜しい。タイトなデッドラインに処理を押しこむのはそれ自体一苦労だし、上にも述べたように、たまのデッドラインミスであれば許容されることが多いという現実もある。

リアルタイム・コンピューティングの実務家としては、功利主義的技術とカント主義的技術をうまく組み合わせ、システムの仕様を睨みながら、最適のところでバランスするのである。


2012年4月28日土曜日

リアル本屋の楽しみ

亀有に引っ越してきて非常に不便なのが、近くに大きな本屋がないことだ。藤沢には、駅前にジュンク堂と有隣堂があり、まさに本屋戦争の様相を呈していた。亀有だって住んでいる人の数はそれなりなのだから、もうちょっと大きな本屋があってもよさそうなものである。

一時期は、本はすべてAmazonで買っていた。リアル本屋で面白そうな本を見つけても、家へ帰ってAmazonで注文していた。Amazonにはリコメンド機能があるからだ。Amazonで買い物をすればするほどリコメンド機能が賢くなる。このリコメンド機能をかなり頼りにしていた。

しかし、最近、リコメンド機能などどうでもよくなってきた。要は、似たような本ばかり読んでもしょうがないのだ。読書も娯楽である。新しい知識と出会う楽しみがある。幅広い、ときには意外な本が読みたいのだ。

この点において、Amazonのリコメンド機能は退屈だ。いわゆる「紙おむつとビール」理論は、売る側にとっての「意外性」であって、買う側にとっての「意外性」ではない。買う側は、そもそも、最初から紙おむつとビールを買いに来ているのである。

リアル書店のいいところは、そこに人間の意思が働いていることだ。大きな本屋へ行くと、新刊書と売れ筋のコーナーの他に、様々な「フェア」が催されていることがある。

例えば、「経済学の古典を読もう」みたいなフェアが開催されていて、そこにケインズの「一般理論」が置かれていたりする。非常に有名な本であるが、普通の人は読まない。そもそも、そういう本を読もうと思いつかない。しかし、そういう本が置かれていて目に入れば、読んでみようかなという気になるかも知れない。

亀有に大きな本屋がないので困っていたのだが、よく考えたら神保町まで行けばいいことに気がついた。神保町は、三田線で大手町の一個隣りである。大手町までは定期で行ける。別に、希少な古本を探しているわけではないが、世界最大の古書の街なら、「意外性」に出会えること間違いない。

3月末にリニューアルオープンしたばかりの、東京堂書店へ行ってみた。フロア面積としては、近くの三省堂本店などにははるかに及ばない。しかし、リアル本屋の楽しみを凝縮したような店である。1階から3階まで見て回ったら疲れてしまった。嬉しいことに、カフェが併設されている。

Kindleの日本進出が近いと言われている。喜ばしいことである。しかし、そうなると、リアル本屋の存在はますます重要になる。はじめから欲しい本がわかっているのなら、人々はネットで買うだろう。リアル本屋は、「なんか面白い本はないか?」という人々に応えねばならない。そのとき、どういう本を出してくるか? 書店員の腕の見せどころだ。

2012年3月10日土曜日

技術者の倫理

ミラクル・リナックスに入社して1ヶ月経った。3月からまた新しい人(NetBSDハッカー!!)が入ったので、昨日は歓迎会だった。つまりは飲み会なのだけれども、ミラクルの人たちと話していてひとつ驚いたことがある。彼らは、会社の飲み会で技術の話をするのだ。往年の親指シフトから、最新の(?)GNU Hurdまでが話題に上がった。

技術者には個性というものがある。強みである。もちろん、弱みともなりうる。前職の三菱電機では、マネジメント上の最大の焦点とされたものに、技術者の個性の無効化がる。無効化という言葉が過激すぎるなら、均質化と言い換えてもよい。逆に、ちょっと過激な言葉を使うならば、前職のマネジャーたちは、技術者を交換可能な標準化された部品とみなした。

天才的技術者がいたとする。すべての製品を彼の天才に頼っていたとする。ある朝、彼が交通事故に遭うようなことがあれば、直ちに事業は破綻する(スーパーコンピュータの父であるシーモア・クレイは交通事故で亡くなった)。したがって、天才的技術者への依存はリスクである。

前職のマネジャーたちは、シーモアの天才的コンピュータ設計能力のごときを利用しないという戦略によって、このリスクを回避しようとした。仕事を設計する際、シーモアの能力を最大限に引き出すようにはしなかった。シーモア以外の技術者でもできるように仕事を設計し、その仕事をシーモアに与えた。そうすれば、シーモアが交通事故に遭っても、別の技術者が引き継ぐことができる。

この戦略は、第1に、組織にとって不幸である。シーモアの能力が本当に価値ある製品を生み出すことができるものだとするならば、当然ながら、この戦略は価値ある製品を生み出さない。技術者の個性を無効化するということは、その組織の生み出す価値も無効化するということだ。

本質的に価値のない製品を売るためには、その製品があたかも価値があるかのごとく見せかけなければならない。例えば、無理な低価格化を行う。これは、多くの場合、技術者の賃金を下げる(サービス残業なども含む)ことによって行われる。一見、低価格は消費者にとってよいことのように思える。しかし、実際には、消費者はよりよい価値を得るチャンスを失っている。

第2に、シーモア自身にとっても不幸である。確かに、シーモアに与えられた仕事は、シーモアほどの天才をもってすれば容易にこなすことができるだろう。しかし、恐らく、シーモアは楽して稼ぐために技術者をやっているのではない。技術者なら誰もが知っていることだが、技術者は仕事そのものを報酬とみなす。自身が良い仕事をしたと思ったとき、最大の満足を得る。

仕事から満足を得られないならば、技術者は単に去るかもしれない(シーモア・クレイはいくつかの組織を転々としている)。もっと悪いシナリオは、技術者が、与えられた仕事に自らの能力を最適化してしまうことだ。余剰の能力を捨ててしまう。他へ移った技術者は、新しい組織で新しい価値を生み出すチャンスがある。能力を放棄した技術者は、もはやいかなる価値を生み出すこともできない。

今、日本企業に元気がないと言われる。なぜ、今の日本にはGoogleやAppleが生まれないのかと言われる。なぜ、日本にはこれだけ多くの企業がありながら、GoogleやAppleのような製品を生み出せないのかと言われる。

当然である。技術者の個性の無効化という戦略では、価値ある製品は生み出せない。技術者の個性の無効化によって、組織の産み出す価値は無効化され、技術者は能力を放棄してしまう。

本田宗一郎や松下幸之助の時代には、日本企業も価値を生み出していたはずだ。価値を生み出したからこそ、日本製が選ばれ、日本経済は発達した。しかし、彼ら戦後日本経済のヒーローが去った後、残された日本のマネジャーたちは、もう彼らには頼るまいと思った。そして、技術者の個性を無効化することを思いついた。その結果、日本製は急速に魅力を失い、退屈な技術者が残った。

私が、前職の同僚たちとの飲み会で最も不満だったことは、彼らが技術について話そうとしないことだった。少なくとも、親指シフトが話題に上ったことはなかった。彼らは、そもそも技術に興味がなかった。技術など、とっくに放棄してしまっていた。話題の中心は、会社の愚痴だった。

昨日の飲み会で、ミラクルの技術者は、少なくとも現時点では技術を放棄していないことがわかった。ミラクルのマネジャーは、技術者を標準化された部品とは考えていないのだろう。私はたまたまミラクルを選んだが、若い企業はどこもそうなのかもしれない。

若い会社は、市場規模は小さいかも知れない。前職とミラクルとでは、売上の単位が違う。しかし、人々は何のために市場を生み出したのかを思い出さなければならない。企業とは何かを思い出さなければならない。

技術とは、昨日よりよい明日を得るために今日行う活動である。市場とはこの活動を加速させる舞台であり、企業とは舞台で踊る主体である。

企業の規模は目的ではない。売上とは、企業がどれだけ価値を生み出しているかを評価するベンチマーキングであって、それ自体が企業の目的ではない。テストの点数それ自体が勉強の目的ではないのと同じである。

どんなに売上を上げていても、もはや価値を生み出せなくなった企業は速やかに市場から退場しなければならない。あるいは、その売上を、価値を生み出す活動へと注入しなければならない。絶対にそうしなければならないというわけではない。これは、倫理の問題である。

ミラクルに入社して1ヶ月、技術者として、私は何だか救われた気がしている。前職では、私は、自身が十分な価値を生み出していないことに気づいていた。このことに後ろめたさを感じていた。仕事とはそういうものだと、自分を誤魔化していた。

ミラクルでは、そのようなバツの悪い思いをしなくても済みそうだ。雇用とは契約である。企業は労働者に何物かを求め、労働者はそれに答える。しかし、労働者も企業に何物かを求める。企業はそれに答えなければならない。

私は、ミラクルに、個性を潰さないで欲しいと要求する。個性を持った、強みと、当然ながら弱みも持った技術者として扱って欲しいと要求する。そうすれば、私は最高の仕事を約束する。少なくとも努力はする。これが、技術者としての倫理である。