仕事に戻った
半年ぶりに人のためにはたらくことになった。と言っても、自分で行動を起こしてポジションをつかみ取ったわけではない。以前よりお世話になっていた縁で依頼してもらえただけで、ただただ運に恵まれただけだ。
もし声をかけてもらえていなかったら、きっともうしばらくの期間を自分のための時間に充てていただろう。とはいえそれにしても、決定を先延ばしにしているだけで、遅かれ早かれなにかしらアクションをとる必要はある。そう思って、今日からまた新しく仕事を始めることにした。
このブログは、今日にいたるまでの数ヶ月のあいだ、すなわちもっとも時間の有り余った時期に始めたものである。とりわけこの1ヶ月半ほどは毎日なにかしらのエントリをアップロードしていた。
そもそも誰に宣言して始めたものではなく、誰に読ませるためのものでもなく、ただ自分の満足のために書いていた。それが気づいてみると、書くことは毎日のルーティンとなり、自分の信念を書くという以上に、むしろ書いた言葉が自分の信念として定着するという思わぬ副産物にも見舞われた。なにをして、なにを学びえたか。なにをしたくて、なにをすべきなのか。その方向付けを得るためにこの場所が果たしてくれた役割は大きい。
今日という日は明らかにひとつの区切りである。仕事は好きだ。自分の能力に期待してもらえて、それに報いることができるのは気持ちがいい。しかし目先の仕事の有無とは別に、10年先の自分がどうなっているかが想像できない不安は変わらない。この先どうなるかはわからない。どうしていくかも決められていない。しかし可処分時間を大きく減らすことになるこのタイミングで、ひとまずの区切りとして自分にこう言い聞かせたい。
よく考えながら生活すること。そのために、アイデアや学びは書き継いでいくこと。量や粒度に囚われることはない。あるいはかえって、書くこと自体を目的化するのも構わない。ただそうして書いていった先にこそ、なにか新しいインスピレーションがあるはず、と願って、愚直にやっていくこととしたい。
std::map と std::unordered_map
map
というデータ構造は連想配列にあたるものと単純に理解していた。unordered_map
について追って知ることとなり、初めて map
のキーが自動的にソートされることを知る。
#include <map> #include <unordered_map> int main() { std::map<int, int> mymap1; std::unordered_map<int, int> mymap2; int numbers[5] = {3, 1, 4, 1, 5}; for (int i = 0; i < 5; ++i) { mymap1[numbers[i]]++; mymap2[numbers[i]]++; } std::printf("map\n"); for (auto x : mymap1) { std::printf("%d: %d\n", x.first, x.second); } std::printf("\n"); std::printf("unordered_map\n"); for (auto x : mymap2) { std::printf("%d: %d\n", x.first, x.second); } return 0; }
# 実行結果 map 1: 2 3: 1 4: 1 5: 1 unordered_map 5: 1 4: 1 1: 2 3: 1
両者について、要素へのアクセスの時間計算量は、要素数をNとして次のようになる。
complexity | |
---|---|
map |
O(logN) |
unordered_map |
O(1) (まれにO(N)) |
unordered_map
のアクセス速度が悪化するのは、要素数が増えてコンテナサイズの拡張が必要となるケースにおいてである。これは要素数が多くなるにつれて線的に悪化する。とはいえ平均的には O(1) で実行されるため、用途に応じて配慮するほかない。
いうまでもなく、任意のサブセットに対してイテレートを行うようなときには、ソートが保証される map
がより効率的である。他方で、任意の要素に繰り返しアクセスする必要があるような場合には、定数時間で処理できる unordered_map
に軍配があがる。
応用から基礎へ
昨日、一昨日と数学に関係するエントリが二日続いたのは、明らかにひとつの方針を指し示している。数学を学び直すこと、ひいては基礎を学び直すこと。これが今後のひとつの軸になるだろうと予感する。
学問的根拠がなくても仕事はできる、とする向きがあるのは理解している。また僕自身、そうして仕事を得ることができていたのも事実。そのような状況で、なんのために学ぶのか?
業務に必要な実践知だけあればそれでいい、という考え方を否定はしない。そういった土壌がなければ僕がこの業界に身を置くことはできなかったのは明らかであるから、そのような風土に感謝こそすれ、頭ごなしの否認などは決してできない。他方で、応用を過大評価し、基礎を過小評価するのであれば、それは反知性主義にほかならない。僕自身、かつてその傾向に毒されていたことは否定できないが...。
競技プログラミングの問題を解くようになり、自分の得手不得手の傾向がわかり始めた。つまり、実装にいたるまでの発想に直感の傾向が強く、数論的分析や証明の手続きに弱い。直感でプログラムを定義できるのは悪いことではない。むしろ誇らしくも思う。しかし不得手な分野、つまり数学的エッセンスが散りばめられた設問をいくつも解いていくうちに、「もっと知りたい!」という思いが鬱勃としてあるのを発見した。
基礎を学ぶこと。僕にとってそれは、「プログラマたるものかくあるべし」的な信念ではなく、純粋な好奇心の問題である。数学を学び直すことでそれを満たすことができるかはわからない。結局のところ、純粋数学というよりは計算機科学を中心に据えて取り組むことになるだろう。場合によっては逸脱的な学習進路をとることになるかもしれないし、あるいは王道をとって大学に再入学することもあるかもしれない。
いずれにしても、20代も半ばをすぎてこのようなことを考えた、というものを書いて、ここに表明しておく。
『数の悪魔』を読んだ
- 作者:ハンス・マグヌス エンツェンスベルガー
- 発売日: 2000/04/01
- メディア: 単行本(ソフトカバー)
あほな質問はやめろ。頭を悩ますことがすごいことなんだ。1
算数を啓蒙する児童書として評判がいいと聞き、読んだ。子供向けとあるが、とんでもない。「ほんとうのこと」を扱う本の前では、大人も子供もなくなる。
素数の話、三角数の話、累乗の話、階乗の話が、手を替え品を替え提示される。数学用語はほどほどに留められている。代わりに、独特な比喩が持ち込まれるから、手垢のついていない新鮮な感覚で対象に向き合うことができる。例えば、フィボナッチ数がウサギの繁殖で解説される。なんのことはないネズミ算になるが、ウサギを想像することはそれだけで認識に爽やかな風を吹き込んでくれる。
悪魔というモチーフもいい。はじめは厳しい悪魔が、次第に読者と喜怒哀楽を共有し、気づくと仲良くさせられてしまっているのがたまらない。アジアの童話で言う小鬼のような憎めなさがある。異教の子供たちが読むとすれば、さらにこじれた愛着が湧くのかもしれない。
著者のエンツェンスベルガーは数学者ではない。詩人である。しかも戦後ドイツの文学界を代表する詩人だという。不明にして知らなかったが、どうりでイメージが鮮やかなわけだ、と腑に落ちた。
調べてみると、同氏が67歳の手によりあらわした作品である。年齢だとか経歴は少しも気にせず、ただ算数の喜びを享受せよ! と後押しまでされたような気分になる。実際、誰よりも純朴な精神をもって臨み、これだけパーフェクトな作品を生み出した詩人を、数学者でないからといって非難することが誰にできよう?
Project Euler をはじめた
ご存知の向きも多いと思うが、 Project Euler は数学の問題をプログラミングで解いていくサービス。フィボナッチ数列の偶数項の和を求めたり、任意の整数の最大素因数を求めたりする。もっとも、これらは難度としては最低レベルとなる。進むにつれてより高度な課題が提示されるはずである。
競技プログラミングの問題を解いていくにつれてこのサービスの存在は知っていた。いずれやるときが来るだろうと思っていたが、思い立ってサインアップした。
25問を解くことをはじめの目標にする。簡単なようにも思われるが、全登録者数の11.48%しか達成していないということを鑑みると実はなかなか難しいのかもしれない。
6月の振り返り
今月のエントリのうちめぼしいものを振り返りながら挙げていく。
Rails を絶対視しないこと
“Rails is omakase” とか “The Rails Way” とかいうキャッチフレーズを盲信してしまう傾向を見つめ直して、少しずつそこから脱却しなければいけないと思い始めている。そのことを、 オマカセからアラカルトへ に書いた。
それから、 Rails のパラダイムを相対化する視点を得るために、 Hanami を触ってみた。このことは hanami でブックマークマネージャを作った と hanami を使ってみて得られた知見と所感 にまとめた。
そして、これらを踏まえた上で、『クリーン・アーキテクチャ』を再読し、 『クリーン・アーキテクチャ』を読んでフレームワーク中心主義からの脱却を考える というエントリを書いた。Rails を相対化するために Hanami という別のフレームワークに取り組む、という自分の発想モデルが、まさしくフレームワーク中心主義に囚われていたことにハッとさせられている。この件について、自分自身に処方箋を提示することはまだできていないものの、自分のなかのよくない傾向を鮮やかにあぶり出された経験として、心に刻み込んでいる。
トレンドに流されないこと
やってきては消えていく一連の流行に振り回せれて、あれもこれも使わなきゃ、と意味なく焦っていた自分を見つめ直して、改めようと努力している。それは 無理して Docker を使わないこと や 無理して SPA を採用しないこと に表している。
いずれの技術も最低限は使いこなせるレベルにいると自分では思っていたが、使えるからと言って、必ずしも使う必要はない、という当たり前のことを自分自身に繰り返し戒める必要がある。ここでも、「詳細についての決定は遅延させる」という『クリーン・アーキテクチャ』の教えを活かしながら、注意を払っていきたい。
世界の歴史を学ぶ
技術が世界に影響を与える、という逸話は多く流通しているが、その逆に世界が技術に影響を与える、というケースをいくつか学んだのは新鮮な経験であった。いずれも余暇のエントリとして、 トップレベルドメインと帝国主義 と 宗教と暦の「歴史的文脈」を担うDateTimeクラスに書いた。
自己紹介ページのアーキテクチャ解説
これはどうももっと以前の話題のように思われたが、今月の投稿であった。いま読み返すと、「こんなにたくさんのサービスを使いました!」というような見栄や虚栄があるような気がして、自分のことながらあまり好ましくは思えない。そう思えるだけ、批判的な思考を展開できているということだとポジティブに捉えようと思うが、あまり自慢できるエントリではないので、こうして末尾に目立たないように紹介しておく。
『クリーン・アーキテクチャ』を読んでフレームワーク中心主義からの脱却を考える
Hanami に触ってみたことを動機として、『クリーン・アーキテクチャ』を再読した。
たぶんに漏れず、例の同心円の図ばかり印象深く記憶していたが、改めて精読してみると、この図にはごく軽くしか触れられない。むしろ繰り返し主張され、議論の中心を占めるのは、「決定を遅らせること」というアドバイスである。
アーキテクチャの形状の目的は、そこに含まれるソフトウェアシステムの開発・デプロイ・運用・保守を容易にすることである。それらを容易にするための戦略は、できるだけ長い期間、できるだけ多く選択肢を残すことである。1
優れたソフトウェアアーキテクチャがあれば、フレームワーク、データベース、ウェブサーバー、その他の環境の問題やツールの意思決定を延期・留保できる。2
要するに、データ構造とアルゴリズムこそがソフトウェアの中核であって、フレームワークやデータベースなど、具体的なプロダクトやツールについては「その他の詳細」に過ぎないと言い切っている。
こうした主張は、僕に DeNA と任天堂による「Super Mario Run」リリース時の逸話を想起させた。
150ヵ国で同時にリリースし、リリース4日で4000万ダウンロードを達成したというモンスターアプリでありながら、バックエンドの構成を決定したのはリリースのわずか3ヶ月前だったという。
「『Super Mario Run』配信当日、そこに“ドラマ”はなかった」というキャッチーな見出しが付けられているが、これも要は、アプリケーションの中核となるビジネスルールはあらかじめ精確に定まっていて、そこにバックエンドを「プラグイン」するような構成になっていたためだろうと推測している。短期間での意思決定とリリースとはいっても、崩壊したプロジェクトのそれとは対極にある。改めて読み返してみても、「決定を遅延させる」という行為の絶好の例であろう。
アーキテクチャを守るためにフレームワークを捨てられるか?
一般通念を打破しようとする意図があってだろう。6部構成の最終部では、「データベース」「ウェブ」「フレームワーク」のそれぞれが、実際のところソフトウェアの中心どころか、取るに足らない詳細に過ぎない、と断定している。
「データベースは詳細」、「ウェブは詳細」、とここまではまあ理解できる。「フレームワークは詳細」と言われると、「そんな無茶な」と読まれる傾向があるらしい。というのも、ほかならぬ訳者ですら訳者あとがきにて次のように留保しているためである。
おそらく異論のある方もいらっしゃるだろう。私もすっきりしていない。たとえばウェブアプリケーションを開発するときに、フレームワークを選定しないことがあるだろうか?3
フレームワークから着手しないことが本当に正しいことなのかは、私にはまだよくわからない。本書で紹介されている例は、いずれも現代的なアプリの話ではない。4
とはいえ、「ウェブは詳細」である。「ウェブアプリケーション」という概念自体が、ウェブというデバイスとアプリケーションのロジックをすでに結合させてしまっている、ともとれる。ウェブでも、APIでも、RPCでも、バッチでも、手段に関わらずに常に中心にあるべきロジック、そこから設計していくべき、ということになるのであろう。
フレームワークとアプリケーションを結合させるのは危険だという主張は説得力がある。実際、われわれは通常フレームワークを従わせることはできず、フレームワークに従わされることになる。これは揺るぎない強制である。
Rails を例にとる。 Rails 6 で ActionText と ActionMailbox が追加されたとき、なぜ今になってこれらが機能追加されるのか、まったく意味がわからなかった。どうしてこのフロントエンド隆盛の時代に、こうした機能がビルトインライブラリとして提供されなければならないのか? と。
今になって思えば、これは hey.com への布石であったことがわかる。オピニオンリーダーでありトレンドセッターである DHH の手腕に文句はつけられない。hey.com はサーバーサイドレンダリングへの揺り戻しという文脈でも注目されているようだし、フロントエンド疲れもあってそれが新鮮に見えるのも確かである。なにより、この先どういう展開を見せるのだろうとワクワクさせられているのは事実である。
しかしつまるところ、 Rails とは初めから今までずっと、 Basecamp のプロジェクト向けに最適化されたフレームワークであるということを、改めて認識しなければならないだろう。
いうまでもなく、 Basecamp 自身が事業を立ち上げるに当たって、 Rails を利用するという選択肢は持たなかった。それどころか、そもそも開発言語に Ruby を選択するのだって、当時は相当にエッジの利いた判断だったのかもしれない。そのような環境から、今や揺るぎないフレームワークに上り詰めたアーキテクチャを生み出して、今の地位を築いている。このことは刮目に値する。
これを踏まえた上で立ち戻って、自分にこう問いかけてみる。「フレームワークは詳細」というのは無茶な主張だろうか?
無茶だと言いたくなる。しかしそれは実際には、「フレームワークがないと何もできない」という自分の未熟さを隠すために、議論を遠ざけようとする心の動きの現れではないだろうか?
オマカセからアラカルトへ
Rails によって御膳立てされた API を使っているだけでは、いつまでも「自分の味」が出せない。「自分の味」などという不安定なものが混入しないように、 The Rails Way という不文律が与えられている、という見方もある。しかしそれではいつまでも与えられているばかりで、進歩がないじゃないか? という思いで、こんな記事を以前書いた。
それから、シリコンバレーの Rails エンジニアのアティチュードをひとつの逸話として提示しているこの記事にも、示唆を受けた。
複雑な現実課題を解決するソリューションには、ありもののライブラリやフレームワークなどというものは存在しません。それぞれが自分の中に持った基礎的な道具を持ち寄って、その場でしか使えない「特別な鍵」を作り出す必要があります。基礎力のない応用はありえないのです。
フレームワークは便利である。ライブラリも便利である。しかしそれらは詳細に過ぎない。詳細をいくら知り尽くしたところで、現実の問題は得てしてそれよりも遥かに複雑であるはず。
現実のキャリアとして、フレームワークを拒否して業務を行うというのは難しい。研究職でもない限り不可能かもしれない。それでも、「フレームワークは詳細であり、些細なものである」という『クリーン・アーキテクチャ』の宣言は、これを心に留めるのとそうでないのとではキャリアの行く末すらも左右しかねないほど大きな認識を与えてくれる。
それはつまり、任意のフレームワークを使いこなそうとしていくら努力しても、ある意味でそれは徒労であるという認識である。
事業にしても、人生にしても、ありあわせの選択肢で満たせない要求というものは確実にある。既存の枠組み=フレームワークに振り回されるのではなく、より本質的な問題を発見し、取り組む。そういうスタンスをこそ、選択しなければならない。
そんな思いを、僕は「オマカセからアラカルトへ」という言葉に表した。そしてそれは『クリーン・アーキテクチャ』の再読を通していっそう深められている。