(Sitenin kapsamından farklı bir yöne giden uzun bir cevap için özür dilerim: açıkçası burada ilk etapta soruyu gördüğüme şaşırdım….)
TeX programlama için değil dizgi için tasarlanmıştır; bu yüzden bir programlama dili olarak değerlendirildiğinde en iyi ihtimalle “tuhaf” olur.
- Donald Knuth, Dijital Tipografi, sayfa 235
Son birkaç yıldır TeX'in erken tarihi (1977 dolaylarında) ve Knuth'un yazdığı birçok şey hakkında çok şey okudum. Sonuç olarak, “TeX (programlama dili olarak)” hakkında konuştuğumuz anda , bir şeyler zaten yanlış.
TeX için daha önce yazılan erken “tasarım belgelerine” bakarsak (bakınız TEXDR.AFT
ve Dijital TipografideTEX.ONE
yayınlanmıştır ), Knuth'un öncelikle Bilgisayar Programlama Sanatını dizmek için tasarlanmış bir sistem tasarladığı açıktır (örneğin ( burada )) akılda tutulan ana kullanıcıların kendisi ve sekreteri olduğu), uygun olarak değiştirilmiş olması daha genel olarak yararlı olabileceği düşüncesiyle. Yazmayı kaydetmek için, birisinin tekrar tekrar yapması gereken şeyler için (örneğin, TAOCP'un bir yazardan bir alıntı içermesi gerektiğinde, belirli bir miktarda dikey olarak hareket etmek, belirli bir satır atlama ayarlamak, belirli bir yazı tipini almak, alıntı sağa hizalı, başka bir yazı tipi seçin, yazarın adını yazın…), makrolar vardı.
Geri kalanını tahmin edebilirsin. TeX'te sahip olduğumuz şey, bir topluluğun ortasında (bilgisayar bilimcileri ve matematikçiler ve DEK'in kendisi de "suçlamak") (maalesef) olan "kazayla Turing-complete" örneğidir ( daha fazla ). bunu görmezden gelmek için çok zekice. (Efsaneye göre Michael Spivak , TeX ile karşılaşmadan önce hiç programlamamıştı, ancak o kadar çok alındı ki, o sırada en karmaşık makro kümelerinden biri olan AMS-TeX yazdı.) Çünkü TeX yazıldı çok sayıda sistemde (o zamanlar büyük bir miktar) taşınabilir olmak için TeX'te her şeyi yapmak için her zaman bir cazibe vardı. Ayrıca derleyici yazma deneyimi nedeniyle, Knuth TeX'i bir derleyici gibi yazdı ve bazen bir derleme olarak tanımladı ve eğer girdinizde çalışan program bir “derleyici” ise, elbette programlama yapıyorsunuz, değil mi?
Knuth'un TeX'te herhangi bir programlamayı nasıl yapma niyetinde olmadığı ve bu yanıtta “TeX'in programlama özelliklerinin çoğunu sadece tekme ve çığlıklardan sonra nasıl koyduğu” hakkında biraz daha fazla bilgi edinebilirsiniz . Niyeti ne olursa olsun, dediğim gibi, insanlar (ab) TeX makro sistemini kullanmanın şaşırtıcı programlama özelliklerini başarmanın yollarını bulmaya başladılar. Knuth, bu büyüleyici ve (TeX kendisi içine bazı özellikler ekleyerek ek olarak) Ek D “Dirty Tricks” bunlardan birkaç dahil buldum Ders Kitabı, ancak, adına rağmen, çıkıyor o dokuz on örnekler dışında oradaki” LaTeX uygulamasında kullanılır ”.
Başka bir şekilde ifade edeyim: Leslie Lamport'un TeX üzerine yazdığı makro sistemi LaTeX, bir fikir olarak harika bir sistem. Belgeleri (Knuth) TeX'in sayfa yönelimli yerine semantik, yapılandırılmış, insan odaklı bir şekilde yazmak (ya da Lamport'un dediği gibi, görsel değil mantıklı ) harika. Ama “uygun” bir programlama dilinde değil, TeX makroları kullanarak LaTeX kadar karmaşık bir şey uygulamak , bence ve en azından bugün yapıldıysa, dev bir hata ile ahlaksız bir sapkınlık eylemi arasında bir yer. Knuth bile , insanların TeX makrolarında her şeyi yapmak yerine sadece TeX programını genişletmediği için şok oluyor .
Bugün “programlama” yapmanın çok daha iyi yolları var; çoğu insanın bilgisayarında yaygın olarak bulunan birçok dilde harici bir program kullanabilir veya LuaTeX ve Lua'da program kullanabilirsiniz (ve yalnızca TeX makrolarıyla yapabileceğinizden daha iyi bir iş yapabilirsiniz, çünkü iç yapıları manipüle edebilirsiniz. algoritmaları doğru düzeyde). Doğru yaparsanız, TeX makrolarına uygulanan programlardan daha iyi veya daha hızlı çalışan programlarınız olabilir.
TeX'te programları daha hızlı yapma görevi, bu ışıkta görüldüğünde neredeyse eğlenceli ve bana başka bir “yanlışlıkla Turing Complete ” programlama “dilini” açıklayan son sözleri hatırlatır: Tom Wildenhain'in güzel “ MS'in Turing Tamamlanması Hakkında Geçen yıldan PowerPoint ( video ):
PPTXTM PowerPoint geliştirme teorik olasılığını kanıtlarken, […]. PowerPoint uygulama optimizasyonunda da iş yapılması gerekir. Burada, PowerPoint'in bir sonraki slaydın otomatik arabelleğe alınmasından yararlanma potansiyeli vardır; bu, dikkatli slayt yerleşimi yoluyla uygulama performansını büyük ölçüde artırmak için kullanılabilir.
Lipton anlatılan fıkra açıklayıcıdır. TeX'in hiçbir zaman resmi bir anlambilimi olmamış, aynı zamanda bir tanesinin olması da olası değildir. Bunun için bir “dil” çok “garip” ve (yukarıda açıkladığım gibi) dil olarak bile tasarlanmamış. Örneğin, makroları işlev olarak yazdığınızı düşünebilirsiniz , ancak içine tek bir sokak karakteri (hatta bir boşluk ) ekleyin ve TeX bunu hemen bir dizgi talimatı olarak kabul eder.
Kısacası: TeX, ilk fırsatta dizgiye geri döner ve makroları genişlettiğinde çok kaba bir şekilde yapar (dizgi “gerçek” çalışmalarına ulaşmak için sabırsızdır) ve bu genişlemeler, yüzlerce çeşit “duruma” bağlı olabilir. TeX programı ( \hsize
veya \baselineskip
kutuların ve diğer kayıtların içeriği gibi parametrelerin değerleri ...), bu yüzden TeX'in herhangi bir resmi anlamının, programın tüm durumunu ve tüm belleğini dikkate alan bir şey olması gerekir. "TeX kodunun anlamı TeX ne yaparsa yapsın" gibi bir şeyle sonuçlanır: TeX programının kendisinden daha karmaşık bir biçimde.
Çok iyi, (sizi ikna ettiysem) TeX bir programlama dili olarak tasarlanmamıştı ve gerçek dil gibi çalışmıyor, resmi bir anlambilim yok ve bugün programlamanın daha iyi yolları var - ama tüm bunlar sizin gerçek soru / problem, yani pratikte, TeX tarafından işlenmesi gereken birçok belge , birbiri üzerine inşa edilmiş korkunç karmaşıklığın çarpıcı yapılarını (LaTeX ve TikZ gibi) karmaşık makrolar kullanıyor. Bunu nasıl daha hızlı hale getirebilir ve “optimizasyon geçişleri” tasarlayabiliriz?
Resmi anlambilim IMO ile oraya olmaz. Son zamanlarda bunu düşündüm ve aşağıdakiler bazı ön düşünceler.
Benim izlenimim Knuth'un 1960'larda deneyimli derleyici yazarlarından biriydi (bu yüzden Bilgisayar Programlama Sanatı'na dönüşen derleyiciler kitabını yazması istendi ) ve TeX (birçok yönden) derleyicilerin olduğu gibi yazılıyor 1970'lerde yazılmış diyelim. Derleyici teknikleri ve tasarımı o zamandan beri gelişmiştir ve TeX programı da öyle olabilir. İşte işleri hızlandırmak yoluyla yapılabilecek bazı şeyler:
Kalbinde TeX, TeX'in “gözleri” ve “ağzı” nın (giriş rutinleri) birer birer yürütülecek olan “midesi” ne (semantik rutinleri) talimat verdiği “yorumlayıcı rutin” gibi yazılır. ( TeX programının bölüm 15'inde bir liste görebilirsiniz .) Örneğin, TeX'in gözleri / ağzı karşılaştığında \hfill
veya \hskip
girdisinde, mide üzerinde çalıştığı bir “hskip” komutu alır. Bu, günümüzde bytecode yorumlayıcıları olarak adlandırılanlara benzer ve TeX programını bu bayt kodları / opcod'ları açıkça yaymak için yeniden düzenlemede değer olabilir, böylece mevcut (bugün daha geleneksel) derleyici tekniklerini kullanabiliyoruz. Ya da en azından işleri yeniden yapmaktan kaçınmak için önbellekleyin. Elbette birçok zorluk var:
“Midede” bir komutun uygulanması genellikle girdinin okunmasını içerir, yani girdi rutinlerinin ve semantik rutinlerin çalışmaları ayrı aşamalarda gerçekleşmez. Örneğin, "hskip" komutu, eğer verilirse \hskip
( girişten ziyade \hfill
) scan_glue
, girişten bir tutkal spesifikasyonunu okumaya çağıracaktır ; bu da, yapıştırıcı için yeterli jeton bulunana kadar, giriş yığınını büyük ölçüde farklı bir durum.
ETeX ve pdfTeX ve XeTeX ve LuaTeX gibi motorlar yeni komutlar ve ilkeller sunar (eTeX / pdfTex ilkelleri pratikte herkes tarafından pratik olarak kullanılır); sadece orijinal Knuth's TeX programındakiler için değil, onları da desteklemeniz gerekir.
“Spekülatif yürütme”, gelecekteki paragrafları (belki yeni bölümler veya bölümler gibi doğal kontrol noktalarından başlayarak) paralel olarak (birden çok çekirdek kullanarak), kullandıkları tüm TeX dahili durumlarını takip ederek (bağlı) ve fırlatma gibi bir şey yapabiliriz Daha sonra, önceki bir paragrafın bu durumun bir kısmını değiştirdiğini öğrenirsek, bu çalışmayı ortadan kaldırır (ve yeniden yapar). Şu anda TeX tamamen 1 işlemcide ardışık olarak çalışıyor; tipik donanım farklı bir yöne hareket etmiştir ve çok sayıda çekirdek mevcuttur.
Daha da basit bir şekilde, işi (TeX durumuna erişilen ve değiştirilen) giriş dosyasının belirli bir bölümü ile önbelleğe alabiliriz. (Bu önbelleği giriş düzeyinde (tüm makroları genişletmenin net sonucu olarak) veya hangi kutu kümesinin monte edildiği düzeyde veya programın toplam durumuna kadar yapabiliriz.) Örn. a \begin{tikzpicture} … \end{tikzpicture}
, sayfa numarası sayacı gibi TeX durumuna çok fazla bağlı değildir, bu nedenle TeX belgesini yeniden derlediğimizde tüm işi yeniden kullanabiliriz - eğer güvenli olduğunu bilmek için yeterli bilgiyi takip edersek. (Tabii ki TikZ'in bunu dışsallaştırmanın ve sonuçları dahil etmenin yolları var, ancak fikir daha genel.
“Delikler” ile bazı TeX işlemleri yapmak için teknikler (örn. Fonksiyonel programlamada kullanılanlar) kullanabiliriz - örneğin, şu anda \ref{foo}
LaTeX'e (gelecekteki say) bölüm numarasına başvurmak için yazdığınızda , yalnızca iki derleme geçişinde çalışır: bölüm numaraları ikinci geçişte daha sonra, bir yardımcı dosyasına yazılır edilir birinci belgenin tamamını (tüm paragraflar dizgi vb sayfalarında yer alan yüzer) işlenir tümiş bu kez gerçekte mevcut olan bölüm numarası ile tekrar yapılır. (Bu tür bir saldırı o zaman kaçınılmaz olabilir ve çalışma süresi üzerindeki etkinin “sadece sabit bir faktör” olduğunu biliyorum, ama….) Bunun yerine, belgeyi bir “delik” ile işleyebilirsek ne olur ( içeriği belirlenmemiş ancak tahmini genişliği olan bir kutu) bölüm numarası için bırakılmışsa, belge işlemenin sonunda kutuyu doldurur musunuz? (Evet, tahmini genişliğimiz yanlış olabilir ve paragrafın yeniden işlenmesi ve sonuç olarak sayfa bile gerekebilir, ancak gerekirse işi yapabiliriz veya hız için yanlış genişliğe izin vereceğimiz bir modu kabul edebiliriz bölüm numarası.)
Benzer teknikler bir TeX belgesinin etkileşimli olarak düzenlenmesi için işe yarayabilir: bir paragrafı düzenlediğinizde, "canlı" olarak işlenebilir, gelecekteki paragraflar kadırgaya doğru hareket ettirilebilir (diyelim). Bunu yapabildiğimizi biliyoruz, çünkü bunu yapan (ticari) TeX uygulamaları var, örneğin BaKoMaTeX ve Texpad ve eski Dokular . ( BaKoMa- TeX'in ana sayfasındaki videoya ve benzer şekilde TeXpad'in videolarına bakın , örneğin bu video - İkincisini denedim ve pratikte dayanılmaz bir şekilde buggy oldu.)
Göz ardı edilmemelidir: Kullanıcıya bir şeyler göstermenin değeri, TeX'i daha hata ayıklanabilir hale getirir. Şu anda, kullanıcılar yalnızca TeX girişlerini görüyor ve TeX'in ne işe yaradığını tam olarak bilmiyorlar, örneğin paragraflar için satır kesmeye veya makro genişletmeye (ve hangi makrolara), hangi kutuları birleştirdiğine ve atmak, hangi paketler tarafından hangi özel ürünler yazılıyor, vb. Ben (belki de iyimser olarak) bu bilgiyi görmek isteyen ve yararlı bulduklarını, örneğin gölgeleme için kullandıkları garip paketin olup olmadığını bilmek arka planda gradyanlı denklemler ucuzdur (işlem süresine çok az eklenir) veya değildir. Çok fazla israflı çalışmanın nerede yapıldığını görünce, bir kısmını dışarı atabilirler (en azından son baskı çalışmalarına kadar). (Bu, derleyiciler veya programlara profil bilgisi ekleyen diğer araçlar gibidir.) TeX'i daha şeffaf ve hata ayıklamak, örneğin büyük bir kullanılabilirlik gelişimi olabilir. (TeX, çok az makro ile çoğunlukla düz TeX kullanırsak, ancak LaTeX veya kullanıcıların büyük çoğunluğunun bugün nasıl karşılaştığıyla ilgili değilse, zaman IMO'su için oldukça kullanıcı dostu ve hata ayıklanabilir.)
Ayrıca, gelecekteki herhangi bir çalışma muhtemelen şu anda sahip olduğumuz TeX'in en iyi modifikasyonu olan LuaTeX'i dikkate almalıdır.
Tüm bunlar sadece boş düşüncelerdir (bunlardan hiçbirini uygulamadım, gereken çabayı veya ne kadar hız kazanacağımızı bilmek için), ancak umarım bu, sorunuza cevap vermek veya gelecekteki yönler için size fikir vermek için bir yol açar .