4 ms·
I share this perspective, it's why Vale chose generational references over a borrow checker. In practice, the borrow checker has to reject a lot of perfectly f
by verdagon 4y ago
I share this perspective, it's why Vale chose generational references over a borrow checker.
In practice, the borrow checker has to reject a lot of perfectly fine patterns, such as observers, dependency injection (the pattern, not the frameworks), delegates, backreferences, many forms of RAII [0], graphs, etc. Sometimes, the workarounds lead to more complexity, less flexibility and decoupling, and more refactoring which would be unnecessary in other languages. This is likely why GUI is difficult with the borrow checker, and why one has to bring in frameworks to compensate.
The borrow checker can prevent certain kinds of logic bugs at compile-time, which might mean a release lets 9 bugs into production instead of 10 or 11 (comparing to a safe language with a strong type system). However, that tradeoff might not be worth it, depending on the domain. Flexibility and decoupling can be more important, at least in the domains I've worked in (roguelike games, web servers, apps) and the size of the program. There are domains where it's better to add more complexity to detect even more bugs at compile-time, that's where I'd choose Rust (or perhaps GC'd FP languages, which prevent even more bugs). Just my two cents!
Note that this is only a problem if a programmer is a bit too religious with borrow checking; in practice Rust offers reference counting which can nicely avoids these problems.
One of Vale's principles is to move checks up to compile time, but prefer not to when it causes too many architectural problems or "infectious leaky abstractions" so to speak. This is also why Vale will be using coroutines (similar to Go) instead of async/await.
It's also why we're adding a region-based borrow checker, which is opt-in and doesn't impose constraints on its callers. [1] If we do it right, it should give Vale a lot of the performance benefits of Rust's borrow checker, but without the complexity and architectural constraints.
[0] https://verdagon.dev/blog/higher-raii-7drl https://verdagon.dev/blog/higher-raii-7drl
[1] https://verdagon.dev/blog/zero-cost-refs-regions https://verdagon.dev/blog/zero-cost-refs-regions