Seconded, thirded, fourthed. I spend a lot of time thinking about how laws, in practice, are not actually intended to be perfectly enforced, and not even in the usual selective-enforcement way, just in the pragmatic sense.
Single-ownership ("affine types") is a separate concept from a borrow checker. Your language doesn't need a borrow checker (or references at all) to benefit from single-ownership, though it may make some patterns more convenient or efficient.
rust would be pretty unusable without references. affine lambda calculus isn’t even turing complete. however, you’re right that a borrow checker is unnecessary, as uniqueness types (the technical term for types that guarantee single ownership) are implemented in clean and idris without a borrow checker. the borrow checker mainly exists because it dramatically increases the number of valid programs.
Supporting single-ownership in a language doesn't mean you can't have opt-in copyability and/or multiple-ownership. This is how Rust already works, and is independent of the borrow checker.
If we consider a Rust-like language without the borrow checker, it's obviously still Turing-complete. For functions that take references as parameters, instead you would simply pass ownership of the value back to the caller as part of the return value. And for structs that hold references, you would instead have them hold reference-counted handles. The former case is merely less convenient, and the latter case is merely less efficient.
> And having used it in rust, I wish more languages had something like that.
Same. I'm at the point where I feel like copy-by-default semantics are one of the ancient original sins of programming languages. Single-ownership is so, so useful, and it's trivial to implement and not at all difficult to understand (especially compared to something like Rust's borrow checker).
Rust existed nearly entirely on paper until 2009, when Mozilla started funding researchers to work on it full-time. It wasn't announced in any sort of official capacity until 2010, and had no official numbered release until 2012. It was less than three and a half years between 0.1 and 1.0, and in that time, hard as it is to believe, it underwent more overall change than Zig has.
In a lot of cases, we could argue that ISAs have been shackled by catering to the specific details of C. But if we're just referring to the CALL instruction (and its equivalents), that's not a reaction to C, it's a reaction to structured programming, which was a good thing.
Whether a CALL instruction (by whatever name) does anything with the stack is ISA dependent. On ARM, the BL instruction saves the return address into the LR register and performs a branch, much like the B instruction.
So the other way around works too, right? I can fire off an email to a noreply address at any given company, call it "Terms Of The Serviced", and that represents a binding contract into which I can insert arbitrary obligations at will?
> The vast majority of rust programs don’t need such validation.
The vast majority of Rust programs would benefit from such validation existing in the language, even if they never bother to explicitly leverage it themselves. For example, a non-panicking effect would be beneficial for both compilation times (don't bother pessimistically emitting unwinding glue for the enormous number of functions that don't need it, only to attempt to optimize it away later) and runtime performance (the guaranteed absence of the aforementioned glue reduces potential branch points and code size, which leads to better inlining and vectorization).
I understand what that is but I just don’t care. I am guessing the vast majority of people using rust also don’t care. Justifying the decision to create this mess by saying it is for embedded makes no sense to me.
Also don’t understand why you would use rust for embedded instead of c
Embedded systems vastly outnumber classical computers. Every classical computer has several embedded systems in them. As does appliances, cars, etc. So yes they are an incredible important use case to secure our modern infrastructure.
> I honestly just don't believe that Rust is more complex to onboard to compared to languages like Python.
Most people conflate "complexity" and "difficulty". Rust is a less complex language than Python (yes, it's true), but it's also much more difficult, because it requires you to do all the hard work up-front, while giving you enormously more runtime guarantees.
Doing the hard work up front is easier than doing it while debugging a non-trivial system. And there are boilerplate patterns in Rust that allow you to skip the hard work while doing throwaway exploratory programming, just like in "easier" languages. Except that then you can refactor the boilerplate away and end up with a proper high-quality system.
> I genuinely struggled to follow the concepts in this article
I read the HN comments before I read the OP, which made me worry that the post was going to be some hifalutin type wonkiness. But instead the post is basically completely milquetoast, ordinary and accessible. I'm no type theorist--I cannot tell you what a monad is--and I confess that I don't understand how anyone could be intimidated by this article.
I don't agree, the article isn't going deep into effects.
The intro where they describe effects as essentially being "function colors" (referring to another article fairly often linked in hackernews) plus give lots of concrete examples (async, const, try) seems like more than enough to be obvious to the readers.
reply