Lua di Moskow 2019: wawancara dengan Roberto Jerusalem



Beberapa waktu lalu, Roberto dari Yerusalem, penulis bahasa Lua, mengunjungi kantor kami di Moskow. Kami mewawancarainya, di mana kami mengajukan pertanyaan dari para pembaca Habr. Akhirnya, kami dapat berbagi dengan Anda seluruh rekaman percakapan.

- Mari kita berfilsafat sebagai permulaan. Jika Anda membangun Lua lagi dari awal, tiga hal apa yang akan Anda ubah dalam bahasa ini?

- Wow! Pertanyaan yang sulit. Ada keseluruhan cerita di balik penciptaan dan pengembangan bahasa. Ini bukan keputusan besar. Ada keputusan yang saya sesali dan yang selama bertahun-tahun saya bisa perbaiki. Dan programmer mengeluh tentang hal itu sepanjang waktu karena kompatibilitasnya rusak. Kami telah melakukan ini beberapa kali. Dan saya hanya memikirkan beberapa tugas kecil.

- Default global (Global-by-default)? Apakah Anda pikir ini jalan yang benar?

- Mungkin. Tetapi jalur ini sangat sulit untuk bahasa yang dinamis. Mungkin Anda harus sepenuhnya meninggalkan konsep "default", tetapi kemudian akan sulit untuk menggunakan variabel.
Misalnya, Anda harus mendeklarasikan semua pustaka standar. Anda perlu one-liner , print(sin(x)) , dan kemudian Anda perlu mendeklarasikan "cetak" dan "dosa" yang lain. Sangat aneh memiliki iklan untuk skrip pendek seperti itu.

Apa pun yang lebih besar seharusnya tidak memiliki apa pun secara default, seperti yang menurut saya. Local-by-default bukanlah solusi, itu tidak ada sama sekali. Ini hanya untuk penugasan, bukan untuk digunakan. Kami menetapkan sesuatu, lalu menggunakan dan menetapkan lagi, dan terjadi kesalahan yang sepenuhnya tidak dapat dijelaskan.

Mungkin globalitas default tidak sempurna, tetapi lokalitas default jelas bukan pilihan. Saya pikir semacam pengumuman, mungkin opsional ... Kami telah berniat berkali-kali untuk membuat semacam pengumuman global. Tetapi jika kita secara membabi buta memperkenalkan segala sesuatu yang kita minta, tidak ada hal baik yang akan terjadi.

(sinis) Ya, kami akan memperkenalkan pengumuman global, menambahkan bahwa, sho, kelima, kesepuluh, mencabut yang lain, dan sebagai hasilnya, kami menyadari bahwa solusi akhir tidak memuaskan sebagian besar programmer, dan kami tidak akan menambahkan semua fitur yang kami minta, dan oleh karena itu kami tidak mengimplementasikan apa pun. Lagi pula, mode ketat adalah kompromi yang masuk akal.

Ada masalah: paling sering kami gunakan, misalnya, bidang di dalam modul, dan sekali lagi Anda memiliki masalah yang sama. Ini hanya satu kasus kesalahan yang sangat spesifik, yang mungkin harus dipertimbangkan dalam solusi umum. Jadi jika Anda benar-benar membutuhkannya, lebih baik menggunakan bahasa yang diketik secara statis.

- Globalitas default masih nyaman untuk file konfigurasi kecil.

"Ya, benar, untuk skrip kecil dan sejenisnya."

- Dan tidak ada kompromi dalam hal ini?

- Selalu ada kompromi. Dalam hal ini, kompromi antara skrip kecil dan program nyata, sesuatu seperti itu.

- Dan di sini kita kembali ke pertanyaan besar pertama: apa tiga hal yang akan Anda ubah jika ada kesempatan seperti itu? Sepertinya saya bahwa Anda cukup senang dengan keadaan saat ini, bukan?

"Yah, aku tidak akan menyebutnya perubahan besar, namun ... Salah satu keputusan gagal yang menjadi perubahan besar adalah nol dalam tabel." Maafkan aku tentang itu. Saya membuat retasan ini ... Apakah Anda tahu apa yang saya bicarakan? Setengah tahun atau setahun yang lalu, saya merilis versi Lua di mana ada nol dalam tabel.

- Nilai nol?

- Tepat. Saya pikir ini disebut nil dalam tabel - yaitu, null. Kami melakukan peretasan tata bahasa untuk memastikan kompatibilitas.

- Mengapa itu dibutuhkan?

"Saya benar-benar yakin bahwa ini adalah keseluruhan masalahnya ... Saya pikir sebagian besar masalah dengan nil dalam array akan hilang jika kita dapat memiliki [nil dalam tabel] ... Lebih tepatnya, masalahnya bukan pada nil dalam array." Mereka memberi tahu saya bahwa array tidak boleh nil, jadi array harus dipisahkan dari tabel. Masalah sebenarnya adalah kita tidak bisa menyimpan nol dalam tabel! Oleh karena itu, masalahnya bukan bagaimana kami mewakili array, tetapi dalam tabel. Jika kita bisa memiliki nil dalam tabel, maka kita akan memiliki nil dalam array tanpa yang lainnya. Jadi saya sangat menyesal tentang hal itu, dan banyak orang tidak mengerti bagaimana segala sesuatunya bisa berubah jika Lua membiarkan nol diletakkan di meja.

- Bisakah saya ceritakan tentang Tarantool? Kami memiliki implementasi nol kami sendiri, yang merupakan CDATA ke pointer nol. Kami menggunakannya dalam kasus di mana Anda perlu membuat fragmen kosong di memori Anda untuk memasukkan argumen penentuan posisi untuk panggilan jarak jauh, dan sebagainya. Tetapi biasanya ini adalah masalah karena CDATA selalu dikonversi menjadi true. Dan nihil dalam array akan memecahkan banyak masalah.

- Ya saya tahu. Inilah yang saya bicarakan - ini akan memecahkan banyak masalah bagi banyak orang, tetapi ini mengarah pada masalah kompatibilitas yang lebih besar. Kami tidak memiliki keberanian untuk merilis versi yang akan sangat tidak kompatibel, dan kemudian menghancurkan komunitas dan merilis dokumentasi lain untuk Lua 5, Lua 6, dll. Tapi mungkin suatu hari kita akan merilis versi seperti itu. Ini akan menjadi perubahan yang sangat besar. Saya percaya bahwa ini seharusnya dilakukan sejak awal, dan kemudian kita akan berbicara tentang perubahan sepele dalam bahasa, kecuali untuk kompatibilitas. Dan hari ini akan merusak banyak program.

- Kekurangan apa yang Anda lihat selain masalah kompatibilitas?

- Dua fungsi primitif baru akan diperlukan. Sesuatu seperti "tombol Hapus", karena menugaskan nil tidak akan menghapus kunci, sehingga Anda akan memerlukan operasi primitif untuk benar-benar menghapusnya dari tabel. Dan Anda akan memerlukan "tes" untuk memeriksa dengan tepat di mana ada perbedaan antara nihil dan kurangnya data.

- Sudahkah Anda menganalisis dampak dari inovasi ini dalam implementasi praktis?

- Ya, kami merilis versi Lua. Seperti yang saya katakan, ini diam-diam memecahkan kode. Beberapa menggunakan panggilan fungsi table.insert(f(x)) . Dan sengaja dilakukan agar jika fungsi tidak ingin memasukkan apa pun, ia mengembalikan nihil. Jadi, bukannya cek terpisah, "Apakah saya ingin menanamkan?" Saya memanggil table.insert , dan jika saya mendapatkan nol, maka saya tahu itu tidak akan dimasukkan. Seperti dalam bahasa lain, bug telah berubah menjadi fitur, dan orang-orang menggunakannya. Tetapi jika Anda mengubah fitur, itu akan merusak kode.

- Bagaimana dengan tipe void? Seperti nihil, hanya batal?

"Yah, tidak, ini mimpi buruk." Anda hanya menunda menyelesaikan masalah. Jika Anda memasukkan satu "tongkat", maka Anda akan membutuhkan satu lagi, dan lebih banyak, dan lebih banyak lagi. Ini bukan solusi. Salah satu masalah adalah bahwa nihil telah berakar di banyak tempat bahasa. Berikut adalah contoh khas: kita mengatakan "hindari nil dalam array, yaitu, lubang". Dan kemudian kita menulis fungsi yang mengembalikan nol dan sesuatu setelahnya, dan kita mendapatkan kode kesalahan. Konstruksi seperti itu sudah menyiratkan sendiri apa yang nihil itu ... Misalnya, jika saya ingin membuat daftar hasil yang dikembalikan oleh fungsi, hanya untuk menangkap semuanya.

- Untuk ini Anda memiliki hack :)

"Itu benar, tetapi kamu tidak diharuskan untuk menggunakan hack untuk menyelesaikan tugas yang begitu sederhana dan jelas." Namun, perpustakaan melakukan ini ... Entah bagaimana saya memikirkannya: mungkin perpustakaan harus mengembalikan false bukan nihil, meskipun ini adalah opsi kasar, itu hanya akan menyelesaikan sebagian kecil dari masalah. Masalah sebenarnya, seperti yang saya katakan, adalah bahwa kita perlu memiliki nol di tabel. Kalau tidak, kita tidak boleh menggunakan nihil sesering yang saya kira. Secara umum, tidak jelas. Jadi jika Anda membuat void, fungsi-fungsi ini masih akan mengembalikan nihil, dan kami tidak akan menyelesaikan masalah sampai kami membuat tipe baru dan fungsi-fungsi mengembalikan batal alih-alih nihil.

- Menggunakan void, Anda dapat secara eksplisit mengatakan bahwa kunci tersebut harus disimpan dalam tabel, kunci dengan nilai batal. Dan nihil bisa bekerja seperti sebelumnya.

"Ya, itu yang aku maksud." Semua fungsi ini di perpustakaan harus mengembalikan void atau nil.

"Mereka juga bisa kembali nihil, kenapa tidak?"

- Karena itu untuk beberapa kasus kami tidak akan menyelesaikan masalah ketidakmungkinan menangkap semua nilai yang dikembalikan fungsi.

"Tapi kita tidak akan memiliki kunci pertama, hanya kunci kedua."

- Tidak, tidak akan ada detik, karena perhitungan akan dilakukan secara tidak benar dan sebuah lubang akan muncul di array.

- Jadi Anda ingin mengatakan Anda perlu metamethod palsu?

- Ya. Saya bermimpi tentang ini:

{f(x)}

Anda perlu mencegat semua hasil yang dikembalikan oleh f(x) . Dan kemudian saya bisa mengatakan %x atau #x , dan dengan cara ini saya tahu jumlah hasil yang dikembalikan. Ini adalah cara kerja bahasa normal. Jadi membuat kekosongan tidak akan menyelesaikan masalah sampai ada aturan yang sangat ketat yang fungsinya tidak pernah mengembalikan nol. Tetapi mengapa kita bahkan perlu nol? Mungkin ada baiknya menyerah begitu saja.

- Roberto, akankah ada dukungan yang lebih kuat untuk analisis statis di Lua? Suka Lua Periksa Steroid? Tentu saja, saya mengerti bahwa ini tidak akan menyelesaikan semua masalah. Anda mengatakan bahwa fitur ini akan muncul dalam versi 6.0, jika sama sekali, kan? Dan jika dalam 5.x akan ada alat yang kuat untuk analisis statis - jika jam kerja diinvestasikan di dalamnya - akankah ini membantu?

"Tidak, aku percaya bahwa alat analisis statis yang sangat kuat disebut ... sistem tipe!" Jika Anda membutuhkan alat yang sangat kuat, gunakan bahasa yang diketik secara statis seperti Haskell, atau beberapa jenis bahasa dengan tipe dependen. Maka Anda pasti akan memiliki alat analisis yang kuat.

"Tapi kalau begitu aku tidak akan memiliki Lua."

- Benar, Lua diperlukan untuk ...

- Ketidakpastian? Saya suka gambar Anda dengan jerapah tentang tipe statis dan dinamis.

- Ya, ini slide terakhir saya dari presentasi.


Slide terakhir presentasi untuk pembicaraan Roberto Jerusalem "Kenapa Lua? (dan mengapa tidak) ”di konferensi Lua di Moskow 2019.

- Untuk mengajukan pertanyaan berikutnya, mari kembali ke gambar ini. Jika saya mengerti dengan benar, Anda berpikir bahwa Lua adalah alat kecil yang nyaman untuk menyelesaikan tugas yang tidak terlalu besar.

- Tidak, saya percaya Anda dapat memecahkan beberapa masalah besar, tetapi tidak melibatkan analisis statis. Saya percaya pada tes dengan sepenuh hati. Ngomong-ngomong, saya tidak setuju dengan Anda mengenai pertanggungan, bahwa kami tidak seharusnya mengejar pertanggungan ... Saya ingin mengatakan, saya sepenuhnya setuju dengan pandangan bahwa pertanggungan tidak memberikan pengujian penuh, tetapi kurangnya cakupan tidak memungkinkan pengujian sama sekali. Saya berbicara di Stockholm tentang ruang ujian, Anda ada di sana. Saya mulai menguji dengan beberapa bug - ini adalah hal yang paling aneh - salah satunya diketahui secara luas, dan sisanya sama sekali tidak diketahui. Sesuatu yang benar-benar rusak di file header Microsoft, C dan C ++. Saya mencari di internet, tapi tidak ada yang khawatir atau bahkan menyadarinya.

Sebagai contoh, ada fungsi matematika modf () , yang perlu melewati pointer ke nilai ganda, karena mengembalikan dua ganda. Kami mengonversi bilangan bulat atau pecahan angka. Fitur ini telah lama menjadi bagian dari perpustakaan standar. Kemudian muncul C 99, dan fungsi ini sekarang diperlukan untuk angka float. Dan file header Microsoft hanya menyimpan fungsi ini dan menyatakan yang lain sebagai makro. Artinya, fungsi pertama mengalami konversi tipe implisit. Ganda dikonversi menjadi float, dan kemudian pointer ke double dikonversi menjadi pointer ke float!

- Ada yang salah dengan gambar ini.

- Ini adalah file header dari Visual C ++ dan Visual C 2007. Jika Anda memanggil fungsi ini sekali, dengan parameter apa pun, dan kemudian memeriksa hasilnya, maka itu akan salah, kecuali jika itu adalah 0. Nilai lain apa pun tidak akan benar. Anda tidak dapat menggunakan fitur ini. Tanpa cakupan. Dan kemudian ada banyak diskusi tentang pengujian ... Panggil saja fungsi sekali dan periksa hasilnya! Masalah ini ada sejak lama, selama bertahun-tahun tidak mengganggu siapa pun. Apple memiliki bug yang sangat terkenal, seperti " if… what… goto… ok ". Seseorang memasukkan ekspresi lain di sini, dan semuanya menjadi normal. Dan kemudian mereka banyak berdebat tentang apakah aturan diperlukan, apakah kurung kurawal harus digunakan dalam gaya kode, dan seterusnya dan seterusnya. Tidak ada yang menyebutkan bahwa ada banyak "seandainya". Tidak ada yang melakukannya ...

- Ada juga masalah keamanan, seingat saya.

- Benar. Bagaimanapun, mereka hanya menguji situasi yang dikonfirmasi. Mereka tidak menguji semuanya secara berturut-turut, karena semuanya akan dikonfirmasi. Ini berarti bahwa dalam aplikasi yang memeriksa keamanan, tidak ada tes tunggal yang akan memeriksa kegagalan dalam koneksi apa pun, atau apa yang harus ditolak di sana. Dan semua orang berdebat tentang apakah tanda kurung diperlukan ... Kita perlu tes, setidaknya tes! Lagi pula, tidak ada yang bahkan menguji apa yang saya maksud dengan "pelapisan". Ini sulit dipercaya, orang bahkan tidak menjalankan tes dasar. Tentu saja, akan sangat sulit untuk menyediakan cakupan dengan tes dasar, menjalankan semua baris kode. Orang menghindari bahkan tes dasar, sehingga cakupannya minimal. Saya ingin mendorong Anda untuk memperhatikan bagian-bagian dari program yang Anda lupakan. Sesuatu seperti petunjuk bagaimana meningkatkan sedikit tes Anda.

- Tahukah Anda apa cakupan tes di Tarantool? 83%! Apa cakupan di Lua?

- Sekitar 99,6%. Berapa banyak baris kode yang Anda miliki? Satu juta, ratusan ribu? Ini jumlah yang sangat besar. 1% dari seratus ribu adalah seribu baris kode yang belum pernah diuji. Anda tidak mengeksekusi mereka sama sekali. Pengguna Anda tidak menguji apa pun.

- Artinya, sekitar 17% fungsi Tarantool tidak digunakan sekarang?

- Tidak mungkin Anda ingin kembali ke apa yang kita bicarakan lagi ... Saya pikir salah satu masalah dengan bahasa dinamis (dan yang statis juga) adalah bahwa orang tidak menguji kode mereka. Bahkan menggunakan bahasa statis - tidak seperti Haskell, tetapi sesuatu seperti Coq - sampai Anda memiliki sistem verifikasi, Anda akan mengubahnya ke sana. Dan tidak ada alat analisis statis yang dapat menangkap kesalahan ini, jadi Anda perlu tes. Dan jika Anda memilikinya, Anda dapat mengidentifikasi masalah global, kesalahan ketik nama, dan sebagainya, semua jenis kesalahan. Anda pasti butuh tes. Kadang-kadang akan sulit untuk di-debug, jika tidak itu sederhana - itu tergantung pada bahasa dan jenis bug. Tetapi intinya adalah bahwa tidak ada alat analisis statis yang dapat menggantikan tes. Di sisi lain, mereka tidak menjamin tidak adanya kesalahan, tetapi dengan mereka saya merasa jauh lebih percaya diri.

- Kami memiliki pertanyaan tentang pengujian modul Lua. Sebagai pengembang, saya ingin menguji beberapa fungsi lokal yang dapat saya gunakan nanti. Pertanyaan: Anda perlu jangkauan pada level 99%, tetapi jumlah situasi fungsional yang harus dihasilkan oleh modul untuk API jauh lebih sedikit daripada jumlah fungsionalitas yang didukung secara internal.

- Permisi, mengapa?

- Ada fungsi yang tidak tersedia untuk antarmuka publik.

"Dia seharusnya tidak ada di sana, hapus saja kode ini."

- Hapus saja?

- Ya, saya kadang-kadang melakukan ini di Lua. Ada semacam cakupan kode, saya tidak bisa sampai di sini, di sana atau di sana, saya memutuskan bahwa itu tidak mungkin dan hanya menghapus kode. Jarang, tetapi itu terjadi. Jika beberapa situasi tidak memungkinkan, cukup tulis di komentar mengapa ini tidak mungkin. Jika Anda tidak dapat masuk ke fungsi dari API publik, itu tidak seharusnya. Penting untuk menulis API publik dengan data input yang salah, ini penting untuk pengujian.

- Menghapus kode itu baik, itu mengurangi kompleksitas. Kompleksitas yang lebih rendah - stabilitas yang lebih tinggi dan kemudahan perawatan. Jangan menyulitkan.

- Ya, dalam pemrograman ekstrim ada aturan seperti itu. Jika sesuatu tidak dapat diuji, itu tidak ada.

- Bahasa apa yang Anda terinspirasi untuk membuat Lua? Paradigma apa, atau fitur fungsional, atau bagian bahasa mana yang Anda sukai?

- Saya merancang Lua untuk tujuan yang sangat sempit, itu bukan proyek akademik. Jadi, ketika Anda bertanya kepada saya tentang menciptakan kembali bahasa, saya menjawab bahwa ada keseluruhan cerita di baliknya. Saya tidak mulai mengembangkan Lua dengan "Saya akan membuat bahasa yang saya sukai, atau yang ingin saya gunakan, atau yang dibutuhkan semua orang." Saya punya masalah: di sini saya perlu bahasa konfigurasi untuk ahli geologi dan insinyur, harus kecil dan dengan antarmuka yang sederhana sehingga mereka dapat menggunakannya. Karena itu, API selalu menjadi bagian integral dari bahasa. Itulah tugasnya. Sebagai inspirasi, pada waktu itu saya akrab dengan sekitar sepuluh bahasa yang berbeda.

"Aku ingin tahu bahasa apa yang ingin kamu sertakan dalam Lua."

- Saya meminjam ide dari banyak bahasa, semua yang cocok untuk menyelesaikan masalah saya. Sintaks bahasa Modula memiliki pengaruh terbesar, meskipun sulit dikatakan, karena ada begitu banyak bahasa. Sesuatu mengambil dari AWK. Tentu saja, dari Skema dan Lisp ... Saya tidak acuh pada Lisp sejak saya mulai pemrograman.

- Dan masih belum ada makro di Lua!

- Ya, sintaksnya sangat berbeda. Mungkin bahasa pertama adalah Fortran ... tidak, bahasa pertama saya adalah assembler, dan kemudian Fortran. Saya belajar, tetapi tidak pernah menggunakan CLU. Diprogram banyak di Smalltalk dan SNOBOL. Juga dipelajari, tetapi tidak menggunakan Ikon, juga bahasa yang sangat menarik. Saya meminjam banyak dari Pascal dan C. Ketika saya membuat Lua, C ++ sudah terlalu rumit bagi saya, ini sebelum template dan hal-hal lain. Saya mulai bekerja pada tahun 1991 dan merilis Lua pada tahun 1993.

- USSR runtuh dan Anda mulai membuat Lua :) Anda tidak suka titik koma dan objek ketika Anda mulai Lua? Sepertinya saya bahwa sintaksnya akan mirip dengan C, karena Lua terintegrasi ke dalamnya. Namun ...

- Saya percaya bahwa sintaks harus berbeda, maka Anda tidak akan bingung, karena ini adalah dua bahasa yang berbeda.

Ini benar-benar lucu, dan terhubung dengan jawaban tentang array yang dimulai dengan satu, yang Anda tidak izinkan saya ungkapkan [di konferensi]. Jawaban saya terlalu panjang.

Ketika Lua dibebaskan, dunia berbeda. Tidak semua bahasa mirip dengan C. Masih ada Java dan JavaScript, Python masih bayi dan tidak melampaui versi 1.0. Jadi tidak semua bahasa mirip dengan C, sintaksinya adalah salah satu dari banyak.

Hal yang sama dengan array. Lucu bahwa sebagian besar dari ini tidak sadar. Array dimulai dengan 0 dan 1 memiliki kelebihannya sendiri.

Berkat C, sebagian besar bahasa populer saat ini menggunakan array yang dimulai dengan 0. Pembuatnya terinspirasi oleh C. Dan lucu bahwa tidak ada pengindeksan dalam C. , , . , β€” , (offset). , , , , .

, , . Java, JavaScript β€” . 0, . , Β« Β».

β€” , , . -, , , - , , . , Lua ? ?

β€” ?

β€” .

β€” . , , . . ? , , . . .

β€” Lua C.

β€” , , . , , … , , - . : , … .

, . , ? , - … ?

β€” .

β€” . ? C , , … ?

β€” 16 ?

β€” , .

β€” , , .

β€” , . , , … , , . β€” , . , , . , … : ?

β€” C++ .

β€” , C++ .

β€” ? ptrdiff_t ?

β€” ptrdiff_t β€” (signed type). , , . ?

, diff , . . , ? Tidak mungkin. , , . 2 , .

, . , . diff , .

, ++.

β€” Lua ?

β€” , C++, - , . , - ++, … .

β€” , ?

β€” . , . , , . , .

β€” JVM?

β€” , JVM. , … β€” , . JVM , .NET, . JVM , Lua. , . JVM, . JVM . Java-, 10 . , JVM , .

β€” JVM, , Mobile JVM?

β€” , JVM. - Java, Java.

β€” , Go Oberon? Lua, ?

β€” Oberon… … Go , runtime- Lua. Oberon , . , , . , , const Pascal Oberon. , . .
, 1994- Oberon Self. Self? JIT- . Self , , . - , β€” ! β€” , - . , …

Oberon, , 10 Self, . Oberon , , .

, .

β€” Haskell?

β€” Haskell, , Lua.

β€” Python, R Julia Lua?

β€” , .

R . , .

Python , . , . , .

Python , , . , , - . API… , Python, . , , Β« Β».

, -: , , , -. . , API , - . , . , , …

- , (pattern matching). , , , . , , .

: Perl. Lua, . , Python . , , . - .

β€” ?

β€” Python. Perl : $1, $2, $3. Perl, …

β€” Python, , ( Tarantool).

β€” , , , API, . Python , .

Julia, LuaJIT, , . , , . , . , , , . , , . : , - . , , - , .

Julia, : , , . , - . , double, []… . .

() Β«, , , , , . , Β». , , .

. R, Python.

β€” Erlang?

β€” . , . , , , - . Erlang , , . , .

, . , . ? , . .

β€” , Erlang , Python . Lua?

β€” , . Lua , , Lua , .

β€” ?

β€” Forth, .

β€” Lua?

β€” , . , . - , . Lua, Lua, .

Java. Java, ? Tidak. (reflection)? Tidak. ? Java, , Java. , , Java, .

, Lua, … , , FFI.

β€” Lua?

β€” , .

β€” Lua ? ?

β€” , . , Haskell. , , … Lua, , , , , .

β€” , Lua.

β€” , , . . , .

β€” , . Lua ?

β€” , , …

β€” Β« Β»? , ?

β€” , . , , , . , .

β€” Lua?

β€” . , , LaTex DocBook. , … LaTex, . @, . Gsub , , - - . , , , .

β€” LaTeX?

β€” LaTeX? -, , . , , LaTex. , inline-. /, . β€” . , , , . , . , .

β€” LaTeX?

β€” , . , , . , 3+1, . , , . , . , , . , 1 Β«andΒ», . . , .

β€” ?

β€” , git . 2html . HTML… , . , , . , , . , TeX. TeX- TeX.

β€” ?

β€” , . , TeX. , . DocBook, . , .

β€” 2html DocBook?

β€” , DocBook.

β€” , , !

β€” .



- , Lua Mailing List .

Source: https://habr.com/ru/post/id459464/


All Articles