Surely better to design the language with static types than to have to awkwardly tack them on later if it gets popular?
Documentation looks excellent though! Especially the language comparison.
Surely better to design the language with static types than to have to awkwardly tack them on later if it gets popular?
Documentation looks excellent though! Especially the language comparison.
Type annotations for locals, fields, and globals are written with a trailing `/Type`. Return types are written with `-> ReturnType`.
See https://github.com/toitware/toit-lsm303dlhc/blob/main/src/ac... for a file I recently edited.
When a type annotation is written, the compiler enforces it. It uses it for static optimizations, and dynamically checks that the type is correct.
When a type can be null, it has to be suffixed by `?`.
How thorough is this? Beartype is also on the front page right now, and its README contains an example of dynamic type checking in Python that takes over an hour to run [0].
Is Toit able to avoid being that slow?
[0] https://github.com/beartype/beartype#why-should-i-use-bearty...
Since these checks also allow some optimizations, the cost of the dynamic checks is maybe 10-15%. And that's before doing a global type-inference, which should remove many of the checks.
Many small decisions help keeping the system fast. The memory layout, the bytecodes, the FFI interface, ...
Separating the compilation process from the running process obviously also helps. It gives us the option to do slower optimizations before-hand, and not pay for them at runtime. (Independent of the fact that the ESP32 wouldn't be able to do big optimizations anyway).
This is actually an area we haven't really spent too much time on yet: optimizations. The current compiler doesn't even do inlining yet. The speed of Toit was never really a problem, and we preferred to spend time elsewhere. Eventually, we will definitely do more there again.