(サイトの範囲とは異なる方向に進む長い回答をおologiesびします。率直に言って、ここで最初に質問を見て驚いた…)
TeXは、プログラミングではなく組版用に設計されました。プログラミング言語として考えた場合、せいぜい「奇妙」です。
—ドナルドクヌース、デジタルタイポグラフィ、 235ページ
私はここ数年、TeXの初期の歴史(1977年頃)とKnuthが書いた多くのことについて多くのことを読みました。私の結論は、「プログラミング言語としてのTeX」について話す瞬間、すでに何かが間違っているということです。
我々は(見る前に書かれたTeXのために早期の「設計書」を見ればTEXDR.AFT
とTEX.ONE
に発表された、デジタルタイポグラフィ)、それはクヌースは、主に組版するためのものシステムの設計されたことは明らかであるコンピュータプログラミングのアートを(彼は言っている(例えばここ)彼が念頭に置いていた主なユーザーは彼自身と彼の秘書でした)、適切に修正すれば、より一般的に役立つかもしれないという考えで。タイピングを節約するために、繰り返し行う必要のある作業(たとえば、TAOCPが著者からの引用を含める必要があるたびに、特定の量だけ垂直に移動し、特定のラインスキップを設定し、特定のフォントを選択し、右揃えで引用し、別のフォントを選択し、著者の名前をタイプセットします...)、マクロがありました。
残りを推測できます。TeXにあるのは、コミュニティ(コンピューター科学者と数学者、そしてDEK自身も(残念ながら)「非難する」)の中で起こったことを除いて、「偶然チューリング完全」(もっと)の場合です。これを無視するには賢すぎる。(伝説によれば、Michael SpivakはTeXに出会う前にプログラミングしたことはなかったが、彼はそれに夢中になって、現在存在する最も複雑なマクロセットの1つであるAMS-TeXを書くことになった。)多数のシステム間で移植可能であること(当時は大したことでした)に、TeXですべてを実行する誘惑が常にありました。その上、彼のコンパイラ作成経験のため、KnuthはTeXをコンパイラのように作成し、ときどき1つと説明しました。入力で動作するプログラムが「コンパイラ」であれば、間違いなくプログラミングされているでしょう。
この回答では、KnuthがTeXでプログラミングを行うことを意図していなかった方法と、「キックと叫びの後でのみTeXのプログラミング機能の多くを投入した」方法についてもう少し読むことができます。私が言ったように、彼の意図が何であれ、人々はTeXマクロシステムを(ab)使用してプログラミングの驚くべき偉業を達成する方法を見つけ始めました。クヌースは、この魅力的なと(はTeXの自体にいくつかの機能を追加することに加えて)の付録D「汚い手口」でこれらのいくつかが含まれていTeXbook、それは、名前にもかかわらず、判明していること 9 10例の外にある、その中に」 LaTeXの実装で使用されます。」
別の言い方をしましょう:LaTeXは、レスリー・ランポートがTeXの上にアイデアとして書いたマクロシステムであり、素晴らしいものです。(Knuth)TeXのページ指向の方法ではなく、セマンティックで構造化された人間指向の方法で(または、Lamport が視覚的にではなく論理的に)文書を作成するのは素晴らしい方法です。しかし、「適切な」プログラミング言語ではなく、TeXマクロを使用してLaTeXのような複雑なものを実装することは、私の考えでは、少なくとも今日行われた場合、巨大な間違いと不当な倒錯行為の間です。Knuth でさえ、TeXマクロですべてを行う代わりにTeXプログラムを拡張するだけではないことにショックを受けています。
今日、「プログラミング」を行うためのはるかに優れた方法があります。ほとんどの人々のコンピューターで広く利用可能な多くの言語のいずれかで外部プログラムを使用できます。またはLuaTeXとLuaでプログラムを使用できます(そして内部構造を操作できるのでTeXマクロだけではできなかったより良い仕事をします)適切なレベルのアルゴリズム)。そして、正しく実行すれば、TeXマクロで実装されたプログラムよりも優れた、または高速なプログラムを作成できます。
TeXでプログラムを高速化するタスクは、この観点から見るとほとんどおもしろく、別の「偶然にチューリング完全な」プログラミング「言語」を説明する論文の最後の言葉を思い起こさせます。TomWildenhainの素敵な「On the Turing Completeness of MS昨年のパワーポイント(ビデオ):
PPTXTMはPowerPoint開発の理論的可能性を証明していますが、[…]。PowerPointアプリケーションの最適化でも作業を行う必要があります。ここでは、PowerPointの次のスライドの自動バッファリングを活用する多くの可能性があります。注意深いスライド配置により、アプリケーションのパフォーマンスを大幅に向上させることができます。
リプトンが記述する逸話は例示です。TeXの正式なセマンティクスが存在したことがなかっただけでなく、存在する可能性もありません。それは「言語」としてはあまりにも「奇妙」であり、(上で説明したように)言語としても意図されていません。たとえば、マクロを関数として記述していると思うかもしれませんが、その中に単一の浮遊文字(スペースさえも)を導入すると、TeXはすぐにそれを組版命令として扱います。
要するに、TeXは最も早い機会に組版に戻り、マクロを展開すると、しぶしぶながら(組版の「実際の」作業に到達するのが待ちきれません)、これらの展開自体が数百種類の「状態」に依存する可能性がありますTeXプログラム(\hsize
またはなどのパラメーターの値、\baselineskip
ボックスやその他のレジスターの内容など)。そのため、TeXの正式なセマンティクスは、プログラムの状態全体とそのすべてのメモリを考慮に入れる必要があります。 「TeXコードの意味はTeXが何でもする」のようなものになり、TeXプログラム自体よりも複雑な形になります。
それで結構です(私があなたに納得させたなら)TeXはプログラミング言語として意図されたものではなく、実際の言語のように機能せず、形式的なセマンティクスもありません。実際には、TeXが処理するためのもので、多くの文書があることで、実際の質問/問題、行う(ラテックスとは、TikZなど)の使用複雑なマクロを、互いの上に構築された巨大な複雑さの見事な建造物。どうすればより速く、「最適化パス」を考案できますか?
正式なセマンティクスIMOではそこに到達しません。私は最近これについて考えましたが、以下は予備的な考えです。
私の印象では、Knuthは1960年代に経験豊富なコンパイラライターの1人であり(そのため、The Art of Computer Programmingになったコンパイラの本を書くように頼まれました)、TeXは(多くの点で)コンパイラのように書かれています1970年代に書かれたと言う。それ以来、コンパイラの手法と設計は改善されており、TeXプログラムも改善されています。以下は、物事を高速化するためにできることです。
本質的に、TeXは「解釈ルーチン」のように書かれており、TeXの「目」と「口」(その入力ルーチン)が「胃」(そのセマンティックルーチン)に命令を送り、1つずつ実行されます。(TeXプログラムのパート15でリストを見ることができます。)例えば、TeXの目/口が出会うとき、\hfill
または\hskip
その入力で、胃は「hskip」コマンドを受け取り、それが作用します。これは、今日のバイトコードインタープリターと呼ばれるものに似ています。これらのバイトコード/オペコードを明示的に出力するようにTeXプログラムをリファクタリングすると、既存の(より一般的な)コンパイラーテクニックを使用できるようになる可能性があります。または、少なくともそれらをキャッシュして、作業のやり直しを避けます。もちろん、多くの課題があります。
「胃」でのコマンドの実行には、通常、入力の読み取りが含まれます。つまり、入力ルーチンとセマンティックルーチンの作業は別々のフェーズでは発生しません。たとえば、「hskip」コマンドが与えられた場合\hskip
(言うのではなく\hfill
)scan_glue
、入力からグルー仕様を読み込むために呼び出され、グルーに十分なトークンが見つかるまでマクロを展開するなどを行い、入力スタックを実質的に異なる状態。
eTeXやpdfTeXやXeTeXやLuaTeXのようなエンジンは、新しいコマンドとプリミティブを導入しています(eTeX / pdfTexプリミティブは実際には誰でも実際に使用されています)。元のKnuthのTeXプログラムのメンバーだけでなく、それらもサポートする必要があります。
「投機的実行」、将来の段落の処理(新しいセクションや章などの自然なチェックポイントから開始)の並列処理(複数のコアを使用)、使用するすべてのTeX内部状態の追跡(依存)、スロー後で以前の段落がその状態の一部を変更することが判明した場合、その作業をやり直します(やり直します)。現時点では、TeXは1つのプロセッサで完全に順番に実行されます。典型的なハードウェアは異なる方向に移動しており、複数のコアが利用可能です。
さらに簡単に、入力ファイルの特定のセクションによって作業(TeXの状態がアクセスおよび変更されたもの)を単純にキャッシュできます。(このキャッシュは、入力のレベル(すべてのマクロを展開した最終的な結果)で、または組み立てられたボックスのセットのレベルで、またはプログラムの全体の状態に至るまで実行できます。) a \begin{tikzpicture} … \end{tikzpicture}
はページ番号カウンターのようにTeXの状態に大きく依存する可能性は低いため、TeXドキュメントを再コンパイルするときは、すべての作業を単純に再利用することができます。(もちろん、TikZには特にこれを外部化して結果を含める方法がありますが、考え方はより一般的です。)
テクニック(関数型プログラミングで使用されるものなど)を使用して、「穴」でTeX処理を行うことができます。たとえば\ref{foo}
、LaTeXで(将来の)セクション番号を参照する場合、2つのコンパイルパスでのみ機能します:最初にドキュメント全体が処理され(すべての段落タイプセット、ページに配置されたフロートなど)、セクション番号が補助ファイルに書き込まれ、次に2回目のパスですべて作業が再び行われ、今回はセクション番号が実際に使用可能になります。(この種のハッキングは当時避けられなかった可能性があり、実行時間への影響は「一定の要因のみ」であることを知っていますが...)代わりに、「穴」のあるドキュメントを単純に処理できたらどうでしょうか(内容が未確定だが幅が推定されたボックス)、セクション番号用に残し、ドキュメント処理の最後にボックスに入力しますか?(はい、推定幅が間違っている可能性があり、段落の再処理が必要になり、結果としてページも必要になる場合がありますが、必要に応じて作業を行うか、速度のために間違った幅を許可するモードを受け入れることができますセクション番号。)
同様の手法は、TeX文書のインタラクティブな編集でも機能します。段落を編集すると、「ライブ」で処理され、将来の段落はゲラの下に移動します(たとえば)。BaKoMaTeXとTexpadおよび以前のTexturesなど、これを行う(商用の)TeX実装が既に存在するため、それが可能であることはわかっています。(BaKoMa-TeXおよび同様にTeXpadのホームページのビデオを参照してください。たとえば、このビデオ —私は後者を試しましたが、実際には耐えられないほどバグがありました。)
過小評価しないでください:ユーザーに物事を見せることの価値。TeXをよりデバッグしやすくします。現在、ユーザーはTeXの入力のみを表示し、TeXが何をしているのか正確にはわかりません。たとえば、段落の改行、マクロ展開(およびマクロ)、組み立てるボックス、捨てる、どのパッケージでどのスペシャルが書き出されるかなど。私は(おそらく楽観的に)この情報を見たいと思っているユーザーがいると信じており、例えば、シェーディングに使用している奇妙なパッケージを知ることができますバックグラウンドに勾配がある方程式は、安価(処理時間をほとんど追加しない)かそうではありません。多くの無駄な作業が行われている場所を確認することで、彼らはそれの一部を捨てることができました(少なくとも最終的な印刷が実行されるまで)。(これは、プロファイリング情報をプログラムに挿入するコンパイラーまたはその他のツールに似ています。)たとえば、TeXをより透過的でデバッグ可能にすることは、使いやすさの大幅な改善かもしれません。(TeXは、非常に少数のマクロでプレーンなTeXを主に使用しているが、LaTeXでは使用しておらず、今日の大多数のユーザーが使用する方法ではない場合、IMOの時点ですでに非常にユーザーフレンドリーでデバッグ可能です。)
また、今後の作業では、おそらく現在のTeXの最適な変更であるLuaTeXを考慮(ビルド)する必要があります。
これらはすべて怠慢な考えです(必要な労力やどれだけ高速化できるかを知るために、それらを実装していません)が、これがあなたの質問に答えたり、将来の方向性についてのアイデアを与えることに役立つことを願っています。