Loading...

百年言語

Original

2003年4月

(このエッセイは、PyCon 2003での基調講演から抜粋したものです。)

100年後、どんな生活をしているか予測するのは難しい。確実なことはわずかしかない。誰もが空飛ぶ車を運転し、ゾーニング法が緩和されて数百階建ての建物が建てられ、ほとんどの時間暗闇で、女性は全員武道に訓練されているだろう。ここでは、この絵の1つの詳細に焦点を当てたい。彼らは、それらの空飛ぶ車を制御するソフトウェアを書くために、どんなプログラミング言語を使うのだろうか?

これは、私たちが実際にこれらの言語を使うようになるからというよりも、もし私たちが幸運であれば、この時点からその時点までの道筋にある言語を使うことになるだろうから、考える価値がある。

私は、種のように、言語も進化の木を形成し、あちこちに枝分かれした行き止まりがあると考えている。これはすでに起こっている。

コボルは、その人気にもかかわらず、知的後継者を持たないようだ。それは進化の行き止まり、ネアンデルタール人の言語である。

私は、Javaも同様の運命をたどると予測している。「Javaが成功しない言語になるというのは、どうして言えるのですか?すでに成功している言語です。」と、時々メールで送られてくる。そして、私は、それが、本棚に置かれたJavaに関する本の量(特に、Javaに関する個別の本)、または就職するためにそれを学ぶ必要があると信じている大学生の数で成功を測るなら、そうであると認める。私がJavaが成功しない言語になると言うとき、私はもっと具体的なことを意味している。つまり、Javaはコボルのように、進化の行き止まりになるだろうということだ。

これは単なる推測である。私は間違っているかもしれない。ここで私が言いたいのは、Javaをけなすことではなく、進化の木の問題提起をし、人々に言語Xが木の上のどこに位置するかを考えさせたいということだ。この質問をする理由は、100年後、私たちの幽霊が「言っただろう」と言えるようにするためだけではない。それは、主要な枝に近づくことが、今すぐプログラミングに適した言語を見つけるための有用なヒューリスティックになるからだ。

いつでも、あなたは進化の木の主要な枝にいるのが一番幸せだろう。ネアンデルタール人がまだたくさんいたとしても、ネアンデルタール人であることはつらかったに違いない。クロマニョン人は、常にやってきて、あなたを殴り、あなたの食べ物を盗んでいただろう。

私が100年後の言語がどうなるかを知りたいのは、今、木のどの枝に賭けるべきかを知りたいからだ。

言語の進化は、種の進化とは異なる。なぜなら、枝が収束することがあるからだ。例えば、Fortranの枝は、Algolの子孫と融合しているように見える。理論的には、これは種にも起こり得るが、細胞よりも大きなものでは起こりそうにない。

収束は、言語の場合、可能性の空間が小さく、変異がランダムではないため、より起こりやすい。言語設計者は、他の言語から意図的にアイデアを取り入れている。

言語設計者が、プログラミング言語の進化がどこへ向かう可能性があるかを考えることは特に有用である。なぜなら、彼らはそれに応じて方向転換することができるからだ。「主要な枝にとどまる」ことは、良い言語を選ぶための方法以上のものになる。それは、言語設計に関する正しい決定をするためのヒューリスティックになる。

どんなプログラミング言語も、公理の役割を果たす基本的な演算子の集合と、原則としてこれらの基本的な演算子で記述できる言語の残りの部分の2つの部分に分けられる。

私は、基本的な演算子が、言語の長期的な生存において最も重要な要素であると考えている。残りは変更できる。それは、家を買うときはまず場所を考慮すべきだというルールのようなものである。他のことは後で修正できるが、場所は修正できない。

私は、公理が適切に選ばれているだけでなく、数が少ないことも重要であると考えている。数学者は常に公理についてそう感じてきた。公理は少ないほど良い。そして、私は彼らが何かを見抜いていると思う。

少なくとも、言語の中核を詳しく調べて、排除できる公理がないかどうかを確認することは、有益な練習になるはずだ。私は、だらしない人間としての長いキャリアの中で、ゴミはゴミを生み出すことを発見し、ソフトウェアだけでなく、ベッドの下や部屋の隅でもそれが起こるのを見てきた。

私は、進化の木の主要な枝は、最も小さく、最もクリーンなコアを持つ言語を通過すると感じている。言語の多くを自分自身で記述できるほど、良い。

もちろん、私は、100年後のプログラミング言語がどうなるかを尋ねることで、大きな仮定をしている。100年後も、私たちはプログラムを書いているのだろうか?コンピュータに何をしてもらいたいのかを伝えるだけではないのだろうか?

その分野では、これまであまり進歩が見られていない。 私の推測では、100年後も、人々は私たちが認識できるようなプログラムを使ってコンピュータに指示を与えるだろう。プログラムを書くことで解決しているタスクの中には、100年後にはプログラムを書かなくても解決できるものもあるだろうが、今日私たちが行っているようなプログラミングは、依然として多く存在するだろう。

100年後のどんな技術も予測できると思うのは、傲慢に思えるかもしれない。しかし、私たちはすでにほぼ50年の歴史を持っていることを思い出してほしい。過去50年間、言語は非常にゆっくりと進化してきたことを考えると、100年先を見据えることは、理解できることだ。

言語は、技術ではないため、ゆっくりと進化する。言語は記号である。プログラムは、コンピュータに解決してもらいたい問題の形式的な記述である。したがって、プログラミング言語の進化速度は、例えば、輸送や通信よりも、数学的記号の進化速度に近い。数学的記号は進化するが、技術で見られるような大きな飛躍はしない。

100年後のコンピュータが何でできているにせよ、現在よりもはるかに高速になることは確実である。ムーアの法則が続けば、74京(73,786,976,294,838,206,464)倍高速になるだろう。それは想像しにくい。そして実際、速度に関する最も可能性の高い予測は、ムーアの法則が機能しなくなるかもしれないということだ。18か月ごとに2倍になるはずのものは、最終的に何らかの根本的な限界にぶつかる可能性が高い。しかし、コンピュータがはるかに高速になることは、私は簡単に信じることができる。たとえわずか100万倍高速になったとしても、それはプログラミング言語のルールを大幅に変えるはずだ。その中には、現在では遅い言語とみなされている、つまり効率の良くないコードを生成する言語に、より多くの余地ができるだろう。

それでも、一部のアプリケーションでは、速度が依然として求められるだろう。コンピュータで解決したい問題の中には、コンピュータによって作られたものもある。例えば、ビデオ画像を処理する速度は、別のコンピュータが生成できる速度に依存する。そして、本質的に無限のサイクルを吸収する能力を持つ、別の種類の問題がある。画像レンダリング、暗号化、シミュレーションだ。

一部のアプリケーションがますます非効率になる一方で、他のアプリケーションがハードウェアが提供できるすべての速度を要求し続ける場合、高速なコンピュータは、言語がますます幅広い効率をカバーする必要があることを意味する。これはすでに起こっている。一部の人気のある新しい言語の現在の実装は、数十年前の基準からすると、驚くほど無駄である。

これは、プログラミング言語で起こるだけのことではない。これは一般的な歴史的な傾向である。技術が向上するにつれて、各世代は、前の世代が無駄だと考えていたことができるようになる。30年前の人々は、私たちが長距離電話をかけることをどれほど気楽にしているかを見て、驚くだろう。100年前の人々は、荷物がいつかボストンからニューヨークまでメンフィスを経由して送られることを、さらに驚くだろう。

私は、高速なハードウェアが今後100年で私たちに与えてくれる、それらの余分なサイクルがどうなるかをすでに知っている。それらはほとんどすべて無駄になるだろう。

私は、コンピュータの能力が不足していた時代にプログラミングを学んだ。私は、4KのTRS-80のメモリに収まるように、Basicプログラムからすべてのスペースを削除していたことを覚えている。このような途方もなく非効率なソフトウェアが、同じことを何度も繰り返してサイクルを燃やしていると思うと、少し気持ち悪い。しかし、私は、ここでの私の直感は間違っていると思う。私は、貧しい家庭で育ち、医者に行くような重要なことにもお金を使うのが我慢できないような人間のようなものだ。

一部の無駄は、本当に気持ち悪い。例えば、SUVは、たとえ枯渇しない燃料で走り、汚染物質を排出しないとしても、気持ち悪いだろう。SUVは、気持ち悪い問題に対する解決策だからだ。(ミニバンをより男性的に見せる方法。)しかし、すべての無駄が悪いわけではない。今では、それを支えるインフラストラクチャがあるので、長距離電話の時間を数えることは、些細なことのように思えてくる。リソースがあれば、相手がどこにいるかに関係なく、すべての電話を1つの種類のものとして考える方が、よりエレガントだ。

良い無駄と悪い無駄がある。私は、良い無駄に興味がある。つまり、より多くのお金を費やすことで、よりシンプルな設計を得ることができる無駄だ。新しい、より高速なハードウェアから得られる、サイクルを無駄にする機会を、どのように活用していくのだろうか?

速度への欲求は、私たちが貧弱なコンピュータを使っているため、非常に深く根付いており、それを克服するには、意識的な努力が必要になる。言語設計では、効率を犠牲にしてでも、利便性を少しでも向上させることができる状況を意識的に探すべきである。

ほとんどのデータ構造は、速度のために存在する。例えば、今日の多くの言語には、文字列とリストの両方がある。意味的には、文字列は、要素が文字であるリストのサブセットである。では、なぜ別のデータ型が必要なのだろうか?実際には必要ない。文字列は、効率のためにのみ存在する。しかし、プログラムを高速に実行するために、言語の意味をハックで乱雑にするのは、ばかげている。言語に文字列があることは、時期尚早な最適化の例であるように思える。

言語の中核を公理の集合と考えるなら、効率のために、表現力を何も加えない追加の公理があるのは、確かに気持ち悪い。効率は重要だが、それは正しい方法ではないと思う。

その問題を解決する正しい方法は、プログラムの意味と実装の詳細を分離することだと思う。リストと文字列の両方を持つのではなく、リストだけを持ち、コンパイラに最適化アドバイスを与える方法をいくつか用意して、必要に応じて文字列を連続したバイトとして配置できるようにする。

プログラムのほとんどでは速度は問題にならないため、通常は、このようなミクロ管理を気にする必要はない。コンピュータが高速になるにつれて、これはますます真実になるだろう。

実装について少なく言うことは、プログラムをより柔軟にすることにもなる。仕様は、プログラムが書かれている間に変化し、これは避けられないだけでなく、望ましいことである。

「エッセイ」という言葉は、フランス語の動詞「essayer」に由来し、「試す」という意味である。エッセイは、本来の意味では、何かを理解しようと試みるために書くものである。これは、ソフトウェアでも起こる。私は、最高のプログラムのいくつかは、エッセイであったと思う。つまり、著者は、書き始めるときに、正確に何を書こうとしているのか分からなかったのだ。

Lispのハッカーは、データ構造を柔軟に扱うことの価値についてすでに知っている。私たちは、プログラムの最初のバージョンを、すべてをリストで処理するように書く傾向がある。これらの最初のバージョンは、驚くほど非効率的であるため、少なくとも私にとっては、ステーキを食べるには、それがどこから来たのか考えないように意識的な努力が必要になるように、それらが何をしているのか考えないように意識的な努力が必要になる。

100年後のプログラマーが最も求めているのは、信じられないほど非効率なバージョン1のプログラムを、最小限の労力でまとめることができる言語だろう。少なくとも、それは私たちが今日の言葉で表現する方法だ。彼らは、プログラミングしやすい言語が欲しいと言うだろう。

非効率なソフトウェアは、気持ち悪いものではない。気持ち悪いのは、プログラマーに無駄な作業をさせる言語だ。プログラマーの時間を無駄にすることは、機械の時間を無駄にすることよりも、真の非効率である。これは、コンピュータが高速になるにつれて、ますます明らかになるだろう。

私は、文字列を削除することは、すでに私たちが考えられることだと思う。私たちはArcでそれを実現し、それは成功しているようだ。正規表現として記述するのが難しい操作のいくつかは、再帰関数として簡単に記述できる。

このデータ構造の平坦化は、どこまで進むのだろうか?私は、私の意識的に広げられた心でさえ、ショックを受ける可能性を思いつく。例えば、配列を削除するだろうか?結局のところ、配列は、キーが整数のベクトルであるハッシュテーブルのサブセットに過ぎない。ハッシュテーブル自体をリストに置き換えるだろうか?

それよりもさらに衝撃的な見通しがある。例えば、1960年にマッカーシーが記述したLispには、数字はなかった。論理的には、数字を別々に考える必要はない。なぜなら、数字をリストとして表現できるからだ。整数nは、n個の要素のリストとして表現できる。この方法で数学を行うことができる。それは単に耐えられないほど非効率的である。

実際には、誰も数字をリストとして実装することを提案したことはない。実際、マッカーシーの1960年の論文は、当時、実装されることを意図していなかった。それは理論的な練習であり、チューリングマシンに対するよりエレガントな代替案を作成しようとしたものである。誰かが、予想外に、この論文を取り上げて、動作するLispインタプリタに変換したとき、数字は確かにリストとして表現されていなかった。それらは、他のすべての言語と同様に、2進数で表現されていた。

プログラミング言語は、数字を基本的なデータ型として削除するほどにまで行くことができるのだろうか?私は、これを深刻な質問というよりも、未来とチキンレースをする方法として尋ねている。それは、抵抗できない力と動かせない物体が衝突するという仮説的なケースのようなものである。ここでは、想像を絶するほど非効率的な実装と、想像を絶するほど豊富なリソースが衝突している。私は、なぜそうではないのか理解できない。未来は非常に長い。言語の中核の公理の数を減らすことができるものがあれば、tが無限に近づくにつれて、賭けるべき側のように思える。もし、100年後もその考えが耐えられないように思えるなら、1000年後にはそうではないかもしれない。

これを明確にしておきたいのだが、私は、すべての数値計算が実際にリストを使って行われることを提案しているのではない。私は、実装に関する追加の記号の前に、言語の中核がこのように定義されることを提案している。実際には、数学をある程度行いたいプログラムは、おそらく数字を2進数で表現するだろうが、これは最適化であり、言語の中核の意味の一部ではない。

サイクルを燃やすもう1つの方法は、アプリケーションとハードウェアの間に、複数のソフトウェア層を持つことである。これも、すでに起こっている傾向である。最近の多くの言語は、バイトコードにコンパイルされている。ビル・ウッズはかつて、経験則として、解釈の各層は速度が10分の1になる、と私に言った。この追加のコストは、柔軟性を買っている。

Arcの最初のバージョンは、この種のマルチレベルの遅さの極端な例であり、それに対応する利点があった。それは、Common Lispの上に書かれた古典的な「メタ循環」インタプリタであり、マッカーシーのオリジナルのLisp論文で定義されたeval関数と明確な家族的類似性を持っていた。全体でわずか200行のコードだったので、理解して変更するのが非常に簡単だった。私たちが使用したCommon Lisp、CLispは、バイトコードインタプリタの上に実行される。したがって、ここでは、2つのレベルの解釈があり、そのうちの1つ(上位の解釈)は驚くほど非効率的だったが、言語は使用できた。ほとんど使用できない、と認めるが、使用できた。

ソフトウェアを複数の層として書くことは、アプリケーション内でも強力なテクニックである。ボトムアッププログラミングとは、プログラムを、それぞれが上の層のための言語として機能する一連の層として書くことを意味する。このアプローチは、より小さく、より柔軟なプログラムを生み出す傾向がある。それはまた、聖杯である再利用性への最良の道である。言語は、定義上、再利用可能である。アプリケーションの多くを、そのタイプのアプリケーションを書くための言語に押し下げるほど、ソフトウェアの多くが再利用可能になる。

何らかの理由で、再利用性の概念は、1980年代にオブジェクト指向プログラミングに結び付けられ、それとは反対の証拠がいくらあっても、それを取り除くことはできないようだ。しかし、一部のオブジェクト指向ソフトウェアは再利用可能だが、それを再利用可能にしているのは、オブジェクト指向であることではなく、ボトムアップであることである。ライブラリを考えてみよう。ライブラリは、オブジェクト指向のスタイルで書かれていようがいまいが、言語であるため、再利用可能である。

ちなみに、私はオブジェクト指向プログラミングの終焉を予測しているわけではない。私は、オブジェクト指向プログラミングは、特定の専門分野を除いて、優れたプログラマーにはあまりメリットがないと考えているが、大企業にとっては魅力的である。オブジェクト指向プログラミングは、スパゲッティコードを書き続けるための持続可能な方法を提供する。それは、プログラムをパッチのシリーズとして蓄積することを可能にする。

大企業は常に、このような方法でソフトウェアを開発する傾向があり、これは100年後も今日と同じように真実であると予想される。

未来について話す限り、並列計算について話す必要がある。なぜなら、その考えはそこに住んでいるように思えるからだ。つまり、いつ話しても、並列計算は、将来起こるもののように思える。

未来は、それに追いつくのだろうか?人々は、並列計算を、少なくとも20年間、差し迫ったものとして話してきたが、それはこれまで、プログラミングの慣習にあまり影響を与えていない。それとも、そうではないのだろうか?すでに、チップ設計者はそれを考慮する必要があり、マルチCPUコンピュータでシステムソフトウェアを書こうとしている人々も、それを考慮する必要がある。

真の疑問は、抽象化の梯子をどのくらいまで並列処理が登っていくのかということだ。100年後、それはアプリケーションプログラマーにも影響を与えるのだろうか?それとも、コンパイラライターが考えることであり、通常はアプリケーションのソースコードでは見えないものなのだろうか?

可能性が高いことの1つは、並列処理の機会のほとんどが無駄になるということだ。これは、私たちに与えられる余分なコンピュータ能力のほとんどが無駄になるという、私のより一般的な予測の特殊なケースである。私は、基礎となるハードウェアの途方もない速度と同様に、並列処理は、明示的に要求した場合にのみ利用可能であり、通常は使用されないものになると予想している。これは、100年後の並列処理は、特殊なアプリケーションを除いて、大規模な並列処理ではないことを意味する。私は、通常のプログラマーにとっては、すべてが並列に実行されるプロセスをフォークできるようなものになると予想している。

そして、これは、データ構造の特定の実装を要求することと同様に、プログラムの寿命のかなり後半、最適化しようとしたときに、行うことである。バージョン1は、通常、並列計算から得られる利点、およびデータの特定の表現から得られる利点を無視する。

特殊な種類のアプリケーションを除いて、並列処理は、100年後に書かれるプログラムに浸透することはないだろう。そうすれば、時期尚早な最適化になるだろう。

100年後、プログラミング言語はいくつあるのだろうか?最近、新しいプログラミング言語が大量に生まれているように見える。その理由の1つは、高速なハードウェアにより、プログラマーは、アプリケーションに応じて、速度と利便性の異なるトレードオフを行うことができるようになったことである。これが本当の変化であれば、100年後には、私たちが持つハードウェアは、それをさらに増やすだけだろう。

それでも、100年後には、広く使用されている言語はわずかしかないかもしれない。私がそう言う理由の1つは、楽観主義である。本当に良い仕事をすることができれば、遅いバージョン1を書くのに最適な言語を作り、コンパイラに適切な最適化アドバイスを与えることで、必要に応じて非常に高速なコードも生成できるだろう。だから、私は楽観的なので、100年後のプログラマーは、許容可能な効率と最大効率の間に大きなギャップがあるにもかかわらず、そのほとんどをカバーできる言語を持つだろうと予測している。

このギャップが広がるにつれて、プロファイラはますます重要になるだろう。現在、プロファイリングにはほとんど注意が払われていない。多くの人々は、高速なアプリケーションを得る方法は、高速なコードを生成するコンパイラを書くことだと信じているようだ。許容可能なパフォーマンスと最大パフォーマンスのギャップが広がるにつれて、高速なアプリケーションを得る方法は、一方からもう一方への良いガイドを持つことであることが、ますます明らかになるだろう。

私が、言語がわずかしかないかもしれないと言っているとき、私はドメイン固有の「小さな言語」を含めていない。私は、そのような埋め込み言語は素晴らしいアイデアであり、普及すると予想している。しかし、私は、それらが、ユーザーが下にある汎用言語を見ることができるほど薄いスキンとして書かれると予想している。

未来の言語を設計するのは誰か?過去10年間で最もエキサイティングなトレンドの1つは、Perl、Python、Rubyなどのオープンソース言語の台頭である。言語設計は、ハッカーによって引き継がれている。これまでの結果は、混乱しているが、励みになる。例えば、Perlには、驚くほど斬新なアイデアがいくつかある。多くは驚くほど悪いが、それは常に野心的な努力に当てはまることである。現在の変異速度では、100年後、Perlが何に進化するのか、神のみぞ知る。

できない者は教える、というのは真実ではない(私が知っている最高のハッカーの何人かは教授である)。しかし、教える者ができないことがたくさんあるのは事実である。研究は、制約的なカースト制限を課す。どんな学問分野にも、研究できるトピックとできないトピックがある。残念ながら、許容されるトピックと禁止されるトピックの区別は、通常、研究論文で記述されたときに、その仕事がどれほど知的であるかによって行われ、良い結果を得るためにどれほど重要であるかによって行われるわけではない。極端な例は、おそらく文学だろう。文学を研究している人々は、それを制作している人々に少しでも役立つようなことを言うことはめったにない。

状況は科学ではより良いが、許される仕事のタイプと、良い言語を生み出す仕事のタイプが重なる部分は、驚くほど小さい。(オリン・シバースは、このことについて雄弁に不平を言っている。)例えば、静的型付けは、私の意見では、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、静的型付けは、真のマクロなしでは、どんな言語も使う価値がないにもかかわらず、