I like discovering new programming languages or more specifically new approaches to programming. I'm looking for new landscapes these languages can help me to explore. And when I say new I mean something I was not aware of, not necessary something recent. This is why I'm both surprised and disappointed when the claim is to be modern without specific novelties.
Agreed. I'd say the link should be to https://docs.toit.io/, which at least attempts to answer the question "why does this language exist?" (the most important question).
[Co-author of 'Revolutionizing Embedded Software' -- the linked thesis with the ... not so understated title -- and co-founder of Toit here.]
Yeah, there certainly is overlap in some of the core ideas, but the scene has really changed with the development of general-purpose microcontrollers like the ESP32 that can run for years on standard batteries and still pack a punch (it's a dual core 240MHz CPU). Also, the global connectivity options like NB-IoT and LTE-M allow devices to connect directly to the internet, which enables us to make them fully serviceable through a cloud-hosted API.
Amazing to see our language linked on Hacker News. A lot of work has gone into, creating a language which is easy and great to use. If you look at our docs, you can see that we are running it on ESP32.
If anyone want to know more, about what we are trying to build, ask away!
What was the motivation for including OO capabilities for a language targeted at embedded systems? The docs seem to make quite a fuss about the fact that it can do OO. As someone who doesn't work professionally in this space I was curious how the domain of embedded stuff is a good fit for thinking in OO?
Not the person asked, but OOP is a great fit for embedded devices IMO. Even the most superficial aspect, a mandatory init function called at creation time and a free function at destruction time, is such a powerful and general method of resource managment and reasoning about lifetimes that C++ folks made it a freaking ideology. Any generic, cliché driver code written in C almost always has the obligatory xyz_init and the corresponding xyz_free/reset boilerplate that has to be remembered and called manually by the programmer. Why memorize patterns when we have compilers though?
Digging deeper, the hardware analogy is pervasive in OOP. Alan Kay called the internet the best and most successful OOP system, Brad Cox saw objects as "software ICs", message passing is explicitly and pervasively modeled after hardware protocols by both. Java was born from research that sought to make OOP the norm in embedded ("Java runs on 3 billion devices!"), and Ada was a reality 10 years before that.
How do you define systems in Hardware Description Languages? you seperate the system into interacting thingies called "modules" whose state is strictly private and communicate through well-defined protocols, sounds familiar?
its not a panacea off course, but modeling a black box machine whose behavior is defined by how it responds to messages - ideally how embedded devices should be designed - is the classic OOP sales pitch.
A large part of the motivation, is also making it easy to work with embedded devices. We try to take a lot of learnings from other languages, which our engineers have worked on, and mix in elements that makes it easy to create well architectured applications. In general we find that many OO principles provides a great foundation in the embedded space.
Thank you for taking the time to explain it so succinctly. This has to be one of the best comments I've read in a while. Now I can't wait to take Toit for a drive...
- Seems to be using gradual typing - type annotations are optional but, if used, are enforced (at run-time if necessary). The traditional problem with this approach has been poor performance - is that an issue here? Can you use `List<Int>` as a type annotation (which would presumably be O(n) to check at runtime) or only `List`?
- Appears to use a Python-like object model (e.g. fields are public by default). I can’t find detailed information about access control, inheritance etc.
- Significant indentation plus Ruby-style blocks. Would be interesting to see how well those work together in practice.
Yes, it's gradual typing. Currently we don't have generic collections, so it's just List, but certainly something that we are thinking about.
Dart is another language we have worked on. It has typed collections, but I think we'll do it slightly differently. But passing a List<int> to a function isn't O(n) in Dart, and I don't think I'm promising too much when I say that it won't be O(n) in Toit either :-)
Performance is pretty good, at least compared with other interpreted languages (Toit is currently interpreted). About an order of magnitude faster than Python on comparable hardware.
But really the inspiration is "Toit like a toiger".
Toit is really just a silly pronunciation of "tight". The idea of tightness is that it's concise and efficient to express something in Toit.
For example, blocks (a bit like lambdas) are introduced with just a colon, and the default name for a single argument is "it". So in Java you would have:
joins.forEach(join -> mIrc.join(mSession, join));
In Toit that might be:
joins.do: irc.join(session, it)
Note that unlike in Java you can manipulate local variables inside the code block, and you can also return early from the whole method using "return". So in some ways it combines the advantages of the old-fashioned for-loop with the neatness of lambdas.
We already have a compiler to bytecodes, so I guess you mean will we have challenges when writing a JIT or a compiler to native code? The answer is there will be lots of challenges, but this is exactly the sort of thing we love working on :-)
18 comments
[ 2.9 ms ] story [ 44.9 ms ] threadI like discovering new programming languages or more specifically new approaches to programming. I'm looking for new landscapes these languages can help me to explore. And when I say new I mean something I was not aware of, not necessary something recent. This is why I'm both surprised and disappointed when the claim is to be modern without specific novelties.
Specifically, Toit is a “software platform for microcontrollers [...] by the team of developers that previously built V8 for Chrome at Google.”
https://toit.io/about
http://esug.org/data/ESUG2003/lars@2bbak@2besug.pdf https://verdich.dk/kasper/thesis.html
Yeah, there certainly is overlap in some of the core ideas, but the scene has really changed with the development of general-purpose microcontrollers like the ESP32 that can run for years on standard batteries and still pack a punch (it's a dual core 240MHz CPU). Also, the global connectivity options like NB-IoT and LTE-M allow devices to connect directly to the internet, which enables us to make them fully serviceable through a cloud-hosted API.
If anyone want to know more, about what we are trying to build, ask away!
Digging deeper, the hardware analogy is pervasive in OOP. Alan Kay called the internet the best and most successful OOP system, Brad Cox saw objects as "software ICs", message passing is explicitly and pervasively modeled after hardware protocols by both. Java was born from research that sought to make OOP the norm in embedded ("Java runs on 3 billion devices!"), and Ada was a reality 10 years before that.
How do you define systems in Hardware Description Languages? you seperate the system into interacting thingies called "modules" whose state is strictly private and communicate through well-defined protocols, sounds familiar?
its not a panacea off course, but modeling a black box machine whose behavior is defined by how it responds to messages - ideally how embedded devices should be designed - is the classic OOP sales pitch.
A large part of the motivation, is also making it easy to work with embedded devices. We try to take a lot of learnings from other languages, which our engineers have worked on, and mix in elements that makes it easy to create well architectured applications. In general we find that many OO principles provides a great foundation in the embedded space.
- Seems to be using gradual typing - type annotations are optional but, if used, are enforced (at run-time if necessary). The traditional problem with this approach has been poor performance - is that an issue here? Can you use `List<Int>` as a type annotation (which would presumably be O(n) to check at runtime) or only `List`?
- Appears to use a Python-like object model (e.g. fields are public by default). I can’t find detailed information about access control, inheritance etc.
- Significant indentation plus Ruby-style blocks. Would be interesting to see how well those work together in practice.
Yes, it's gradual typing. Currently we don't have generic collections, so it's just List, but certainly something that we are thinking about.
Dart is another language we have worked on. It has typed collections, but I think we'll do it slightly differently. But passing a List<int> to a function isn't O(n) in Dart, and I don't think I'm promising too much when I say that it won't be O(n) in Toit either :-)
Performance is pretty good, at least compared with other interpreted languages (Toit is currently interpreted). About an order of magnitude faster than Python on comparable hardware.
To the creators of the language:
How is it pronounced? And a bit about the etymology please.
Do you foresee any challenges/inefficiencies when building a compiler for Toit?
But really the inspiration is "Toit like a toiger".
Toit is really just a silly pronunciation of "tight". The idea of tightness is that it's concise and efficient to express something in Toit.
For example, blocks (a bit like lambdas) are introduced with just a colon, and the default name for a single argument is "it". So in Java you would have:
joins.forEach(join -> mIrc.join(mSession, join));
In Toit that might be:
joins.do: irc.join(session, it)
Note that unlike in Java you can manipulate local variables inside the code block, and you can also return early from the whole method using "return". So in some ways it combines the advantages of the old-fashioned for-loop with the neatness of lambdas.
We already have a compiler to bytecodes, so I guess you mean will we have challenges when writing a JIT or a compiler to native code? The answer is there will be lots of challenges, but this is exactly the sort of thing we love working on :-)