2 poin oleh GN⁺ 6 jam lalu | 2 komentar | Bagikan ke WhatsApp
  • Sintaks JavaScript mudah menjadi rumit karena tanda kurung bertingkat dan callback, dan bahkan UI kecil pun sering menarik banyak library sehingga terjadi pembengkakan
  • WebAssembly membuka jalan untuk menjalankan bahasa lain di browser, tetapi seperti pada Pyodide, biaya penghubung asinkron dengan event loop JavaScript cukup besar
  • Sumber daya browser dan memori WebAssembly terbatas, jadi yang dibutuhkan bukan menggantikan JavaScript melainkan pendekatan bernegosiasi dengannya
  • LispE memuat lebih dari 450 fungsi dalam satu biner WASM berukuran 3.3MB, serta menyediakan string, perhitungan, matriks, dan regular expression sekaligus
  • Dengan evaljs dan asyncjs, LispE memanfaatkan fungsi JavaScript dan DOM sambil mengurangi pembengkakan kode lewat satu biner yang bisa diaudit, alih-alih banyak library eksternal

Pembengkakan JavaScript dan keterbatasan browser

  • Sintaks JavaScript mudah menjadi rumit karena tanda kurung biasa, kurung kurawal, dan kurung siku saling bertumpuk dan urutan penutupannya harus tepat
    • Ada contoh forEach callback yang mengisi nilai ke beberapa objek dan memperbarui cache secara kondisional
newNames.forEach((name, i) => {
    allAgentContents[name] = contents[i];
    agentModes[name] = modes[i];
    if (compiled[i]) agentCompiledCache[name] = compiled[i];
    agentViewingCompiled[name] = viewing[i];
});
  • Untuk pemrosesan yang umumnya sudah tersedia di bahasa pemrograman dasar, di JavaScript kita sering harus mengunduh banyak library
    • C atau C++ juga memerlukan include untuk bekerja, tetapi pada library JavaScript sering kali tidak jelas siapa yang mengimplementasikan dan siapa yang merawatnya
    • Ada juga halaman yang terasa seperti memuat “setengah internet” hanya untuk menampilkan hello di jendela kecil
  • Internet bergantung pada JavaScript, dan meski disamarkan dengan TypeScript, ia tetap menjadi penjaga gerbang yang harus dilewati setiap kali halaman dibuka di browser
  • Pernah ada impian bahwa browser akan menjadi sistem operasi pamungkas yang membuat Windows atau Mac OS tidak lagi diperlukan, dan JavaScript dipilih sebagai bahasa untuk mewujudkan impian itu

Hubungan WebAssembly dan JavaScript

  • WebAssembly lebih dekat ke mesin virtual dengan bahasa mesin sendiri, sehingga membuka kemungkinan menulis kode dengan cara lain di dalam browser
  • Pyodide adalah pencapaian rekayasa yang mengesankan untuk menjalankan Python di browser, tetapi juga memperlihatkan biaya bekerja di dalam wilayah JavaScript
    • Dunia asinkron Python asyncio dan event loop JavaScript harus saling berbicara
    • Jembatan di antara keduanya rapuh, dan kita harus selalu ingat setiap await termasuk ke dunia yang mana
  • Sumber daya browser terbatas, sehingga dibutuhkan cara berpikir seperti di awal ilmu komputer, ketika setiap instruksi dan struktur diperiksa sampai ke tingkat bit
    • Dijadikan patokan bahwa pemrograman dimulai pada 1981 di komputer yang hanya menyisakan tepat 15772 bytes
    • Memori browser modern memang tidak seterbatas komputer pertama itu, tetapi WebAssembly tidak bisa memiliki memori secara bebas seperti program biasa dan harus lebih dulu mendapat izin dengan cara yang terbatas
  • Sikap kuncinya bukan melawan JavaScript, melainkan bernegosiasi dengannya

Alternatif yang ditawarkan LispE

  • LispE menyediakan lebih dari 450 fungsi dalam satu biner tunggal
    • Ukuran biner WASM adalah 3.3 MB
    • Fitur pemrosesan string, perhitungan, matriks, dan regular expression dikemas dalam satu tempat
    • Biner WASM tersedia di binaries/wasm
  • Meski merupakan interpreter kecil, ia dapat menangani string, Float64Array, integer, bilangan riil, dan array string sebagai nilai kembalian
  • Karena berbasis Lisp, LispE memiliki struktur AST yang tetap hidup
  • Jika sintaks Lisp tidak cocok, kita bisa memakai sintaks transpile untuk bahasa yang nyaris sulit dibedakan dari Python atau Basic
    • Kita bisa mengubah grammar untuk membuat bahasa dengan gaya yang diinginkan
    • Bahkan bisa dalam bahasa Yunani, dan sudah ada contoh bahasa Yunani
  • LispE bekerja sama dengan JavaScript dengan memanfaatkan fungsi JavaScript dan kemampuan DOM, bukan melawannya

Memanggil JavaScript: evaljs dan asyncjs

  • Untuk menjalankan kode JavaScript dari dalam LispE, kita bisa menggunakan evaljs dan asyncjs
    • evaljs menjalankan kode JavaScript dan mengembalikan nilainya
    • asyncjs menghubungkan fungsi JavaScript buatan pengguna yang didefinisikan di halaman dengan callback asinkron
(setq a (evaljs "10 + 20 + 30")) ; execute some JS code

; call_llm is a user-defined JS function in the page
(asyncjs `call_llm("Implement a piece of code in Python to sort strings");` 'mycallback)

(defun mycallback(theresult) ...)
  • asyncjs bekerja sebagai Promise yang akan kembali setelah tugas selesai

Mengurangi pembengkakan kode

  • Kutipan Wirth pada 1995 mengarah pada kesimpulan bahwa komputer yang lebih cepat dan model yang lebih besar tidak menyelesaikan masalah, dan kode harus dijaga tetap ramping
  • LispE menyediakan 450 fungsi yang diekspos ke browser dalam satu biner yang bisa diaudit
    • Jika tiap fungsi diimplementasikan terpisah, kita perlu memuat library seperti mathjs untuk komputasi numerik, lodash untuk koleksi, voca untuk manipulasi string, dan simple-statistics untuk distribusi statistik
    • Pendekatan ini bisa membesar menjadi ratusan MB kode dengan penulis, bug, dan jadwal pemeliharaan yang berbeda-beda
  • LispE menyediakan semua fungsi itu dalam satu kode yang dipelihara, dan karena open source seluruh kodenya dapat diaudit
  • Diyakini bahwa Garbage Collector tidak akan merusak performa kode pada saat terburuk
  • Ia berkomunikasi secara transparan dengan JavaScript lewat pemanggilan API sederhana, dan bisa mengembalikan struktur yang sudah ditentukan sebelumnya
// floats here is a Float64Array
const floats = callEvalLispEToFloats(0, `(normal_distribution 100)`);

2 komentar

 
crawler 5 jam lalu

Tulisannya agak terasa tiba-tiba, jadi saya sempat meragukan sumbernya, ternyata dari Naver 
Tapi ya, memang reaksinya kurang bagus... Jujur saja, JavaScript yang dibesar-besarkan sampai mengunggah WASM 3,3MB demi memakai Lisp itu terasa seperti over-engineering yang tidak mudah dipahami wkwk

Soal kenapa akunnya akun Naver, ada komentar dari pengembang proyek bernama Claudius; katanya dia bekerja di Naver Labs Europe dan ini diunggah setelah disetujui Naver sebagai proyek open source.
Sepertinya tidak terlalu berkaitan besar dengan Naver, mungkin cuma orang-orang yang benar-benar sangat mencintai Lisp...

 
GN⁺ 6 jam lalu
Opini di Lobste.rs
  • Rasanya aneh kalau bilang ingin mengurangi bloat JavaScript tapi malah menambahkan gumpalan WASM 3,3MB yang opak dan menyuruh aplikasi ditulis dengan Lisp
    Dengan JavaScript murni dan tanpa dependensi tambahan pun, kita masih bisa membuat banyak hal sebelum mendekati sepersepuluh ukuran itu

    • Semoga orang tidak langsung men-dismiss hanya dari satu bagian kecil dokumentasinya
      Saya juga tidak cocok dengan cara pemakaian ini, tetapi ini adalah proyek passion Lisp yang menarik dengan keanehan yang jarang terlihat akhir-akhir ini, dan saya suka karena seluruh dokumentasinya terasa jelas ditulis tangan oleh manusia dengan kalimat-kalimat yang khas
  • Hal-hal yang layak masuk ke standard library selalu terbuka untuk diusulkan
    Beberapa tambahan terbaru mencakup union/intersection untuk himpunan, sum, base64, dan lain-lain
    Namun saya hampir tidak pernah mendengar permintaan untuk fungsi kalkulus, dan untuk string yang terus diminta biasanya hanya .reverse atau .titleCase
    .reverse tidak punya banyak penggunaan yang benar-benar meyakinkan di luar soal-soal mainan, dan .titleCase memang memungkinkan, tetapi butuh data internasionalisasi sehingga pembahasannya masih berjalan
    Lagipula keduanya juga tidak ada di library ini

    • Banyak orang tampaknya tidak mengenal anggota tc39 secara langsung, atau tidak sadar bahwa mereka ada di sekitar kita
      Mereka merasa walaupun mengajukan proposal, realisasinya akan butuh 3 tahun sehingga tidak layak dicoba, dan berpikir folder utils/ memang kurang ideal tetapi bisa dibuat sekarang juga
    • Standard library ternyata bergerak lebih banyak daripada yang saya ikuti, jadi saya perlu sedikit merevisi tulisan saya
      Argumen saya lebih dekat ke model distribusi daripada soal JavaScript kekurangan fungsi
      Bahkan jika standard library sudah penuh, aplikasi rata-rata tetap mengirim dependensi npm transitif dalam ukuran megabyte
      LispE-as-WASM berukuran 3,3MB, punya sekitar 450 fungsi yang terdokumentasi, inti C++, serta source code publik di GitHub, sebagai eksperimen untuk melihat seperti apa runtime yang bisa diaudit
      Saya benar-benar sudah membangun harness agen di atasnya, dan menjalankan aturan LispE secara ad-hoc langsung di dalam browser
      JavaScript event loop-nya sangat saya sukai
  • Kalau seseorang bilang sintaks itu yang bikin bloat, saya jadi waspada
    Sintaks minimal justru bisa jauh lebih sulit dibaca dibanding sintaks yang memakai karakter berbeda untuk pembedaan visual
    Kalau melihat apa yang ditawarkan LispE sebagai alternatif, hasilnya seperti ini:

    (defun gol8(⍵) ((λ(⍺) (| (& (== ⍺ 4) r) (== ⍺ 3))) (⌿ '+ (⌿  '+ (° (λ (x ⍺) (⊖ ⍺ x)) '(1 0 -1) (↑ (λ (x) (⌽ ⍵ x)) '(1 0 -1)))))))  
    

    ... !?
    https://github.com/naver/lispe/wiki/5.3-A-la-APL

  • Titik masuk ke proyek ini agak aneh, dan halaman https://github.com/naver/lispe/wiki/1.-Introduction tampak lebih baik
    Ini adalah proyek Lisp native yang juga menargetkan WASM, dan ada unsur-unsur menarik yang mungkin disukai para penggemar bahasa pemrograman

  • Kesan pertama saya adalah ini terasa seperti contoh JavaScript yang cukup dipaksakan
    Sebagian besar kebencian terhadap JavaScript tampaknya berasal dari ketidakcocokan browser era awal, DOM API yang menyakitkan, dan jebakan sintaks, dan hal-hal itu praktis tidak berdampak pada keseharian saya sekarang
    JavaScript modern, terutama dengan TypeScript dan aturan lint yang masuk akal, sudah cukup baik sebagai bahasa
    Masih ada masalah seperti CJS vs ESM, risiko supply chain, dan perubahan ekosistem, tetapi sebagian besar itu berada di luar bahasa itu sendiri

  • Pengalaman yang sampai membuat orang menciptakan ekstensi editor hanya demi menyeimbangkan tanda kurung justru dianggap hebat?
    Kalau yang diinginkan adalah gaya pemrograman seperti ini, yaitu kepadatan sintaks rendah dan pendekatan fungsional, lebih baik membalik arahnya dan memilih bahasa concatenative

  • Saya penasaran bagaimana hasil kompilasi interpreter Lisp bisa sampai 3,3MB
    Apa ini yang disebut mengurangi bloat?

    • Kemungkinan besar karena ada standard library besar yang ikut disertakan
      Meski begitu, saya setuju bahwa mendistribusikan standard library besar berikut kode yang tidak dipakai jelas jauh dari semangat mengurangi bloat
  • Kejutan! Kengerian!
    Harus menutup tanda kurung dalam urutan yang benar, sungguh mengejutkan

    • Kalau Anda ingin bahasa yang tidak mengharuskan penutupan dalam urutan yang benar, ada J
      Bahkan para penggemar Lisp yang muak dengan kebawelan bahasa seperti JavaScript pun sering berbalik arah saat berhadapan dengan bahasa keluarga APL, lalu mulai berdebat bahwa kejelasan dan keterbacaan jauh lebih penting daripada sekadar sependek mungkin
      Penulis LispE tampaknya memang punya ketertarikan tertentu pada operasi dasar APL, tetapi tetap sulit dipahami mengapa setelah mengenal bahasa dengan notasi sepadat itu, ia masih memilih Conway's Life dalam bentuk s-expression yang lebih panjang, lebih renggang, dan bertingkat dalam dibanding versi APL, J, K, atau bahkan Q