Interfacing with other libraries, is ofc, a different matter, but you can usually wrap the library API in your own functions to minimize this mismatch.
Interfacing with other libraries, is ofc, a different matter, but you can usually wrap the library API in your own functions to minimize this mismatch.
if std::collections::HashSet::is_empty(&basket) {
... is perfectly legal Rust, it would just be more idiomatic to write: if basket.is_empty() {
The availability of all functions as "free functions" is convenient when you need, say, a filter predicate, since of course std::collections::HashSet::is_empty is exactly what you wanted if what you wanted to express was the predicate "is this HashSet empty?" and in languages that aren't allowed to do this you'd need to pointlessly shuffle chairs around to achieve the same thing instead.Under UFCS I could extend your Rust type by simply writing a new free function which matches the type, and this is in fact deliberately forbidden. (I can write the free function, but, doing so does not extend the type and I can't call it using the "method" syntax).
You can also write literal C and use the C std-lib in C++ but it is the same problem. You're not using C++ at that point
Rust's stdlib assumes not only that there is malloc behind the scenes, but that it is ok to panic. Rust itself, including its stdlib, lacks a stable ABI. It also assumes that lots of little allocations and deallocations with a single owner is a valid memory pattern, and that writing directly to specific memory locations is something you never want to do. These are all wrong assumptions for someone writing baremetal. Look up abi_stable and no_std.
If you're learning, however, you know have to understand why you can't use generics (monomorphisation means you're not getting a stable ABI), why you shouldn't use native tagged unions and instead should write your own with unsafe (for total control of how the tag is handled), why you can't use the standard library, why you need to tag most things with repr(C), why the standard ownership patterns the borrow checker beat into you are in the way when writing your own allocator (with plenty of unsafe). Do you see my point?
Both Rust and C++, when writing baremetal, ask you to ignore how to write idiomatic code in their respective languages. This is fine for experienced devs, who will make good use of the additional features for abstraction, but not for newbies IMO.
C and Zig, on the other hand, do not have this problem, as idiomatic C barely uses its standard library (which is garbage anyway) and idiomatic Zig is designed to work baremetal, including the standard library. I certainly don't recommend using C for new developments in most cases, but for learning, well, you need to learn it anyway, even if you're using Rust baremetal. It's effectively what you're writing, albeit with lots of repr and unsafe strewn around.