なぜ〇〇というプログラミング言語は流行らなかったのか?
最近、私は古くからあるプログラミング言語に興味があり、LispやSmalltalkなどの言語に興味があります。触っていくうちに、結構面白いな。と思うことがあるのですが、それほど人気があるとは言えません。
例えば、プログラミングの人気を表すTIOBE Indexでも、ランクが高いとは言えませんし、それらの言語はプログラミング言語の歴史。という中で、ちょっと学ぶぐらいで、それほど詳しくは知らない。という人が多いでしょう。
Quoraを探してみると、「Lispはなぜ覇権を握らなかったのでしょうか?」の回答であったり、「Smalltalk が広く使われなくなったのはなぜですか?」という回答が見つかります。
そのように各プログラミング言語に関する言説を読んだり、実際に使って見たり、歴史を紐解いていくうちに、思うことがあったので、まとめたいと思いました。かなりポエム的です。
現在、プログラミング言語の中で、流行っている・流行っていないものとの違いは、
インターネットの登場以後にプログラミング言語が設計されているか?
だと思うようになりました。
この記事は、比較的古い言語について考察する記事であり、比較的新しい言語、RustやNim、Zigなどの言語のどっちが伸びそうか?ということを考察する記事ではありません。
ソフトウェア開発に関する年表
以下の年表は「プログラミング言語」「ソースコード管理システム」「パッケージ管理システム」「プログラミング言語特化のパッケージ管理システム」「インターネットの歴史」の5つの視点からまとめたものです。
ある時、「プログラミング言語に優劣などほとんどない。難しいプログラミングなど必要なく、ライブラリを切り貼りする程度でソフトウェア開発は十分。重要なのはどれほどのライブラリを利用できるかである。」という言説を見ました。この言説は私のものではないですが、一旦では納得する部分もあるな。と思いました。確かに、最近のプログラムの"難しい部分"というものはラップされがちで、それをライブラリ経由で叩くことが多く、どれだけユーザーを獲得し、ビジネスを回すか?いかにPMFできるか?みたいなもので、技術投資をするのではなく、UXを磨きこみ、ユーザーの反応をいち早く見るためにビルドアンドスクラップを高速に回すことが重要である。というのが、少し前の流れかな。ということを考えていました。
まぁそれが技術者として正しいのかは不明ですが、その言説を支えているのは、おそらく大量のライブラリであり、ライブラリを検索できる機構であるのではないか?と考えました。では、その「ライブラリ管理・パッケージ管理システムっていつ頃できたのだろうか?」という疑問が生まれました。
Perlのパッケージ管理であるCPANは有名ですが、それ以前にCTANというものがあったそうです。これは、組版のTeXのパッケージ管理システムだそうです。このファーストリリースが1992年です。
その後で、Debian系であるdpkg,aptの流れであったり、Cent系であるrpm,yumの流れを追い始めました。dpkgが1994年、aptが1998年。rpmが1997年、yumが1999年である。ということが分かりました。
この辺りで、 パッケージ管理システムの最初が1990年代に集中している。 ということが分かり始めました。
そのあと、言語固有のライブラリ管理を調べていきました。JavaのMavenであったり、Rubyのgems。Pythonであればeasy_installなど、とりあえず思いつくだけ調べていきました。
そうすると、 1990年以降に作られた言語は、言語固有のパッケージ管理システムが多いが、1990年以前に作られた言語には、言語固有のパッケージ管理システムが少ない。 ということが分かり始めてきました。
このように言語固有のパッケージ管理システムに関して、議論してきましたが、最後に「ソースコード管理システム」に関して調べていきました。ソースコード管理システムとは、少しずれますが、「ソースコードの共有」という文脈で、1971年に策定されたFTPを上げています。ソースコード管理に特化した古典的なシステムには、SCCSというシステムが1972年に作られたそうです。よく知られているシステムであれば、CVSが1990年、SVNが2000年に作られています。2005年頃、BitKeeperとLinux周りの軋轢からリーナスがGitを作り始めました。その周辺では、SVNやCVSのような中央型のソースコード管理システムから、分散型への興味が高まり、Mercurial(2005)やBazaar(2007)なども作られていました。このようにソースコードの分散管理が主流になってきたのは主に2005年以降であることが分かります。
調査を進めていく中で、1990年あたりで、時代を分かつものがあるな。ということが分かり始めてきました。では、それが何か?と考えると、 インターネットの普及 かな。ということを思うようになりました。1982年、4.3BSDでTCP/IPがOSレベルで実装されました。ただこの時期のBSDはAT&Tのライセンスを必要としていたようです。1991年に、CERNが初めてWebページを公開しました。その後、ライセンス的にフリーなUnixであるLinuxの1.0が1994年に公開され、TCP/IPやInternetExplorerが搭載されたWindows95が1995年に販売されました。この辺りから日本にもインターネットが普及したように思います。
古典的なプログラミング言語を学んだ感想
最初、私はLispについて学び始め、Paul GrahamのOn Lispを読んでいました。Paul GrahamはYahoo!Storeの原型をLispで作り、売却した人であり、Y CommbinatorというVCを作った人でもあります。これを読んだ後、LispでREST APIでも書こうと思って、色々調べたのですが、どうもライブラリのインストール周りが分からない。いや、なんとなくわかるんだが、そもそもどんなライブラリがあるかが分からない。npmぐらいの楽さでインストールできるかと思ったらそうでもないらしい。Wikipediaによると
LISPは実装の容易さゆえに非常に多くの方言を生んだ。マクロを用いれば文法構造それ自体を拡張できるので、ある意味では利用者ごとに方言があるとさえいってよい。1970年代から1980年代にかけては、大きく分けてMACLISP系とInterlisp系の二つの主流が存在し、後のLISP方言に影響を与えている。
という風にLispというものは、のちにANSIで標準化されるようですが、元々処理系によって癖が割とあるようです。「そのため、Lispってもしかしてパッケージ管理しても処理系の方言のために再利用性が低いから、あまりそういうライブラリを再利用する文化圏ではない・・・?」みたいなことを思い始めました。
次に、私はSmalltalkについて学び始めました。Smalltalkに関する入門はオージス総研のオブジェクト指向再入門が非常に良かったです。Smalltalkは、ほぼほぼGUIが前提となる作りで、開発環境自体が一種のOSめいた動きをするような仕組みになっています。
興味の一端として、これをどのように分散開発するのか?どのようにバージョン管理するのか?という疑問がありました。Smalltalk界隈のソースコード管理は割と特殊で、その特殊性がよくまとまっているのが、この「Source Code Management with Pharo Smalltalk - Pharo Smalltalkソースコード管理方法」です。上記の記事によると、その特殊性からSmalltalkのソースコードがgithubで割と楽に管理できるようになったのは、2012年のFileTreeを待たないといけなかったようです。
また、旧来のパッケージ管理であったMCZでは、リポジトリサーバーが乱立してしまったり、依存関係の解決がうまくいかなかったり(それを手動で解決する必要があったり)とコードの再利用が難しい一面があったようです。そして、また似たような話で趣味でライブラリを使ってみようと思いましたが、Lispと同じ話で、パッケージ管理が少ないため、どんなライブラリが使えるのかが分からない。インストール方法もよく分からない。ということがSmalltalkでも起こりました。
もう1つ古典的な言語と、コードの再利用性に関して、Wikipediaのシェルスクリプトの欄に以下のような記述があります。
また、プラットフォーム間の互換性問題もある。Perlの作者ラリー・ウォールの有名な言葉として「シェルスクリプトを移植するより、シェルそのものを移植する方が簡単だ」というものがある。
という風に古典的な言語、シェルスクリプトは移植が難しい(≒再利用性が低い)ことが分かります。
(ただし英語版Wikipediaでも引用文献がないため、本当にラリー・ウォールが言ったのかは疑わしい面があります。)
インターネットとプログラミング言語
今の技術だと結構簡単にLispって作れちゃうんですよね。私自身、Pythonで書くLispインタプリターは1日で出来ました。
それは、Smalltalkでも言えて、「Smalltalkだめ自慢」というスライドで指摘されています。
Smalltalkの場合、予約語がnil,true,false,self,superの5つしかないですし、Lispの場合、文法構造は全てがS式ですし、予約語的なもの(SpecialForms含め)は、20程度しかないです。(純LISPなら9つ程度)
そのため、基礎的なものだったら結構簡単に作れます。このように作るハードルが低いものは、処理系の乱立が起きて、相互の処理系の互換性が難しい状態になります。
また、小さな処理系で短いコードを目指すとモジュールの独立性も今ほど厳しくなく、namespaceやpackagingなどの概念も希薄になりがちです。この辺は、環境へ密結合するシェルスクリプトの移植性が低い問題と近い話でもあります。
しかし、インターネットの登場によりソースコードの流動性が飛躍的に高まり、モジュールの再利用性が容易なものが求められるようになりました。そうすると、インターネット以前にデザインされたプログラミング言語は、モジュールの再利用性が低く、インターネット時代に活躍できなくなってきました。そのため、パッケージ管理システムも作られることなく(そもそもパッケージ管理を作るのに向いていないプログラミング言語でもある)、主流から外れていった。一方で、インターネット以後にデザインされたプログラミング言語は、モジュールの再利用性が高くデザインされることになったので、パッケージ管理システムが作られたり、インターネットと相互に発展することになった。と、言えるのではないか。と思いました。
ただし、この理論では全部のプログラミング言語は説明できなくて、C/C++言語はメインとなる言語のパッケージ管理システムが無いにも関わらず今でも使われています。1つ理屈として考えられるのは、aptやyumなどがパッケージ管理を担ってる。とは、言えなくないかな?というところはあります。
まとめ
- インターネット以前のプログラミング言語は、
- 仕様自体が簡単で、処理系が乱立しやすかった。
- 流動性が低いため、自分で書く割合が多かった。そのため、環境と密結合した手早く書けるプログラミング言語が好まれた。
- モジュールの再利用性が低かった。
- インターネットが普及し、ソースコードの流動性が高まった。
- 他人が作ったモジュールを使いたい社会圧が高まった。
- プログラミング言語のモジュールの再利用性が重要となった。
- インターネット普及後のプログラミング言語は、
- モジュールの再利用性を重要視されデザインされた。
- インターネットによりライブラリが流通するようになった。
- パッケージ管理システムとともに広く使われるようになった。
したがって、
インターネットの登場以後にプログラミング言語が設計されているか?
= プログラミング言語におけるモジュールの再利用性や独立性が保たれているか?
が、現在の、「プログラミング言語の流行っている・流行っていないの分け目」になっているのではないか?という仮説です。
感想
過去に、npm registryをプライベートで管理しているプロジェクトに参加したことがあります。そのとき、パブリックなnpm registryにあるモジュールと、プライベートなnpm registryにあるモジュールを共存させて使うのがまぁまぁめんどくさいなぁ。と思ったことがありました。もう手順もあまり覚えていませんが、npmのコンフィグをいじったりする必要があって、一発で npm install 的な感じではインストールできなかった記憶があります。これは、npmというモジュール管理のデザインが中央集権的なもので、そもそもあまり分散した管理を目指していないからかな。と思っていました。
私自身は、2017年ぐらいにGoを少し触り始めましたが、最初はパッケージ管理はglideで、その次はdepで、最終的には今の標準のgo modに落ち着いては居ますが、Goというのは結構、(よく経緯は知りませんが)この周りは紆余曲折あったなぁというイメージです。そんな中で、最終的にGoが選んだスタイルというのが、import "github.com/gin-gonic/gin"
みたいなデザインで、ライブラリ自体の管理も分散化するのが前提な時代かなぁと思うようになりました。
最近、「ご飯食べに行くのに、大体事前に食べログの点数とか見るよね?」という話もあるように、インターネットによって人間の行動が変わった。という側面はありますが、それはプログラミング言語の設計にもあるのかなぁ。と思った調査でした。