Latex3: Mendeklarasikan variabel lokal

Dibuat pada 18 Okt 2017  ·  49Komentar  ·  Sumber: latex3/latex3

Dokumen Paket expl3 dan pemrograman LaTeX3 (v. 2017/09/18) menyatakan pada hal. 7:

Konvensi pengkodean LaTeX3 adalah bahwa semua variabel harus dideklarasikan sebelum digunakan.

Demikian pula, dokumen The LaTeX3 Interfaces (v. 2017/09/18) menyatakan pada hal. 10:

... berbeda dengan variabel, yang harus selalu dideklarasikan

expl3 tidak menyediakan fasilitas untuk mendeklarasikan variabel secara lokal; hanya secara global. Namun, masih dimungkinkan untuk membuat variabel lokal secara implisit menggunakan berbagai fungsi \..._set:N... .

Ini adalah prinsip pemrograman terstruktur bahwa membuang variabel ke dalam lingkup global yang tidak perlu harus dihindari. Bahasa TeX, seperti semua bahasa pemrograman tingkat tinggi yang saya tahu (termasuk C, C#, Fortran, Java, Lisp, Pascal, dan Python), menyediakan konstruksi pelingkupan untuk membuat variabel lokal, yaitu grup. Selain itu, bahasa pemrograman LaTeX3 itu sendiri, untungnya, mendukung pembuatan variabel lokal, terlepas dari apa yang disarankan manual.

Menurut pendapat saya, peringatan yang dikutip di atas harus dihapus dari manual, dan harus dijelaskan bahwa variabel dapat, dan harus, dibuat secara lokal bila memungkinkan.

Selain itu, jika memang diinginkan untuk mendorong gaya pemrograman di mana semua variabel dideklarasikan sebelum digunakan (saya pribadi berpikir ini adalah masalah gaya pemrograman yang harus diserahkan kepada selera masing-masing programmer), fungsi perlu disediakan untuk mendeklarasikan variabel lokal seperti halnya ada fungsi untuk mendeklarasikan variabel global.

expl3 feature-request

Semua 49 komentar

Posisi saat ini mengikuti sejumlah eksperimen oleh tim untuk membentuk pola yang bekerja dengan dasar-dasar TeX yang mendukung expl3 . Secara khusus, penting untuk dicatat bahwa variabel dapat diimplementasikan menggunakan makro atau menggunakan register, dan untuk mengingat cara kerja pengelompokan TeX.

Saat menggunakan register (_e.g._ untuk tipe int ) kita memerlukan pengalokasi untuk menghubungkan nomor register dan cs yang kita gunakan untuk akses. Sebaliknya, untuk penyimpanan berbasis makro yang tidak diperlukan. Jadi sementara \cs_set_eq:NN dapat digunakan untuk menghasilkan nama tl (misalnya), itu akan gagal dengan apa pun yang menggunakan register:

\int_set_eq:NN \l_undeclared_int \l_tmpa_in

akan memunculkan kesalahan.

Dimungkinkan untuk membuat pengalokasi register lokal, dan kami telah mencobanya di masa lalu untuk _e.g._ \int_local_new:N . (Lihat paket etex untuk satu implementasi tersebut, atau lihat kembali sejarah expl3 .) Tim akhirnya memutuskan untuk tidak melakukannya karena tampaknya tidak 'cocok' dengan pelingkupan TeX. Kuncinya di sini adalah bahwa pengelompokan TeX tidak didasarkan pada deklarasi melainkan pada grup eksplisit, dan bahwa variabel lokal ada dalam grup bersarang apa pun:

\begingroup
  \def\foo{}
  \begingroup
  \show\foo

Ketika kami mencoba _creation_ variabel lokal, tampaknya ada bahaya mengaburkan cara kerja pengelompokan TeX, dan pemrogram dapat disesatkan.

Oleh karena itu kami memutuskan untuk menggunakan _deklarasi_ variabel 'semua global', tetapi dengan _pengaturan_ lokal dan global dari variabel tersebut (konvensi \l_... _versus \g_... ). Ini melokalisasi hal yang penting: nilai. Oleh karena itu, kami merekomendasikan bahwa semua deklarasi berada di tingkat atas

\tl_new:N \l_my_tl
\int_new:N \l_my_int

...
\cs_new_protected:Npn \my_func:nn #1#2
  {
    \group_begin:
      \tl_set:Nx \l_my_tl { \tl_lower_case:n {#1} }

Sampai saat ini, pola ini tampaknya berfungsi dengan baik untuk tugas yang telah digunakan expl3 .

Di tex bahkan variabel yang didefinisikan secara lokal tidak sepenuhnya dihancurkan setelah akhir grup. Mereka masih menggunakan beberapa ruang string: https://tex.stackexchange.com/questions/316999/release-space-in-the-string-pool . Jadi lebih baik melihat variabel sebagai objek global.

@u-fischer Poin bagus: bukan yang sebenarnya kami pertimbangkan saat itu tetapi patut diingat.

Menurut pendapat saya pendekatan ini keliru. Ini bertentangan dengan prinsip pemrograman terstruktur, dan bertentangan dengan TeX, yang memungkinkan pembuatan variabel lokal. Itu juga membuat LaTeX3 tidak konsisten, karena beberapa tipe data mengakomodasi variabel lokal dan beberapa tidak.

Saya ingin meminta Anda untuk melembagakan kembali pembuatan variabel lokal dari semua jenis. Ini memberi para programmer pilihan: mereka yang lebih suka mendefinisikan semua variabel secara global dapat melakukannya, dan mereka yang ingin mendefinisikan beberapa secara global dan beberapa secara lokal juga dapat melakukannya.

Jika ada peringatan, dari segi memori atau lainnya, mereka dapat disebutkan dalam dokumentasi.

Pada 18 Oktober 2017 pukul 21:17, EvanAad [email protected] menulis:

Menurut pendapat saya ini adalah pendekatan yang salah, dan saya ingin meminta itu
Anda melembagakan kembali pembuatan variabel lokal. Ini memberi programmer
pilihan: mereka yang lebih suka mendefinisikan semua variabel secara global dapat melakukannya, dan
mereka yang ingin mendefinisikan beberapa secara global dan beberapa secara lokal dapat melakukannya juga.

untuk variabel berdasarkan tipe register Anda mengalokasikan sumber daya dari a
kumpulan global tetap sehingga alokasi nama global sebenarnya jauh lebih banyak
alami. Mengingat bahwa kita mengasumsikan etex sehingga ada lebih dari 256 register
setiap jenis, perilaku alokasi mungkin dapat disembunyikan lebih dari itu
bisa dengan teks klasik tetapi masih merupakan fitur mendasar dari
sistem TeX yang mendasarinya. expl3 tidak akan pernah bisa menjadi pemrograman yang sepenuhnya umum
bahasa: itu harus bekerja dengan sistem TeX yang mendasarinya. Anda seharusnya tidak
membandingkan dengan C# tetapi dengan bahasa berbasis TeX lainnya dan khususnya dengan
\newcount dan teman-teman.

Juga tidak benar untuk mengatakan bahwa semua bahasa lain mengizinkan variabel menjadi
dideklarasikan dalam lingkup lokal, fortran misalnya hanya mengizinkan variabel menjadi
dideklarasikan pada awal fungsi/subrutin.

Tidak satu pun dari hal di atas yang berarti bahwa kami pasti tidak akan menambahkan deklarasi lokal
sistem, tetapi menarik untuk bahasa tujuan umum bukanlah kasus penggunaan yang baik.
Perlu ada kasus penggunaan yang masuk akal dalam pengaturan huruf tex di mana
menggunakan sistem deklarasi global adalah masalah.

Fakta bahwa Fortran membutuhkan variabel untuk dideklarasikan pada awal fungsi/subrutin tidak berarti bahwa variabel tersebut bersifat global. Jika Anda bersikeras untuk mendorong gaya pemrograman di mana semua variabel harus dideklarasikan, biarlah, tetapi kemudian berikan fungsi untuk mendeklarasikan variabel lokal yang sesuai dengan variabel untuk mendeklarasikan variabel global.

Alasan untuk pelingkupan dan variabel-variabel lokal adalah yang paling konseptual. Fakta bahwa mesin TeX yang mendasari tidak melepaskan beberapa sumber daya yang terkait dengan variabel lokal tidak dapat diabaikan, tetapi, menurut pendapat saya, ini tidak dapat menjadi alasan untuk menghilangkan gagasan pelingkupan dan variabel lokal. Kecuali untuk pemrogram daya, implementasi yang mendasarinya tidak menjadi perhatian; dan untuk pemrogram daya, tip dan peringatan dapat ditawarkan dalam dokumentasi.

menarik untuk bahasa tujuan umum bukanlah kasus penggunaan yang baik.

Saya akan mengatakan bahwa menyimpang dari prinsip-prinsip pemrograman terstruktur yang telah diterapkan di hampir setiap bahasa pemrograman dari tahun 1960-an hingga hari ini, termasuk TeX, harus menjadi sesuatu yang tim LaTeX3 harus memiliki alasan yang sangat kuat untuk melakukannya. Beban pembuktian harus pada mereka yang ingin menghapus apa yang dianggap sebagai praktik pemrograman yang baik di mana-mana, dan apa yang sudah ada di TeX; bukan pada mereka yang ingin melestarikannya.

@EvanAad Daftar Token, urutan daftar koma dan variabel daftar properti sebenarnya adalah makro TeX, tetapi variabel dari jenis yang berbeda tidak. Mari kita asumsikan mendeklarasikan variabel integer secara lokal diperbolehkan. Ini menghabiskan register dan perlu untuk menangani ini secara global sehingga alokasi tidak menyentuh register yang sudah ditetapkan.

Katakanlah variabel integer lokal Anda \x ditugaskan register 100 yang sudah diambil oleh variabel \y di tingkat atas; menggunakan \y pada tingkat yang sama di mana \x didefinisikan secara lokal akan sangat berbahaya. Jadi pembukuan global dari register yang ditugaskan diperlukan, sehingga sangat sulit untuk merilis register yang ditugaskan secara lokal. Memesan blok register untuk tugas lokal bukanlah solusi.

Saya tidak mengatakan itu tidak bisa dilakukan, tetapi saya pikir itu tidak sepadan dengan rasa sakitnya.

Anda melewatkan fakta bahwa \newcount tidak hanya secara lokal (atau global)
mendeklarasikan nama, itu mengasosiasikan nama dengan tetap yang ditentukan secara eksternal
sumber. hanya ada satu hitungan register 42 dan semua nama itu
dinyatakan berarti count42 mengacu pada register yang sama, baik
alokasi nama bersifat lokal atau global. Seperti yang saya sebutkan perbandingan dengan yang lain
bahasa tidak begitu berguna tetapi jika Anda ingin perbandingan, Anda harus
bandingkan mengalokasikan aliran file atau semacamnya: Anda tidak selalu dapat mengisolasi
deklarasi lokal ketika mereka berinteraksi dengan definisi eksternal
sumber.

Pada 18 Oktober 2017 pukul 21:43, EvanAad [email protected] menulis:

Fakta bahwa Fortran membutuhkan variabel untuk dideklarasikan di awal a
fungsi/subrutin tidak berarti bahwa variabel tersebut bersifat global. Seperti saya
menulis, jika Anda bersikeras untuk mendorong gaya pemrograman di mana semua variabel
harus dideklarasikan, biarlah, tetapi kemudian menyediakan fungsi untuk mendeklarasikan local
variabel yang sesuai dengan variabel untuk mendeklarasikan variabel global.

Alasan untuk pelingkupan dan variabel lokal adalah yang utama
konseptual. Fakta bahwa mesin TeX yang mendasarinya tidak merilis beberapa
sumber daya yang terkait dengan variabel lokal tidak boleh diabaikan,
tapi, menurut saya, ini tidak bisa menjadi alasan untuk melenyapkan gagasan itu
pelingkupan dan variabel lokal. Kecuali untuk pemrogram daya,
implementasi yang mendasari tidak menjadi perhatian; dan untuk pemrogram daya, tip
dan peringatan dapat ditawarkan dalam dokumentasi.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/latex3/latex3/issues/410#issuecomment-337721923 , atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/ABNcAimMfBDqA-e96Q7tkS-ERr5fv_2Mks5stmLqgaJpZM4P-Mpq
.

Poin penting adalah bahwa, seperti yang disebutkan Joseph dan David, mengizinkan int s untuk didefinisikan secara lokal dapat (dan telah ) dilakukan. Saya pikir itu adalah layak sakit dalam rangka menciptakan bahasa yang menyajikan abstraksi lapisan yang konsisten yang sesuai dengan prinsip-prinsip pemrograman terstruktur.

Namun, mengatakan itu sepadan dengan rasa sakit itu mudah bagi saya untuk mengatakannya, karena saya bukan orang yang mengalami kesulitan dalam mengimplementasikan bahasa LaTeX3. Jadi mari kita mengambil pendekatan yang penuh belas kasihan, dan mengatakan bahwa itu sebenarnya tidak sebanding dengan rasa sakitnya. Bagus. Dalam hal ini, bagi tipe data menjadi dua kategori: yang memungkinkan pembuatan variabel lokal, dan yang tidak. Dan jelaskan kategori-kategori ini dalam manual. Jangan katakan: semua variabel harus dideklarasikan sebelum digunakan. Katakan: "Ada dua kategori tipe data. Yang pertama, terdiri dari cs , tl , clist , ... mengakomodasi variabel lokal, dan yang kedua, terdiri dari int , ... tidak." Dan jelaskan mengapa kategori kedua ada. Dengan cara ini dokumentasinya sesuai dengan fakta, dan para pemrogram mendapat informasi yang baik dan memiliki pilihan. Beberapa program tidak perlu menggunakan tipe data kategori kedua sama sekali, dan dalam kasus ini mengapa programmer harus mendeklarasikan variabel global?

@EvanAad Saya menduga ini karena saya terbiasa dengan pemrograman TeX (termasuk batasan 'tradisional' TeX90), tetapi saat ini saya tidak yakin apa masalahnya dengan pendekatan saat ini. Kami mendukung dan memang mendorong variabel yang ditetapkan secara lokal: mereka sangat umum dan memang bagian dari sintaks yang kami miliki untuk penamaan variabel ( \l_... / \g_... ). Fakta bahwa mereka dialokasikan/'dipesan' secara global tidak mengganggu itu.

BTW, kami tidak ingin mengikat antarmuka ke implementasi: misalnya, tipe data prop memiliki setidaknya beberapa implementasi berbeda yang saya tahu, salah satunya menggunakan register dan yang sekarang menggunakan makro.

Untuk menambahkan satu catatan lagi untuk ini, jerami yang mematahkan punggung unta (dalam ingatan saya) bahwa sistem alokasi register/variabel lokal jatuh adalah karena inconsistency . Karena makro dan register berperilaku berbeda, Anda berakhir dengan perilaku berbeda saat menulis

\group_begin:
  \int_new_local:N \l_tmpa_int
  \int_gset:Nn \l_tmpa_int {7}
\group_end:
% `\l_tmpa_int` undefined

vs

\group_begin:
  \tl_new_local:N \l_tmpa_tl
  \tl_gset:Nn \l_tmpa_tl {7}
\group_end:
% `\l_tmpa_tl` defined as `7`

Dan satu-satunya cara untuk menyelesaikan masalah ini adalah dengan menulis sistem alokasi untuk makro, yang tidak pernah dipertimbangkan secara serius karena overhead. (TeX memperlambat semakin banyak variabel yang ditentukan, sehingga menggandakan jumlah daftar token dapat memengaruhi kinerja secara nyata.)

Saya masih berpikir bahwa expl3 melakukan hal yang benar dengan mengabstraksikan makro dan register ke dalam fungsi yang terlihat dan terasa sama — dan jika kelemahannya adalah sintaks tidak secara alami mendukung variabel dan register yang benar-benar lokal, yang telah dilihat penggunaan yang sangat terbatas di TeX karena alasan yang diuraikan di atas, maka dari sudut pandang saya itu adalah pertukaran yang dapat diterima.

@wspr Tapi contoh yang Anda kutip sebagai yang mematahkan punggung unta adalah contoh di mana programmer menyalahgunakan bahasa dengan menetapkan secara global ke variabel lokal. Ini ada di programmer. Sistem saat ini tidak menyelesaikan masalah penyalahgunaan bahasa, karena seorang programmer masih dapat menggunakan variabel \l_... seolah-olah bersifat global.

... yang sesuai dengan prinsip-prinsip pemrograman terstruktur.

itu pernyataan yang cukup berani mengingat ada lebih dari satu set
prinsip dan mengingat bahwa upaya untuk menyatukan prinsip-prinsip yang berbeda dalam
superset biasanya menciptakan bahasa yang besar tetapi tidak berguna di masa lalu.

Poin penting belum tentu sesuatu dapat dilakukan (sebagai
dalam basis lengkap Turing semua hal sama pada level itu) tapi
apakah sesuatu dapat dilakukan secara efisien dan konsisten, dll.

@wspr : Mengapa Anda menutup masalah ini seperti pengganggu? Ini adalah apa-apa tapi diselesaikan.

@EvanAad — hanya mencoba untuk menjaga semuanya tetap rapi. Diskusi pasti bisa berlanjut dan jika dijamin kami akan buka kembali.

Saya mengunci masalah ini sementara karena beberapa komentar panas.

Saya pikir ini adalah pertanyaan yang relevan. Salah satu hasil diskusi ini setidaknya harus kami jelaskan lebih hati-hati dalam dokumen mengapa kami memilih deklarasi global saja. @EvanAad Saya tidak berpikir Anda cukup menghargai keterbatasan sistem TeX, tetapi mari kita mundur dan mengabaikan masalah itu sejenak. Bisakah Anda memberikan contoh (dari 10-20 baris, katakanlah) menggunakan hipotetis \int_local_new:N atau sistem pilihan Anda yang berbeda dengan semantik pilihan Anda? Ini akan membantu membingkai diskusi dalam pengaturan yang lebih konkret, dan kami dapat menjelaskan manfaat/kekurangan.

Agaknya kita harus menunggu kuncinya terbuka, saya tidak tahu bagaimana melakukannya. Bagaimanapun kebanyakan orang dalam percakapan ini akan tidur selama beberapa jam. (Omong-omong, saya tidak berpikir menyalin #410 ke #411 sebagai diskusi campur aduk sangat masuk akal.)

Melihat fakta bahwa ini adalah diskusi yang cukup rinci, saya pikir ada baiknya meringkas sejarah teknis dan sosial yang membawa kita ke tempat kita sekarang.

Pada tingkat teknis, TeX menyediakan register dan makro untuk penyimpanan. Makro hanya dapat 'dibuat' menggunakan \def , tetapi untuk menggunakan register dengan nama, kita memerlukan beberapa pengalokasi untuk menautkan nomor register global, _e.g._ \count40 , ke beberapa nama, misalnya \mycount . Itu telah disediakan sejak 'hari pertama', dengan TeX biasa \newcount , _etc._ menyediakan modelnya. Sederhananya, \newcount mengalokasikan secara global dan, terlepas dari namanya, tidak melakukan pemeriksaan apa pun. Format lain, terutama LaTeX2e dan ConTeXt, keduanya mengadopsi pendekatan ini secara umum. Mereka juga umumnya mengadopsi gagasan bahwa register individu kemudian _ditugaskan_ baik secara lokal maupun global, karena ini mencegah penumpukan save-stack.

TeX90 hanya menyediakan 256 register dari tipe umum, jadi penggunaan kembali register dalam konteks lokal sangat penting. Orang melihat bahwa di _e.g._ graphics tempat menyimpan kode 'waras', sejumlah besar register diberi nama baru di dalam grup, dan digunakan murni secara lokal. Dengan e-TeX kami memiliki _lot_ lebih banyak register, jadi pendekatan ini tidak terlalu diperlukan: kami dapat dengan bebas mengalokasikan lebih banyak register (dan makro) untuk tujuan khusus. Secara khusus, itu berarti bahwa kita tidak seperti ditekan untuk 'mendaur ulang' register dengan beberapa nama.

Basis kode expl3 telah dikembangkan selama _lama_, dan awalnya tidak memerlukan e-TeX. Pengembangan expl3 juga dilakukan terutama 'di atas' LaTeX2e, dengan prinsip umum bahwa expl3 tidak mencemari ruang nama dokumen atau mengubah perilaku inti LaTeX2e.

Secara khusus, kita harus ingat bahwa \newcount LaTeX2e mirip dengan plain: ia mengalokasikan secara global dan tidak memeriksa. Jadi khususnya

\def\foo{%
  \begingroup
    \newcount\localfoocnt

adalah 'bad style' seolah-olah \foo dipanggil beberapa kali maka kita akan menggunakan register yang tidak pernah dirilis.

Untuk expl3 , tim telah mencoba untuk menghindari mengikat perilaku variabel yang didokumentasikan ke implementasi makro atau register. (Saya perhatikan bahwa kami mengizinkan penggunaan tl tanpa pengakses, yang pada akhirnya bergantung pada mereka sebagai makro.) Kami juga masih menggunakan register untuk bilangan bulat, dimens, _etc._ karena tersedia dan ditawarkan kinerja yang lebih baik dan 'penghentian diri' daripada melakukan segala sesuatu di makro. (Itu bisa dilakukan dengan menggunakan e-TeX dan berbagai primitif \<thing>expr .) Karena itu, kita perlu memiliki sistem pengalokasi, dan agar konsisten kita mengalokasikan semua jenis variabel, bukan hanya yang didasarkan pada register . Seperti yang diamati oleh @EvanAad , ketika pemeriksaan tidak aktif, seseorang dapat melakukan _e.g._ \tl_set_eq:NN \l_new_tl \l_existing_tl tanpa kesalahan, tetapi ini bukan perilaku yang didukung (misalnya, pemeriksaan akan menandainya).

Sebagai bagian dari expl3 pengalokasi, keputusan dibuat bahwa new _would_ memeriksa keberadaan, berbeda dengan \newcount , jadi

\cs_new_protected:Npn \my_foo:
  {
    \group_begin:
      \tl_new:N \l_my_tl

akan memunculkan _error_ jika \my_foo: digunakan berulang kali. Ini mendorong seseorang ke arah yang telah menjadi praktik standar TeX sejak hari-hari pertama: alokasi keluar dari makro. (Perhatikan bahwa secara sederhana, \newcount adalah \outer begitu juga 'dilarang' di dalam makro.)

\tl_new:N \l_my_tl
\cs_new_protected:Npn \my_foo:
  {
    \group_begin:
      \tl_clear:N \l_my_tl

Paket etex memperkenalkan pengalokasi register bertahun-tahun yang lalu yang dapat melakukan alokasi register lokal maupun global, \loccount _versus_ \globcount , _etc. Untuk beberapa waktu, expl3 memuat etex dan digunakan untuk menyediakan fungsionalitas untuk \int_local_new:N dan sejenisnya. Mengingat fakta bahwa sebagian besar programmer TeX terbiasa melakukan alokasi global, mungkin tidak mengejutkan bahwa ini tidak digunakan secara luas. Namun, tim juga khawatir tentang kemungkinan kesalahpahaman. Dengan sesuatu seperti

\cs_new_protected:Npn \my_foo:
  {
    \group_begin:
      \tl_local_new:N \l_my_tl

kami memiliki pertanyaan tentang apa yang terjadi pada panggilan bersarang ke \my_foo: , atau lebih mungkin tempat di mana beberapa nama 'sederhana' seperti \l_my_tmp_tl akan digunakan. Berdasarkan gagasan umum bahwa kami ingin new melakukan pemeriksaan, itu seharusnya merupakan kesalahan. Pemrogram yang berasal dari banyak bahasa lain mungkin menganggapnya agak aneh. Tentu saja, ini sesuai dengan aturan pelingkupan TeX.

Khususnya, perubahan pada kernel LaTe2e dalam beberapa tahun terakhir berarti kami tidak ingin lagi memuat etex (sebenarnya, kami telah bekerja keras untuk membuat expl3 'mandiri'). Jadi setiap pengalokasi lokal baru harus ditulis untuk bekerja dengan LaTeX2e tanpa perilaku 'mengganggu' bagi mereka yang tidak menggunakan expl3 : dapat dilakukan tetapi tidak sepenuhnya sepele.

Untuk sesuatu seperti \l_my_tmp_tl tentu saja seseorang mungkin masih melakukan alokasi global, tetapi kemudian kita harus tahu variabel \l_... mana yang dialokasikan secara lokal dalam grup saat ini dan mana yang dialokasikan secara global tetapi ditetapkan secara lokal.

Saya tidak punya data pengujian, tetapi mungkin perlu dicatat bahwa mengalokasikan variabel lebih banyak pekerjaan daripada hanya mengaturnya (tentu saja saat memeriksa tidak aktif), jadi menggunakan pengalokasi lokal akan sedikit lebih lambat daripada pengalokasi global plus tugas lokal.

Jadi untuk campuran alasan teknis dan 'sesuai dengan sejarah' kami memutuskan untuk tetap berpegang pada _alokasi_ global. Ini sama sekali tidak mencegah _penugasan variabel lokal, yang didorong dan sangat banyak digunakan.

Itu membawa kita ke elemen 'sosial'. Pengambilan expl3 dalam beberapa tahun terakhir sangat terbantu dengan membuat suku cadang 'secara luas' stabil. Pada tahap tertentu tim harus membuat keputusan tentang hal-hal, sebagian agar orang dapat menggunakannya dan sebagian lagi agar kami beralih ke tugas lain. Itu tidak mencegah kita meninjau kembali hal-hal, tetapi konvensi yang lebih mapan membutuhkan alasan yang baik untuk diubah.

Di sini, saat ini saya kira saya tidak melihat apa yang salah dengan pendekatan 'biasa' dari

\tl_new:N \l_my_tl
\cs_new_protected:Npn \my_foo:
  {
    \group_begin:
      \tl_clear:N \l_my_tl

setidaknya ke titik di mana kami harus kembali dan mengubah pengaturan saat ini.

@blefloch Ya, saya setuju bahwa reaksi saya terhadap penutupan utas @wspr tidak masuk akal dan saya meminta maaf kepadanya dan kepada Anda semua. Saya merasa saya disingkirkan dan dibungkam, dan saya bereaksi dengan amukan. Ini tidak bisa diterima. Maaf tentang itu.

@josephwright terima kasih atas jawaban terperincinya. Setelah memikirkan masalah ini, saya menyadari bahwa jika saya hanya menggunakan \<module>_clear_new:N , maka pada dasarnya semua variabel saya akan berperilaku seolah-olah mereka lokal untuk grup di sekitarnya, selama saya menetapkan menggunakan \<module>_set... daripada \<module>_gset... . Selain itu, saya pikir praktik ini sesuai dengan konvensi LaTeX3 untuk mendeklarasikan variabel sebelum digunakan, jadi saya tidak akan ditandai jika pemeriksaan aktif.

Mengikuti praktik ini, saya akan menulis ulang @josephwright contoh terakhir sebagai berikut:

\cs_new_protected:Npn \my_foo:
{
    \group_begin:
        \tl_clear_new:N \l_my_tl

Satu-satunya tipe data yang tidak sesuai dengan skema ini adalah cs , tetapi sejauh yang saya tahu legal untuk membuat variabel jenis ini dengan \cs_set:Npn et al. tanpa terlebih dahulu mendeklarasikannya, karena LaTeX3 tidak benar-benar memperlakukan cs sebagai tipe data normal yang setara dengan yang lain (yang merupakan masalah terpisah yang ingin saya bahas dengan kalian, tetapi saya akan pergi ke thread lain). Dengan menggunakan pendekatan ini, variabel cs juga dapat dibuat secara lokal. Jika saya ingin menjaga sintaks tetap konsisten, saya selalu dapat menulis pembungkus \cs_clear_new:N saya sendiri.

Jadi, sejauh yang saya ketahui, sekarang Anda dapat menutup masalah ini jika Anda mau, @wspr .

@EvanAad Pada \<thing>_clear_new:N , perhatikan bahwa deklarasi _is_ global di mana variabel belum ada. Jadi

\cs_new_protected:Npn \my_foo:
{
    \group_begin:
        \tl_clear_new:N \l_my_tl
    \group_end:
}
\my_foo:
\tl_show:N \l_my_tl

akan menunjukkan bahwa \l_my_tl didefinisikan dan kosong, dengan asumsi Anda sebelumnya tidak mengaturnya ke sesuatu yang lain.

Saya ingin bergabung dengan @blefloch dengan harapan diskusi ini akan menghasilkan dokumentasi yang lebih baik. Secara khusus, saya berpikir bahwa ketika Anda menulis bahwa programmer "harus" mengikuti pola pengkodean tertentu, seperti dalam kalimat yang saya kutip di posting asli saya, dokumentasi harus menjelaskan apa arti "harus" ini. Apa yang akan terjadi jika polanya tidak dipatuhi?

  1. Akankah perilaku bahasa tidak terdefinisi?
  2. Apakah ketidakpatuhan saat ini didukung, tetapi mungkin tidak demikian di versi mendatang?
  3. Apakah mesin akan melaporkan kesalahan?
  4. Akankah mesin melaporkan kesalahan, tetapi hanya ketika pemeriksaan menyala?
  5. Apakah beberapa ketidaknyamanan kecil akan terjadi?
  6. Akankah tim LaTeX3 menggerutu karena tidak puas, tetapi tidak ada kesalahan atau hilangnya fungsi yang dihasilkan?

Sebagai contoh untuk 5, ambil konvensi penambahan spesifikasi argumen di akhir nama fungsi. Sejauh yang saya tahu, satu-satunya fungsi yang tidak akan berfungsi dengan baik jika konvensi ini tidak dipatuhi adalah \cs_new:Nn , tetapi sisanya, termasuk `cs_ new:Npn ' akan berfungsi dengan baik.

Sebagai contoh untuk 6, ambil konvensi penandaan variabel lokal dan global dengan \g_... dan \l_... . Sejauh yang saya tahu sama sekali tidak akan ada akibat jika tidak mengikuti konvensi ini. Semuanya akan bekerja dengan baik.

@EvanAad — permintaan maaf diterima, dan saya minta maaf karena menutup masalah sebelum diskusi selesai.

@josephwright — sebagai salah satu keuntungan kecil dari manfaat alokasi lokal, jika saya menulis

\cs_new_protected:Npn \my_foo:
  {
    \group_begin:
      \tl_new_local:N \l_my_tl
      ...

maka saya tahu bahwa \l_my_tl tidak hanya bebas dari gangguan dari luar, tetapi tidak seperti menggunakan fungsi _clear saya tahu bahwa semua jejak variabel hilang di luar penggunaan fungsi. Dengan kata lain, hanya dengan melihat kode saya tahu bahwa itu tidak dapat digunakan sebagai variabel semi-global di telepon. (Dan saya dapat memeriksa bahwa tidak ada hal aneh yang terjadi dengan menggunakan \tl_if_exist_p:N .)

(Harus dijalankan tetapi dapat dilanjutkan nanti jika ada gunanya membahas lebih lanjut.)

@wspr Ya tapi itu kembali dengan fakta bahwa ini didasarkan pada cakupan grup TeX. Jadi bisa digunakan 'semi-global' dalam konstruksi bentuk

\cs_new_protected:Npn \my_foo:
  {
    \group_begin:
      \tl_new_local:N \l_my_tl
      \tl_set:Nn \l_my_tl { foo }
      \__my_foo:
     ..
  }
\cs_new_protected:Npn \__my_foo:
  {
    \group_begin:
        \tl_use:N \l_my_foo % Definition from \my_foo: => "foo"
...
  }

yang setidaknya merupakan bagian dari pemikiran kita.

Saya pikir sebelum kita meninggalkan ini, saya ingin menekankan bahwa pada tingkat teknis ada beberapa cara untuk mengatur pengalokasi register lokal.

@josephwright — Saya belum pernah melihatnya sebagai contoh yang membingungkan; di Matlab misalnya mereka membedakan antara sub fungsi yang tidak berbagi ruang lingkup, dan sub fungsi bersarang yang melakukannya. Jadi pemikiran saya yang selalu, baik, mengapa tidak \__my_foo: mewarisi lingkup fungsi “luar”? Ini sangat konsisten dengan perilaku pengelompokan TeX.

(Maaf karena diskusinya terus berlanjut. Sudah lama sekali. Apakah ada yang tertarik untuk melanjutkan?)

Am 19.10.2017 um 09:23 schrieb Joseph Wright:

Saya pikir sebelum kita meninggalkan ini, saya ingin menekankan bahwa di a
tingkat teknis ada beberapa cara untuk membuat register lokal
pengalokasi.

ya tapi cukup dekat dengan argumen Turing, yaitu implementasi seperti itu
akan menjadi sangat tidak efisien saat runtime karena mesin yang mendasarinya
mengelola penyimpanan register secara global. Dan expl3 (pada level itu)
harus tetap "cukup efisien.

itu seperti, katakanlah, variabel global dan lokal dan mutatornya. Lebih tepatnya
daripada pengujian di setiap fungsi jika melakukan operasi global pada a
variabel lokal, konsepnya secara default hanya ada dalam nama,
misalnya \l_... seharusnya menjadi variabel lokal dan tidak boleh digunakan
dengan fungsi global seperti ..._ gset:Nn tetapi kami tidak mengujinya di
waktu berjalan

Namun kami menawarkan modul pemeriksaan (yang berjalan berapa kali lebih lambat)
yang memastikan bahwa semua konvensi ini benar-benar dipatuhi.

Jadi untuk kembali ke variabel global/lokal

konsep standar expl3 adalah

  • mendeklarasikan nama variabel sekali (secara global) -- banyak karena at
    setidaknya beberapa jenis hanya memiliki tempat penyimpanan global

  • gunakan konvensi nama \l_ \g_ untuk menunjukkan variabel lokal dan global

yang memberi Anda global dan lokal tetapi memiliki batasan yang

  • Anda tidak mendeklarasikan variabel lokal di awal cakupannya,
    alih-alih Anda menggunakan _set atau _clear_new pada saat itu dan yang terakhir
    dapat berarti bahwa nama variabel dapat muncul pada saat itu secara global
    dalam keberadaan

  • di luar ruang lingkup variabel masih ada dengan default
    nilai tipe (misalnya _int menjadi 0 dll) sehingga Anda tidak mendapatkan kompiler
    kesalahan jika Anda merujuk ke variabel seperti itu "secara tidak sengaja" di luar yang dimaksudkan
    cakupan

Jadi pada dasarnya satu-satunya hal yang tidak Anda dapatkan adalah dapat mendeklarasikan
variabel lokal sehingga namanya menghilang di luar ruang lingkup (dan menghasilkan
semacam kesalahan yang tidak ditentukan saat runtime jika dirujuk di luar
ruang lingkup yang dinyatakan).

Untuk melakukan itu (yang ya mungkin) expl3 perlu mempertahankannya sendiri
kumpulan sumber daya jauh melampaui hubungan sederhana antara nama dan global
kolam renang yang ditawarkan oleh mesin dan itu berarti semua akses akan
sangat lambat dilakukan - yang bertentangan dengan kriteria desain expl3.

@FrankMittelbach — sekarang Anda membuat saya penasaran; apakah pendekatan etex.sty untuk register benar-benar tidak efisien? Atau mungkin maksud Anda untuk variabel tl, dalam hal ini saya setuju!

@FrankMittelbach Menurut pendapat saya, penting untuk membedakan, dan memperjelas dalam dokumentasi, apa praktik terbaik menurut tim LaTeX3 vs. apa persyaratan formal, baik tata bahasa atau semantik, dari aturan bahasa LaTeX3.

Dua aturan yang Anda kutip, yaitu:

  • mendeklarasikan nama variabel sekali (secara global)
  • gunakan konvensi nama \l_ \g_ untuk menunjukkan variabel lokal dan global

termasuk dalam rubrik konvensi pengkodean yang dianggap disarankan oleh tim LaTeX3, tetapi tidak satu pun dari mereka yang diamanatkan oleh aturan tata bahasa bahasa, dan tidak mematuhi konvensi ini tidak menyebabkan kesalahan atau hilangnya fungsionalitas.

Dengan kata lain, mengikuti aturan ini adalah masalah selera pribadi dan gaya pengkodean, dan menurut saya ini harus dijelaskan dalam dokumentasi.

itu agak seperti mengatakan bahwa tanda 50mh bukan aturan tapi mengemudi
konvensi dan itu masalah selera jika pengemudi mematuhinya (hanya
karena tidak segera diperiksa sebagian besar waktu)

jika Anda menggunakan variabel \l_ dengan _gset maka Anda masih memprogram dalam TeX tetapi
Anda telah berhenti mematuhi aturan tata bahasa dari expl3
bahasa. Apakah itu segera merusak kode Anda? mungkin tidak, tapi kamu
menghasilkan savestack build-up (lihat indeks TeXbook)

apakah Anda mengatakan itu hanya aturan tata bahasa jika kami memeriksanya di
run-time, katakanlah, setiap hari Selasa?

@FrankMittelbach Tentu, jika Anda mendefinisikan ini sebagai bagian dari aturan bahasa daripada itu menurut definisi, tetapi poin saya adalah bahwa ini tidak boleh didefinisikan sebagai bagian dari aturan bahasa, karena tidak pernah diperiksa, dan karena tidak mengikuti konvensi ini tidak dengan sendirinya menyebabkan kesalahan atau hilangnya fungsionalitas.

Ini adalah perbedaan antara mengatakan "Ketika Anda menulis bahasa Inggris, yang terbaik adalah memegang pena di tangan kanan Anda karena ini menghindari noda tinta." dan mengesahkan undang-undang yang mengatakan bahwa bahasa Inggris harus ditulis dengan pena yang dipegang di tangan kanan. Tentu, Anda dapat mengesahkan undang-undang semacam itu, dan ada alasan yang masuk akal untuk membenarkannya, tetapi pada akhirnya pilihan tangan mana untuk memegang pena harus diserahkan kepada masing-masing penulis. Dan akan ada orang yang memilih untuk tidak mematuhi aturan ini, dan tetap menulis dengan rapi seperti mereka yang mematuhinya.

Saya pikir @FrankMittelbach melebih-lebihkan overhead deklarasi lokal ( \loccount mengelola hitungan secara lokal, tidak ada yang dilakukan secara global, sehingga membuat overhead tetap baik).

Saya tidak melihat masalah besar dengan menyediakan \int_local:N dan \tl_local:N (= \tl_set_eq:NN #1 \c_empty_tl ) dll yang akan sangat analog dengan \int_zero_new:N dan \tl_clear_new:N tetapi hanya akan melakukan "baru" secara lokal. Ini membutuhkan sedikit kerja untuk register tetapi tidak berlebihan.

@EvanAad Anda harus tahu bahwa tidak mendeklarasikan variabel dapat menggigit Anda di beberapa titik (peringatan: kode ini menghasilkan banyak halaman).

\documentclass{article}
\usepackage{expl3}
\begin{document}
\ExplSyntaxOn
\tl_put_left:cn { l_my_tl } { foobar \par }
\l_my_tl
\end{document}

@blefloch Yang saya katakan adalah, tidak apa-apa mendeklarasikan variabel di dalam makro (dengan \<module>_clear_new ), dan Anda tidak perlu menamainya \l_amount_paid_int , Anda cukup menelepon itu \amount_paid atau \amountPaid , seperti yang Anda lakukan dalam bahasa pemrograman lainnya. \l_..._int adalah mnemonik yang bagus untuk mengingatkan Anda bahwa itu bilangan bulat dan seharusnya digunakan secara lokal, tetapi Anda tidak boleh dipaksa untuk menggunakan ini, atau mnemonik lainnya.

karena tidak pernah diperiksa, dan karena tidak mengikuti konvensi ini
tidak dengan sendirinya menyebabkan kesalahan atau hilangnya fungsionalitas.

tapi itu intinya

a) itu menyebabkan kerusakan tergantung pada keadaan - yaitu ketika Anda mencampur
penugasan global dan lokal ke variabel yang sama

b) kami melakukan pemeriksaan berdasarkan permintaan (dan saat ini kode tersebut mungkin tidak
fungsional tetapi dulu dan mungkin akan kembali lagi pada akhirnya karena a))

ps ya saya mengerti maksud Anda tentang memegang pena (kidal) dan ya saya
telah di atas batas kecepatan (pada sepeda saya) tetapi saya tetap menganggap ini sebagai
peraturan lalu lintas bukan konvensi lalu lintas dan ya orang bisa tidak mematuhinya
tanpa bahaya, tetapi seseorang juga bisa mati karenanya atau setidaknya berakhir dengan denda

(Apa yang ditunjukkan oleh contoh kode saya sebelumnya adalah bahwa bahkan untuk tl, penting untuk mendeklarasikannya sebelum digunakan. Ada opsi pemeriksaan yang menguji deklarasi tetapi dalam penggunaan normal kami tidak menginginkan biaya tambahan seperti itu.)

Saya setuju dengan @EvanAad bahwa nama hanyalah sebuah konvensi. Kita dapat memeriksa bahwa penetapan lokal dan global tidak tercampur bahkan tanpa konvensi nama l_/g_: karena kode pemeriksaan diperbolehkan agak lambat, cukup masuk akal untuk menyimpan informasi tentang apakah variabel yang diberikan digunakan di lokal/global penugasan. Untuk memeriksa jenis situasinya serupa, kecuali untuk dua pasang jenis yang tidak dapat dibedakan (saya tidak akan mengatakan yang mana untuk menghindari menggagalkan percakapan).

Pada 'konvensi', \amountPaid adalah perintah dokumen sementara \l_amount_paid_int tidak, dan yang terakhir adalah bagian dari namespace amount (berdasarkan konvensi tetapi yang cukup penting di TeX ). Itu tidak berlaku untuk \l_ / \g_ , meskipun saya pikir banyak bahasa memiliki 'pengarah' yang kuat pada penamaan tanpa itu diberlakukan pada tingkat teknis.

Pada 19 Oktober 2017, pukul 16:58, Joseph Wright [email protected] menulis:

Pada 'konvensi', jumlahPaid adalah perintah dokumen sementara \l_amount_paid_int tidak, dan yang terakhir adalah bagian dari namespace jumlah (berdasarkan konvensi tetapi yang cukup penting di TeX). Itu tidak berlaku untuk \l_/\g_, meskipun saya pikir banyak bahasa memiliki 'pengarah' yang kuat pada penamaan tanpa itu diberlakukan pada tingkat teknis.

Mimpi buruk terburuk dalam pemrograman LaTeX2e adalah mendefinisikan perintah
di "ruang tingkat pengguna", katakan \foo, untuk mengetahui bahwa itu bentrok
dengan perintah paket lain yang ditentukan untuk penggunaan _internal_ (jadi
tidak didokumentasikan dalam manual).

Apakah itu benar-benar terjadi? Ya, dan tidak hanya sekali. Menempel pada
\Konvensi @commandname sangat membantu dalam menghindari
masalah seperti itu.

Tentu saja bentrokan di "ruang tingkat pengguna" juga dapat terjadi,
tetapi mereka jauh lebih mudah dikenali dan dipecahkan. Ketika datang ke
internal, sering kali perlu mengejar ekspansi dengan sangat
tingkat yang dalam.

Berbeda dengan legislator, kita tidak bisa menjatuhkan denda atau penjara
yang tidak mematuhi hukum pemrograman LaTeX3. Tapi kami
sebuah komunitas dan semua orang harus.

Pedoman kami tentang konvensi penamaan akan membantu dalam tidak pernah menemukan
perintah internal paket untuk berbenturan dengan yang lain.

Untuk kode pribadi, seseorang berhak melakukan apa pun yang mereka inginkan: ada
tidak ada hukum yang melarang seseorang untuk mempercepat di properti pribadi mereka, tapi
ada satu tentang melakukan itu di jalan umum.

Jika Anda ingin mendefinisikan variabel \f jenis apa pun secara lokal,
Anda harus khawatir tentang perintah yang ditentukan oleh beberapa
paket dan, menurut hukum Murphy, berakhir persis di argumen
ke fungsi menggunakan variabel \f. Bisakah Anda membayangkan yang lebih buruk?
skenario?

Ciao
Enrico

dan Anda tidak perlu menamainya \l_amount_paid_int, Anda cukup menyebutnya dengan jumlah_bayar seperti yang Anda lakukan dalam bahasa pemrograman lain. \l_... adalah mnemonic yang bagus untuk mengingatkan Anda bahwa itu seharusnya digunakan secara lokal, tetapi tidak harus menggunakan ini, atau mnemonic lainnya.

Tentu. Anda juga dapat menggunakan md5-fc693aa157832059d7daeeb61c55 cddb:paid atau

@eg9

Untuk kode pribadi, seseorang berhak melakukan apa pun yang mereka inginkan

Anda tidak akan tahu ini dengan membaca dokumentasi, hanya itu yang saya katakan.

Jika Anda ingin mendefinisikan variabel \f secara lokal, Anda harus khawatir tentang perintah yang didefinisikan oleh beberapa paket

saya tidak setuju. Jika kode Anda ada di dalam \group_begin: ... \group_end: , dan jika Anda mendefinisikan semua variabel lokal dengan \<module>_clear_new:N , dan jika Anda hanya menetapkan variabel lokal dengan \<module>_set:N... , Anda tidak perlu khawatir nama variabel lokal Anda bentrok dengan paket lain, kecuali kode Anda menggunakan paket lain.

@u-fischer

Tetapi bahkan jika nama-nama itu hanya sebuah konvensi: itu membuat komunikasi lebih mudah jika orang tetap berpegang pada konvensi tersebut.

Saya tidak mengatakan tidak ada alasan bagus untuk tetap berpegang pada konvensi. Yang saya katakan adalah, konvensi ini tidak boleh dijadikan aturan bahasa, dan dokumentasi harus dengan jelas membedakan antara konvensi, yang alasannya harus dinyatakan, dan aturan. Dan pilihan apakah akan mengikuti konvensi pada akhirnya harus berada di tangan programmer.

@EvanAad Anda perlu khawatir tentang bentrokan nama bahkan dalam kasus yang Anda jelaskan. Katakanlah Anda menulis

\cs_new_protected:Npn \evanaad_halve:n #1
  {
    \group_begin:
      \int_zero_new:N \f
      \int_set:Nn \f { (#1) / 2 }
      \iow_term:x { \int_use:N \f }
    \group_end:
  }

maka pengguna paket Anda melakukannya

 \int_const:Nn \f {123}
 \evenaad_halve:n { \f }

Mereka akan terkejut melihat 0 dan bukan 62.

Di sisi lain jika Anda tetap menggunakan nama seperti \evanaad_f dll (atau lebih pendek \@@_f dll menggunakan sihir l3docstrip ), Anda harus aman.

Anda tidak akan tahu ini dengan membaca dokumentasi, hanya itu yang saya katakan.

Maaf tapi expl3.pdf menggunakan kata "konvensi" sekitar 20 kali. Dalam kasus perintah publik versus pribadi bahkan ada kalimat "(hampir) tidak ada cara untuk menegakkan ini tanpa overhead komputasi yang parah, jadi kami menerapkannya hanya melalui konvensi penamaan,".

@blefloch Poin bagus.

@u-fischer Oke, cukup adil. Bagaimana dengan konvensi bahwa nama fungsi harus diakhiri dengan penentu argumen? Ini tidak sepenuhnya merupakan konvensi, karena fungsi bagian 3.3 memeriksa penentu argumen, tetapi fungsi ini hanyalah "gula sintaksis", dan jika Anda tidak menggunakannya, tidak ada halangan untuk menggunakan nama fungsi seperti \mymodule_myfunc , tetapi Anda tidak akan mengetahuinya dari manual.

Pada 19 Oktober 2017, pukul 17:52, EvanAad [email protected] menulis:

@u-fischer Oke, cukup adil. Bagaimana dengan konvensi bahwa nama fungsi harus diakhiri dengan penentu argumen? Ini tidak sepenuhnya merupakan konvensi, karena fungsi bagian 3.3 memeriksa penentu argumen, tetapi fungsi ini hanyalah "gula sintaksis", dan jika Anda tidak menggunakannya, tidak ada halangan untuk menggunakan nama fungsi seperti \mymodule_myfunc.

Itu diperlukan untuk cs_generate_ varian:Nn , tentu saja.

Ciao
Enrico

Dengan \mymodule_myfunc Anda tidak akan dapat menggunakan fungsi apa pun dari
l3expan . Fungsi ekspansi ini, dan gagasan varian, adalah a
bagian inti dari expl3.

Sementara saya setuju bahwa nama variabel dapat dibuat lebih pendek (menghapus
"l_"/"g_" dan "_int"/...), tanda tangan fungsi sebenarnya bukan "hanya a
Konvensi".

@blefloch Saya mengerti maksud Anda, dan itu bagus, tapi tetap saja, menurut saya jika yang Anda inginkan hanyalah menulis perintah dokumen, Anda harus tahu bahwa Anda dapat melakukannya dengan mendefinisikan fungsi seperti

\ExplSyntaxOn
\cs_new:Npn \MyDocumentCommand {Hello,~world!}
\ExplSyntaxOff

dan Anda tidak harus terlebih dahulu mendefinisikan fungsi "bayangan" \mymodule_my_document_command: , lalu menyalinnya dengan

\cs_new_eq:NN \MyDocumentCommand \mymodule_my_document_command:

@blefloch Dan, omong-omong, selain \cs_generate_variant:Nn , yang disebutkan @eg9 , apakah ada fungsi lain dari modul l3expan menggunakan bagian penentu argumen dari nama fungsi?

sekarang kedengarannya bagi saya bahwa Anda sebagian besar berdebat demi berdebat

ya Anda dapat melakukan semua ini dan pada akhirnya satu-satunya bahasa yang sulit
aturan adalah apa yang tertanam dalam mesin TeX pada primitifnya. Dan diberikan
bahwa TeX adalah bahasa modifikasi diri yang pada dasarnya dapat Anda gunakan di mana saja
disana misalnya

\endlinechar-1\def~#1{\catcode`#113}~Q~S~U~_~V~W~J~K~L~M~N~O~@~X~Y~[~] ~(
~|~&~Z~'~"~ ~h~z~:~q~j~k~;~/~)~!~,~$~+\let_\let_~newcount~$$-1~Q ~J~V~S~K~W~U~L~,~''1~""2~ *1_&\count&144'&155'&145"&154"_[\ifnum_(\ifcase_O\or
_|\else_]\fi_N\number_@\advance_X\expandafter_Z\global_Y\typeout_~newif
~\ifG~\if_~\def~j{[0 T[0Jk|$]|$]|$]|$]}~k{&1NQNJ}~\2#1#2{}~:#1{

11#12#13#14#15#16#17#18}~h#1#2{#2:{~\q#1}~#2^^J}~\q#1#2{(&1 #1#2~~OO$]}

~/{Y{Baris dan kolom? misalnya E6}\read$toM\ifcat~X\2M~$$X\jM|!input!]}~!#1!{
Y{Tidak Valid #1.}/}~\j#1#2{Q #1@Q- @J #2@J- 0;(V!move!]}~;{V0 (jS1z1z0z{$} S
0z1z{$}S$z1z0z{$}]}~_{@,\ifodd'-]}~z#1{{\trueK#1{\falseq}}}~q{@ QS@JK [j="
\ifZk'Z_2]@V1q|[j='ZVV\ifG\if|\aftergroupq]]]]}~\,#1{Q#1:.}~.#1{J#1;[0
WWVUQLJ]]}~+#1{(#1O2O-2O0O0O0O0O-2O2]}~){'X"X"N'Y{^^J :
~^^Jh1Ah2Bh3Ch4Dh5Eh6Fh7Gh8H :~^^J}\GfalseW(W$|0]~:\,\Gtrue[0 /];k'_1][$=WY{(,Tie| Pemain [0>,.|$]~menang dengan N[0>,-],].}X\dump])}~~{ })

yang merupakan dokumen TeX yang indah (sebenarnya dokumen LaTeX yang indah)
tetapi sejauh menyangkut kodenya sama sekali tidak berguna. Dan
fakta bahwa Bruno dapat menulis dokumen seperti itu tidak berarti itu
manual expl3 (atau dalam hal ini manual LaTeX) harus menjelaskan semua itu.

Kode LaTeX (2.09 dan juga 2e) memiliki masalah besar yang pada awalnya
terlalu banyak orang yang memprogram itu mengerti tentang pintasan tingkat rendah
di TeX dan menggunakan serta menyalahgunakannya karena mereka menganggapnya tidak
berbahaya. Akibatnya sejumlah besar paket 2e yang ada adalah
tidak kompatibel satu sama lain atau memiliki masalah halus di beberapa tempat saat digunakan
bersama-sama dll atau putus sesekali karena mereka melewati satu atau
antarmuka pengguna (karena tampaknya berfungsi tanpa itu).

Anda pada dasarnya meminta kami berulang kali untuk mendokumentasikan hal ini,
yaitu, kemungkinan jalan pintas yang melanggar prinsip-prinsip desain saja
karena mereka kadang-kadang bekerja (atau bahkan saat ini selalu). Tapi expl3
dan konvensi/aturannya sebagian besar berasal dari pengalaman itu
coders tidak mematuhi aturan seperti itu di masa lalu dan kekacauan yang diakibatkannya
dari sini. Jadi tidak, aturannya disengaja dan bukan hanya keinginan belaka (kebanyakan .)
waktu) dan meskipun "jika Anda tahu apa yang Anda lakukan maka Anda
dapat melewati sebagian besar dari mereka dalam situasi tertentu" itu tidak berarti bahwa
jika Anda memindahkan kode Anda maka dari satu tempat ke tempat berikutnya akan tetap
kasus atau apakah itu perlu menjadi kasus dari waktu ke waktu.

Seperti yang dikatakan oleh orang lain, ada perbedaan besar antara kode yang Anda tulis
terbang untuk diri sendiri dan kode yang Anda tulis sebagai "resmi" didistribusikan
kemasan. Setidaknya untuk yang terakhir, kami meminta untuk menerima aturan dan
menganggap mereka sebagai bagian dari bahasa. Untuk diri sendiri, Anda mungkin ingin
pelajari cara membuat kode dokumen seperti di atas tetapi pengetahuan bagaimana melakukannya
itu tidak akan keluar dari manual expl3


karena itu, saya tidak ingin mengecilkan hati Anda dengan konsep yang menantang,
perintah, antarmuka, apa yang Anda miliki. Banyak poin yang Anda kumpulkan
kesempatan lain telah diambil dengan baik (atau setidaknya membuat kami memikirkan kembali satu)
atau titik lainnya).

Tetapi sejauh menyangkut manual expl3, saya pikir apa yang Anda dengar dari
beberapa orang adalah bahwa tidak ada minat untuk mendokumentasikan
"non-konvensi" dan "non-aturan". Apalagi jika kode mengalihkan terlalu banyak
dari apa yang kita sebut aturan/konvensi maka itu akan tetap menjadi kode TeX tapi
tidak lagi expl3 kode.

Saya pikir kita sudah membicarakan yang ini: Saya akan tutup tetapi tentu saja akan dibuka kembali jika diminta.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat