4 puan yazan GN⁺ 2023-10-09 | 1 yorum | WhatsApp'ta paylaş
  • Berry, düşük performanslı gömülü cihazlar için dinamik tipli bir betikleme dilidir; ARM Cortex M4 temelinde yorumlayıcı çekirdeği 40KiB’den küçüktür ve 4KiB’den küçük heap ile de çalışabilir
  • Çalışma zamanı, tek geçişli derleyici ve register tabanlı VM’den oluşur; tüm kod ANSI C99 ile yazıldığı için mevcut gömülü koda eklenmesi kolaydır
  • Performans için int, real, boolean, string sınıf nesnesi olarak oluşturulmaz; yalnızca list, map, range sınıf nesnesi olarak ele alınır
  • Dil özellikleri, imperatif, nesne yönelimli ve fonksiyonel programlamayı birlikte destekler; GC, FFI, exception handling, bytecode dosyaları ve genişletme modüllerini içerir
  • Derleme zamanı nesne oluşturma ve flash’a sabitleme özellikleri, kod, sınıf ve modüllerin RAM kullanımını azaltabildiğinden bellek kısıtı yüksek ortamlar için uygundur

Gömülü ortamları hedefleyen çalışma zamanı

  • Berry, mikroişlemci gibi düşük performanslı gömülü cihazlarda kullanılmak üzere tasarlanmış dinamik tipli bir betikleme dilidir
    • ARM Cortex M4 CPU, Thumb ISA, ARMCC compiler temelinde yorumlayıcı çekirdek kod boyutu 40KiB’den küçüktür
    • Aynı koşullarda 4KiB’den küçük heap ile çalışabilir
  • Yorumlayıcı ANSI C99 ile yazılmıştır; tek geçişli bytecode derleyici ve register tabanlı sanal makine içerir
  • Tip tasarımı, çalışma performansını önceliklendirmek için değer tipleri ile nesne tiplerini ayırır
    • Sınıf nesnesi olmayan tipler: int, real, boolean, string
    • Sınıf nesnesi olan tipler: list, map, range
  • Derleme zamanı nesne oluşturma, çoğu sabit nesneyi salt okunur kod veri segmentinde saklayarak yorumlayıcı başlatıldığında RAM kullanımını düşürür

Dil özellikleri ve yürütme modeli

  • Temel tipler nil, boolean, integer, real, string, class, instance, module, list, map, range içerir
  • İfadeler ve operatörler; atama, karşılaştırma, mantıksal, aritmetik, bit, alan, indis, string birleştirme, koşul operatörü, parantez ve bytes buffer desteği sunar
  • Kontrol yapıları if elif else end, while, for, break, continue sağlar
  • Fonksiyon özellikleri; yerel değişkenler ve blok kapsamı, return ifadeleri, iç içe fonksiyon tanımları, Upvalue tabanlı closure’lar, anonim fonksiyonlar ve lambda ifadelerine kadar uzanır
  • Sınıflar yalnızca public single inheritance destekler; metotlar ve operatör overloading, constructor metodu ve destructor metodu sunar
  • GC, Mark-Sweep GC kullanır
  • Exception handling, raise ifadesiyle herhangi bir exception değerinin fırlatılmasına izin verir ve birden fazla catch modunu destekler
  • Bytecode dosyası özelliğiyle fonksiyonlar bytecode dosyası olarak dışa aktarılıp tekrar yüklenerek çalıştırılabilir

Modüller, C entegrasyonu, örnekler

  • Modül yönetimi, yerleşik modüller ve genişletme modüllerini birlikte destekler
    • Genişletme modülleri; betik modülleri, bytecode dosyası modülleri ve *.so·*.dll gibi paylaşımlı kütüphane modüllerini içerir
    • Kod, sınıf ve modüller flash’a sabitlenerek RAM kullanımı azaltılabilir
    • İsteğe bağlı Regex desteği ve isteğe bağlı LVGL mapping sağlar
  • Native C arayüzü sayesinde mevcut koda bir kütüphane gibi gömülebilir; Tasmota gibi kodlar örnek olarak gösterilir
    • Berry’den C kodu çağırmak için isteğe bağlı easy mapping sağlar
  • Söz dizimi örnekleri; liste üzerinde dolaşma, map oluşturma ve anahtarlar üzerinde dolaşma, class bildirimi ve : operatörüyle single inheritance kullanımını gösterir
  • Ek örnek kaynaklar GitHub üzerinde görülebilir

1 yorum

 
GN⁺ 2023-10-09
Hacker News yorumları
  • 40 KB runtime için şaşırtıcı derecede zengin özellikli: çöp toplama özelliği olan bir VM üzerinde Python/Ruby benzeri bir dil çalışıyor; prosedürel, nesne yönelimli ve fonksiyonel stilleri destekliyor.
    Üstünkörü bakınca bile yazması oldukça rahat görünüyor. Özellikle sabit nesneleri önceden oluşturup büyük ölçüde ROM’a koyması, RAM’i ise yalnızca gerçekten değiştirilebilir veriler için kullanması dikkat çekiyor. Bildiğim kadarıyla MicroPython veya Lua’da olmayan bir yaklaşım; ROM/flash bol ama RAM’i sınırlı MCU’larda büyük fark yaratır.

    • MicroPython da modülleri freeze ederek flash’ta saklayabiliyor; bu durumda flash’a yalnızca önceden derlenmiş bayt kodu giriyor.
      Modülde string veya bytes() gibi değişmez nesneler biçiminde saklanan veri varsa, önce RAM’e kopyalanmadan doğrudan flash’tan okunuyor. Ancak freeze işlemini yapmak için kodu bir kez masaüstü bilgisayarda çalıştırmak gerekiyor.
      https://docs.micropython.org/en/latest/reference/constrained...
    • Açıklamayı okuyup siteye tekrar baktım; ana sayfadan çok daha kapsamlı ve çekici geldi.
    • @snops’un açıkladığı gibi MicroPython, frozen code biçiminde kodu flash’tan çalıştırabiliyor. Bunun sonucu olarak firmware ikili dosyasına derlenip eklenmesi gerektiğinden MicroPython’un olağan hızlı geliştirme döngüsü yavaşlıyor.
      Bu yüzden rahat akış, kod tabanı kararlı hale gelene veya ürünleştirme aşamasına yaklaşana kadar runtime’da dağıtmak, o noktada kodu firmware’e freeze etmek. Daha kullanışlı bir model olarak mapfs desteği önerisi var; flash’ın bir kısmını kod depolama için ayırıp Python’u bayt koduna derleyerek (mpy_cross) bu alana yüklemeyi ve runtime’da çalıştırmayı sağlıyor. Kavram kanıtı şimdiden çıktı, ancak mainline’a girmeden önce temizlenmesi gereken ayrıntılar var.
      https://github.com/micropython/micropython/pull/8381
    • Oldukça ilginç görünüyor ve birçok açıdan Lua’ya benziyor gibi, ama göze çarpan farklar da var. Bu arada eLua’da da bazı verileri şeffaf biçimde ROM’da tutmaya yönelik çalışmalar vardı.
      https://eluaproject.net/doc/v0.9/en_arch_ltr.html adresindeki rotables’a bakılabilir.
  • Berry, Tasmota içinde kullanılıyor: https://tasmota.github.io/docs/Berry/

    • Tasmota ilginç görünüyor. Kullandıysanız veya toit/jaguar ile karşılaştırdıysanız düşüncelerinizi merak ederim.
  • Gerçekten iyi görünüyor. Kişisel olarak şimdiye kadar gördüğüm belgeler arasında en üst düzeye yakın olduğunu düşünüyorum.
    Deneyimli bir geliştiricinin dili hızlıca kavramasını sağlayan “short manual” özellikle iyi. Tasmota’yı daha önce bilmiyordum, ama bir projede denemek için bahane arayacak gibiyim.

  • En çok merak ettiğim şey, Lua’ya kıyasla performansı ve bellek kullanımı nasıl, ayrıca sandboxing’in ne kadar mümkün olduğu.
    Güvenilmeyen kodu çalıştırmanın mümkün olup olmadığını da merak ediyorum.

    • Lua ile karşılaştırması en ilginç kısım. Çalıştığım şirketlerin çoğu Python’u kaba saba bir proxy ya da CLI aracı gibi kullanıyordu; ama Lua’yı metatable tabanlı nesne yönelimi kafa karıştırıcı olduğu için önermek zordu.
      Bu dil basit struct’lar ve temel constructor’larla geçerli bir alternatifse, Python script’lerini ve bağımlılıklarını söküp atmak için önerebilirim gibi görünüyor.
    • Varsayılan olarak kod dosya sistemini açıp yazabildiğinden, güvenilmeyen kod olduğu gibi çalıştırılamaz.
      Sandboxing uygulamanın sorumluluğunda olmalı. Sandboxing için WebAssembly iyi bir alternatif.
    • async anahtar sözcüğüyle yerel thread yönetimi eklenirse oyun motoru kullanımları için Lua’dan net biçimde ayrışacak gibi.
  • Buna neredeyse aynı ama daha az paradigma içeren ve statik tipli bir şey olsaydı, yapılandırma dili olarak kullanmak gerçekten iyi olurdu.
    Karmaşık yapılandırma gerektiren birçok projede yüzlerce satır YAML yazdırmak yerine Lua veya Starlark/Python kullandıran örnekler vardı; çok daha iyi hissettirmişti. Yine de her zaman otomatik tamamlama ve reflection eksikliği hissediliyor. Bu kullanım için tam uygun bir aday pek görünmüyor; küçük, gömülebilir script dillerinin neredeyse tamamı dinamik tipli.

    • Benzer bir yönü düşünüyordum, ama statik tipten çok güçlü biçimde doğrulanan yapılandırmaya daha yakın. Tüm yapılandırmayı yükledikten sonra sorunların listesini çıkarabilmek daha iyi olur; doğru yapılırsa iyi editör desteği de mümkün olmalı.
      Yine de https://dhall-lang.org/ pek çok yapılandırmanın statik tiplerle ele alınabileceğini ve bunun büyük faydası olduğunu gösteriyor. Birçok dile programatik olarak gömülebiliyor gibi görünüyor.
      https://docs.dhall-lang.org/howtos/How-to-integrate-Dhall.ht...
  • İyi görünüyor. Yine de şimdilik uLisp(http://www.ulisp.com) tarafına epey sıcak bakıyorum; ama böyle şeylerin çıkması sevindirici.

  • Dili anlamak için önce kod örneklerine bakanlardansanız, örnekler dizinine bakmak iyi olur: https://github.com/berry-lang/berry/tree/master/examples

  • Diğer diller için binding sağlansa çok iyi olurdu. Biz Rust’ta quickjs kullanıyoruz ve oldukça iyi çalışıyor.
    VM’e yalnızca istediğiniz şeyleri sunabildiğiniz için güvenilmeyen kodu da çalıştırabiliyorsunuz.

  • Gömülü kullanım için optimize edilmiş bir dil gibi görünüyor. Tasarımı ve belgeleri iyi; garip ya da beklenmedik davranışlar sergilemiyor gibi.
    Sözdizimi de hoş biçimde minimal ve zevkime uygun. Bir sonraki ESP32 projemde kesinlikle aklımda tutacağım.

    • Hemen deneyeceğim. Parlayan Cadılar Bayramı süsleri yapmak için bir ESP-32 geliştirme kitiyle uğraşıyordum; bunu deneme fikri beni heyecanlandırıyor.
      Bu niş alana gerçekten iyi uyuyor gibi görünüyor; özellikle de başka dillerde birebir karşılığı aklıma gelmeyen şeyler yapıyor olması hoşuma gitti.
  • Yerel stack trace’lerde stack frame’lerde script fonksiyon adlarını göstermenin standart bir yaklaşımı var mı merak ediyorum.
    Bir çökme olduğunda veya CPU profiler kullanırken, yerel stack trace ile script stack trace’i karışık biçimde göstermek mümkün mü bilmek isterim.