Island Life

< 業界 | 教育について >

2011/11/25

多段ビルド文化

The price of a messy codebase: No LaTeX for the iPad - Valletta Ventures

表題から、増築を繰り返した老舗旅館みたいなコードベースは移植しようにも手がつけられないよ、って話かと思って読んだら、まあそうなんだけど、ちょっと違うニュアンスもあった。そんで複雑な気分になった。

基本的には、LaTeXをiPadに移植するために単一バイナリ化しようとしたけれど諦めたって話。 正確には、多段のビルドプロセス (大元のソースαをプログラムβで処理して得られた言語γのソースδを別のプログラムεによって言語ζのソースηに変換しそれをζコンパイラでコンパイルして得られるオブジェクトθとやはり言語ζで書かれた拡張ライブラリιをリンクして…) をさんざん苦労しながら移植してたんだけど、kpathseaがランタイムにbashスクリプトを呼んでそっから別のバイナリを呼び出してて、それを単一バイナリで実行するならbashインタプリタを内蔵しないとだめじゃん、ってとこで心が折れた、というようなことらしい。

まあ似たような経験あるからその気持ちはわかる。時々、ソフトウェアって庭つくりみたいだなと思うことがある。一度作ったら完成、ってんじゃなくって、継続的に手をかけてやらないと、色々枯れたり雑草が生えたりしてしまいには荒地と区別つかなくなる。昔のコードに戻って古いスタイルを整理していると、雑草取りしてるみたいだなあと感じたり。

ただ、元記事は要点がちょっと混ざってる気がした。(La)TeXのコードベースがレガシーを引きずってて無用に複雑化している、書き直せばもっとすっきりするはず、っていうのと、複数言語の混用とか多段のビルドが移植の障害になってる、っていう点。前者については完全同意なんだけど。

これは言語実装者の性向なのかもしれないけど、「ソースコードを生成する」というのに私はあまり抵抗がない、というより、少しでも「機械的に」ソースを書かなければならないことがあると積極的にそこを自動生成しようとする。Cがメインだった頃にもawkでプリプロセッサ書いて記述量減らしたりとか、Cソースをパーズしてメタ情報を取り出してインタプリタから呼ぶスタブコード生成したりとか。そうやって多段に抽象化を重ねられることがソフトウェアの強みなんだから、むしろそういうのを推奨すべきだと思ってる。

最近の統合開発環境に馴染めない理由のひとつは、統合開発環境が「ソース」→「バイナリ」の一段変換を前提としてデザインされている感じがすることだ。もちろん設定をいろいろいじれば、「まずこのソースをこのスクリプトで変換してからコンパイルして、出来たバイナリでデータを読み込んでソースに変換して、それを別のソースと合わせてコンパイル」みたいなことを記述できるけれど、一気に面倒臭くなる。makefileなら一段ビルドも多段ビルドも同じくらい簡単なのに。まあ、新しい技術についていけないロートルになっただけかもしれないんだけど、こういう多段生成をやりにくくするっていうのは、技術の大事な面をそぎ落としてるような気がするんだなあ。

言語内にメタプログラミングの機能があればソースからの一段変換前提でも色々なことが出来る。あるいはIDEにコード生成機能をつけてみたりとか。でもそれらは部分的な解決であって、単純な問題の一部だけを取り出して大げさに解決しているように見える。(C++のテンプレートは強力で、特に型に触れるところはLispのマクロより強いと思うけれど。例えば外部のデータファイルをコンパイル時に読み込んで宣言を生成したかったら?)

こういう多段の抽象化の積み重ねに自分が触れたのって、思い返すとKernighan/Pikeの『The Unix Programming Environment』でUnixを学び始めた時だと思う。既存のツールをシェルスクリプトで組み合わせる。それで足りなければ、足りない機能ひとつを実現するプログラムをCで書く。Cでの表記が冗長になるなら、「Cプログラムを生成するプログラム」を使う。この文化では、kpathseaが実行時にシェルスクリプトを呼び出すのは自然だ。それぞれの言語が得意分野を分担して、それを組み合わせて使えばいい。私はこの文化は「良いこと」だと思ってるので、それがレガシーになってしまうとしたらちょいと寂しい。

まあ、選択肢が「Cか、グルー言語(shとかawkとか)か」しか無かった時代(Lispはあったけど…)に比べ、今ではほぼ両方の領域をカバーできる単一言語の選択肢が増えているんで、今ならそういうスクリプト言語で全部書き直す、って選択肢はありだと思う。でも、多言語混在、多段ビルドがふさわしいものについて、「将来別プラットフォームへの移植が大変だから」という理由でまわりくどい単一言語、一段ビルドにこだわるのは、長期的にみて良くないんじゃないか。新しい抽象化は、それまで積み上げた抽象化の上に作られるものだ。 積み上げることを許さない環境は、新たな抽象化の芽を摘んでしまう。

レガシーなスクリプトの移植に関しては、新しい言語がそういうものを解釈できるようになってれば良いんじゃなかろうか。Gaucheでもいつかbash互換モジュールを書きたいと思ってるんだけど、なかなか手をつけられずにいる。それが出来たらログインシェルをgoshにするんだけど。

Tag: Programming

Post a comment

Name: