6 ms·
Some small corrections: > It’s an error handling magic for async functions The question mark operator is unrelated to async - you might say "fallible function
by Diggsey 4y ago
Some small corrections:
> It’s an error handling magic for async functions
The question mark operator is unrelated to async - you might say "fallible functions" instead.
> This indicates that it’s a macro. Basically a shortcut.
I don't think "shortcut" has a specific meaning that is related to macros in either Javascript or Rust.
> An implementation of trait. So class (?).
Not really a class. There isn't a good parallel to this in most other languages. It is the link between a trait and a type, and provides a specific implementation of the trait.
> Unlike JS, Rust has a type for the result of the promise/future called Result
The `Result` type is not related to futures. Any function can return a `Result`, and a future can yield any type (not necessarily a `Result`, although it is commonly used in that way).
> The Result enum has Ok and Err. If the future is successful, it returns Ok, otherwise Err.
Again, no relation between `Result` and futures.
> Use this when you’re confident that it won’t error.
Personally I would recommend never using `unwrap` outside of tests. If you want to panic on the `Err` case, then `expect("...")` allows you to provide an explanation for why the `Err` case should not have been possible.
- eyelidlessness 4y ago> The question mark operator is unrelated to async - you might say "fallible functions" instead. This jumped out at me too and I think it would be better stated as “this function doesn’t handle this error” or “this function may produce this error”, which is basically checked exceptions ~without error handling as arbitrary control flow. > Not really a class. There isn't a good parallel to this in most other languages. It’s a lot more like a class than the next most obvious TypeScript idiom (structural type compatibility/duck typing). It has to be explicitly defined and that’s the most important part coming from a JS/TS background. I agree with and fully endorse the rest of this comment.
- brabel 4y ago> which is basically checked exceptions ~without error handling as arbitrary control flow. With the `?` operator, Rust behaves identically to a language with checked exceptions as it also has "arbitrary control flow" in that the code may "jump" elsewhere on errors. The implementation may be different, but the abstraction is identical.
- pkolaczk 4y agoThe places it may jump are explicitly marked in the code, though. And that makes a tremendous difference in readability. The problem with exceptions is not the alternative control flow, but the fact it is hidden, and an exception can come out of nowhere, from 10 layers below (that's particularly bad for unchecked where you can't see them even in signatures).
- eyelidlessness 4y agoYou responded while I was typing but your response is much better.
- kaba0 4y agoI really don’t think it is that much of a problem. You almost always want a high-level error handling logic, and not all errors can or should be handled at callsite. Rust’s ? macro is a good tradeoff, but I really do think that exceptions are the best way of error handling — optionally marking a given exception type as “should be handled” aka checked exceptions. Though existing implementations are not without errors.
- eyelidlessness 4y agoI genuinely don’t think this is right! The syntax is equivalent to try->catch->throw or whatever but it doesn’t change the fact that the function has a clear either/Result type. Every call site gets the same return and has the same error semantics whether that syntax is used or an explicit return statement/expression is used. ? just means it’s a potential early return. Not a goto.
- rmbyrro 4y agoYou seem knowledgeable about Rust, is this article pointing in good directions to learn the language from a dev primarily coding in JS?
- ZephyrBlu 4y agoI've recently started learning Rust with very little experience in low level languages. Just go build something and read the Rust book: https://doc.rust-lang.org/book/title-page.html https://doc.rust-lang.org/book/title-page.html. The trickiest thing is ownership and lifetimes, but that's not really something you can understand just by reading. You need to build an intuition for how ownership and lifetimes work.
- jen20 4y agoMy recommendation for people learning rust for years has been to read both the Rust Programming Language book and Programming Rust at the same time.
- csomar 4y agoNo. The article is terrible (sorry). The OP was probably generous with "some small corrections". Not only the article touches up on some minor details about the language (mostly syntax) but gets them wrong or with a mistake half the time. These details are hardly 10% of the journey into Rust. The best place to start is still the Rust book: https://doc.rust-lang.org/book/ https://doc.rust-lang.org/book/ and then start coding with it. I'd also suggest you learn some C along the way, if you only have a JS background.
- michaelsalim 4y agoDo let me know the mistakes and I will fix them! And agreed, the Rust book is excellent. I did have experiences with C which made going into Rust that much easier. But for others that don't, wouldn't you think going straight to Rust would be easier than learning C on the side?
- eyelidlessness 4y ago
- toomanydoubts 4y agoI don't know rust, so pardon my lack of knowledge. But given a quick look, can't "traits" be seen just like "typeclasses" in haskell? Btw, I feel like I should learn rust now.
- ylyn 4y agoThey are exactly typeclasses.
- mernen 4y agoYes, Rust traits are Haskell typeclasses. What he's saying has no parallel in most other languages are the `impl` blocks (which can be used to both define arbitrary methods and implement traits, the latter being directly analogous to Haskell's `instance` definitions).
- tialaramex 4y agoNot just methods, impl defines all associated functions for a type, and Rust automatically allows you to call any associated function as a method if its first argument is some form of "self". If you've got a Cat named puss, the call puss.meow() is effectively shorthand for something like Cat::meow(&puss) where that first parameter was the &self parameter to your "method". Because this is namespaced, there's no problem if your Cat type has this meow() method and a Trait (say, AnimalNoises) it implements also has a meow() function, Rust knows those are different functions and the confusion only arises for a human reader, and only in code that actually wants to call one of the two identically named functions. AnimalNoises::meow(&puss) and Cat::meow(&puss) are distinct, but writing thing.meow() requires inspecting other nearby code to discover whether from context this code knows thing is a Cat or just wants to make AnimalNoises. Where this might be confusing you should write AnimalNoises::meow(&thing) to make your intention clear to humans, and have it checked by the compiler. Only the type's author gets to implement it, and only once (the standard library and especially core are special) so there's an essential distinction between SomeType::function() which was necessarily provided by the SomeType author, and just third party code that works with this type.
- 4y ago
- michaelsalim 4y agoThank you so much! I've corrected them on the article.