世界を動かす技術を、日本語で。

NIHは誤った依存関係よりも安価です

概要

  • 依存関係 には見落とされがちな コスト が存在
  • TigerBeetleのような ゼロ依存方針 の事例紹介
  • 依存関係評価のための 5つのフレームワーク 提示
  • 良い依存例とその評価基準の具体的解説
  • 依存選択時は 批判的思考 と慎重な判断が必要

コーディングにおける依存関係の誤解

  • 依存関係 は「無料の機能」と誤解されがち
  • 実際は 学習コスト導入コスト が発生
  • 複雑な依存 は自作よりも導入・習得が困難な場合も
  • インターフェース変更 による自前コードの大幅修正リスク
  • クライアント環境への配布デプロイの複雑化 問題
    • コンテナ化バンドル 設定の煩雑化
    • 本来の機能とは無関係な「新しい車輪」の再発明に繋がることも

TigerBeetleのゼロ依存アプローチ

  • TigerBeetleVanilla Zig のみで構築、 ゼロ依存方針
  • 依存関係は サプライチェーン攻撃安全性・性能リスクインストール遅延 の原因
  • インフラ基盤では 依存コスト がスタック全体に波及
  • 少数精鋭の標準ツール 運用によるシンプルな開発環境維持
  • Zig への投資で 新規課題 にも迅速対応

依存関係評価フレームワーク

  • 「自作シリコンウエハー論」等の極論は置いておく

  • すべての依存が同等ではないという前提

  • 5つの評価軸 を提案

    • 普及性 (Ubiquity)
      • 対象環境に 既に存在 するか
      • 導入やデプロイ の複雑化有無
    • 安定性 (Stability)
      • 破壊的変更非推奨化 の頻度
    • 深さ (Depth)
      • API・インターフェースの 裏に隠れた機能量
      • 自作困難度
    • 使い勝手 (Ergonomics)
      • 宣言的抽象化 か、APIの 快適さ
    • 水密性 (Watertightness)
      • 抽象化の漏れ の有無
      • 基盤技術 を意識する頻度
  • 依存推奨者は 使い勝手 のみを強調しがち。他の観点も重要

良い依存関係の例と評価

  • POSIXシステムコール

    • 普及性 :Linux, Android, macOS, BSD等で利用可
    • 安定性 :極めて高い
    • 深さ :open一つで数十万行のカーネルコード
    • 使い勝手 :やや古いが許容範囲
    • 水密性 :高いがストレージ仕様差に注意
  • ECMA-48ターミナル制御コード

    • 普及性 :ほぼ全ての主要ターミナルエミュレータで対応
    • 安定性 :1991年以降変更なし
    • 深さ :自作標準作成は現実的でない
    • 使い勝手 :エスケープ文字の煩雑さはあるが許容範囲
    • 水密性 :非常に高い
  • Webプラットフォーム(Web API, HTML, JS, CSS等)

    • 普及性 :地球上で最も普及したアプリ・ドキュメントプラットフォーム
    • 安定性 :後方互換性維持に注力
    • 深さ :ブラウザ自作は非現実的
    • 使い勝手 :多少の古さはあるがドキュメントとツールが充実
    • 水密性 :ファイル・音声・動画以外はほぼ水密

依存関係選択の心得

  • 悪い依存関係 の例は読者の練習問題として残す
  • コスト便益 を常に批判的に評価
  • 賢明な選択 の重要性

Hackerたちの意見

完全に同意だね。どの依存関係が良いか悪いかを見極めるのは、最も重要なスキルの一つだと思う。私の意見だけど、有料の依存関係はだいたい悪いことが多い。なぜなら、その依存関係を提供している会社には、ユーザーを縛りつけるインセンティブがあるから。あと、「依存関係ミニマリズム」っていうのはいい名前だね。

それに、有料の依存関係は通常、サポートが一つのソースしかないから、会社が倒産したり、製品のサポートをやめたりすると、厳しい状況になるよね。ほとんどの会社が永遠に続くわけじゃないから、自分のプロジェクトがその会社のサポート能力に依存していると、影響を受けるかどうかを考えなきゃいけない。

私の意見だけど、有料の依存関係はだいたい悪いことが多い。なぜなら、その依存関係を提供している会社には、ユーザーを縛りつけるインセンティブがあるから。ベンダーロックインは、購入したコンポーネントだけでなく、メンテナンスを引き受けたくない組織のFOSSにもリスクがある。サードパーティのコンポーネントを組み込むチームがリスクを管理し、適切な代替案を見つけて、ソリューションをモジュール化する責任がある。

有料の依存関係が悪いなら、もしかしたらその価値に見合った金額を払ってないのかも。私のコードに依存関係があるなら、それをサポートするのが自分の仕事だと思っている人がいるといいな。サポートするために十分な人数が雇われているか、あるいはそのコードに自分の価値やアイデンティティが強く結びついている人がいて、誇りを持ってサポートしてくれる必要がある。放置される可能性のある会社は要らないし、「バグは私の問題じゃない。ソースがあるから、自分で直せば?」って言うフリーソフトウェアの作者も要らない。そんな選択肢なら、自分で書いた方がマシだね。

非エンジニアのチームから強制された悪い有料の依存関係を経験したことがある。コミュニティで広く使われている「オープンコア」タイプの依存関係には、いくつか良い経験があるよ。例えば、sidekiqとかね。そういうのは、突然消えちゃう可能性が低いから、他の人たちにフォークされてメンテナンスされるだろうし。お金を払うメリットは、オーナーや会社が安定している限り、無給のソロメンテイナーが燃え尽きてログインしなくなる心配をしなくていいことだね。

https://opensourcemaintenancefee.org/ は、プロジェクトを続けるためのインセンティブとして支払いを利用しているから、依存関係を更新できるんだ。 .NET Rocks! が彼らにインタビューしたよ。 https://www.dotnetrocks.com/details/1948

開発者はこう言って、AWS LambdaやVercelにデプロイするんだよね、ほんとに。

そのアイデアは、もしお金を払っているなら、依存関係は何らかのオープンスタンダードやインターフェースを実装する必要があるってことだと思う。少なくとも他の実装に移行できる選択肢があるから、ベンダーはこの要件でロックインできないんだよね。ちょっと高くつくかもしれないけど、移行する選択肢は常にあるから、脅しとして存在しているだけなんだ。

エネルギー業界にいるから、依存関係は意図的に避けてるんだ。実際に変更をレビューしなきゃいけないからね。これを大いに助けてくれているのがAIコードアシスタンス。主な使い方は、ツールチェーンのコードや設定生成のためのCLIツールを書くことだよ。外部の依存関係を使わずに、生活を楽にするためのものなんだ。例えば、LLMを使ってopenapiドキュメントを作成して、それをGoのnet/http + FileServerで提供するから、標準ライブラリから出ることはない。もちろん、LLM自体はサードパーティの依存関係だけど、それを使ってCLIツールを書いてコード生成をするから、実際にはコードを見ることはないんだ。それにより、そのCLIツールの品質はあまり重要じゃなくなる。出力が大事だからね。もちろん、限界はあるけど。フロントエンドエンジニアたちがReactを使えない世界に住みたいとは思わないだろうけど、彼らの製品は外部のものとして扱われているからね。とにかく、「生活の質」を向上させる依存関係を使わないようにエンジニアを止めるのは、彼らの生活を楽にする何かを与えるとずっと簡単になるよ。

LLMは訓練された依存関係のコードを吐き出すだけじゃないの?それって、依存関係をフォークして自分のものとして扱うのと何が違うの?

著者はニュージーランド出身なんだ。これを理解するには、あそこに根付いている「ナンバー8ワイヤー」の考え方を知っておく必要があるよ。

今日は学んだこと。オーストラリアの「She'll buff out, mate」っていうミームを思い出した。

知ってる経験豊富な開発者は、ほとんどがこのアーティクルに同意すると思うよ。大体、みんな一度は間違った依存関係を使って痛い目にあったり、必要ないライブラリをアップグレードする時の面倒くささを経験してるからね。

純粋に雰囲気だけど、ニュージーランド人として言わせてもらうと、ナンバー8ワイヤーの精神はもう20年くらい前に死んでる気がする。

こういうことを言う人が多いけど、私の経験では逆だね。多くの人は新しいコードを書くのが好きで、ビジネスに悪影響を与えてもやっちゃう。でも、10回中9回は「悪い」依存関係を使う方が、社内で書くよりもずっと効果的だよ。

あなたの会社はセキュリティの脆弱性やライセンスについてどれくらい真剣に考えてるの?前は依存関係に対して結構緩い態度だったけど、そういうことを真剣に考える会社に入ったら、かなり変わったよ。

依存関係は二面性があるね。声を大にする人たちは「使い捨て」のソフトウェアに関わってることが多い。ソフトウェアの巨人たちは、組織の隅に追いやられたコードを維持するよりも、エンジニアの時間を使って書き直す方が安上がりなんだ。小さなブランドやウェブショップが高品質でメンテナンスしやすいコードを作る意味はあまりないけど、なぜ「エンタープライズパターン」が存在するのかを再考することをお勧めするよ。これらのアーキテクチャを使う主な理由は、5年後にドキュメントが古くなっても、そのコンポーネントに関する組織の記憶が残っていない状態で、元の開発者が別のチームや部署に移ったり、会社を辞めたりしても、コンポーネントがしっかりと隔離されていて、分析可能で作業が可能な状態を保つためなんだ。外部依存関係を導入することには、2つのビジネスリスクがある。依存関係のサポートが打ち切られる可能性があるから、自分でメンテナンスの負担を背負うか、依存関係を切り替えなきゃいけなくなるか、もしくは破壊的な変更が入る可能性があるから、メンテナンスされていないバージョンに留まるか、製品コードを更新しなきゃいけなくなる。どちらの状況も最終的には機能の流れに影響を与えるよ。トランクとリーフの妥協(依存関係のプッシュとプル)はモジュール化に内在していて、常に存在するけど、内部コンポーネントの場合はその妥協が内部的なもので、外部的なものではない。> 多くの人は新しいコードを書くのが好きで、ビジネスに悪影響を与えてもやっちゃう。でも、10回中9回は「悪い」依存関係を使う方が、社内で書くよりもずっと効果的だよ。もしあなたがSaaS企業なら、たぶんそうだね。短期的な成果がビジネスの成功を決定するから。でも、安全性やサポートの要件がある業界で働いているなら、長期的な視野がビジネスの成功を示すことになるよ。新しいコードを書くことは、成熟した組織ではほとんどボトルネックにならないからね。

NIHは、自分が何を引き受けるか現実的に考えれば素晴らしいよ。例えば、自分の問題領域に特化したオーダーメイドのウェブフロントエンド「フレームワーク」を維持するコストは、多くの場合正当化できるかもしれない。でも、データベースやゲームエンジン、ウェブサーバー、暗号化プリミティブなどについては、そうはいかないよ。もし既存のRDBMSやエンジンがサポートできないほど難しい問題を抱えているなら、その問題を解決する実用性を真剣に疑問視すべきだね。まだ発見していない理論的な制約や問題空間の見方があるかもしれない。問題を再整理する方が、SQLiteのテストスイートをゼロから再発明するよりもずっと安上がりだよ。

問題を再整理する方が、SQLiteのテストスイートをゼロから再発明するよりもずっと安上がりだよ。確かにそうだけど、既存のDBに満足していないなら、ファイルシステム上のファイルレイアウトの方が必要だと思ってるのは間違いかもしれないね。

サードパーティの依存関係を使う理由は二つ考えられる。1) サードパーティのサービスプロバイダーへの依存。もしそのサービスプロバイダーが現行であれば、依存関係はメンテナンスされるはず。2) 書きたくないコードのショートカット。1)には異論はないけど、ビジネス上の理由があってライフサイクルが一致するべきだよね。でも、アプリケーションを動かすためにはメジャーバージョンの破壊的変更があることは覚悟しておくべき。2)については、避けられるコードの複雑さに依存するから、得られるメリットはあまり明確じゃない。依存関係を持つということは、他の誰かが自分の時間を使って更新やテストをしなければならないことを決めることになる。サードパーティの依存関係を持つことは、コードベースを維持する責任を負うこと、またはそれを怠るリスクを負うことでもある。

あなたのRDBMSの例は面白いね。ここにはたくさんのRDBMSがあって(ウィキペディアには100以上のリストがある)、ほとんどのものが解決できない問題も多いけど、解決できるものもある。彼らは自分たちの解決策の実用性を考慮して、実装に進んだんだ。

じゃあ、なんでこんなに多くのデータベースエンジンがあるの?それぞれのデータベースのインスタンスはNIHのインスタンスなの?もちろん、答えは、どんな複雑なコンピュータシステムでもトレードオフをしなきゃいけないってことだよね。制約が必要か、スケーラビリティが必要か、同時実行性やセキュリティが必要か?データが特定の形式で、特定の圧縮可能なストレージ形式から利益を得る場合もあるし、書き込み一回読み取り多回の最適化が必要だったり、いろいろあるよね。記事の主旨、つまり依存関係のコストについてだけど、依存関係が自分の依存関係を最小限に抑えようとしているなら、私はその依存関係を受け入れるのがずっと嬉しいんだ。つまり、森のような依存関係を抱えたくないってこと。私の見解では、多くの自動依存関係管理システムが、彼らが解決しようとしている混乱を生み出すのを助けていると思うし、慎重な手動の依存関係管理が負担を減らすのに役立つよ。

RDBMSでは解決できない問題にすぐにぶつかるよ。データセットの同時変更をサポートするように作られているから、すごく制約されてるんだ。もしそれが必要ないなら、かなり単純なインデックス実装でも、データが不変であると仮定すれば、RDBMSよりも桁違いにパフォーマンスが出るよ。

データベース、ゲームエンジン、ウェブサーバー、暗号プリミティブなどについては同じことは言えない。多くの場合、絶対に言えるよ。- 多くのアプリケーションは、ファイルとランタイムインデックスさえあれば、あまり多くのデータベースを必要としない。データベースサーバーを立ち上げたり、SQLiteを埋め込むのは、場合によってはオーバーキルだよ。- 私の意見では、ほとんどのゲームはカスタムのゲームエンジンを使った方がいいと思う、特に小さなチームが作ったものはね。確立されたエンジンを使う唯一の本当の利点は、置き換え可能なアーティストのための慣れ親しんだアセットパイプラインだけど、それには大きなオーバーヘッドがかかる。カスタムエンジン、または少なくともゲーム開発者が維持している大幅に修正されたものが標準だったことを思い出して。最近のトレンドは「Unity^WUnrealを使え」って感じだよ。- シンプルなウェブサーバーとFastCGIアプリケーションの間に複雑さの違いはないよ。- 暗号プリミティブのすべての使用がセキュリティの問題になるわけじゃない。もしデータの破損をチェックするためにハッシュを計算するなら、それを自分で実装することもできるし(既存の実装をコピーすることもできる)、巨大なライブラリを取り込む必要はないよ。既存のデータをオフラインで復号化するのが目的なら、暗号セキュリティはあまり気にしないし、正しく復号化された出力が得られればいいんだ。こういうケースは他にもたくさんあるよ。「難しい」テーマに対する学習された無力感は誰の役にも立たない。既存の解決策があなたの問題を「解決」しているからといって、それが最良または最も効率的な方法だとは限らない。

あなたがどのような責任を持つかについて現実的である限り。トレーニングやオンボーディングも含めてね。「人気」のライブラリや言語、パターンなどが人気である理由があるんだ。ひとつの「勝利」は、タレントを探すときのネットワーク効果だよ。彼らは少なくともジョギングを始めることができるから。

NIHって何?記事をざっと読んだけど、二回読んでもまだ理解できない。Googleによると、国立衛生研究所って出てくるけど。

依存関係はリスクをもたらすけど、全く使わないと、使ってる人たちに対して競争で不利になるよね。彼らは開発時間や市場投入までの時間を早めてるから。必要なのは依存関係を管理するプロセスだね。1) オープンソースの依存関係だけを考慮する。2) 新しい依存関係を導入するにはレビューが必要。プルリクエストのコードレビューだけじゃなくて、ライセンスの確認、取り除くのにどれくらいの作業が必要かの見積もり、セキュリティの脆弱性やバグの履歴の監査、まだ更新されてるか、コミュニティの活気などをチェックすること。3) 可能であれば、依存関係のセキュリティ問題をレビューする。これを大規模にやるのはコストがかかるし、経済的な問題はまだ解決されてない(自分の考えはあるけどね: https://blog.majid.info/supply-chain-vetting/)。4) メンテナンスを引き継ぐ覚悟がない依存関係は採用しない。最低でも、一度はソースからビルドしてることが必要で、他の誰かが管理してるバイナリパッケージだけを使ってるのはダメ。5) すべての依存関係を事前にフォークしておく。人は気まぐれでリポジトリを削除することがあるからね、left-padの例を見てみて。

これは驚くほど洞察に満ちてる、ありがとう。これを今後使う依存関係の手続きファイルにコピーするつもり。唯一の問題は、JavaScriptの世界に見られるような非常に深い依存関係ツリーだね。

4)と5)はすごく重要だけど、しばしば忘れられがち。自分の小さなプロジェクトでも、長期間の休暇から戻ると依存関係が完全に古くなって使えなくなってたり、リポジトリが完全に削除されてたりすることがあった。だから「フォーク」方式を採用したんだ。依存関係のソースをプライベートでフォークして、依存関係をビルドする。これを彼らの依存関係にも再帰的に行って(言語レベルのライブラリで止める)、ビルドチェーンに慣れるためにね。それから初めて、その依存関係をプロジェクトに追加する気になれる(そして彼らの公開されたアーティファクトを使う)。ちょっと手間だけど、この努力は前もってかける価値があると思うし、プロジェクトが長生きすればエコシステムが変わるときに未来の手間を省けるからね(追従したくない時もあるし)。時々、事前にビルドされたバイナリよりもソースライブラリの方が良いと感じることもある。ソースをフォークしてプロジェクトにリンクするだけで済むから、依存関係のビルドチェーンについて学ぶ必要がないし。

5については、フォークするのはちょっとやりすぎかも。フォークを最新の状態に保つのは大きなメンテナンスの負担になるからね。でも、依存関係をベンダリングする(gitやgit LFSに突っ込むとか、キャッシュプロキシを運営するの)は有効だよ。特に長寿命のソフトウェアプロジェクトにはね。NodeJSベースのものにはあまり当てはまらないかもしれないけど、依存関係が小さなファイルをたくさん使うから。でも、YarnやPNPMがあれば、依存関係をもっと便利なアーカイブファイルに保管してくれるよ。

4と5について。少なくとも一度も、全てのコードはネットワークケーブルを抜いた状態でもビルドできるべきだし、できればバイナリアーティファクトなしでね。でも、それが常に可能とは限らないけど。

4については、時々同意するけど、SQLite(や他の似たような依存関係)は、私が作っている製品よりも100%長生きすることを認識しているよ。だから、自分の製品がそれらよりも長生きすると言うのはちょっと傲慢だと思う。依存関係だからってLinuxカーネルを作るつもりはないよ。

著者はTigerBeetleを例に挙げてるけど、私はそれを知らなかったから、調べてみた。すごいね。もしZigで安全性とパフォーマンスが最優先の金融台帳トランザクションデータベースをゼロから書いてるなら、1秒間に100万件のトランザクションを単一のCPUコアで処理できるようにするために、依存関係を導入するリスクを取る余裕なんてないよね。全くその通りだと思う(皮肉じゃないよ)。でも、平均的な開発者は、ほとんどの業務用CRUDシステムを書くとき、正直言ってそんなに強くない。ほとんどの依存関係はバグだらけのゴミかもしれないけど、でも多くの開発者ができることに比べれば、まだ質は高い。ほとんどの企業は、現実的に採用して維持できる才能のレベルにボトルネックがかかってるし、内部の開発基準は給与に見合った平均的なレベルを反映してる。だから、インターネットで読むアドバイスのように、みんなそれぞれの状況が違うことを忘れないで。真逆のアドバイスも、異なる状況ではどちらも正しいことがあるから。

開発者の質に関係なくてもいいんだよね。どんなツールチェーンや製品を使っても、他の誰かの依存関係を使ってるわけだし。場所によっては特にそうだけど、大抵の人は自分で行列の掛け算コードを実装してるわけじゃないし、実装してる人も、自分のビジネスに関係ないライブラリ#24を実装することはないよね。だから、この議論は白黒つけたがるけど、実際には人々が気にしてるのは、規制の義務があるかどうか、特定の実装に個人的な興味があるか、特定のライブラリに執着してるかってことだけ。誰もこれを完全に適用してるわけじゃないし、そうだったらまだビーチで砂を集めてるはずだよ。

TigerBeetleを例に出すのはあまり好きじゃないんだ。なぜなら、彼らは非常に新しいスタートアップだから。まだ1.0にも達してなくて、プロダクションリリースからちょうど1年ちょっとしか経ってない。彼らのアプローチが実際に成功したかどうかを判断するには早すぎるよ。

(私はTigerBeetleで働いています)+100、コンテキストが重要だよね。TigerBeetleもrust-analyzerも、物事の進め方に強い文化があるけど、_特定_の文化はかなり異なる。なぜなら、彼らは非常に異なる問題を解決しているから。とはいえ、あなたは依存関係の良い/悪いという議論に少しパターンマッチしているかもしれないし、TFAは別のレベルにあると思う。使われている依存関係の例に注目してみて:POSIX、ECMA-48、ウェブプラットフォーム。これらはライブラリじゃなくて、システムインターフェースだよ!ライブラリへの依存は大したことじゃない --- もしそれが問題になるなら、コードを再実装すればいいだけだ!でも、そのライブラリが行っている基盤となるものへの依存は、通常変更できないか、変更するのが非常にコストがかかる。自分のソフトウェアの範囲内で「Xをすることは可能か?」に「いいえ」と答えるのは強力だよ。兄弟コメントに言及すると、もし行列の掛け算コードを書くことがコアビジネスのチームがあれば、彼らはライブラリ#24を他の目的で使うことができるけど、しばしばソフトウェアデザインを適用すると、行列の掛け算を取り巻く製品は#24の問題を扱うべきじゃないって気づくかもしれない。#24の問題が全く扱われていないわけじゃなくて、むしろ全体のシステムをより良く分割して、重要な依存関係を区分けしようとしているんだ。

ここに著者がいるよ!TigerBeetleを指摘したのは、彼らが依存関係についての哲学を持っていて、かつそれを簡単に引用できる文書でオープンに話している数少ない会社の一つだから。成功したかどうかはわからないけど、「依存関係」という言葉を非常に広い意味で使いたかったんだ。ライブラリやサービスだけでなく、構築やデプロイに必要なものも含めてね。単に依存関係を使わないようにという呼びかけではなかったんだ。依存関係について考え、何に依存しているのかを明確にすることを呼びかけたんだ。TigerBeetleはそれを実践して、理由を示しているよ。

でも、平均的な開発者は、ほとんどの業務用CRUDシステムを書いているわけで、正直言って、最初からそんなに強くないんだよね。これはちょっと過激な意見だね。開発者は通常、自分が働くシステムを選ぶことはできないし、開発中にはリソースの制約がある。私たちは毎日トレードオフの決定をしていて、「安い」依存関係を取り込むことが、出荷される動作するソフトウェアと単なる「何もない」の違いを生むことが多いよ。あなたのこの意見は、かなり一般的で間違っているように見えるから、実際のソフトウェア開発にあまり関わっていないように感じるよ。

この考え方に対する俺の問題は、底辺の開発者についてだけ通用するってことだよね。技術の世界って、最低限のレベルに合わせてアドバイスを簡単にしがちだけど、正直言って、俺はそんな環境で働いたことない。開発者がクソみたいな依存関係の機能を複製しながら問題を解決できないなんてことはないと思うし。CRUDを馬鹿にするのが好きな人も多いけど、悪い抽象化はCRUD作業をしているチームにとっては本当に厄介な負担になることもあるよ。人気のあるものでも、基本的なことを繰り返すだけのチュートリアルをやっている限り、時間の無駄になることが多いしね。

ライブラリとフレームワークの違いについても触れたいな。ライブラリは特定のことをうまくやるツールで、フレームワークはアプリ全体の構造を決めちゃうものだよね。これは考え方としても大事。俺は主にGoの文脈でこの元の言葉を知ってるんだけど、コミュニティ全体(少なくともSlackサーバーにいる部分)は大きなフレームワークを避けて、標準ライブラリや軽量アーキテクチャ、専門的なライブラリを好んでるんだ。別の言語から来た人たちが「GoにSpringみたいなものはあるの?」って聞くことが多いし、Gin(ウェブAPIフレームワーク)やGORM(データベースORM)みたいな大きなフレームワークや抽象化についての助けを求めることもよくあるよ。でも、Ginはもうあまり必要ないかな。SDKが一般的なウェブAPIのユースケースにしっかり対応してるし、GORMは単一のテーブルをクエリする以上のことが必要になるとすぐに厳しくなるし、しかも大きくて複雑なのにリードデベロッパーが一人だけ(確か)で、背後に大きな組織もないからね。GinとGORMは少なくともアプリの一部の構造を決めちゃうけど、特に後者は間接的なレイヤーを追加するから、「SQLで二つのテーブルを結合するにはどうするの?」じゃなくて「GORMで二つのテーブルを結合するにはどうするの?」って聞かなきゃいけなくなって、これがすぐに専門的になっちゃうんだ。まあ、標準ライブラリを使うのが好ましいし、標準ライブラリでは解決できない特定の問題には小さくて集中したライブラリを使うのも全然アリだよ。必要な関数だけをコピー&ペーストするのも全然OK。

ECMA-48にはあまり感心してないな。昔、VT-100がVAXに接続されていたり、9600ボーのモデムでBBSにログインしていた頃は満足してた。ちょっとしたラインノイズがあってもね。1990年頃から「telnet」やxterm、CMD.EXE、他のGUIアプリケーションを使うようになってからは、100%正しく動くとは信じられなくなった。99.5%くらいは期待するけど、カーソルが本来あるべき位置から列がずれてたり、ちょっとしたずれがあったりするのは覚悟してる。周りの人は文句言わないけど、映画館でセンターのチャンネルが壊れてたり、Linuxデスクトップで59pxのスペースに179pxのラベルがあるときも文句言わないからね。これが理由でemacsを諦めて、知ってるviの20%だけを使ってる('i'を押してNotepadだと思い込む。ESC + :wqは^Sが検索だと混乱しないから)んだ。壊れたLinuxインストールにログインしてパッケージマネージャーを再起動させるときは、できるだけIntelliJ IDEAを使うようにしてる。

まあ、戦いの傷を持つ古い戦馬として言えるのは「それは状況次第」ってことかな。「それは状況次第」は、俺がやるほとんど全てのことのマントラになってるし、経験があれば「それは状況次第」の瞬間に道を選ぶ能力が身につくんだ。若い頃は、俺の世界は「硬直した」ルールに支配されてた。例外は許されず、俺が書いた最悪のコードのいくつかは、不適切なライブラリやパラダイムをプロジェクトに押し込むために必要な体操だった。俺は自己開発した依存関係をたくさん使う傾向がある。これは俺が頻繁にやることの要約だから、スタンドアロンのパッケージにまとめてるんだ。そうすれば、車輪を再発明する必要がなくなるし、品質と出所に自信が持てる。でも、必要な機能があって、自分ではどうしようもない理由がある場合は、品質や他の問題に納得できる限り、依存関係を含めることには常にオープンだよ。