4 ms·
I disagree on the things you've lost. > - concise, readable code Rust code is significantly more readable. Use the type system to your advantage. > - - reall
by csomar 5y ago
I disagree on the things you've lost.
> - concise, readable code
Rust code is significantly more readable. Use the type system to your advantage.
> - - really smart type inference
Rust has really smart type inference too and only rarely ask for an explicit type. I've found that I prefer annotating my types. It adds to documentation and readability.
> - a bunch of time thinking about the borrow checker
You can use Arc/Mutex to overcome some of these and review them in a refactoring.
> - ease of iteration
At the cost of introducing a bug/technical debt.
- muglug 5y agoRust has smart type checking. The really smart stuff is (IMO) the beauty of the borrow checker. In PHP, modern typecheckers can verify that the first element always exists on an array after an emptiness check: if ($some_arr) { echo reset($arr); } Whereas in Rust you have to explicitly unwrap: if !some_vec.empty() { print!("{}", some_vec.first().unwrap()); // .. more code } The Rust version requires you to use your intuition to figure out that `unwrap()` will never panic here. In my Rust port I consistently rely on the PHP typechecker's knowledge of the equivalent code when using `unwrap()`, because it knows which array fetches are safe. > At the cost of introducing a bug/technical debt. At the cost of shipping a product! ------- Edit: user ibraheemdev proposes this Rust equivalent which more closely matches the idealised pseudocode, and type-checks: if let [first, ..] = &some_vec { print!("{}", first); // .. more code } It's preferable IMO to if let Some(first) = some_vec.first() { because the latter relies on a property of a non-empty vec, and checks that property, rather than checking the non-emptiness of the collection.
- ibraheemdev 5y agoYou can usually use pattern matching to get around a check followed by an unwrap. I would rewrite your example as: if let [first, ..] = &some_vec { print!("{}", first); // .. more code }
- muglug 5y agoThanks, I did not know about that particular solution — that adheres more closely to the idealised pseudocode than any of the other Rust alternatives.
- deleted 5y ago[deleted]
- deleted 5y ago[deleted]
- ob 5y agoRust noob here but couldn't you write if let Some(element) = some_vec.first() { println!("{}", element); // .. more code } and avoid the unwrap and the empty check? Edit: Added a `let` I had forgotten.
- kccqzy 5y agoExactly (well other than "if let" here.) Every time you have a Boolean if condition with an unwrap, it means you are not taking advantage of the type system.
- ob 5y agoThanks, added.
- muglug 5y agoYes, but IMO that makes the code a bit more abstract: You've left behind an explicit "is this collection non-empty" and you're instead relying on a property of a non-empty collection. The PHP version can also be written as if (($element = reset($some_arr)) !== null) { echo $element; } But that code is similarly divorced from the imaginary pseudocode equivalent
- saghm 5y ago> Yes, but IMO that makes the code a bit more abstract: > You've left behind an explicit "is this collection non-empty" and you're instead relying on a property of a non-empty collection. More abstract for who? I think virtually all Rust programmers would easily understand the `if let` snippet, virtually all PHP programmers would understand the PHP snippet, and virtually all programmers of any language would understand that a non-empty array has a first element. I'm not at all convinced that most programmers would correctly guess that a function called `reset` is used to access the first element in an array though.
- kccqzy 5y agoA collection is non-empty if and only if it has a first element. Therefore checking for non-emptiness is the same as checking for the existence of a first element.
- csomar 5y ago> The Rust version requires you to use your intuition to figure out that `unwrap()` will never panic here. You should not use `unwrap` in a production product. It's there for prototyping and I think it's a mistake they have it (though the language already requires a good upfront time investment as it is). Use `?` and have your error propagate accordingly to the top of the chain. Have your own error types and convert from other error types. if !some_vec.empty() { print!("{}", some_vec.first().unwrap()); // .. more code } I don't know why you would check the first element of a vector. Use Rust type system to your advantage, and don't "convert" PHP code into Rust. Re-design your program. Also you don't need to check that the Vector is empty if you are using "first". "first" returns an Option with None if your vector is empty. My guess is that you have yet to exhaust the idioms Rust offers and approaching it in a PHP-like manner. > > At the cost of introducing a bug/technical debt. > At the cost of shipping a product! Okay!
- verdagon 5y agoWe tried this style in one of Google Earth's packages for a while (using an internal C++ class similar to Rust's Result). So many operations could theoretically fail (e.g. indexing out of bounds or an expected key not existing) that pretty much every single function in that package returned a Result. These "unexpected" errors would just fly up the stack, manually unwinding it, because nobody could really do anything with them. Once we had that, I really questioned some of our policies. I can imagine a language where panics don't crash the entire application, but instead blast away the surrounding "region" of memory, leaving the rest of the program intact and able to keep running. Similar to catch_unwind, but if the language is aware of region boundaries, and only allows certain methods of communication between them, it would leave the rest of the memory in much more predictable possible states. It may sound surprising, but it's actually possible with the right language constructs (Erlang folks know what I'm talking about!) and that way, we could once again have panics for unexpected errors, and Results for expected errors.
- Too 5y agoSounds like what you want is how exceptions behave in most languages? Including c++?
- staticassertion 5y agoThat sort of "flow typing" is extremely cool and I'd love to see it added to Rust. Perhaps something like mypy's proposed TypeGuard.
- chx 5y ago> Rust code is significantly more readable. You should put down the Rust kool-aid. Rust is incredibly hard to read due to its sigil and abbreviation heaviness.
- bfrog 5y agoI guess I didn’t see it that way, then again I’ve been bitten by C++ which is crazy land for overloads
- staticassertion 5y agoI think that's obviously a matter of opinion. I don't think Rust is hard to read at all, nor do I think of it as being particularly sigil heavy, but that's me. I think the syntax is probably unfamiliar for some, and familiarity is almost always what people mean when they say "readability". Coming from c++, Rust was pretty familiar. PHP isn't that hard to read either.
- chx 5y agoNo, what I mean is https://github.com/rust-lang/rust-wiki-backup/blob/master/Sigil-reference.md https://github.com/rust-lang/rust-wiki-backup/blob/master/Si... and that's just pointers, you have #[] #![] and then three ways to invoke a macro !() !{} ![] and of course a lot more. Maybe all this is necessary for a system level programming language, fine, but don't tell me this is easy to read.
- staticassertion 5y agoI have no problem telling you that Rust is extremely easy to read.
- staticassertion 5y agoOh, and the @ ones don't even exist anymore, haven't for like a decade afaik
- mustache_kimono 5y ago