えいのうにっき

a-knowの日記です

「UNIXという考え方」を読んだ

以前に、kabuという半分ネタのCLIツールを作ったことがあった。Goの手習いに、という目的もあったのだけど。

blog.a-know.me

今でも月に一度は使うくらいの(自分にとっての)便利ツールなのだけど、このコマンドについて、「コマンドとしてあるべき姿」といった観点で、同僚からいくつか指摘をもらうことができたことがあった(「ネタにマジレスだけど......」と前置きしつつとても丁寧に添削してくれた :pray: )。

  • 引数がない場合は標準入力から取ると良い
  • いま標準出力に出してるようなメッセージは、標準エラー出力に出すと良い。そうすると他ツールとの連携がしやすくなる
    • -verbose オプションを設け、それがonのときだけ出す、などとする
  • 候補が見つからなかったときは、non zero exit statusで終わるのが綺麗

こうした指摘は大変ありがたい一方で、「そういう感性みたいなものは、どうやって身につけられたんだろう......」とも感じていた。なにせ kabu は完全に雰囲気で作っていたので...。。そういう経緯もあって、上記の指摘のときに一緒にオススメされたのだったかどうかは覚えてないのだけど、「UNIXという考え方」という本を読む必要性を肌で感じ、このたびようやく読んだ。

結果、まさに僕にとってドンピシャな本だったのでとても良かった。それだけじゃなく、現代の「マイクロサービス」や「アジャイルな開発」、「OSSエコシステム」や「ポータビリティ」といったところにも通じるたくさんのエッセンスがあるな、とも思った。やはりこういうところの思想・哲学のようなものは何年経っても色褪せないなーと。

読書メモ

UNIXという考え方における9つの定理

  1. スモール・イズ・ビューティフル
  2. 一つのプログラムには一つのことをうまくやらせる
  3. できるだけ早く試作を作成する
  4. 効率より移植性
  5. 数値データはASCIIフラットファイルに保存する
  6. ソフトウェアの梃子を有効に活用する
  7. シェルスクリプトを使うことで梃子の効果と移植性を高める
  8. 過度の対話的インタフェースを避ける
  9. すべてのプログラムをフィルタにする

さらなる10のUNIXの考え方

  1. 好みに応じて自分で環境を調整できるようにする
  2. オペレーティングシステムのカーネルを小さく軽くする
  3. 小文字を使い、短く
  4. 木を守る
  5. 沈黙は金
  6. 平行して考える
  7. 部分の総和は全体よりも大きい
  8. 90パーセントの解を目指す
  9. 劣るほうが優れている
  10. 階層的に考える

肝に銘じたい

  • 巨大で複雑なプログラムの開発者は、「将来が予測可能で、そして現在とそう大きくは変わらない」という勝手な思い込みを前提としている。(P.22)
  • 「しのびよる多機能主義」(P.23)
  • 一つのことをうまくやるようにプログラムを作れないのであれば、おそらく問題をまだ完全には理解していないのだろう。(P.26)
  • 試作は、具体的に目標を示すことで全員の合意を醸成する。(P.31)
  • では、どのようにすれば、第三のシステムを作れるのだろうか? 最初に他の二つのシステムを作るのだ。それ以外の方法はない。(P.43)
  • ところが、次世代のハードウェアは10倍の性能向上を「ただ」で実現してしまうかもしれないのだ。ただし、この新しい高速なマシンの利点を活用するためには、ソフトウェアが移植できなければならない。(P.50)
  • UNIXプログラマはコードだけでなく、データにも移植性を持たせる。(P.57)
  • ASCIIテキストファイルの真の力を実感できるのは、UNIX上でパイプを使ったプログラムを開発するときだ。(中略)UNIXのプログラムの多くは、いくつもの小さなプログラムを一連のパイプで結んだだけのものと言えるかもしれない。(P.59)
  • 一般に信じられているところとは反対に、独自技術症候群は創造性を伸ばさない。他人の仕事を見て、自分のほうがうまくできると主張してみてもそれだけで創造性が増えるわけではない。既存のアプリケーションをゼロから設計し直すことは模倣ではあっても創造とは言わない。(P.71)
  • 生き残るために、企業は順応と独立という矛盾する二つの目標を目指すことを要求される。勝者となる条件は、車輪を発明し直すことではなく、既存の車輪を光らせることにある。(P.73)
  • アルバート=アインシュタインは、かつて「私は人生で2度しか奇跡を見たことがない」と言った。「一つは核融合、もう一つは複利だ」。(P.85)
  • 二つめに、小さなものは、人間とはよく馴染まなくても、互いにはよく馴染むということだ。(P.89)
  • 一般的なUNIXコマンドは、人間の介入を完全に排除して、すべての作業を実行しようとする。コマンドからのプロンプトは、何らかの不可逆なアクションを実行する直前に限られる。(P.93)
  • UNIXの長所の一つは、プログラム同士が効果的に対話することにある。(P.95)
  • ソフトウェアの梃子が働かないために拘束的プログラムは、その効果(および開発者の努力の効果)をコンピュータ世界に広めていくことができない。(P.97)
  • すべてのコンピュータとプログラムは、データをフィルタにかける。(中略)データを処理するとは、データをフィルタにかけることだ。(P.98)
  • コンピュータは、データの収集とフィルタリングを効率よく行えるようにする道具にすぎない。生成された「新しい」データは、実は少しも新しくない。(P.99)
  • UNIXプログラマがstdioをどう扱うかで、プログラムがフィルタとしてうまく機能できるかどうかが分かれる。(中略)要は、stdioを使用するようにソフトウェアを書くことだ。(P.101)
  • 入出力をハードワイアするという裏には、プログラムの使い道が完全に分かっているという思い上がりがある。(P.102)
  • ユーザーがソフトウェアをどう使うかは、決して予測できない。設計者である自分の意図に全員が従ってくれるはずだ、などとは絶対に考えてはならない。(P.102)
  • プログラムに何ができるかという内向きのことばかり考えず、プログラムがどういう場所に入り込めそうかを考えてほしい。そうすれば、プログラムを一部とする大きな全体が見えてくる。プログラムをフィルタとみなすとき、ソフトウェア設計者はアプリケーションを小さなプログラムに分割し、一つひとつにアプリケーションの一機能を受け持たせる。(P.103)
  • UNIXにおいては、言うべきことだけを言うのが重要だ。(P.114)
  • 90パーセントの解とは、難しい部分を故意に無視することを意味している。(中略)一番難しい10パーセントを無視してよいのであれば、世界中のほとんどの問題はすぐにでも解決できる。(P.119)

まとめ

いまは Web API: The Good Parts を読んでいて、Web API にも、UNIXという考え方は大いに適用できるなーと感じている。

UNIXの考え方とは、常に将来を見据えながらオペレーティングシステムとソフトウェアの開発にアプローチすることだ。そこでは、常に変化し続ける世界が想定されている。将来は予測できない。現在についてあらゆることを知っていても、その知識はまだまだ不完全なことは認めざるをえない。(P.144)

やっぱりこれは、世界にとって未来というものが不確かなものであり続ける限り、世界のプログラマが根底に近いところに持っていると良い、共通の哲学なんだろう。