Spinach Forest

February, 2025

/ Link: johnousterhout/aposd-vs-clean-code   / Long Flu   / Link: Tracing Summit 2022 - Analysing Perfetto Android traces at every scale - YouTube   / インフラ・プロセス・速さ   / Links of January   / ... 

Link: johnousterhout/aposd-vs-clean-code

GitHub - johnousterhout/aposd-vs-clean-code: A discussion between John Ousterhout and Robert Martin about differences between John's book "A Philosophy of Software Design" and Bob's book "Clean Code".

"Philosophy of Software Design" aka POSD の著者 John Ousterhout と "Clean Code" の著者 Bob Martin が GitHub 上で文通をした結果が HN に流れてきたので興味深く読んだ。

しょうじき内容自体はそんなに興味深くはなかったが、著者同士が直に議論をするフォーマットは好感が持てた。みてこの commit history. ふたりで仲良くやってんじゃん、ほほえましー。

内容としては John Ousterhout が Clean Code のいくつかの主張を攻撃し、Bob Martin がそれを擁護するという展開。これだけ読むと John Ousterhout は随分ぶしつけだな・・・と思ってしまうが、Clean Code が年月を経て(一部で)権威化したという事実を踏まえると、まあいいんじゃないか。

内容への感想はどうかというと、厳密な TDD (テストを先に書く) は無益有害というのは、そうですねと頷く。

TDD は、単体テストが一般的でなかった頃に行われたアジャイル過激派による thought provoke 目的のアクティビズム/カルトなので、単体テストが一般化した昨今に真顔で主張を貫き続けるのは厳しい。一方、その時期のアクティビズムに傾倒して価値観を内面化しすぎたおっさんはなかなか抜け出せない。Bob Martin のコメントを読むと泥沼感が伝わってくる。

個人的には Bob Martin が変に言い訳せず「TDD は・・・ワシの青春なんじゃよ・・・ッ」って俯きがちに吐き捨てればみんな涙をウルっとさせて許してくれると思うんだけど、そういう non-verval communication ができないのは文通スタイルの限界かなと思う。どのみち John Ousterhout はそういう emphathy なさそうなのでダメかもしらんが。読者は許してくれるよ。たぶん。

Clean Code 再読 (しなくていい)

自分は POSD はそんな好きでもなく過去の2つくらい苦情を書いている。

上の悪口を書いたあと、フェアネスのためにいちおう Clean Code も再読したのを思い出した。今よむと、なんというか、かなりどうでもいい本だったね。いま売れ行きを気にせずタイトルをつけるとしたら「Uncle Bob の Java Style Guide Java 5 Edition」みたいなかんじだろうか。

昔の、Java の言語機能がショボく、かつ最先端がゴテゴテエンタープライズフレームワークに振り切れつつ、もう一端では static おじさん (死語) みたいな人々がゴミコードを量産していた時代には、こういう議論は新鮮で、意味があった。でも Java がプログラミングの主役の座をよりモダンな言語に譲り、また言語に限らずフレームワークとかも市場原理の力で OSS のシュッとしたデザインが標準となった昨今、こんなこまっちいルールとかどうでもよくね・・・と思ってしまう。

「Uncle Bob の Style Guide」と言ったのは、議論の粒度が Google Java Style Guide みたいなんだよね。こういうのには別にいいとか悪いとかはなくて(あるが)、それよりは誰かが決めて一貫させておき、無駄に消耗しがちな論争を予防する役割がある。Clean Code も、OSS 隆盛以前のエンタープライズ Java が主役だった時代には一定程度そうした役割を果たしただろうし、その当時どこかの CTO や TL が「うちの Java は Clean Code で行く!」とか言い出してドグマを押し付けてきても、会社や開発チームくらいの粒度なら一貫性の価値が抑圧の被害に勝ったかもしれない。

ただ「残念なエンタープライズ Java 暗黒時代に射した希望の光」という文脈を超えて人々が Clean Code を信奉しすぎた結果、そのドグマによる抑圧と思考停止の被害が広がりすぎた。John Ousterhout はそこに苦言を呈したと言える。

文脈

文脈といえば、そもそもこの二人の話が噛み合うはずも無いよなあ。BM は言うまでもなく Enterprise Java の人である。一方の John Ousterhout は OS のカーネルや分散システムインフラの人。価値観が違うし、その違いは分野の要件の違いを反映している。

たとえば Bob Martin が「複雑さ」と言ったとき、その複雑さは Enterprise の複雑さであり、ビジネスロジックの複雑さである。ビジネスロジックの複雑さというのは数学的な複雑さというより、慣習や法規や歴史的経緯などなどによって積み重なった幾千の、時に理不尽な、そしてコロコロ変わる、ルールやフローである。そういう問題を、なんとかしてモデルを作って理解・保守しようと試みるというのが、たとえば DDD / Ubiuqitous Language であった。

一方の OS や分散システム。OS のシステムコールとかそんなコロコロ変わらない。一方で下位互換性、しかもコードレベルじゃなくてバイナリ互換性、みたいのを求められる。そりゃ「細かくメソッドわけて」とか言われたらキレたくなるし、「深いインターフェイス」みたいなこと言い出すのもわかるわ。ioctl() とかモダン言語を生きる人から見たらゴミかもしれないけれど、色々仕方ない面はある。

John Ousterhout の複雑さ、分散システムの複雑さというのは、アルゴリズムの複雑さであり数学的な複雑さである。John Ousterhout は合意形成アルゴリズム Raft の論文を共著したガチ勢で、授業でも Raft を書かせているらしい。John Ousterhout にとってプログラムの複雑さといったらこういうやつなわわけ。分散アルゴリズムのような、ある意味「本質的な複雑さ」は、ちょっとコードをリファクタリングしたくらいでは解決しない。だから Clean Code を読んでもピンとこない。

でも Bob Martin のいってる複雑さはそれじゃないのだよ。もっと世俗的で、しょーもない複雑さなんだよ。そしてわけもなくしょっちゅう変わるんだよ。Raft とかアルゴリズムをいじろうと思ったらもう一本論文かける勢いだけど、「ビジネスロジック」とかもう毎週みたいな勢いで変わるわけじゃん。そういう「モデル」を破綻させないのも何らかのスキル。扱っている複雑さの種類が違う。

ただこうした複雑さの多様性を理解していないのは John Ousterhout だけでなく、Bob Martin も同じである。先の議論で、John Ousterhout は Clean Code に載っていた素数計算のコードを非難している。曰く、リファクタリング結果が解りやすくなっていない。

この批判は正しい。件のコードは Knuth の改良版 sieve で、ある種のアルゴリズム的複雑さを孕んでいる。Bob Martin はコードをいじりながらロジックを理解したが、それはコードをいじるという行為が理解を助けただけで、第三者にとってのわかり易さを助けていなかった。こうした、エンタープライズとは違う「複雑さ」への無理解と、無理解に伴う傲慢さを John Ousterhout は嗅ぎつけた。Bob Martin が文通の中で「わかりやすいバージョン」としてレイテンシを倍にする悪手をうち、John Ousterhout がブチ切れる一幕がある。Bob Martin の感度の低さが伝わってくる。アルゴリズムの教科書に載ってるコードが難しいのは、それなりにわけがあんのよ。

一方で、John Ousterhout がエンタープライズ Java... じゃなくてもよくて Android でも Web でもなんでもいいんだけど、アプリケーションレイヤで客や PM の突きつけてくる無理難題をそつなく取り込みつつ肥大化していくコードベースの秩序を保つとか、出来るとは思えないのだよね。そして John Ousterhout のまわりにはそういうのに興味ある人いなそうじゃん?同僚にも生徒にも。 CMU ならともかく Stanford の分散コンピューティングの研究室だからねなにしろ(スタートアップやってる卒業生の話とか出てくるけど)。Bob Martin と話が噛み合わないのもやむなし。

内省

John Ousterhout も Bob Martin も、わりかし限られた文脈で話をしていた。Clean Code が「Uncle Bob の Java Style Guide Java 5 Edition」で、Philosophy of Software Design が 「Prof Ousterhout のインフラレイヤプログラミングガイド」とかだったらなんの喧嘩も起きなかった。(後者の方が若干カッコいいが、それは時代なので仕方ない。)

どちらも主語がデカすぎた。

翻り:これは専門家、第一人者になることの対価だと見ることも出来る。Bob Martin は、今はさておき当時は Java, Agile 界の第一人者だった。John Ousterhout は...どうみてもガチ専門家なわけです。そうやって自分の世界に深く切り込んでいる人々が他の分野に多少疎いのは仕方ないし、自分の立場に強い信念があるのも分かる。自分とかなんの専門性もなく鼻ほじりながら外野で騒いでるだけなので好き勝手言ってるけど。

ついでにいうと二人とも割といい年である。 John Ousterhout は年齢を超越した謎の現役感があるのに対し、Bob Martin は年相応にセミリタイア、メンテナンスモードの風情がある(ウェブサイトとか)。二人とも 70 過ぎてこんなガシガシ GitHub 文通やってるのすごいよね。

とはいえまだ先の長い我々はあまり年寄りの話を真に受けすぎず、もっと現役な人々の声に耳を傾けるほうが良いのではないか。Ageism と言われたら言い返せないけど、もしかしたらこの文通も「おまえら若者が Clean Code vs POSD とか言って時間を無駄にしないように年寄り同士で話をつけて SEO も済ませたから前を向いて生きなさい。」というメッセージ、かも、しれないですよ?

Long Flu

二週間すこし前の今月初頭に flu にかかった。その後熱は下がったのだが、咳やだるさ、微熱がなくならない。自分が喘息持ちなせいもあり、咳はもともと長引く傾向があった。しかしだるさや熱が長引くのは困る。

そういえば七年前にもひどい風邪(たぶん flu) をひき、そのときも全然治らなかったのを思い出した。記録によれば1月にかかって3月にもまだ直りきってないと書いている。夏くらいには元気になっていた気がするが、そういえば甲状腺ホルモン異常もあってしばらく通院し、フィナーレは帯状疱疹だった・・・。

これって Anti-Viral Fatigue だよなあ。Long COVID のおかげで認知度があがった、どのくらいで治るのなのかわからない厄介者。七年前には名前も知らなかった。

当事者としては、回復を待ちつつ日常はよく寝て無理せずやり過ごすほか、特にできることはない。ただ depression を伴いやすいようなので、心の健康には気をつけないといけない。しかし脳内麻薬を出せるような心拍を使う運動はできず、そりゃ気分もめげるわ・・・。

七年前と違うのは、まず今は喘息の薬を処方されているので咳や気管支の症状が悪化しにくいこと。あと "Anti-Viral Fatigue" というラベルがついたので「治んねえなーくそー」とかイライラせずに賽の目を待つ諦めがついていること。不安があるとすれば七年分の加齢で、昔ほど元気じゃないことだろうか。

もう一つうっすらと不安なのは勤務先の景気。しばらく仕事がはかどらないのは確実なわけだが、そんなタイミングで "lower performer からレイオフでーす" とか言われるとクビになってしまう。7 年前も、チームをうつった直後だった不慣れと重なって過去最低の人事考課スコアを記録してしまった。七年前は景気が良かったから給料が下がるだけで済んだけど、今はなー。病人に不景気成果主義は厳しい。

とはいえ無理に働いても体がついてこなそうなので「元気になるまでしばらくは低調ですが許してちょうだいね」と上司に heads up する必要がある。はーあ。

家事負担もなんとか調整しないといけないが、こちらもメンテナンスモードで許してね、というしかない。とはいえ妻にしわ寄せると cascading failure の可能性が増すからそれはそれで・・・はーあ。家庭内 services を gracefully に degrade するっていうのは一つのスキルなんだけど、言うは易しである。


日本の昔話や童話にはしばしば「病気がちな母・祖母」が出てくる。布団に横になって咳をしていたりする。ああいうのも anti-viral fatigue / chronic fatigue syndrome だったのではないか。なぜ母や祖母が多く父や祖父ではないのというと、女性の方が罹りやすいのと、父や祖父や無理して働いて死んでしまったんじゃない?過労死もジェンダーバイアスあるよね多分。

わたくしも父ですがリベラル現代人なので女々しさを恐れず無理せずやってこうと思います。はい。願わくば夏までには元気になりたい。

追記 (March 10)

これを書いた(Feb 20)翌週くらいから徐々に体調が回復し、今はほぼ回復したかんじがする。走るとすぐ疲れるが、症状というより体力が著しく落ちているからな気がする。しばらくは徒歩で慣らし、再来週くらいからはまた走れるようになりたい。というわけで一ヶ月と一週間くらいかかった感じ。Long ナントカを名乗るほどではないが、まあ、なかなか治らないものです。

Link: Tracing Summit 2022 - Analysing Perfetto Android traces at every scale - YouTube

https://www.youtube.com/watch?v=eWF3h0VW1mk

Android の中の人がどうやって Perfetto を使っているかという tech talk. 社内ベータユーザから様々なタイミングで Perfetto trace を収集し、それをバッチで集計している。

自分ものこのインフラでカメラアプリの性能解析をしている。個人的には今のしごとの中で一番面白いところだなと思っている。Long tail の問題を白日ものとに晒すことができてすごい。

この講演が三年前 2022 で、ここで紹介されている Batch Trace Processor というのはその 1-2 年前からあって、今はそれよりちょっと洗練された(が機能としてはだいたい同じような)インフラにアップグレードされていて・・・というかんじで、結構前から色々ある。

が、自分たちは去年から今年になってようやくこの「マスで解析する」というのを有効活用できるようになってきた感じ。長いこと宝を持ち腐れていたと反省する。でもまあ、他に low hanging fruits というか table stake みたいなしょーもない仕事がいろいろあっていそがしかったんですよ・・・。

Perfetto の全体像はこちら。

https://www.youtube.com/watch?v=C10gmidnw7A


Perfetto と Kotlin はここ 10 年くらいで Android dev に起こった数少ない良いことだと言える・・・と言おうと思ったら Android Studio も 10 周年らしい。まあここ 5 年くらいと言ってもいいかもしれない。Kotlin は五年以上前からあるけどまあ、自分のなかではそんなもんです。

インフラ・プロセス・速さ

ZUCKERBERG: We’ve changed our internal motto from "Move fast and break things" to "Move fast with stable infrastructure."

Mark Zuckerberg on Facebook's Future, From Virtual Reality to Anonymity | WIRED

Zuck 氏が "Move fast with stable infrastructure." と言ったのが 10 年前。

Feature Flags の必要性

アプリの社内ベータリリースを派手に壊した若者が retrospective を書いたというので眺めていると「単体テストのカバレッジが足りませんでした。テスト真面目に書きます。」と書いてあり、固まってしまった。いや、テスト書くのはいいんだけどさ・・・。

「フラグがあるといいんじゃない?」とコメントしたら若者の上司が出てきて「うちのチームでも会社全体でも、フラグの外側でバンバンコード書いてんじゃん?アンラッキーな事故だよ」という返事。ふたたび固まってしまった。

あんたそれ稼ぎ頭のアプリ相手に言ってごらん・・・。


インターネット動画部門のアプリチームで仕事をしていた頃、すべての変更はじっさいフラグの裏で行われていた。リファクタリングさえも、明らかに安全なものを除けばフラグの裏だった。毎週のように出ていくリリースで何かが壊れるとアラートがあがりチャットが開かれ、ばばばっと問題のフラグが特定され、壊れる挙動はサーバからのフラグデータ更新で無効化される。これは動画部門に限った話ではなく何億人もユーザがいる他のアプリたちでも同じだと思われる。同じインフラが使われているし。

そのむかし大企業で働き始めた頃「このプロジェクトは revert first だから、何かが壊れたら怪しい変更はバンバン revert するんだよ」と言われて感慨を受けた。フラグプッシュで問題を直すのはその先を行っている。バイナリを配り直さない。モバイルのようにバイナリの再配布が難しい環境ではフラグに圧倒的優位がある。

もちろんこれは、特にサーバ側の世界では特段珍しい話ではなく、アプリが使っているフラグの仕組みもそっちの世界から来たものである。Devops の国 Amazon の Builder's Library には、フラグやリリースをロールバックする時に壊れないようちゃんとデザイン・テストしようななんて話まであるわけ。だからさ、いまどきフラグくらい面倒がらず使ってくれよ。

Feature Flags の面倒臭さ

・・・と思ったが、ここでふと思い返す: そういう洗練された世界のフラグ地獄に音を上げ、この荒くれ者チームに戻ってきたんじゃなかったっけ?

Feature flag first が徹底し、全てが Controlled Online Experiment な世界に住む人のコミット一覧を見ると、アプリのコードを書くよりフラグの設定をいじるコミットの方が多い。フラグの追加・削除だけでなく、rollout のようなデプロイ作業もバージョン管理されており(えらいね!)、いつもなにかしらフラグを触っているのが見える。ちょっと粒度のあるタスクを始める最初の作業がフラグの追加。そんな世界。

大きな機能追加だと、むしろフラグを足したあとしばらくはその裏でコードを書く時間が続くので相対的に面倒は少ない。一方で既存コードをリファクタリングするのは大変。IDE がサポートする完全に副作用フリーなリファクタリングならともかく、それなりにエッジケースのある非純粋な「リファクタリング」をしようとおもったら、やはりフラグ。

フラグで隠すリファクタリングには独自の難しさがある。いつも Branch By Abstraction みたいに綺麗な切り口があるわけではない。フラグ歴の長いエンジニアはごく自然にその離れ業をやってのけるが、比較的 junior なエンジニアは苦労しており、結果としてリファクタリングは諦められることが少なくない。結果として複雑さは段々と積み重なり、コードベースを扱いにくいものにしていく。

これは (特にアプリでの) feature flag first が持つ本質的な複雑さで、避け難い。積み上がったゴミを一掃しようとたまにすごいシニアなエンジニアがでてきて新しいフレームワークとかを導入するが、移行は数年がかり。前の大変更が終わらないうちに次の大変更がやってきたりする。それぞれ別のフラグの裏で。ちょっとまって!たすけて!

Moving "Fast" and Not Breaking Things

Feature flags や experimentation, 段階的 rollout といった洗練されたインフラを使うのは、サービスを壊さない、止めないためである。何億人もが使うサービスを止めると色々問題があるし、金銭的な被害も無視できない。

究極的には "velocity" のためとも言える。サービスは止められない、サービスが止まると、すべての進捗は問題が解決するまで止まってしまうから。洗練されたインフラの流儀に従えば blast radius が小さくなり、サービス全体を止めなくて済む。

つまりフラグは個々のエンジニアの velocity を下げるかもしれないが、インフラのおかげで安定性を犠牲にすることなく開発人員を増やせる。そのスケーラビリティは個々人の低速化を補ってあまりある。

開発人員を増やすのが常に良いアプローチとはいえない。けれどサービスがスケーラブルな問題を扱っているなら・・・これは巨大なインターネットサービスはだいたいそうだが・・・人員追加によるスケールアウトは普通。こうしてインターネット大企業は大きくなってきた。冒頭の Zuck 発言も同じ趣旨と言えよう。

個人の視座

インターネットサービスにおいて Feature Flags は正しい。Online Experiments は正しい。Staged, Continous Rollout は正しい。それはサービスとしての速さを支えているから。

しかし開発者個人としてはどうか。フラグや実験はめんどくさい、時間もかかる。認知負荷も高い。必要なのはわかっているからやめろとはいわないが、楽しくはない。しかもフラグの「楽しく無さ」は、ミーティングのような一時的に我慢すれば済む通り雨的かったるさではなく、仕事の楽しさのコアであるコード書き体験全体に影を落とす税金的かったるさである。一番の楽しみがうっすらと損なわれる(あなたがリファクタリングパズル愛好家でない限りは - 巨大インターネットサービスのアプリ開発者として偉くのに必要な素養の一つには違いない)。

巨大インターネットサービスを覆うそんなフラグ文化を、マイナー電話機付属アプリを作っているだけの荒くれチームに布教してしまっていいのだろうか。その戦いを自分は信じているのか。社外には continous delivery なんてせずリリース前にブランチを切ってきちんと安定させるんだから、社内ベータくらいたまに壊れてもいいじゃない?数千人くらいユーザいそうな気がするけれど・・・。

そういえばフラグを押し返した件の上司はもともとはアプリの開発者。アプリに飽きて社内ライブラリチームを立ち上げたのだった。今回壊れたのもそのライブラリ。まあ気持ちはわかるよね。ライブラリ内部の書き換えに関するフラグなんて、いちいち公開・フリップしたくないよな。めんどくさい。

代償の払い方

インターネットサービスでもないんだし、たまに社内ベータが壊れるくらいいいじゃない。でかい変更を隠すフラグは必要だけど、何から何までフラグに隠せなんて言いたくない。

基本的には賛成したい姿勢だが、躊躇がある。なぜか。

と、バグが起きた時にけっこうな確率で自分が "triage" に巻き込まれるからだろう。他人のおこしたバグの分析を押し付けられ数時間・一日潰れる。自分の仕事は進まない。うんざり。しかも急ぎの仕事でめちゃストレス。これは安定しないサービスを保守する開発者が毎日のように pager によばれ疲弊/Burnout するのに似ている。自分は burnout すると困る妻子持ちなのでなんとかしないといけない。

ここでの教科書的な答えは 1) 辞める か 2) 近代化にむけて立ち上がる、なわけだが、1) は失敗しており、失敗した理由の一つは 2) の現実が気に入らなかったからなので、教科書的でない答えを模索する必要がある。

それについては、また今度。

Links of January

パブリックな日々の箇条書きをやめているので、リンクくらいは残しておこうという試み。


電話機周辺

エーアイ

DeepSeek R1

どうでもよいもの・政治


以上。