This is very nice article, objectively lists possible pitfalls.
It's however not quite that simple.
I am in favor of removing as, but then try_from needs to work with more types, for example try converting u64 into f32 without using as. It turns out to be very hard. TryInto does not work in single step.
Important aspect is performance. HPC code needs to be able to opt out of math checks.
Also Results and Options are very costly, as they introduce lot of branching. Panic is just faster. Hopefully one day rust will use something like IEX by default https://docs.rs/iex/latest/iex/
It has the same benefits as Results, but if error is returned in less than 15% of function calls, then IEX is much faster.
Btw. allocation failure in std returning Result anytime soon?
What came before was regression. Which is to this day no 1 method if we want something interpretable, especially if we know which functions our variables follow. And self attention is very similar to correlation matrix. In a way neural networks are just bunch of regression models stacked on top of each other with some normalization and nonlinearity between them. It's cool however how closely it resembles biology.
This. Traits and macros are two real problems with rust. Orphan rule is one, but also const, async and unnamable types (mostly closures). These barely work with traits or do not work at all. If rust did not have closures, it'd be a lot simpler to solve these. Is it so hard to just create a normal function instead of closure?
Perhaps we need to go back to the basics a bit? What is a trait?
1. A set of functions, associated types and generic types
2. A marker/tag (e.g. Send, Sync)
Orphan rules do not seem to be problem for marker traits. Library authors must be responsible for enforcing whether their types are Send/Sync, etc or not.
As for normal traits, it's too late for rust, but I'd just limit traits to being only sets of function definitions, e.g.
Then adding set operations (and, or, xor, not) for traits would be pretty easy, keeping most of power for defining generics.
More importantly traits could be just aliases and two traits with the same set of functions would be equal. This solves orphan problem - you would not need to import or export traits, it would be just normal resolution of functions. Do I call this function from crate A, or crate B? That's a solved problem.
The hard problem is not sharing the trait, but sharing the trait instance.
With your solution, if too modules define traits with identical type signatures but different implementations, it would be impossible for the compiler to decide which impl to use.
If there are two modules module_a and module_b, and each defines a function called foo, how does the compiler decide which foo should be used? It just checks whether you imported module_a::foo or module_b::foo.
Perhaps I should have been more clear. The point is you would not implement traits. You would just implement functions. You would not implemet traits, you would just write functions iter and len for your type.
When calling a function, compiler would check separately for existence of each function defined in the trait. That is a trait would be just like any other type alias so that you do not need to repeating complex function names everywhere:
Important aspect is performance. HPC code needs to be able to opt out of math checks.
Also Results and Options are very costly, as they introduce lot of branching. Panic is just faster. Hopefully one day rust will use something like IEX by default https://docs.rs/iex/latest/iex/ It has the same benefits as Results, but if error is returned in less than 15% of function calls, then IEX is much faster.
Btw. allocation failure in std returning Result anytime soon?
reply