Berry एक अल्ट्रा-लाइटवेट, dynamically typed embedded scripting language है
(berry-lang.github.io)- Berry कम-परफॉर्मेंस embedded devices के लिए dynamically typed scripting language है; ARM Cortex M4 के आधार पर इसका interpreter core 40KiB से कम है और यह 4KiB से कम heap पर भी चल सकता है
- runtime में one-pass compiler और register-based VM शामिल हैं, और पूरा code ANSI C99 में लिखा गया है, इसलिए इसे मौजूदा embedded code में जोड़ना आसान है
- performance के लिए int, real, boolean, string को class object नहीं बनाया जाता, और केवल list, map, range को class object के रूप में扱 किया जाता है
- language features imperative, object-oriented और functional programming को साथ में support करते हैं, और इनमें GC, FFI, exception handling, bytecode files, extension modules शामिल हैं
- compile-time object construction और flash pinning feature से code, class, module की RAM usage घटाई जा सकती है, इसलिए यह कड़ी memory constraints वाले environments के लिए उपयुक्त है
Embedded environment को ध्यान में रखकर बनाया गया runtime
- Berry microprocessor जैसे कम-परफॉर्मेंस embedded devices में उपयोग के लिए dynamically typed scripting language है
- ARM Cortex M4 CPU, Thumb ISA, ARMCC compiler के आधार पर interpreter core code size 40KiB से कम है
- इन्हीं conditions में यह 4KiB से कम heap के साथ चल सकता है
- interpreter ANSI C99 में लिखा गया है, और इसमें one-pass bytecode compiler और register-based virtual machine शामिल हैं
- type design execution performance को प्राथमिकता देकर value types और object types में अंतर करता है
- class object नहीं होने वाले types: int, real, boolean, string
- class object types: list, map, range
- compile-time object construction अधिकांश constant objects को read-only code data segment में store करता है, जिससे interpreter शुरू होते समय RAM usage कम होती है
Language features और execution model
- basic types में nil, boolean, integer, real, string, class, instance, module, list, map, range शामिल हैं
- expressions और operators assignment, relational, logical, arithmetic, bit, field, subscript, string concatenation, conditional operator, parentheses, bytes buffer को support करते हैं
- control structures
if elif else end,while,for,break,continueप्रदान करते हैं - function features में local variables और block scope, return statement, nested function definitions, Upvalue-based closures, anonymous functions, lambda expressions तक शामिल हैं
- classes केवल public single inheritance support करती हैं, और methods व operator overload, constructor method, destructor method प्रदान करती हैं
- GC Mark-Sweep GC का उपयोग करता है
- exception handling में
raisestatement से कोई भी exception value throw की जा सकती है, और कई catch modes support होते हैं - bytecode file feature से functions को bytecode file में export करके फिर load कर execute किया जा सकता है
Modules, C integration, examples
- module management built-in modules और extension modules दोनों को support करता है
- extension modules में script modules, bytecode file modules, और
*.so·*.dllजैसी shared library modules शामिल हैं - code, classes, modules को flash में pin करके RAM usage घटाई जा सकती है
- optional Regex support और optional LVGL mapping प्रदान करता है
- extension modules में script modules, bytecode file modules, और
- Native C interface के जरिए इसे मौजूदा code में library की तरह embed किया जा सकता है, और Tasmota जैसा code इसका उदाहरण है
- Berry से C code call करने के लिए optional easy mapping प्रदान करता है
- syntax examples list traversal, map creation और key traversal,
classdeclaration,:operator के जरिए single inheritance दिखाते हैं - अतिरिक्त example source GitHub पर देखे जा सकते हैं
1 टिप्पणियां
Hacker News की राय
40KB runtime के हिसाब से इसकी capabilities हैरान करने वाली हद तक समृद्ध हैं: garbage collection वाला VM, जिसमें Python/Ruby जैसी language चलती है, और procedural, object-oriented, functional—तीनों styles को support करता है
ऊपर-ऊपर से देखने पर भी इसे लिखना काफ़ी सुविधाजनक लगता है। खास तौर पर constant objects को पहले से बनाकर ज़्यादातर ROM में रखने और RAM को सिर्फ़ वास्तव में बदलने योग्य data के लिए इस्तेमाल करने वाली सुविधा ध्यान खींचती है। मेरी जानकारी में MicroPython या Lua में यह तरीका नहीं है, और जिन MCU में ROM/flash पर्याप्त हो लेकिन RAM कम हो, वहाँ इसका फ़र्क बड़ा होता है
अगर module में strings या
bytes()जैसी immutable objects के रूप में stored data हो, तो उसे पहले RAM में कॉपी किए बिना सीधे flash से पढ़ा जाता है। हालाँकि freeze करने के लिए desktop computer पर code को एक बार चलाना पड़ता हैhttps://docs.micropython.org/en/latest/reference/constrained...
इसलिए सुविधाजनक workflow यह है कि codebase स्थिर होने या productization के क़रीब पहुँचने तक runtime पर deploy किया जाए, और उस बिंदु पर code को firmware में freeze कर दिया जाए। इससे भी सुविधाजनक model के रूप में
mapfssupport का प्रस्ताव है, जिसमें flash के एक हिस्से को code storage के लिए allocate करके Python को bytecode (mpy_cross) में compile किया जाए, उस हिस्से में upload किया जाए और runtime पर चलाया जाए। proof of concept पहले ही आ चुका है, लेकिन mainline में जाने से पहले कुछ details को अभी सुलझाना बाकी हैhttps://github.com/micropython/micropython/pull/8381
https://eluaproject.net/doc/v0.9/en_arch_ltr.html के rotables देखें
Berry का इस्तेमाल Tasmota में होता है: https://tasmota.github.io/docs/Berry/
यह सचमुच बहुत अच्छा लगता है। निजी तौर पर मुझे लगता है कि अब तक देखे गए docs में यह सबसे बेहतरीन documentation में से है
अनुभवी developers को language का feel जल्दी पकड़ाने वाला “short manual” खास तौर पर अच्छा है। Tasmota के बारे में पहले नहीं जानता था, लेकिन अब लगता है किसी project में इसे इस्तेमाल करने का बहाना ढूँढूँगा
मेरी सबसे बड़ी जिज्ञासा यह है कि Lua की तुलना में performance और memory usage कैसा है, और sandboxing कितनी संभव है
यह भी जानना चाहूँगा कि क्या इसमें untrusted code चलाया जा सकता है
अगर यह language simple structs और basic constructors के साथ एक वैध alternative है, तो Python scripts और उनकी dependencies हटाने के लिए इसे recommend किया जा सकता है
sandboxing की ज़िम्मेदारी application को लेनी होगी। sandboxing के लिए WebAssembly एक अच्छा alternative है
asynckeyword के साथ native thread management आ जाए, तो game engine use cases में यह Lua से साफ़ तौर पर अलग नज़र आएगाअगर ऐसा कुछ हो जो लगभग यही हो लेकिन paradigms कम हों और static typing हो, तो वह configuration language के रूप में बहुत अच्छा होगा
कई projects में, जहाँ complex configuration चाहिए होती थी, वहाँ लोगों को सैकड़ों lines का YAML लिखवाने के बजाय Lua या Starlark/Python इस्तेमाल करने देने के मामले देखे हैं, और वह काफ़ी बेहतर लगा। बस हमेशा autocomplete और reflection की कमी खलती है। इस use case के लिए बिल्कुल सही उम्मीदवार मिलना मुश्किल है, और छोटे embeddable scripting languages लगभग सभी dynamic typed होते हैं
हालाँकि https://dhall-lang.org/ दिखाता है कि बहुत-सी configurations को static typing के साथ संभाला जा सकता है, और उसके फ़ायदे भी बड़े हैं। यह कई languages में programmatically embed किया जा सकने वाला लगता है
https://docs.dhall-lang.org/howtos/How-to-integrate-Dhall.ht...
अच्छा लगता है। फिर भी अभी भी मेरा झुकाव काफ़ी हद तक uLisp(http://www.ulisp.com) की ओर है, लेकिन ऐसी चीज़ें सामने आना स्वागतयोग्य है
अगर आप language का feel लेने के लिए पहले code examples देखते हैं, तो examples directory देखना अच्छा रहेगा: https://github.com/berry-lang/berry/tree/master/examples
अगर यह दूसरी languages के लिए bindings दे, तो बहुत अच्छा होगा। हम Rust में quickjs इस्तेमाल कर रहे हैं और यह काफ़ी अच्छा काम करता है
VM को सिर्फ़ वही चीज़ें दी जा सकती हैं जो आप चाहें, इसलिए untrusted code भी चलाया जा सकता है
यह embedded use cases के लिए optimized language लगती है। design और documentation अच्छे हैं, और यह अजीब या अप्रत्याशित behavior करती नहीं दिखती
syntax भी सुखद रूप से minimal है और मेरी पसंद के अनुकूल है। अगला ESP32 project करते समय इसे ज़रूर ध्यान में रखूँगा
यह इस niche area के लिए वास्तव में बहुत उपयुक्त लगती है, खासकर इसलिए कि यह ऐसे काम कर रही है जिनके दूसरे languages में समान विकल्प तुरंत याद नहीं आते
मैं यह जानना चाहता हूँ कि native stack trace में stack frames पर script function names दिखाने का कोई मानक तरीका है या नहीं
crash होने पर या CPU profiler इस्तेमाल करते समय, क्या native stack trace और script stack trace को मिलाकर दिखाया जा सकता है?