Toit – A Language Designed for Microcontrollers
toitlang.org
toitlang.org
Here is the Toit version of it: https://docs.google.com/document/d/1K-TYea7jbYfj2ecMUmr0T0zd...
And here the MicroPython: https://www.makerfabs.com/desfile/files/Get-Started-MicroPyt...
remembered_ = List width/2: initial_value
half_height := height / 2
...
min_value := remembered_.reduce: | a b | min a b
These lines (with seemingly context-sensitive meanings for the / and : characters) feel less obvious to me than the examples on the home page.The `/` are also the same (division), but it's true that we also use `/` to introduce types. For example `x/int`.
I think Toit is relatively easy to learn, but there are definitely a few things that need explaining in the beginning.
We then experimented with different tokens, and `/` felt best.
[Yes, colons are nice as block introducers but don’t play nice with colons for type ascription, which is where we got Python’s asinine f(x: int, y: bool) -> str; don’t know why Rust went with that instead of ML’s uniform f(x: int, y bool): str.]
Also types are optional in Toit, so they are a bit like comments (though they are now checked so they are less like comments now). So they look a little like // comments.
In particular, Python basically won the significant-indentation argument. Since all programs are formatted with correct indentation the punctuation is redundant clutter. So for a new language it just feels right to go with indentation instead of curlies.
We also wanted to be free to add type annotations and other enhancements, so it was never going to be compatible with Ruby anyway. And we didn't want to raise expectations of Ruby-compatibility that would immediately be dashed.
- the GC is a sliding compacting GC. As such there is no fragmentation for heap-allocated memory.
- the memory on these devices is tiny. The GC thus doesn't take long time.
- the ESP32 has really good peripherals, making timing sensitive operations very rare. In most cases there is a hardware module that does the job for you. The timing requirements then usually become significant less important.
I think you can easily do 90% of iot projects with this. Which means you have more time for the 10% of projects that are actually hard.
From an embedded system PoV, your sensor might be a 1-Wire protocol device with a super strict signal timing. How do you mix both timing requirements? How do you differentiate embedded projects requiring "precise timing" from those others requiring "every 60 seconds"?
Unless Toit provides drivers for all kind of buses, sensors and peripherals AND it orchestrates the GC with the strict timing requirements. Otherwise it's probably a good fit only if it just runs on a known controlled development board/architecture/platform.
For example the 1-wire protocol is implemented using the RMT (remote control) peripheral. The pixel strips driver uses the UART or i2s.
If really necessary, we could drop down to C, but the hardware is usually better (more precise and leaves us to do other things in the meantime).
Maybe the title should be "Toit is a modern high-level language designed specifically for ESP32".
How often are you bitbanging non standard protocols? And if so, which field are you in?
Not true at all.
> How often are you bitbanging non standard protocols?
Regarding protocols: bitbanging 1-Wire. Not all microcontrollers have this peripheral. You might be lucky if you can adapt some other peripheral like an UART (with due effort). Or you can use for example an external ds2482 and drive it through I2C.
WS2812B: sometimes you can emulate it with some other peripheral, sometimes you have to do it by bitbanging some GPIO.
I don't bitbang so often in general. But it's not just about available "hardware blocks": introducing undesidered delays in embedded applications is a terrible, terrible idea.
You can have a perfectly working sensor through I2C with DMA, super optimized with 0 CPU intervention. This sensor has an ODR of 1kHz. A GC stopping the microcontroller for 400ms makes you stand behind 400 samples you might be processing in real time (FIFO aside, and because you know you shouldn't be doing any processing in an interrupt handler, right?). You don't lose the buffered samples of course, but your processing is now delayed.
Or perhaps you are doing some 44100, 16-bit stereo audio processing (in or out). You have implemented the perfect I2S/DMA mechanism and all that, combined with perfect SDIO reading. What would happen in a real-time processing audio application if the GC introduces even 20ms delays now and then? Horrible latency and/or artifacts... And because your MCU has 32KB of RAM you don't have the luxury of big buffers, so you have to be quick reading, processing and outputting. Stopping the processing = stopping the output.
Or you might be dealing with some external peripheral that needs an answer within a time limit...
You can see it's not just about "hardware blocks".
Following what I said before, even if "60 seconds" is the application required timing, there are other things that might be happening in the background that require precise timing.
Is Toit a bad language? I don't know. But as I said before, it only makes senses if ran under a known platform like ESP32 where the language developers have tuned everything, and the programer doesn't pretend real-time applications. A generic language for every microcontroller? I am not so sure...
https://www.ptc.com/en/products/developer-tools/perc
https://www.aicas.com/wp/products-services/jamaicavm/
Also I should note that many embedded computers in 2022 are supercomputers when compared to the 1961 IBM mainframes running Lisp.
On microcontrollers, which often have very limited RAM, I'd prefer avoiding doing any heap allocation at all. If there is any need for any dynamic allocations, they are within fixed-size memory pools — each with only fixed-size objects or with objects on a stack.
Maybe they don't do[1] dynamic memory allocation in code segments that have real time constraints, or after initialization, etc. (Most embedded projects actually don't have hard real-time constraints, or have them in extremely localized places like bit banging loops...) This is sounds like a good idea and is orthogonal to whether the language's dynamic allocation support is via malloc/free or gc.
1) A compiler flag or similar optional static check that throws a warning if you have dynamic memory allocation. In scripting languages it can be easy to do accidentally
2) A way to block the gc from happening in a time critical section of code, like how you can disable interrupts
3) Some guarantee on the maximum time gc will take
Main restriction is, that we haven't finished the Windows implementation yet. Specifically networking and spawning processes only works on Linux/macOS so far. (The main reason we ported the LSP server to Go).
The `host` package (https://pkg.toit.io/package/github.com%2Ftoitlang%2Fpkg-host...) provides some functionality for running things on the desktop.
Whenever a new program is ready, it gets pushed (over WiFi) to the device. The whole process only updates the actual program (not the whole OS), thus making the development cycle really fast.
Compared to MicroPython, Toit is significantly faster. In my (obviously biased) opinion, it's also more robust.
You can't link C drivers directly without modifying the Toit code base, but there is a bridge to talk between C and Toit code. Generally, we prefer to reimplement the drivers in Toit. However, for some bigger ones it clearly makes sense to keep the C version.
As others have noted, Toit seems like a bad name. I suppose non-French speakers will tend to inadvertently mispronounce Toit.
Getting traction is hard. In my opinion, having a restrictive license and a bad name make it less likely Toit will gain traction. Finally, Toit's licensing reminds me of Mongoose OS https://github.com/cesanta/mongoose-os#mongoose-os---an-iot-....
Basically if the thought of your code ever ending up in something that someone might somehow make money from, like maybe in an iOS app, is somehow icky - then GPL is for you! If you just want to put it out there and code, not politics, is your thing - go MIT.
Source... https://www.reddit.com/r/roguelikedev/comments/4g738z/commen...