7 ms·
> experimental support for WebAssembly as a target, wasm32-unknown-emscripten [...] check out Tim’s example of the classic TodoMVC project. On one hand this is
by libria 10y ago
> experimental support for WebAssembly as a target, wasm32-unknown-emscripten [...] check out Tim’s example of the classic TodoMVC project.
On one hand this is really cool and potential for client-side Rust. On the other hand:
let id = node.parent().unwrap().parent().unwrap().data_get("id").unwrap().parse::<usize>().unwrap();
Eh, no thanks. :) If I could get a macro or shorthand for that, I'd welcome all the other benefits of a large scale client-side platform with strong typing.
- deleted 10y ago[deleted]
- bbatha 10y agoWhen the carrier trait lands this becomes: let id = node.parent()? .parent()? .data_get("id")? .parse::<usize>() .ok()?; I'd also expect that someone will write higher level libraries so that you aren't doing raw DOM manipulation. A rust vdom wasm library would probably be blazing fast.
- libria 10y agoSwell! I was hoping that existed in this language. The rest of the code looks concise FWIW, https://github.com/tcr/rust-todomvc/blob/master/src/main.rs https://github.com/tcr/rust-todomvc/blob/master/src/main.rs
- leeoniya 10y ago> A rust vdom wasm library would probably be blazing fast. Most of the cost of vdom is the resulting DOM ops and reflow/restyle the browser needs to do. It may be faster than the fastest today, but you're unlikely to see any kind of performance leap or even anything noticeable.
- steveklabnik 10y agoSmall note, we don't _technically have to stabilize Carrier to land this, just implement it for Option. (yay standard library types) However, ? for Option is a bit controversial, so we'll see...
- masklinn 10y ago> However, ? for Option is a bit controversial Because people wouldn't expect it to return due to behaviour of existing languages yet that's what it does in Rust?
- Rusky 10y agoMore because Option is not really intended to handle errors while Result and ? are.
- steveklabnik 10y agoYes, that's correct. If we make ? go to more than just result, you could implement it for any type, and it's not totally clear that changing it from "error handling" to "general control flow" is a good idea. Many are in favor of doing it, though. I'm personally against it.
- int_19h 10y agoWhether it's ? or something else, having a very concise form of syntactic sugar to unwrap option types is desirable. Most languages that don't have it, eventually acquire it due to demand.
- lobster_johnson 10y agoThe "?" operator looks like a more specialized, error/success-specific version of monads. Has there been any discussion about generalizing everything into monad-style chaining operators? I see that there is some discussion here [1], including a suggestion to add a Haskell-style "do" block. But that's just one guy's blog post. [1] https://m4rw3r.github.io/rust-questionmark-operator https://m4rw3r.github.io/rust-questionmark-operator.
- steveklabnik 10y agoYes, that was endlessly discussed as part of all of this. The TL;DR is: it's not simple. ? is very straightforward and helps people out a lot today. So if and when (and it is a big if) Rust ever gets do notation, this might be a little redundant, but blocking one of people's largest pain points today is worth the (possible) little bit of redundancy.
- lobster_johnson 10y agoThanks, that makes perfect sense. I haven't followed the internal discussion at all. It sounds like there are some that would like to move Rust in the direction of becoming more Haskell/ML-like (which is to say more purely functional) rather than the current balance between imperative and functional? Is there any internal tension in that regard?
- steveklabnik 10y agoIt's not even a philosophical difference, really, there are technical objections that would have to be addressed somehow before it would even be possible, let alone figure out if it's a feature that's desired. These involve things like "it's still unclear if HKT is going to end up in Rust or not, and how", which is a pre-requirement, as just one example.
- mathw 10y agoI believe one of the biggest obstacles to a general monad system in Rust is that the type system can't actually handle it at the moment - it requires higher-kinded types, which may or may not ever actually be added to the language.
- killercup 10y ago> A rust vdom wasm library would probably be blazing fast. Even regardless of performance, it would be quite nice to have! I've been meaning[1] to build a small prototype to do something clever[2] with it, but didn't have the time yet. Feel free to steal these ideas :) [1]: https://scribbles.pascalhertleif.de/impl-virtual-dom-cli-libui.html https://scribbles.pascalhertleif.de/impl-virtual-dom-cli-lib... [2]: https://scribbles.pascalhertleif.de/rich-diffs-of-rendered-html.html https://scribbles.pascalhertleif.de/rich-diffs-of-rendered-h...
- topspin 10y agoEven without the ? sugar I don't see what's so offensive about this; the least little formatting effort produces: let id = node.parent().unwrap() .parent().unwrap() .data_get("id").unwrap() .parse::<usize>().unwrap(); If there is something horrible about that I don't see it.
- 102030485868 10y agoIt hurts to type sometimes. Typing at work isn't really an issue since I have an ergonomic keyboard, but big side projects can sometimes hurt. ? is far easier and faster to type than .unwrap(). So no, there's nothing horrible that I see, there is something horrible that I feel though.
- oblio 10y ago> If there is something horrible about that I don't see it. Isn't unwrap(): a) boilerplate b) repetitive?
- steveklabnik 10y agoIt's boilerplate in a certain sense. Those are all points where what you've written might not work. Rust makes you deal with possible problems _somehow_. Specifically, this is a replacement for null. If you legitimately don't care, then it can feel boilerplate-y, but it also lets you start by not having to care, and then searching for unwrap and replacing it with better handling. In other words, it's boilerplate here because this particular operation has many possible failure modes, and Rust is pointing those out to you. It's repetitive in this particular instance, but doesn't have to be in general.
- stymaar 10y agoc) a bad practice since it will make your program crash is a node has no parent. if the node always having a parent is a invariant of your application, you should use `expect` with a clear error message when the invariant is broken. if your node can have no parents then you want to handle this case explicitly with a `if let Some(parent) = node.parent() {` pattern.
- echelon 10y agoThis is NOT idiomatic Rust. If you're new to Rust, please don't let this give you a taste for the language. Clean Rust code looks very elegant.
- netcraft 10y agohow would this be written idiomatically today?
- lisivka 10y agoWith proper error handling instead of unwrap(), which means "I don't care about errors here".
- Dylan16807 10y agoWhat does proper error handling look like when I want to use the same "invalid node" error for most of those unwrap calls?
- EugeneOZ 10y agoUse "try" or "?" if possible, pattern matching otherwise.
- staticassertion 10y agoYou can use map or and_then, you can write a macro, you can use try!, you can use if let, etc. There are lots of ways to handle errors in rust.
- echelon 10y agoThere are so many nice options here. For the cleanest code, I would use `?` and a `From` impl for the error transformation. If I didn't want to use `From`, I'd use `map_err`, `and_then`, etc. Both the Result and Option types have wonderful interfaces for chaining.
- cgag 10y agoI wish it were u and e rather than unwrap/expect. Or just "yolo" or "!" or something. Is there a way to rename / alias methods like that? edit: I see ? is going to be a trait you can implement to do that, so that'll be nice (probably).
- openasocket 10y agoThere is: make a trait called SimplerUnwrap<T> or something with the method u(self) -> T. Implement it for Option<T> and you are good to go!
- lisivka 10y agoWhy not use C instead? I see no benefit to use complicated language which cares about errors and then completely ignore that care.
- Rusky 10y agoBecause while you may not care at first, you will later, and Rust will help you out then.
- openasocket 10y agoYou're not ignoring errors with unwrap(): if there is an error, the program will print out a stack trace and exit. If you have some operation that could potentially fail but you know it won't (like if you are sure that node has a parent) what do you do? If the operation actually does return an error, it means what you thought to be true was wrong, and in some cases that means something has gone seriously wrong, and your program should immediately stop so you can debug it. You can try to handle the error yourself, using try! or the ? operator, but unless you plan to be able to recover from that error, or you want to output a more end-user-friendly error message than a stack trace, what's the point?
- deleted 10y ago[deleted]
- killercup 10y ago
- openasocket 10y agoI'd like to see some sort of macro for DOM navigation that takes a node and an XPATH expression or something, and the macro expands it to the above. Never played around with macros in Rust, so I don't know how involved that would be, or even if it would be possible.
- steveklabnik 10y agoThat sounds very possible.
- lisivka 10y agoEvery unwrap() is the point, where you need to check return value for an error, unless you are writing one-time code. If you don't care about errors, don't use Rust. Use C instead. Simple solution.
- jcurbo 10y agoSo, I see tons of unwrap() in Rust code I've looked at in the wild. I understand the concept of unwrap() and Option types. What would this type of code look like with proper error handling? It seems like it'd devolve into a ton of if-then statements like in C.
- akiselev 10y agoFirst, you'd use match statements instead of if-then so the worst case scenario already looks much better than in C, especially since Rust has enum decomposition and makes expressions first class (you can do let y = if (...) { y } else { z }). There are a lot of ways of combining control flow and assignment operators to decompose union types like Option and Result (which is Option with error E instead of None). For example, you can do if let, while let, or let x = match(y) { ... } that allow you to handle errors without jumping through hoops like you would with C returns or C++ exceptions. For a library consumer this covers a large number of cases. Second, most of the time you can use the ? operator to greatly simplify error handling. Any code path that shares the same error type can just pass through errors as if they were an exception. The ? operator is also aware of Into/From trait implementations so in many (or even majority of) cases you can use the ? operator even if the function you're calling has a different error type! If I remember correctly, you can even exploit the module system to provide a per-file Into/From implementation for your custom error type if it doesn't map cleanly across use cases (they just have to be in the same module as the type). Rust's zero cost abstractions and trait system make it really easy to reduce boilerplate without compromising on readibility or discoverability. Third, the Result type has a number of functional operators for responding to and combining results. You can do Result.and_then(...) with a closure or function call to do something when there is no error and Result.or_else(...) to do something when there is an error. You can use the and or or operators to combine multiple results and there are many other utility functions that are universal to Rust error handling that make the entire experience very pleasant, composable, and readable with a little experience.
- sidlls 10y agoIt does turn into if-then statements (some implicit, e.g. via try! or ?), if done properly. But I don't understand the objection or calling it "devolving". Errors have to be handled. This way is as efficient as any other. And, in my view, is cleaner than exception handling systems.