UNIXという考え方
https://gyazo.com/00cc3f5c2556117dbc2815b3169eb124
イントロダクションより
UNIXの創造者たちは、ある極端なコンセプトから始めた。ユーザーは初めからコンピュータを使えるとみなしたのだ。UNIXは「ユーザーは、自分が何をしているかを分かっている」との前提に立っている。
これがすごい。この考え方とかアプローチって現代で何かサービスを作るときには絶対選ばないんじゃないかと思う。
でもこの思想が今日のUNIXの隆盛に寄与している部分が少なからずあるなら、この考え方を掘り下げてみるべきかもしれないと思った。
UNIXが生まれた背景から始まり、思想として重要な考え方から順に紹介されていく
定理1:スモール・イズ・ビューティフル
肌感覚でなんとなくそうだな、と思っていることが見事に言語化されている感じ。
小さなプログラムは、わかりやすく、保守しやすく、システムリソースにやさしく、他のツールと組み合わせやすい
そして小さいプログラムには、定理2:一つのプログラムには一つのことをうまくやらせる
上記はソフトウェアエンジニアの成長の話にもつながってくる。
最初から正しくソフトウェアを書くことは非常に難しい。ソフトウェアのエンジニアという職業には、継続的な改訂作業がつきものだ。試行錯誤は当然であり、嫌気がさすようなやり直し作業を数えられないくらい行って初めてアプリケーションが生まれる。〜中略
平均的な学習曲線は、平坦に伸びていき、徐々に急激な傾きになっていく。現代社会には、生涯を持ってしても完全な知識など得ることができないような専門分野が多くある。
こんな風にはっきり言われると勇気が湧く。
このような専門分野の一つに自分が身を置いていて、仕事として給料をもらって今働いていることがどれだけ幸運だろうと思う。一生かけても学び終わらないと分かっているなんて、こんなにワクワクすることはない。
定理3:できるだけ早く試作を作成する
「できるだけ早く」とは本当に「できるだけ早く」ということだ。「大至急」だ。
アプリケーションの立案に少しの時間をかけたらあとはまっしぐらに進め、と書いてある。
ついつい頭で考えて不確実なことに対してモヤモヤ考え込んで、立ち止まってしまうが、そうではない。先に手を動かしてみることだ。設計もやってるうちにうまくなるかもしれないなぁ。
試作によって学ぶ
試作によって何がうまくいくかが分かり、さらに重要なことに何がうまくいかないかが分かる
とにかくつくって、見せて、フィードバックをもらえ、と書いてある
早い試作はリスクを減らす
正しい設計は一つしかないのに対し、間違った設計は何百通りもある。〜中略 これらの試行錯誤は、籾殻をふるいにかけ穀粒だけを残す作業にも例えられる。
システムの三段階の話
第一のシステム→第二のシステム→第三のシステムと進歩していく
一人か、または数からなる小さなグループが作るらしい。そこではアイデアが一番大事で正しくやることは二の次。
まさに、できるだけ早い試作、を実践するということか。
荒削りながら人間の創造性・想像力を刺激するアイデアから小さく始まる第一のシステム
追い詰められた人間が作る第一のシステムを創る
第一のシステムをベースにしていろんな人が集まって(本書では委員会と揶揄されてた)大きく作り直される、ぜい肉がつき遅い第二のシステム
色んな人の合意をもって設計されるシステムは最大公約数的な観点からどんどん膨張していく
「専門家」が、第一のシステムで証明されたアイデアを用いて第二のシステムを作る
第二のシステムの反省を生かし、第一のシステムの思想(コンセプト)をしっかり受け継いで最良の特徴を備える第三のシステム
第三のシステムは、第二のシステムで「火傷」した人が作る
オリジナルのコンセプトはそのまま残り常識となる
定理4:効率より移植性
ムーアの法則によりハードウェアがどんどん改良されていく中で、一つのプラットフォームに特化したプログラムよりも、移植性の高いプログラムの方が有利であるという話。
よいプログラムは死なず、ただ新しいハードウェアに移植されるのみ
これエンジニアとか技術者にも言える。。。
さらに、「動かせないデータは死んだデータだ」とも。プログラムを早くすることより移植性を高めておく方が結果として得。
ハードウェアの特殊機能を利用して効率を高めようとすると、そのソフトウェアはハードウェアを売るための道具になってしまう。
なるほどこうやって言い切ると説得力が違う。ハードウェアで動く前提なのにハードウェアに依存しないということ
定理6:ソフトウェアの梃子(てこ)を有効に活用する
独自技術に偏ることなく、良いコードを借りてくる
よいプログラマーはよいコードを書く。偉大なプログラマはよいコードを借りてくる。
いわゆる巨人の肩に乗る。ということでもあると思う。そして、他の人がコードを梃子として使うのを認める、というのもすごくよく分かる。「コードは多くの人に引用された方がいい」というエンジニアのかっこいい文化はここからきたってことか
定理7:シェルスクリプトを使うことで梃子の効果と移植性を高める
シェルスクリプトをC言語で書き直す誘惑に負けない、とあるがこれは実行速度の話っぽいな
定理8:過度の対話的インターフェースを避ける
対話的プログラムの危険性
拘束的ユーザーインターフェースは問題点がいくつかある、とのこと
拘束的ユーザーインターフェースは対処すべき状況が少数のときに適している
結果的にユーザーが覚えるべきことが増える、ユーザーが人間であることを想定している、他のプログラムと結合しづらい、大きいものは美しい的なアプローチを取りがち、スケーラビリティに欠ける、などなど
定理9:全てのプログラムをフィルタにする
プログラムはデータを作らない。人間がつくる
コンピュータの出現以来、描かれてきた全てのプログラムはフィルタだ
Garbage in garbage out
さらなるUNIXの考え方
いくつか抜粋
沈黙は金
必要以上にプログラムに喋らせない、ということ
例えばコマンドに該当する結果がない場合何も出力しない、など
90%の解を目指す
何をやるにせよ、100%を目指すより90%を目指すほうが簡単だ。〜中略 一番難しい10%を無視してよいのであれば、世界中のほとんどの問題はすぐにでも解決できる。~中略
ソフトウェアが名前の通り、いつまでも「ソフト」ウェアにとどまり、ハードウェアになれない異常、100%の解を実装するソフトウェアはありえない。
SREの考え方に通じる。元ネタこれかな。
階層的に考える
UNIXでのタスクまたはプロセスも木構造になっている。プロセス番号1番がinitプロセスであり、木のルート(根)になる。その他のプロセス(ユーザーセッションを含む)は、initもしくはその子プロセスの子だ。
UNIXの考え方:総括
小さなプログラムには明らかな利点がある
人間にとって分かりやすい、理解しやすい、つまり保守も容易になる
システムリソースをあまり使わないので、読み込み→実行→開放がすばやく行える
他のツールと簡単に結合できる
その代わり、小さなプログラムは目的をしぼってひとつのことをうまくやることに専念する
大きくて複雑なプログラムになる危険を避けることができる
試作をできるだけ早く作る
作ってみて何がうまくいくか、いかないかを知ることが大事
試作は一つのことだけを行う小さなプログラムを使い、徐々に進める
ソフトウェアは作るものではなく、成長していくものである(だから移植性を優先する)
新しいハードウェア、新しいアーキテクチャは頻繁に現れる
移植できるソフトウェアは生き残る
新しい環境に移植できること(移植性)は効率より優先される
移植性のあるデータ(ASCIIフラットファイル)に保存すること
プログラマの仕事の結果は、誰のどのような仕事であれ、福利計算で増大し、大きな梃子の効果を発生させる。〜中略 誰かがすでにやっていることを改めてやり直すのは、時間の無駄だ。今日、世界に存在するソフトウェアは偉大な共有資産だ。種をまくだけでなく、実った稲穂は刈り取ろう。もちろん、合法的なやり方で。