2016/03/09

転職して7年が過ぎた

これを一部でシェアしたのは2014年なので結構前ですが、エンジニアのキャリアパスを考えるにあたって参考になるかと思って公開します。あくまで個人的な体験談で会社の見解などとは関係ないということに注意してください。

--------

入社日記念の無料マッサージクーポンのメールを受け取って気づいたんだけど、こないだで入社後7年が経過したらしい。僕は結構長い期間をここで過ごしたことになるんだなと思った。ちょっと以前のことを振り返ってみようと思う。言うまでもないけどこれは僕の書ける範囲での個人的な感想と体験談であって会社の見解等を表しているものではない。

きっかけ


そもそも最初は2007年にGoogle Japanのリクルーターからメールをもらったのがきっかけだった。Google Japanの知り合いから紹介で誘いがきて、「お、これは引き抜きってことかな?」と思ってよろこんで話を聞きに行ったのだった。話を聞いてみるとなんだか想像していたのとは違って、ただ採用面接を受けてくれといわれた。そちらからコンタクトがあったということで有利な点はあるんですか?と聞くと、書類や電話面接を抜きにしていきなり実地の面接から始まることですかね、というようなことを言われた。つまり特に有利になっているというわけではなく、その返答には結構がっかりした。とはいえ面接はたいして難しくもなく無事採用された。

モバイルUIチーム


一番最初にアサインされたのはモバイル検索UIチームだった。2007年当時のモバイルというと、ガラケーだった。まだiPhoneは存在してない頃で、iモードブラウザとかに向けて、そういう端末で表示可能な検索結果を返す、そのUIを作るのが仕事だった。当時はチームも小さかったし、また全世界においてそれなりにネットが使える携帯電話の台数は日本が相対的にとてもに多かったので、日本の仕事というのは結構な重要性を持っていた。

いまから考えてみると非常にどうでもよいテクニックばかり追求していたけど(たとえばHTMLのモバイル向けの亜流であるCHTMLで1ピクセルの横線を引くく方法とか)、そういうのを調べるのはそこそこ面白かった。

そうこうしているうちにiPhoneが発売された。今の世の中から考えるとiPhoneの発売開始は社会全体が大騒ぎするようなイベントだったように感じられるけど、当時は単なる普通の(コンピュータ業界における)一つの新製品という感じだった。

初代iPhoneは日本では発売されなかったので日本では実機に触れることができなかったけど、どういうものかは知っていたので早く使ってみたかった。いまでもよく覚えているけど、アメリカに出張にいったときに、モバイルチームのリードをやっているエンジニアにiPhoneをランチを一緒に食べながら、iPhoneを見せてもらった。「ほー、やっぱりこういう感じか」と思った気がする。使ったのは初めてだったけど知識はあったので驚きはなかった。

で、iPhoneは非常によく売れて、日本でも発売されることになった。当時はGoogle Japanは渋谷にあって、渋谷から原宿のソフトバンクのフラッグショップに急遽買いに行った記憶がある。そのときはあまりにも列が長すぎて、代々木公園に向かう歩道橋のあたりまで伸びていたので、あきらめて帰ってきて、後日あらためてゲットした。

しばらくするとAndroidも発売された。初代Android端末のHTC G1を会社からもらって結構楽しんで使っていた。G1は思い返してみるとちょっと古めかしい端末で、表と裏でスライドするようになっていて、スライドすると物理的なキーボードがでてくるようになっていた。BlackberryとiPhoneの合いの子のような感じがした。もらったのはSIMフリー端末でもあったので、ニューヨークに出張にいったときにプリペイドのAT&TのSIMを入れて使って、Google Mapsでセントラルパークとか博物館とかを観光をして回って、これはなんて便利なんだと思った。いまでは知らないところに行ってスマホでマップをみるなんて普通のことだけど、当時はまだみんな紙の地図を使っていた。

そのころにはすでに、iPhoneに最適化された検索結果が表示されるようになっており、まともなブラウザを積んでいるiPhone向けの検索結果はまだまだいくらでもできることがあるということで、エンジニアはみんなスマホ向けの検索結果のほうに力を注ぐようになっていた。いままでフィーチャーフォンのブラウザで四苦八苦してなんとかやりくりしていたのに比べれば、これは夢のような仕事だった。基本的には画面が小さいだけで、普通のブラウザでできることはJavaScriptでもなんでも使えるのだ。

しかし、スマホの仕事がメインになってみると、日本でやる仕事は今までと同じというわけにはいかなくなった。ガラケー向けには市場もあるし、日本にいないとできない仕事でもあるから、それがメインの仕事として成立していたが、スマホは全世界同じだから、僕もグローバルな機能を作成するというのがメインの仕事になってきた。

グローバルな機能を作るのは面白かった。自分の作った機能がアメリカでもインドネシアでもナイジェリアでも同じように表示されるわけだ。チープな携帯電話だけがネットに接続する唯一の手段であるような発展途上国のどこかの村のことを想像してみたりした。誰かにとって死活的に重要な仕事をしているような気がしたし、文字通り世界中で何億人もが使う機能を作るのは面白かった。

それと前後してアメリカに引っ越した。別に必要はなかったのだけど、やっぱりこの世界で仕事をするならシリコンバレーは本場かなと思ったのだ。

しかしフィーチャーフォンというガラパゴスがなくなり、また英語が下手という問題点が前面にでてくると、自分できることが少なくなってしまった気がした。というか実際少なくなっていた思う。その後はモバイル向けのイメージ検索結果を作ったりとか、デスクトップ向けの検索結果の機能とかを作っていたんだけど、前にやっていた仕事ほどにはインパクトがあるようには感じられなかった。

外国で外国語で仕事をするということ自体の大変さで別種の苦労は増えていんだけど、それはマイナスをゼロにするという努力であって、もともとその点で努力を必要としない人たちが活躍しているのをみると、こんなことでよいのかなぁと感じていた。もっと面白いことが起こってもいいんじゃないかと思っていた。

とはいえすぐにそんなものが改善できるわけでもなく、趣味のプログラミングでなにかを作ろうとふと思い立った。それで8ccというCコンパイラを作った。(そのほかにも作ったりもしたけど。)

コンパイラを作っているときは本当に集中していた。毎日午後6時までは仕事をするのだけど、その後は寝るまではひたすら自分のコンパイラを書いて、朝起きてもちょっと続きをして仕事に行くということをしていた。土日は起きてる間は基本的にコンパイラを書いていた。週末は1日14時間くらいはやっていたと思う。数ヶ月はそういう生活をしていた。

Cコンパイラを作った意義はそこそこ大きかった。きちんとしたコンパイラというのはかなり複雑なソフトウェアだ。僕が言語処理系や低レイヤに相当詳しいということを示すこともできたし、それ以上に自分自身での達成感が大きかった。しかしそんなこともしばらくたつと忘れていた。

コンパイラチームへ


その後1年くらいして、社内の誰かとチャットしていたら、面白い求人が社内で出ているという話になった。

最初に知ったのはAndroidのランタイムの求人だった。ここのチームに面接にいってみたら、何人かのエンジニアがでてきたんだけど、そのひとたちがすごい人たちだった。一人は、命令セットからすべて独自のオールTTLのCPUを自作して、それにlccというCコンパイラとMinix(という小規模なUnix)を移植したという、とても考えられないレベルの自作派のハッカーだった。コンパイラやOSを作るならともかく(それも普通ではないが)、その人はCPUやマイクロコードから作っていたのだ。もうひとりはガベージコレクションの専門家でゲーマーなプログラマだったと思う。彼には、日本人なんだったらどうして任天堂に就職しないの?と訊かれた。その疑問のほうが逆にすごいよと思った。結局このチームには採用されなかった。

LLVMのC++コンパイラチームにも話をしにいった。ここのチームのマネージャと話したときに、Cコンパイラをスクラッチから作ったんですよという話をしたら、「どうしてそんなことを? なぜ?」とマジレスされたのを覚えている。「どうしてっていわれても…… まぁ暇だったので」みたいにしか返事できなかった。「で、応募者結構いるみたいですけどどうやって決めるんですか?」と訊いたら「じゃあ君でいいよ」ということで、その場でチームを変わることが決まった。そういう流れでGoogleのLLVM/Clangチームに移ることになった。

ここはC++に詳しいひとたちばかりで、これがC++コンパイラ業界の最先端なのかという感じだ。このチームはC++の世界で、実装面でも標準化の面でもかなり存在感が大きいようだ。逆に言うと、本物のC++ハッカーでもCコンパイラを趣味でゼロから書いたというとびっくりするというのは、ちょっと驚きだった。ただ趣味で本を読んで実践していただけだけど、それがプロも驚かせるレベルになっていたわけだ。

そういえば僕のマネージャのマネージャはC++コンパイラハッカーでありつつ弁護士資格を持っているという人で、世の中とんでもない人もいるもんだなと思った。

あとこのチームのいいところはすべてオープンソースなので秘密が少ないことだ。僕が書いたコードは直接パブリックなのリポジトリにチェックインしているし、議論もすべて公開のメーリングリストで行われているし、最初からだいたいなんでも外から見えるようになっている。

Go言語


そういうわけでLLVMチームで仕事をしていたんだけど、だいたい僕はなにかを仕事でやると、別のことを仕事以外にやりたくなるものらしく、そのときにはGoでなにかをやろうと思って、Goの言語仕様をまず全部読んでみた。なかなかよさそうな言語に思えたので、ソースコードを読んでみることにしたら、いくつかバグを見つけたのでパッチを投げてみることにした。最後には50個くらいパフォーマンス改善およびバグ修正のパッチを投げて、コミット権がもらえるまでになった。

Goで働いている人たちもすごかった。Brad Fitzpatrickとは結構仲良くなったんだけど、かれはLiveJournalを立ち上げた人で、memcachedとOpenIDを作った人だった。Rob PikeはAT&Tベル研でPlan 9を作ったうちの一人で、神様みたいなプログラマだ。Goコンパイラをメインで書いているRuss Coxは青年時代から天才プログラマとして名が知れていた人物で、ある話によればRob Pikeがいままでみたなかで一番優秀なプログラマであると言っていたらしい。Rob Pikeは(Unixを作った)Ken Thompsonとかとも一緒に仕事をしていたから、そうしてみるとRuss Coxは世界最高のプログラマといっていいのではないだろうか?

で、Goを最近やっていて、という話をしていたら、LLVMのGo言語フロントエンドllgoのコードレビューをしてね、みたいな仕事が僕に回ってくるようになった。LLVMチームはC++は詳しいけどGoはよくわからないから、君が一番詳しいでしょ、みたいな。

このあたりまでくると、Ken ThompsonやRob Pikeとウィークリーミーティングをするとこまであと一歩といってよいのではないか? という気もする。Goチームがウィークリーミーティングしているのかは知らないけど、チューリング賞(コンピュータにおけるノーベル賞と言われる賞)の受賞者のチームと一緒に仕事をするくらいになるとしたら結構すごいと思う。

振り返ってみると、蛇足でどうでもいいことをやっているとキャリアにとってポジティブなことが起こってきた気がする。そもそもプログラマとしてGoogleに就職したのもそうだし(それまではプログラミングは片手間でメインの仕事というわけではなかった)、コンパイラチームもそうだし、Goだってそうだ。損得を考えてやっているのではないのに得になっているんだから、おかしな話だなと思うけど、世の中まあそういうこともあるのだろう。

--------

あとがき: 最近(2016年)は、LLVMのサブプロジェクトでリンカを作るプロジェクトのリードエンジニアになって、既存のものより倍くらいは速いリンカの開発を進めています。Unixの標準開発環境の主要パートを置き換えるプロジェクトというのは野心的だし、私がオリジナル開発者なので発言権もあって面白いです。これもまた、Windows向けのリンカを私が作ったら思いのほかシンプルで高速なものができてしまったのでUnixに移植したところからスタートしたという、おまけから始まったプロジェクトなんですが。

上は結論が特にない文章ですが、改めて読んでみるとこれは社内転職の話ですね。自分に向いているポジションを見つけることが大切だなと思いました。

大きな会社だと同じエンジニアリングポジションといっても多種多様で、Webプログラミングから私のやっているようなシステムプログラミング、あるいは巨大なデータ解析まで必要なスキルはかなり違います。プログラミングを片手間でやっていたところから今の会社に転職して、「なんだ俺でもこういう最先端の企業で普通にソフトウェアエンジニアとして通用するのか」と思ったんですが、今のチームに移ってみると「システムプログラミングだと俺はこういう会社でも明らかに上手い方に属しているのか」という発見がありました。最初からそういうプロジェクトに所属しておけばよかったんでしょうね。最初の頃はそんなに自信もなかったし、一度所属してしまうとそれなりに愛着ができたりして、なかなか難しいんですけど。

得意ではない分野でも役に立てばまだマシですが、個人的にどうみても見込みがなさそうなプロジェクトもあるわけで(別に批判的なわけではなく、会社には山ほどプロジェクトがあって、すべてのプロジェクトに自分が納得できるわけがない)、そういうプロジェクトにうっかりアサインされてしまったときには、極力早く見切りをつけて何らかの方法で脱出するしかありません。漫然と今の延長線上のことを続けていけば、うまくいくように周りの人が自分のためにお膳立てをしてくれる、ということはないですからね。結局のところ、どこにいても自分の仕事の選択は人任せにはせず自分で責任を持つしかないということでしょう。

筆者のTwitter / Facebook


2015/05/12

アメリカではIT企業はコンピュータサイエンティストが経営しているケースが多い気がする

アメリカではコンピュータサイエンスに長けた人が経営を行っている例が目立つよなぁと思っていた。ちょっと思いついたものをリストアップしてみた。

エリック・シュミット
Googleの元CEOで現会長。UCバークレーで電子工学・コンピュータサイエンスの博士号を取得。コンパイラを書くときに使われるLexのオリジナル作者の一人としてコンピュータサイエンスの歴史に名を刻んでいる(論文)。1990年台後半にNovellの社長を務めたあと、2001年から2011年までGoogleの社長を務める。総資産83億ドル(1兆円)で、創業者でもなくこれだけの財を成した人物は珍しい。社長をできる人物を探していたラリー・ページとサーゲイ・ブリンを感銘させてCEOとして雇われたらしいが、確かに彼は話がいちいち説得力があって面白い。趣味としてパイロット免許も持っている。

ビル・ゲイツ
マイクロソフトの共同創業者で、1995年以降いまだに世界で一番金持ちの男(2015年現在、資産総額800億ドル=9.5兆円)。13歳のころ、まだパーソナルコンピュータというものがなかった1960年台からプログラミングを始めるという幸運に恵まれる。その後Microsoftを創業し、BASICインタープリタなどを書いて売ってかなり儲ける。極めてテクニカルな部分までよく知っている経営者で、Microsoft創業後の5年間ほどは出荷するプロダクトのコードの一行一行をレビューしていたという。ミーティング中に「本物のプログラミング」が行われていないと思った時は「君たちがやっているのはコードをただいじくりまわしているだけだ。私はFATファイルシステムをフライト中に書いたぞ」(I wrote FAT on an airplane, for heaven's sake)などと言って発破をかけていたりしたらしい。確かにこういう異常に詳しい人物がCEOをやっているといろいろと(いい意味で)面倒だ。

マーク・ザッカーバーグ
中学生からプログラミングを始めて、高校生のころに音楽プレーヤーソフトを作ってSlashdotに投稿したりしていた。ハーバードに入学したころにはすでにプログラミングがうまい人物として周囲には名前が知られていたらしい。2002年にはTopCoderをちょっとやっていた(mzuckerberg)。2004年にFacebookを書いて、その後爆発的にユーザが増えたのは御存知の通り。相当ユーザが増えた後でもプロダクションのPHPを直接変更してテストする(無論バグっているとユーザにそのまま見えてしまう)といったようなことをやっていたらしい。まあ本来はよくないんだが、わからなくもない。

リード・ヘイスティングス
1988年にスタンフォードのコンピュータサイエンスで修士号を取得。不正なメモリアクセスを検出するツールPurifyを書いて(Purifyの論文)、それを元にPure Softwareを設立。Purifyの手法は当時としては斬新だったのだろうと思う。1995年に上場、1997年にRationalに買収される(IBMがその後Rationalを買収して、IBM Rational Purifyとしてまだ製品が存在する)。その資金を元手に次はNetflixを創業する。Netflixは最初は郵送DVDレンタルサービスだったが、ビデオストリーミングサービスをいち早く立ち上げて大成功させる。現在北米のインターネットトラフィックの1/3はNetflixのトラフィックだという。なぜレンタルDVD屋が急速にストリーミングサービスを立ち上げるのに成功したのか不思議に思っていたが、CEOは極めてテクニカルな人物であった。

ジェフ・ベゾス
プリンストンを電子工学・コンピュータサイエンス専攻で卒業。ウォール・ストリートで働いた後、いろいろ検討した結果、書籍をネットで売るビジネスはいけるということになり、1994年にオンライン書店としてAmazonを創業。自宅のガレージから始めるという典型的なスタートだった。当初は客が本を購入すると取次に発注をかけてそれを転送するという在庫なしの商売をやろうとしていたが、届くまでに日数が掛かり過ぎるのは問題だということで倉庫を持って在庫を持つモデルに転換。その後商品の取り扱いを増やし、さらにそのインフラを使ってAmazon EC2やS3といったクラウドコンピューティング分野を切り開く。フォーブスの資産家ランキング15位。個人的にエンジニアリングに興味を持ち続けていて、最近では数年間かけて大西洋を探索させて、初めて月に着陸したアポロ11号の一段目のロケットエンジンを海底から発見・回収したりしている。金持ちの趣味というのはすごい。

ラリー・ページ
スタンフォードのPhDの学生だったころに検索エンジンの新しいランキングのアルゴリズムを考案してPageRankと名付ける(論文)。考案するだけでなく実装するためには、インターネットの主要なページをすべてダウンロードしてきて大規模な計算を行わなければいけないので難易度が高い。最初のころのURLはgoogle.stanford.eduだった。後に法人化してGoogleを創業。確かに検索精度は群を抜いてよかった。当時はデータセンターは電力消費量に関係なくラック単位で課金されていたので、コルクボードを絶縁のために下にしいて安価なPCのマザーボードをラックに詰め込めるだけ詰め込んだカスタムのシステムを作って、分散処理を行ったりしていた。他のサーバと違って下りのトラフィックのほうが多いからというので(回線は上り下りが対称だけどサーバはだいたいユーザに送るデータのほうが多いので下りが余りがち)、ラリーがデータセンターと交渉して値引きさせていたりしたらしい。

マリッサ・メイヤー
よく雑誌の表紙などに出てくるYahooのCEO。1999年スタンフォードでコンピュータサイエンスの修士号を取得。昔はラリー・ページとデートしていたらしい(狭い世界だ)。その後Googleをやめて、ごたごたの続いていたYahooのCEOに就任。低迷していた株価を数倍引き上げることに成功する。

ポール・グレアム
有名なLispハッカーの一人。Common LispでViawebというオンラインショッピングサイトのASPを立ち上げて成功させて、それをYahooに売却した。当時は競合がCGIで苦労して書いていたものをCommon Lispでは簡単に実装できたので、Lisp使いだったというアドバンテージは相当あったようだ。その後、その資金を元にY Combinatorを立ち上げる。Y Combinatorの最初のプログラムが始まった時のことは私はまだ覚えているが、なんだかよくわからない学生か何かに数ヶ月の生活費とサーバ費用を提供するので部屋にこもってハックさせる、みたいな話で、へぇと思っていたのだけど、その後そこからDropboxやAirBnBのようなユニコーン企業が続々と生まれて大変なことになってしまった。自分の会社を成功させて、その後他の会社を続々と成功させる仕組みを作るということにも成功して、2回うまくやっていて本当にすごい。ちなみに今では常識的なものになっている統計的スパムメールフィルタを考案したのもこの人。

ロバート・モリス
ViawebとY Combinatorをポール・グレアムと一緒に始めた男。あまり名前がでていなのは本人が目立たないようにしていたからで、なぜそうしていたかというと、1988年に世界で最初のインターネット・ワームを書いて、MITのネットワークから放って、当時インターネットに接続されていたコンピュータの何%〜何割かをダウンさせたという前歴があるからである。本人が思っていた以上に増殖してしまったらしい。ちょうどコンピュータの不正使用を犯罪として扱う法律が成立したころで、目新しかったこともあり、モリスは新聞の一面をでかでかと飾ることになってしまった。結局、社会奉仕活動と罰金が科せられることになったのだけど、それ以降はしばらく目立つことは避けるようになってしまった。そんなに悪意があったとは思えないし、やろうとしてできることでもないが、いずれにせよその後実業界で成功し、現在はMITの教授。

(余談だが警察関係といえば、Facebook以前に世界最大だったソーシャルネットワーキングサイトのMySpaceの共同創業者のトム・アンダーソンは、1985年、14歳の頃Chase銀行をクラッキングしていて自宅を15人ものFBI職員に急襲された。若すぎたので罪に問われなかった。スティーブ・ジョブズも長距離電話ただ掛け装置を売って一儲けしていたりしている。)

このリスト、いくらでも長くできそうなのでこれくらいにしておく。マイクロソフトの新CEOのサトヤ・ナデラもコンピュータサイエンスで修士号だ。むしろコンピュータサイエンスの素養がないひとが経営しているケースというのがあまり思いつかない気がする。別の畑の人というと、ペプシコーラのCEOからアップルのCEOに転職して、スティーブ・ジョブズを追放したジョン・スカリーなんかが思い浮かんでしまう。

卑近な例で言えば、昔日本企業に務めていたころの僕の仕事は「わかっていない上の人」(あるいは「わかっていない取引先の人」)に、プログラムというものを多少正確さは犠牲にしてでも噛み砕いて説明する、というのがまあまあ大きな割合を占めていたりした(一方向ハッシュ関数とは何かみたいな説明をしたのを覚えている)。最近ではむしろ上の人のほうが異常に詳しいのでそういうのは全然ない。正直なところ、技術的にいまいちな人がやっているIT企業かメディア企業か曖昧な程度の会社ばかり目立ってもなんだかがっかりなので、アメリカ以外でもこういうふうな会社がどんどん増えて成功事例が増えると面白いと思う。


2015/03/29

ダメなコードを改造しなくてはいけなくなったときは、ダメさを片っ端から潰していくしかない

仕事としてプログラミングをしていると、ときどき、どう見てもダメなコードを扱わないといけないことがある。そういうコードでも動いている以上はそれなりの価値を提供しているわけだけど、ときどき触るのすら嫌悪感を感じるようなものがある。

なぜ嫌悪感を感じるのかといえば、自分で最低限だと思っている想定すら守られていないからだ。常識の通じない人たちの書いたコードには身の毛もよだつような何かがある。
  • コーディングスタイルが統一されていない
  • インデントが狂っている
  • 到達不能なデッドコードがたくさんある
  • 無意味なコメントやコメントアウトされたコードがある
  • コメントの文章が文章としておかしい
  • コピペの繰り返しがたくさんある
  • ネストが恐ろしく深い
  • 関数が絶望的に長い
  • 無意味に複雑
こういったコードを触らなくてはいけなくなったとき、そのままで編集するのはかなり難しい。コードの内容以前に、不自然な部分でいちいち引っかかりが生じるので、コードが何をしているのか理解することに精神を集中することすら難しいからだ。

こういうコードを読むときにはどうしたらいいだろうか。

こういうコードを読むときには書き換えまくるのがよいと思う。「この関数は意味ありそうにみえるけどほとんど何もしていない」とか「ここのインデントは狂っているが前回もそう思った」といった付加情報を頭にすべて入れつつコードの全体像を掴むのはかなり困難だからだ。

こういうときには、機械的に等価で、しかし簡潔なコードに置き換えるつもりで、ひたすらブルドーザーのように小さな改良パッチをチェックインし続けるのがよい。意味不明なコードも等価で簡単なコードにステップを踏んで変換していくことで理解可能な範囲に収まることがよくある。デッドコードなら跡形もなく削除してしまえばよい。命名規則も、微妙に引っかかるだけのものも含めて、すべて統一されたきれいな形に書き換えてしまうほうがよい。無意味なコメントは、瑣末なものであっても徹底してキレイに消してしまえばよい。ちょっとしたくだらないことであっても、コードそのものをわかりやすくなるよう修正すべきだ。

こういったことは個人の好みといったレベルの物事ではないと思う。世の中にはよいコードと悪いコードというものがあり、悪いコードというのは本当に悪いコードなのだ。とにかく低レベルでの引っ掛かりをなくさないことには普通のレベルでの改良も満足に進めることはできない。

プログラマをしているなら、最低限、低レベルでの引っ掛かりを他のプログラマに生じさせように気をつけるべきだと思う。これは別に難しいことではない。ほかの周りのコードと同じように見えるようにコードを書けばよいだけだ(全体的に腐っている場合を除く)。どういうコードが普通なのか、という感覚を身につけるためには、よいオープンソースのコードを読んでみるのがよいと思う。

ネイティブの言語である日本語であっても、文章が多少おかしい人というのはたくさんいる。それと同じように、お手本のコードを嫌というほど目にした後でも「普通に見える」コードがなぜか書けない人というのはいるようだ。そういう人はどうすればいいのかは僕にはよくわからない。とにかくインデントや命名規則といった機械的な規則は最低限守ればよいとは思うのだが、それすら守れない人というのがいるようだ。心あるプログラマならそのラインはクリアしてほしいと思う。




2015/01/31

コードを書くことは無限の可能性を捨てて一つのやり方を選ぶということ

なにかの機能を実現するためにコードを書いているというのに、そこから脱線して意味不明なコードを書く人たちがいる。汎用性は高いつもりらしいけど無意味に難しいものを作りたがったり、必要がないのに「念のため」に既存の機能を残したがったりする人たちがいる。どうやら柔軟性あるいは汎用性が至上の価値であって、その価値に反するものはなんであれよくないものだと思っている人たちがいるようだ。

そういう考え方は間違っていると思う。

ある機能を実現するにはいろいろな方法がある。プログラマはそのうち一つの方法を選んでそれを実装しなければいけない。機能を実装する前は無限の可能性がありえたが、機能を実装したあとは具体的に実装したこと以外のことはできない。芸術家が大きな大理石のブロックから一つの彫刻を削りだすように、具体化することによってそれ以外のありえた形というのがなくなってしまうが、それは避けられないことだ。全部の可能性を実現しつつ、なんらかの具体的なコードを書くということはできない。

無理に両立させようとすると、おかしなことになる。

無限の可能性を担保しようと思うと、究極的には何らかのインタープリタを実装してその上で機能を実装することになる。でもそれ自身ではなにも機能を実現していることにならない。

難しいコードを書いてしまうある種の人たちは、適切なレベルの具体的さで書かれたコードよりも、インタープリタに近いコードがよいと思ってしまう人たちであるようだ。いま現在特に必要性もないのに、データを解釈して動作を変えるようにしようとか、設定ファイルで動作を不必要にカスタマイズできるようにしようとか、そういうことをやりだすとインタープリタみたいになってしまう。そういうのはわかりにくいだけだ。

コードを書くというのは、ある形に向かって特殊化していくということである。

コードを書くにあたって、このやり方だと別の(仮想的な)ケースだとカバーできないからなぁ、とか思った時にはこの話を思い出してほしい。自分の書くコードは机上の空論までカバーする必要はない。将来のあらゆる可能性をカバーする必要もない。具体的なコードを書くことを恐れる必要はない。抽象的すぎるコードは具体的な問題を解決できないコードであることがほとんどだ。必要ならあとでコードを書き換えればいい。いま何かを実現したいのなら、それに必要なことを直接やるだけのコードをそのまま書くのがいい。


2015/01/24

ミッションクリティカルなシステムの思い出

大昔の話だけど、公共関係のミッションクリティカルなシステムの構築に関わっていたことがあった。止まっても人が死んだりとかはしないけど、それなりの時間止まったりしたら各方面にいろいろ面倒なことになるようなシステムだった。

しかし、そこに導入しようとしていた機器は結構新しいもので、わりと不安定だった。二重化されていたと思うんだけど、頻繁に片方がハングしてしまうというような問題があった。その状態でもう片方もハングすると完全にシステムがダウンしてしまうので、これはなんとかしなければいけないということになった。

そこで誰かが、シリアルポートがついていて、それ経由でコマンドを送ると電源の差込口ごとに電源のオン・オフができる電源タップというのをみつけてきて、それを間に噛ませようという話になった。マシンの状態を監視しておいて、おかしくなったら自動でコンセント抜き差し的なことをして復帰させようというのだ。そしてそれが実際に導入された。監視して電源タップにコマンドを送るスクリプトは僕がbashか何かでちょろっと書いた。1番目の口の電源を入れ直すのに echo 'off 1' > /dev/ttyS0; sleep 5; echo 'on 1' > /dev/ttyS0; とする(電源オフにして数秒待ってオンにする)、みたいな非常に素朴な感じだったと思う。

空調のバリバリに効いたデータセンタに置かれたミッションクリティカルなシステムの電源が全部なんだかよくわからないタコ足経由になっているというのはシュールな光景だった。電源タップの見かけは本当に普通の電源タップだった。これはすごいなと思ったのだけど、特にそれについて意見したりしなかったので、あるいは僕しかそう思わなかったのかもしれない。こういう現場の工夫みたいなものが事故を引き起こすというような工学上の話はよくある。しかしその電源タップは黙って使っているぶんには特に問題を引き起こすことはなかった。

僕のスクリプトがバグっていたりしたら両方のマシンを同時に再起動してシステム停止というのも容易に起こり得たけど、そういうことも起こらなかった。

それどころか僕はその電源タップ用のWebインターフェイスまで書いた気がする。そのページにいくとマシン一覧みたいなのがあり、そこからボタンをクリックして任意の機器を再起動できるのだ。こんな気軽なものになっちゃってよいのだろうかという気はしたけど、簡単に使えてお客さんからの評価は大変高かった。アドホックさを一番恐れていたのは僕で、それ以外の人たちは、お客さん含め全員仕組みを知っていつつ、それでもそれに満足しているみたいだった。世の中よくわからないものだなと思ったのだった。



2015/01/20

Futureパターンのfutureは未来ではなく先物という意味

Javaには結構昔からあって、最近ではC++11に導入され、JavaScriptでも提案されているFutureというものがある。

このFuture、日本語に訳すのなら「未来」ではなく「先物」が正しいのだと思う。英語では未来も先物もどちらもfutureという。まだ存在しない現物の代わりに、未来のある時点で現物を引き渡すことを確約するオブジェクト(あるいは契約)がfuture。同じだよね。


2015/01/19

コードを削除したら喜ぶべき。知らない人がみたら意味不明なコードが残っていませんか?

昔はよくわかっていなくて、今は身にしみてよくわかっていることの一つは、追加した行数がマイナスのパッチは素晴らしいということだ。コードは削除できるなら消したいし、自分の書いたコードであれ、誰かが消してくれたらとてもよいことだと思う。

昔はがんばって書いたコードはなるべく「活用」したいと思っていた。活用というのはつまり、捨てるのはなんとなくもったいないから、そのコードをなるべく消さずにすませたいということだ。

しかし無理にコードを生かしておくことの意味など何もない。

コードの履歴などは全部いったん置いておいて、ある時点のソースコードを初めて見たものとしよう。そのソースコードが、そのプログラムが実装するべき機能を実装するために十分かつ最小限のコードであるのと、十分かつ最小限のコードに加えて何かよくわからないコードのどちらかであるとしたら、どちらのほうがいいコードだと思うだろうか? 前者のほうがいいコードに違いない。何かよくわからないコードというのは余計な混乱を引き起こすだけだからだ。

履歴を考慮してみると、本来はばっさり削っても問題がない蛇足のコードに愛着を感じるのはわからないでもない。しかし、フレッシュな目で見てみると、そういうコードは率直に言って意味がよくわからないはずだ。コードの健全性のためにそういうものは思い切って跡形もなく消すのがよい。

Gitのようなソースコード管理システムを使っていれば、削除したコードを復活させるのはわりと簡単だ。これはコードをばっさり削除することの心理的障壁を下げる理由にはなる。ただし僕は、ばっさり削除されたコードがやっぱり必要だからということで復活させられた例はほとんど見たことがない。つまりそもそもが杞憂というか非合理的な執着心なのだ。経済学でサンクコスト(埋没費用)といっているものと同じだと思う。

僕の参加しているプロジェクトでは、どのプロジェクトであれコードを削除すると歓迎される。昔は何千行とか何万行とか削除するパッチを誰かが投げると、みんながよってたかってCongratulations!とかWoohoo!などと言うので、自分の書いたコードが最初から存在しなかったみたいになってしまって一抹の寂しさなどを感じないのだろうか? などと思っていたのだけど、いまではすっかり僕もGreat!などと返信するようになってしまった。ちょっと考え方を改めるだけなのだ。コードは簡潔でわかりやすいのが一番だし、変なコードがあると変更が無駄に難しくなるので、無駄なコードは消してくれると大変ありがたい。コードは変化し続けるものだ。単調増加などしていたら誰にも理解できないものになってしまう。

あなたのプロジェクトは変なコードが残っていないだろうか? 変更履歴を知らない人が見たら意味不明なコメントアウトされたコードとか、使われていない関数とかクラスとか、あとで使うだろうと思ったけど結局使っていない無駄な抽象化されたコードとか、もういらない機能とか、そういうものはないだろうか? そういうものがあったら消したほうがいいと思う。ソースコードは基本的に現時点が常に「完成品」、つまりフレッシュな目でみてキレイで、変なものがついていなくて、全体的に素直になっているように保つのがよいと思う。

Rui Ueyama @rui314