4 poin oleh GN⁺ 2023-10-09 | 1 komentar | Bagikan ke WhatsApp
  • Berry adalah bahasa skrip bertipe dinamis untuk perangkat embedded berperforma rendah, dengan inti interpreter berukuran kurang dari 40KiB pada ARM Cortex M4 dan dapat berjalan dengan heap kurang dari 4KiB
  • Runtime-nya terdiri dari kompiler satu lintasan dan VM berbasis register, dan seluruh kodenya ditulis dalam ANSI C99 sehingga mudah ditempelkan ke kode embedded yang sudah ada
  • Demi performa, int, real, boolean, dan string tidak dijadikan objek kelas, sedangkan hanya list, map, dan range yang diperlakukan sebagai objek kelas
  • Fitur bahasanya mendukung pemrograman imperatif, berorientasi objek, dan fungsional sekaligus, serta mencakup GC, FFI, penanganan pengecualian, file bytecode, dan modul ekstensi
  • Dengan konfigurasi objek saat kompilasi dan fitur penetapan ke flash, penggunaan RAM untuk kode, kelas, dan modul dapat dikurangi sehingga cocok untuk lingkungan dengan keterbatasan memori besar

Runtime yang menargetkan lingkungan embedded

  • Berry adalah bahasa skrip bertipe dinamis yang ditujukan untuk perangkat embedded berperforma rendah seperti mikroprosesor
    • Pada CPU ARM Cortex M4, Thumb ISA, dan compiler ARMCC, ukuran kode inti interpreter kurang dari 40KiB
    • Dalam kondisi yang sama, bahasa ini dapat berjalan dengan heap kurang dari 4KiB
  • Interpreter ditulis dalam ANSI C99 dan mencakup kompiler bytecode satu lintasan serta mesin virtual berbasis register
  • Desain tipenya membedakan tipe nilai dan tipe objek dengan prioritas pada performa eksekusi
    • Tipe yang bukan objek kelas: int, real, boolean, string
    • Tipe yang merupakan objek kelas: list, map, range
  • Konfigurasi objek saat kompilasi menyimpan sebagian besar objek konstan di segmen data kode baca-saja, sehingga menurunkan penggunaan RAM saat interpreter dijalankan

Fitur bahasa dan model eksekusi

  • Tipe dasarnya mencakup nil, boolean, integer, real, string, class, instance, module, list, map, range
  • Ekspresi dan operator mendukung penugasan, relasi, logika, aritmetika, bit, field, subskrip, penggabungan string, operator kondisional, tanda kurung, dan bytes buffer
  • Struktur kontrol menyediakan if elif else end, while, for, break, continue
  • Fitur fungsi mencakup variabel lokal dan block scope, pernyataan return, definisi fungsi bersarang, closure berbasis Upvalue, fungsi anonim, hingga ekspresi lambda
  • Kelas hanya mendukung pewarisan tunggal publik, serta menyediakan metode, operator overloading, metode konstruktor, dan metode destruktor
  • GC menggunakan Mark-Sweep GC
  • Penanganan pengecualian memungkinkan pelemparan nilai pengecualian arbitrer dengan pernyataan raise, dan mendukung beberapa mode catch
  • Fitur file bytecode memungkinkan fungsi diekspor ke file bytecode lalu dimuat kembali untuk dijalankan

Modul, integrasi C, contoh

  • Manajemen modul mendukung modul bawaan dan modul ekstensi sekaligus
    • Modul ekstensi mencakup modul skrip, modul file bytecode, dan modul pustaka bersama seperti *.so dan *.dll
    • Kode, kelas, dan modul dapat dipatok ke flash untuk mengurangi penggunaan RAM
    • Menyediakan dukungan Regex opsional dan LVGL mapping opsional
  • Dengan antarmuka Native C, Berry dapat di-embed ke kode yang sudah ada seperti pustaka, dan kode seperti Tasmota menjadi contohnya
    • Menyediakan easy mapping opsional untuk memanggil kode C dari Berry
  • Contoh sintaks menampilkan iterasi list, pembuatan map dan iterasi key, deklarasi class, serta pewarisan tunggal melalui operator :
  • Sumber contoh tambahan dapat dilihat di GitHub

1 komentar

 
GN⁺ 2023-10-09
Pendapat di Hacker News
  • Untuk runtime 40KB, fiturnya luar biasa kaya: bahasa mirip Python/Ruby berjalan di VM dengan garbage collection, dan mendukung gaya prosedural, berorientasi objek, serta fungsional
    Sekilas pun terlihat cukup nyaman untuk ditulis. Yang terutama menarik perhatian adalah kemampuan membuat objek konstan terlebih dahulu, menaruh sebagian besar di ROM, dan memakai RAM hanya untuk data yang benar-benar dapat berubah. Setahu saya MicroPython atau Lua tidak punya pendekatan seperti ini, dan pada MCU yang ROM/flash-nya lapang tetapi RAM-nya terbatas, perbedaannya besar

    • MicroPython juga bisa freeze modul dan menyimpannya di flash; dalam kasus ini, flash hanya berisi bytecode yang sudah dikompilasi sebelumnya
      Jika modul memiliki data tersimpan dalam bentuk objek immutable seperti string atau bytes(), data itu dibaca langsung dari flash tanpa disalin dulu ke RAM. Namun untuk melakukan freeze, kode harus dijalankan sekali di komputer desktop
      https://docs.micropython.org/en/latest/reference/constrained...
    • Setelah membaca penjelasannya dan kembali mengunjungi situsnya, rasanya jauh lebih komprehensif dan menarik dibanding halaman utamanya
    • Seperti dijelaskan @snops, MicroPython bisa menjalankan kode dari flash dalam bentuk frozen code. Akibatnya, kode harus dikompilasi ke dalam binary firmware, sehingga siklus pengembangan cepat yang biasa di MicroPython menjadi lebih lambat
      Jadi alur yang nyaman adalah mendistribusikan kode saat runtime sampai basis kode stabil atau mendekati tahap produk, lalu pada titik itu melakukan freeze kode ke firmware. Untuk model yang lebih nyaman, ada proposal dukungan mapfs, yang mengalokasikan sebagian flash untuk penyimpanan kode, lalu mengompilasi Python menjadi bytecode (mpy_cross), mengunggahnya ke area tersebut, dan membuatnya bisa dijalankan saat runtime. Proof of concept-nya sudah ada, tetapi masih ada detail yang perlu dirapikan sebelum masuk mainline
      https://github.com/micropython/micropython/pull/8381
    • Terlihat cukup menarik dan dalam banyak hal mirip Lua, tetapi ada juga perbedaan yang menonjol. Sebagai catatan, di eLua juga pernah ada pekerjaan untuk menaruh sebagian data secara transparan di ROM
      Lihat rotables di https://eluaproject.net/doc/v0.9/en_arch_ltr.html
  • Berry dipakai di Tasmota: https://tasmota.github.io/docs/Berry/

    • Tasmota terlihat menarik. Kalau pernah mencobanya atau membandingkannya dengan toit/jaguar, saya penasaran dengan pendapatmu
  • Benar-benar terlihat bagus. Secara pribadi, menurut saya dokumentasinya mendekati kelas terbaik di antara dokumentasi yang pernah saya lihat
    “short manual”-nya terutama bagus karena membantu developer berpengalaman cepat menangkap rasa bahasanya. Saya sebelumnya tidak tahu Tasmota, tetapi sepertinya akan mencari alasan untuk mencobanya di sebuah proyek

  • Yang paling membuat penasaran adalah bagaimana performa dan penggunaan memorinya dibanding Lua, serta sejauh mana sandboxing memungkinkan
    Saya juga penasaran apakah kode yang tidak tepercaya bisa dijalankan

    • Perbandingan dengan Lua paling menarik. Perusahaan-perusahaan tempat saya bekerja kebanyakan memakai Python seperti proxy kasar atau alat CLI, tetapi Lua sulit direkomendasikan karena OOP berbasis metatable-nya membingungkan
      Kalau bahasa ini bisa menjadi alternatif yang valid dengan struct sederhana dan constructor dasar, saya rasa bisa direkomendasikan untuk menyingkirkan skrip Python beserta dependensinya
    • Pada dasarnya kode bisa membuka dan menulis file system, jadi kode yang tidak tepercaya tidak bisa dijalankan begitu saja
      Sandboxing harus menjadi tanggung jawab aplikasi. Untuk sandboxing, WebAssembly adalah alternatif yang bagus
    • Jika ada manajemen thread native dengan keyword async, ini tampaknya akan membedakannya jelas dari Lua untuk penggunaan game engine
  • Kalau ada yang hampir seperti ini tetapi dengan paradigma lebih sedikit dan static typing, itu akan sangat bagus sebagai bahasa konfigurasi
    Di beberapa proyek yang membutuhkan konfigurasi kompleks, ada kasus ketika orang bisa memakai Lua atau Starlark/Python alih-alih menulis ratusan baris YAML, dan rasanya jauh lebih baik. Namun autocomplete dan reflection selalu terasa kurang. Kandidat yang pas untuk kebutuhan ini sulit ditemukan, dan hampir semua bahasa skrip kecil yang bisa di-embed bersifat dynamic typing

    • Saya juga memikirkan arah serupa, tetapi lebih dekat ke konfigurasi yang divalidasi kuat daripada static typing. Akan lebih baik jika seluruh konfigurasi bisa dimuat lalu menghasilkan daftar masalah, dan jika dibuat dengan benar, dukungan editor yang bagus juga semestinya memungkinkan
      Namun https://dhall-lang.org/ menunjukkan bahwa banyak konfigurasi bisa ditangani dengan static typing dan manfaatnya juga besar. Tampaknya bisa di-embed secara programatis ke berbagai bahasa
      https://docs.dhall-lang.org/howtos/How-to-integrate-Dhall.ht...
  • Terlihat bagus. Meski begitu, saat ini saya masih cukup condong ke uLisp(http://www.ulisp.com), tetapi senang melihat hal seperti ini muncul

  • Kalau Anda tipe yang melihat contoh kode lebih dulu untuk menangkap rasa sebuah bahasa, ada baiknya melihat direktori contoh: https://github.com/berry-lang/berry/tree/master/examples

  • Akan sangat bagus jika tersedia binding untuk bahasa lain. Kami memakai quickjs dari Rust, dan itu berjalan cukup baik
    Karena kita bisa menyediakan hanya hal-hal yang diinginkan ke VM, kode yang tidak tepercaya pun bisa dijalankan

  • Tampaknya seperti bahasa yang dioptimalkan untuk penggunaan embedded. Desain dan dokumentasinya bagus, dan sepertinya tidak melakukan hal-hal aneh atau tak terduga
    Sintaksnya juga terasa minimalis dengan menyenangkan dan sesuai selera saya. Sepertinya pasti akan saya pertimbangkan untuk proyek ESP32 berikutnya

    • Saya akan langsung mencobanya. Saya sedang mengutak-atik kit pengembangan ESP-32 untuk membuat dekorasi Halloween yang menyala-nyala, dan antusias untuk mencoba ini
      Ini tampak sangat cocok untuk ceruk tersebut, terutama karena ia melakukan hal-hal yang tidak langsung terpikir ada padanannya di bahasa lain
  • Saya penasaran apakah ada pendekatan standar untuk menampilkan nama fungsi skrip pada stack frame di native stack trace
    Saat terjadi crash atau saat memakai CPU profiler, saya ingin tahu apakah native stack trace dan script stack trace bisa ditampilkan secara bercampur