[HN Gopher] Berry is a ultra-lightweight dynamically typed embed...
___________________________________________________________________
Berry is a ultra-lightweight dynamically typed embedded scripting
language
Author : dannyobrien
Score : 148 points
Date : 2023-10-07 12:26 UTC (10 hours ago)
(HTM) web link (berry-lang.github.io)
(TXT) w3m dump (berry-lang.github.io)
| Borg3 wrote:
| Hmm, written in C99 :) Thats super cool, considered its very new
| language. It can even run on my ancient toaster ;) I will keep an
| eye on that project. For now im happy with old Ruby.
| vitiral wrote:
| Seems cool, has a lot of the Vibe of Lua but with bit-twiddling
| types
| 0x6461188A wrote:
| If like me you like to look at examples of code to get a feel for
| the language, take a look at https://github.com/berry-
| lang/berry/tree/master/examples
| happens wrote:
| I'd love something exactly like this, but with less paradigms and
| statically typed, for use as a configuration language.
|
| I've used several projects requiring non-trivial configuration
| that, instead of requiring you to write hundreds of lines of
| yaml, simply let you write Lua or Starlark/python, which feels so
| much better to me. I'm always missing autocompletion and
| reflection though. There doesn't seem to be a good candidate for
| this, pretty much all small embeddable scripting languages are
| dynamically typed...
| mst wrote:
| I've been thinking along these lines but more 'strongly
| validated' than statically typed in the sense that you'd be
| better off being able to load the entire config and then
| produce a list of problems (and should be able to offer good
| editor support if done correctly).
|
| Though https://dhall-lang.org/ demonstrates that you can
| statically type quite a lot of configuration to great
| advantage, which appears to be programmatically embeddable in
| multiple languages per https://docs.dhall-lang.org/howtos/How-
| to-integrate-Dhall.ht...
| spacechild1 wrote:
| No coroutines :-(
| geenat wrote:
| https://hyperscript.org/
| ryanschaefer wrote:
| Very cool language, but it doesn't seem to have anything to do
| with the purpose of the language in the original post. Can this
| be used in embedded systems too?
| [deleted]
| rcarmo wrote:
| Looks nice. I'm still rather partial to uLisp
| (http://www.ulisp.com), but it's great to see this.
|
| Erm... Berry good :)
| RunningDroid wrote:
| Note that Berry is used by Tasmota:
| https://tasmota.github.io/docs/Berry/
| Pxtl wrote:
| It looks neat. But the goals sound very similar to venerable old
| Lua. I wonder what Berry has to set it apart from Lua, besides a
| few of Lua's idiosyncratic language decisions that come from its
| age.
| Sytten wrote:
| It would be very nice to provide bindings to other languages. We
| use quickjs from rust and it works pretty well, you can provide
| what you want to the VM so it can run untrusted code.
| traverseda wrote:
| I think the thing I'd miss most from python if I was using this
| is multiple-inheritance. Not even necessarily true multiple
| inheritance, but at least some kind of mixin.
| MarkMarine wrote:
| This language is targeted toward embedded machines with very
| low resources, are you using python with multiple inheritance
| on embedded?
| traverseda wrote:
| Sure, I use micropython on the rare occasion when I'm playing
| with microcontroller stuff. Mostly that's hobbyist stuff, but
| still it's a feature I'd miss.
| MarkMarine wrote:
| I've been using C for work on embedded for so long the idea
| of that is foreign to me, do you have any code in GitHub
| that is a good example? I'd like to read it.
| traverseda wrote:
| Not really, I was working on a little web interface for
| the some hardware called "eduponics" but my day job has
| been keeping me pretty busy.
|
| Obviously micropython has a lot of downsides as compared
| to writing stuff in C, much higher energy requirements
| for one thing, but there are some nice things as well. A
| REPL can be really nice when you're a hobbyist using
| hardware that you aren't familiar with, makes it really
| easy to try stuff out.
|
| Performance wise you _can_ do hard real time stuff in
| interrupts, as long as you don 't treat it like python at
| all, no creating objects, if you need to do real stuff
| try to pass it back to a soft real-time event loop
| (python asyncio does a reasonable approximation of a co-
| operative real-time multitasking OS). You can also inline
| assembly directly into your functions, or some other
| python-like DSLs that have much better performance.
|
| I don't think anyone is using it seriously in any
| commercial products yet honestly, but for quickly hacking
| together something with some SPI peripherals it's a
| pretty nice environment.
| rollcat wrote:
| Class-based inheritance is IMHO overrated. Most of the time
| you're interested in specific behavior (what is the area under
| this shape?), rather than some abstract taxonomy (is square a
| specialized rect or is rect a generalized square?).
|
| Composition and interfaces tend to produce less convoluted
| designs, and the most obnoxious problem with multiple
| inheritance ("diamonds") has to be explicitly addressed at the
| call site, rather than by meditating on the globally-determined
| method resolution order.
| runlaszlorun wrote:
| How do feel about prototypical inheritance and/or mixins as
| an alternative? I sorta feel like the component in the
| Entity/Component/System model that's been getting popular in
| gaming drifts into the same territory as well though I've
| never written games.
| gabereiser wrote:
| ECS is different. Systems coordinate entities, entities
| have components, some of them can be behaviors, some of
| them are not (vertex data). You would need to provide
| something that a component can inherit to derive that it's
| a behavior. Unity does this by calling it a MonoBehavior
| (not Mono as in singular, mono as in Mono runtime, the name
| stuck).
|
| Having an ECBS system: one could model all the permutations
| as described while keeping code concise, shareable, and
| non-repeatable. Unity is really an ECBS.
|
| Inheritance vs non is as old as OOP vs functional. Each has
| their place, each has their pros and cons. Having
| functional components and behavior traits attached to
| object inheritance based entity nodes is probably the best
| of all composition. Entities can get more and more complex
| with inheritance chains (further classifying what
| components can be attached), components can include
| behaviors, data, events/triggers, sub-components. Behaviors
| (triggering events or waiting for) is where your game logic
| would mostly reside.
| runlaszlorun wrote:
| Aha, thx for the insight. Very helpful. A couple
| questions:
|
| 1) If I wanted to learn more about ECS/ECBS, would Unity
| be a decent place to learn? I know sometimes the terms
| get coopted (for example, MVC as a term gets fairly
| abused at times in web development) so I wasn't sure if
| their implementation was a good one to learn from. And
| while I'm a fan of open source, Unity certainly does seem
| to be a leader in adoption and available assets, etc and
| not a bad place to start. I'm not really looking to
| develop a commercial game, but in addition to my poking
| around game engines to see if and what might be
| applicable ideas for a more classic business/personal
| type apps, I am interested in building something that
| broadly speaking sorta acts like an FPS or Arma type game
| but just for the sake of playing around and simulating
| different drones and drone swarms, etc in a 3D
| environment and playing with that. Pretty crude is fine,
| and AAA level graphics aren't really a huge concern. I
| think I honestly could prob get pretty far with just a
| non-graphical, non-gamelike OO design with
| JS/Python/whatever as a crude simulation. But I've heard
| that standing up something like an FPS in Unity is not
| too difficult. And I don't plan on pushing boundaries
| from a graphics or asset perspective.
|
| 2) > Systems coordinate entities Could you elaborate a
| bit? Systems are the one aspect that for me are hardest
| to get my head around coming from more standard
| web/business development. So physics engines would be a
| system right? But I'm not sure what are other examples.
|
| Thx for the info. And feel free to just refer to links if
| you know amy decent ones. I've been poking around ECS
| from a far for a couple years now but haven't really
| found articles that fill in the gaps for things like
| systems in ECS. Though I'm sure the fact that I have
| little context in game development sure doesn't help...
| lol.
| skitter wrote:
| > Systems are the one aspect that for me are hardest to
| get my head
|
| In an ECS architecture, the world is a database of
| entities, which are just identifiers, which have
| components associated with them. Systems is simply code
| that query this database and operate on the returned
| data. For example, if you want burning entities to set
| burnable entities on fire, you might write a system like
| this, using Bevy as an example: fn
| fire_spread(mut commands: Commands, burning:
| Query<&Collider, With<Burning>>, flammable:
| Query<(Entity, &Collider), With<Flammable>>) {
| for col_1 in &burning { for
| (flammable_entity, col_2) in &flammable {
| if col_1.touches(col_2) {
| commands.entity(flammable_entity).insert(Burning)
| } } } }
|
| The Commands here exists to defer archetype moves -
| otherwise what should the query do if you added Burning
| to an entity while the query was running? And of course
| in a real game, you might want to use a spatial query so
| time complexity isn't mxn. You could then run this system
| every tick: app.add_systems(Update,
| fire_spread)
|
| If you're familiar with C++, I can also recommend you
| check out https://www.flecs.dev/flecs/
| reactordev wrote:
| Unity is just the loudest, they certainly aren't the
| first and they definitely didn't invent the paradigm.
| ECS/ECBS is a pretty common construct.
|
| This wiki is the Bible for ECS/ECBS systems:
| http://entity-systems.wikidot.com/
| skitter wrote:
| That page seems to be more about the entity-component
| architecture (entities are composed of components, which
| define data and behavior for one aspect of the game) then
| about entity-component-systems architecture (entities are
| composed of components, which are pure data; systems can
| query this database). Traditional Unity, as that site
| points out, is EC; Unity DOTS is ECS. Not sure why the
| site would be the bible on the topic either as it only
| some surface-level information and links (and hasn't been
| kept up to date much).
| reactordev wrote:
| Much like other bibles ;)
|
| Wikipedia has some links to some more recent approaches.
| The biggest problem (and the reason why you don't see
| medium articles about it) is it's extremely difficult to
| sell in the enterprise. Even if it is the right
| architecture. Most developers can't grok it because of
| the MVC issue you already alluded to. My biggest advice -
| crack open VSCode and write one. You'll learn more by
| doing. Forget games. Try writing a database. This is what
| it is really. How do you handle 100,000 objects that
| interdepend on a web of code? Start basic, arithmetic.
| Components can add, subtract, etc. end goal is query the
| scene for Fibonacci sequence entities.
|
| Bonus points for updating (randomizing) values and
| picking different entities next tick.
|
| Deductions for use of Dictionary<K,V> or std::map
| rollcat wrote:
| I think any object/type system is good, as long as it
| doesn't encourage atrocities. I personally am guilty of
| implementing a fully-blown class-based inheritance system
| on top of Lua's metatables, and thank $DEITIES it didn't
| make it into any production project!
|
| Nowadays if I write Lua, I mostly see metatables as a
| memory usage optimization. If you have thousands of small
| objects with many methods, and all of them share the same
| set of methods, it makes a lot of sense to have a single
| vtable, to save some memory. Otherwise I wouldn't bother,
| it's not like Lua lets you control struct member padding to
| ensure they fit in a single cache line.
| Pxtl wrote:
| Imho it's just that method signatures are enough work to
| write and maintain that inheritance is needed for simple code
| reuse sometimes.
|
| A language with good constructs for convenient call-signature
| reuse and redirection at the function level could probably
| skip implementation inheritance.
| canadianfella wrote:
| [dead]
| CharlesW wrote:
| What are some reasons this is interesting when great embedded
| JavaScript/TypeScript runtimes (like Moddable's XS, which runs on
| microcontrollers with as little as 32 KB RAM) exist?
| jlnho wrote:
| 1) If you use Berry, you won't have to write JavaScript
| dvdkon wrote:
| This looks nice, especially the small runtime. One nitpick: Why
| not "if" expressions, or even "for" expressions? Ternary
| operators aren't something any new language should copy. It might
| even reduce parser code.
| nine_k wrote:
| A surprisingly rich feature set for a 40-KB runtime: a VM with GC
| that runs a Python/Ruby lookalike language, supporting
| procedural, OO, or functional styles. From the cursory look,
| seems pretty ergonomic to write.
|
| What stood out for me is the ability to pre-create constant
| objects and put them mostly into ROM, so that the RAM is only
| used for the actually mutable data. This is something you can't
| have with MicroPython or Lua, AFAICT, and this makes a lot of
| difference in MCUs where ROM / flash is plentiful, and RAM is
| scarce.
| paulclinger wrote:
| It does indeed look interesting and looks to be similar to Lua
| in several aspects (although, there are some noticeable
| differences too). FWIW, there has been work done in eLua to
| keep some of the data (transparently) in ROM:
| https://eluaproject.net/doc/v0.9/en_arch_ltr.html (see
| rotables).
| snops wrote:
| You can "freeze" micropython modules and have them saved in
| flash with Micropython, where flash only stores the precompiled
| bytecode.
|
| If your module contains stored data in the form of an immutable
| object, like a string or bytes(), it will be read straight out
| of flash without copying to RAM first.
|
| This needs you to run some code on a desktop computer to
| perform the freezing though.
|
| https://docs.micropython.org/en/latest/reference/constrained...
| tomcam wrote:
| I have to admit, I went back to the site after reading your
| description. I find it much more comprehensive and appealing
| than the home page.
| bwanab wrote:
| There's got to be an xkcd strip on the trajectory of computer
| languages:
|
| 1. Starts out fast, compact and lightweight. 2. Bugs and corner-
| cases get fixed. 3. Features demanded by users get added. 4. No
| longer fast, compact or lightweight.
| [deleted]
| xonix wrote:
| True. Probably, only AWK is an exception.
| vitiral wrote:
| And Lua
| IshKebab wrote:
| 1. Dynamically typed!
|
| 2. Ok that didn't work too well we've added static type hints.
|
| Does anyone know of any good embedded _statically typed_
| languages? It seems to be a very unexplored design space. The
| only real ones I know of are AngelScript (which
| catastrophically fails rule 0 of programming languages) and
| Gluon which is just a bit too weird and aggressively functional
| for me.
| vitiral wrote:
| I made a prototype that works in 3000 lines of C
|
| github.com/civboot/fngi
|
| It was super fun. I'm going to be going in a different
| direction (Lua implemented in Lua, with Lua-library
| assemblers and assembly type system), but it's certainly very
| possible
| zkldi wrote:
| What's rule 0?
| IshKebab wrote:
| Show examples on the main web page.
|
| Try and find an AngelScript example. It's stupidly hard.
| Compare it to these web sites:
|
| https://dlang.org/
|
| https://koka-lang.github.io/koka/doc/index.html
|
| https://vale.dev/
|
| http://mu-script.org/
|
| https://go.dev/
|
| https://www.hylo-lang.org/
|
| Sadly Rust fails this too but at least the Playground is
| only one click away. And Rust is mainstream anyway so it
| doesn't matter as much. I completely failed to find a
| single AngelScript example accessible from my phone's
| browser. Even its Wikipedia page doesn't have any.
| runlaszlorun wrote:
| I'd think this actually applies to nearly everything in
| software and is def a useful thing to keep an eye on.
|
| Underemployment for the last 3 years has given me a great
| opportunity to dive deeper into a lot of CS topics for things
| we use daily and read (or at least try to read) specs and code
| bases etc.
|
| I've come to firmly believe that languages or other open source
| projects that get popular, usually do so for the things that
| are in its early versions.
|
| For example, the HTTP 0.9 spec is like 1 page. UDP is like 3
| pages.
|
| I'd seen an article on HN recently (cant remember the name)
| that described this well. A language or what not starts simply
| and many jump on the bandwagon. Then starts adding incremental
| features, none of which are difficult to incrementally learn
| for existing users but the footprint of the product keeps
| expanding. C++, Javascript, Web APIs, graphics languages like
| OpenGL all are examples in my eye.
|
| The fact that our system (broadly speaking) incentivizes
| inventing something 'new' rather than fixing or simplifying an
| existing something certainly exacerbates this.
| carapace wrote:
| When I try to explain this to non-programmers I often use
| this metaphor: Imagine that you enjoy mountain climbing, but
| the act of climbing the mountain causes more mountain to rise
| above you.
|
| That's what we see in software development: a runaway process
| of elaboration and ever-increasing complexity and levels of
| abstraction.
| vitiral wrote:
| Lua has done pretty well to avoid this IMO. Notably they
| added coroutines with basically zero cost to the
| implementation (essentially just a pointer keeping track of
| function position on top of the already existing closures).
| The whole language is incredibly constrained yet powerful
| influxmoment wrote:
| Don't care for the way they do exceptional handling. Make errors
| part of the type system
| tomcam wrote:
| Can you ELI 5?
| MrBuddyCasino wrote:
| This looks like a language optimized for embedded use. It looks
| well designed and documented, and doesn't do anything stupid or
| unexpected. The syntax is pleasantly minimalist and tasteful.
| I'll definitely keep it in mind for my next ESP32 project.
| MarkMarine wrote:
| I will use it right now, I've been messing with my ESP-32 dev
| kits for some flashy Halloween decorations, and I'm excited to
| try this out. I agree, it looks great for the niche it's in,
| especially since it's doing things that I don't really think
| have an analog in any other language.
| i_am_a_squirrel wrote:
| Their marketing page loaded absurdly fast
| [deleted]
| nightowl_games wrote:
| Is there a standard approach to making native stack traces
| capable of marking stack frames with the name of the scripted
| function? Like when you get a crash or use a cpu profiler, is it
| possible to interleave native and script stack traces?
| ginko wrote:
| I guess the main questions I'd have would be:
|
| What's the performance & memory usage compared to Lua?
|
| How sandboxable is it? Can you run untrusted code through it?
| deadf00d wrote:
| An native thread management with an `async` keyword would
| really make it stand out from Lua for game engine uses.
| loa_in_ wrote:
| You can't run untrusted code because by default code can open
| and write to the filesystem. Sandboxing is up to the
| application. For sandboxing wasm is a good alternative.
| qznc wrote:
| Removing the API for file access would be easy. Limiting
| compute time is the harder thing.
| sweetjuly wrote:
| Limiting compute is trivial on any modern operating system.
| On Linux you can create a second supervisor thread, block
| on a mutex with a timeout, and then if you timed out before
| acquiring the mutex you can just tgkill the runner thread.
| On BSDs it's even easier since you can just hand the runner
| thread port to your supervisor thread and, after you
| timeout, you can just set RIP/PC to whatever location you
| want without having to screw around with signals.
| foobazgt wrote:
| I'd love to better understand what you're describing.
| Thread-level compute limits generally seem like they need
| to be managed in some sort of cooperative fashion,
| otherwise you end up with the possibility of dangling
| locks and other kinds of corruption on forcible
| termination.
|
| What signal are you sending to the running thread? What's
| the handler look like? How does that translate to
| terminating the thread? How do you do this forcibly
| (without cooperation from user code)? Schemes that I have
| seen look more like generating/ instrumenting
| polling/checkpoints into user code.
| norir wrote:
| Yes, it is very easy to remove the entire standard library
| from lua. Could compute time be handled with signal
| handlers in at least some cases? If not, one (admittedly
| somewhat hard) option is to write a small lua to lua
| compiler that injects yields into loops and recursive
| function calls.
| JTyQZSnP3cQGa8B wrote:
| The comparison with Lua is the most interesting to me. Most
| companies I worked for used Python as a shitty proxy or CLI
| tool, but I never could recommend Lua due to its confusing OO
| system (meta tables??)
|
| If this language is a valid alternative with a simple struct
| and a basic constructor, I may recommend it to remove all the
| Python scripts and their dependencies.
| zdragnar wrote:
| Having a lot of experience wrangling prototypes in JS was a
| nice benefit to my first forays into lua, though I wrote more
| functional code than OO anyway.
|
| Honestly, off by one errors due to indexing was a lot harder
| to shake than getting used to meta tables.
| runlaszlorun wrote:
| I'm assuming that the indexing off by one errors were due
| to Lua 1-based indexing? If so, was it due to you being
| used to 0-based indexing or something else?
|
| Just curious. I've been kicking around some attempts to
| make programming simpler (though hopefully no less
| powerful) for casual programmers. Lua's 1-based indexing
| gets a lot of critiques and, while I haven't written a ton
| of Lua, can't help but think that the critiques are due to
| us all being used to 0-based indexing. Which is a valid
| critique, especially for a scripting language, but one that
| applies less to novices.
| zdragnar wrote:
| Bingo. All of the languages I have used prior to (and
| since) use 0-indexed arrays.
|
| There's times where doing math with array indexes is
| simpler with 0 and with 1-indexed arrays. I don't think I
| really found 0 to be difficult to learn; there are a
| great many more challenging things.
|
| I wouldn't say "don't use a 1 indexed language" but I've
| also never found the arguments in favor of it to be
| compelling when using lua.
| [deleted]
| norir wrote:
| This is somewhat inefficient but zero indexed strings can
| easily be simulated in lua: local array =
| function(backing) local res = { len = function()
| return #backing end } setmetatable(res, {
| __index = function(_, k) return backing[k + 1] end,
| __newindex = function(_, k, v) backing[k + 1] = v end
| }) return res end local x = array {
| 1, 2, 3 } print(x[0]) -- 1 x[1] = 5
| x[x.len()] = 6 for i = 0, x.len() - 1 do
| print(x[i]) end -- 1\n5\n3\n6
| vitiral wrote:
| Metatable types are indeed kind of awkward, but it's pretty
| easy to build a type system on them in a library. Check out
| metaty where I built a type system, formatter and deep
| equality checking in like 700 LoC. I'm adding the ability to
| document types/functions as well, after which it will be
| "done"
| chadcmulligan wrote:
| Would you have a link? my googling skills have failed me
| vitiral wrote:
| https://github.com/civboot/civlua/tree/main/metaty
| runlaszlorun wrote:
| Man, this looks great. And, personally, I think this is some of
| the best documentation I've seen. Kudos to those who put it
| together! I love the "short manual" for experienced devs to
| quickly get a sense of the language. And I wasn't familiar with
| Tasmota before but def will be looking for an excuse to try it on
| a project.
___________________________________________________________________
(page generated 2023-10-07 23:00 UTC)