Berry is a ultra-lightweight dynamically typed embedded scripting language
berry-lang.github.io
berry-lang.github.io
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.
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...
Though I guess part of the pitch for micropython is being able to iterate without a flash step every time. Possibly addressed by having your dev boards fitted with a version of the MCU with enough RAM to run it all that way.
So a convenient workflow is to deploy at runtime (ie not in flash) until you stabilise your code base or approach production; at which point you can freeze your code into your firmware.
For an even more convenient model, there is the proposal to support 'mapfs' so that some flash will be allocated to store code. You can then compile your Python to bytecode (with `mpy_cross`) and upload it to - and run from - this area at runtime.
Although this feature has been demonstrated as a proof-of-concept, there are some subtleties to sort out before it hits mainline. If you're interested in the feature, please read or comment on the PR:
As far as I can tell, the combination of all three of the above is the equivalent to tasmota + tasmotizer + berry?
I guess what I am asking for is how does developing on the ESP32 when using toitlang + toit SDK compare to issuing commands against Tasmota using berry?
What's the performance & memory usage compared to Lua?
How sandboxable is it? Can you run untrusted code through it?
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.
You can get lucky and sometimes avoid corruption, but eventually you're going to hit something important like leaving a libc heap allocator mutex locked when you kill a thread in the middle of an allocation.
This doesn't limit compute power of the thread.
It's an all or nothing approach; either the thread runs or is killed, which doesn't work (as you point out) for all circumstances where you want to limit the amount of compute pwr a thread can use.
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.
Honestly, off by one errors due to indexing was a lot harder to shake than getting used to meta tables.
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.
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\n6There'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.
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...
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...
Erm... Berry good :)
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.
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.
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.
This wiki is the Bible for ECS/ECBS systems: http://entity-systems.wikidot.com/
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
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 m×n. 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/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.
A language with good constructs for convenient call-signature reuse and redirection at the function level could probably skip implementation inheritance.
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.
1. It appears straight forward to add native functionality to berry.
2. Berry has the ability to compile code to ROM.
Maybe xs has that functionality too, but I don't see it anywhere in the top levels of it's docs. One thing I see missing from the berry docs is the debugging process. That could be a rather significant drawback of it isn't easy.
(eg syntax, compilation, etc)
Tiny JavaScript-like interpreter. It's pretty small. You might be able to glean insight.
Presumably the source for this project would be insightful as well. It appears like there is more code for berry script compared to ucode though.
The type system (especially for Rust and Haskell) forces you to always handle the error, or you have a compilation error. With some syntactic sugar (? in Rust, do notation in Haskell), you can be as concise as exception-based languages.
That's actually a good fit for coroutines! Cooperative multi-tasking can be very useful in single-threaded environments; it's basically syntactic sugar for a state machine. Lua has had coroutines since 2003, so I'd be curious why Berry chose to omit them.
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.
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.
That's what we see in software development: a runaway process of elaboration and ever-increasing complexity and levels of abstraction.
Sort of like if the Peter Principle and Parkinson's Law had a child.
https://en.m.wikipedia.org/wiki/Peter_principle
https://en.m.wikipedia.org/wiki/Parkinson%27s_law
Or just Zawinskis Law:
https://en.m.wikipedia.org/wiki/Jamie_Zawinski#Zawinski's_La...
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.
Try and find an AngelScript example. It's stupidly hard. Compare it to these web sites:
https://koka-lang.github.io/koka/doc/index.html
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.
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
FYI the real power of / for comments is /token to comment out one token. So useful to add a bit of doc sugar when calling something
call(x\sugar)
call(x/*sugar*/)
Also Thing \(inline comments) other--