5 ms·
> "what's the status of this can we please get this merged?" Having written Rust professionally for a number of years, this didn't happen too much. Where it di
by insanitybit 4y ago
> "what's the status of this can we please get this merged?"
Having written Rust professionally for a number of years, this didn't happen too much. Where it did it was stuff like "yeah you need to Box the thing today", which... did not matter, we just did that and moved on.
> It can ever so slightly give one the impression that the rust community has decided that the language is mature and the only thing missing is faster compile times.
That is generally my feeling about Rust. There are a few areas where I'd like to see things get wrapped up (async traits, which are being actively worked on) but otherwise everything feels like a bonus. In terms of things that made Rust difficult to use, yeah, compile times were probably the number one.
- nicoburns 4y agoThere are a few more fundemental missing pieces for me: - It's impossible to describe a type that "implements trait A and may or may not implement trait B" - It's impossible to be generic over a trait (not a type that implements a trait, the trait itself)
- tialaramex 4y ago> It's impossible to describe a type that "implements trait A and may or may not implement trait B" How is this different from just describing a type that only "implements trait A" ?
- nicoburns 4y agoIt would allow you to call a function to check for trait B and downcast to "implements trait A and B" in the case that it does implement the trait.
- merely-unlikely 4y agoI’m still learning the language but couldn’t you use an enum containing two types to accomplish the same thing?
- nicoburns 4y agoYou can if you know all of the possible types in advance. But if you want to expose this as an interface from a library that allows users to provide their own custom implementation then you need to use traits.
- tialaramex 4y agoIt seems like a way to ask "Can this thing implement X and if so how?" from say the Any trait would be what you want here, I have no idea how hard that would be to deliver but I also don't see how the previous trait thing is relevant, like, why do we need to say up front that maybe we will care whether trait B is implemented?
- insanitybit 4y ago> - It's impossible to describe a type that "implements trait A and may or may not implement trait B" So, specialization? Or something else? I haven't found a need for specialization. I remember when I came from C++ I had a hard time adjusting to "no specialization, no variadics" but idk I haven't missed it in years. > - It's impossible to be generic over a trait (not a type that implements a trait, the trait itself) Not sure I understand.
- nicoburns 4y ago> So, specialization? Basically yes. But that works with dynamic dispatch (trait objects) as well as static dispatch (generics). > Not sure I understand. A specific pattern I'd like to be able to represent is: trait AlgorithmAInputData { ... } trait AlgorithmA { trait InputData = AlgorithmAInputData; ... } trait DataStorage<trait AlgorithmA> { type InputData : Algorithm::InputData; fn get_input_data() -> InputData; } fn compute_algorithm_a<Storage: DataStorage<AlgorithmA>>() { ... }
- dcow 4y agoI mean this is what you have to do to access variables from an async block: let block = || { let my_a = a.clone(); let my_b = b.clone(); let my_c = c.clone(); async move { // use my_a, my_b, my_c let value = ... Ok<success::Type, error::Type>(value) } } And you can't use `if let ... && let ...` (two lets for one if) because it doesn't desugar correctly. And error handling and backtraces are a beautiful mess. Your signatures look like `Result<..., Box<dyn std::error::Error>>` unless you use `anyhow::Result` but then half the stuff implements std::error::Error but not Into<anyhow::Error> and you can't add the silly trait impl because of language limitations so you have to map_err everywhere. It's not just "oh throw a box around it and you're good". It's ideas that were introduced to the language when there was lots of steam ultimately not making it to a fully polished state (maybe Moz layoffs are partly to blame IDK). Anyway I love Rust and we use it in production and have been for years, but I think there's still quite a bit to polish.
- dcow 4y agoI just want to reiterate how ridiculous the async block example is. You have to add a wrapper block that captures the variables and clones them because there is no way to specify how you want variables to be captured and what works in a normal block does not work in an async block. Then, because of some other language/compiler limitations, the return type of the block can't be inferred so you have to specify it manually even when you use the block in a context where it ought be inferred trivially. All this adds up to the existence of the block syntax being more complicated than just defining a function to do the same thing (when blocks are supposed to be a convenience so that you don't need a bunch of function with context pointers taking pointers to other functions everywhere like you do in C). Which you'd happily do but wait, you're trying to curry a function for a specific use case where you pass it to an async iterator function, so the signature is fixed and you have to use a block to curry because rust doesn't support that either. So you end up with the above just to say "run this piece of code concurrently for each element in a list.
- insanitybit 4y ago> I mean this is what you have to do to access variables from an async block: I am clearly missing some context because that code is needlessly complex. Are you just trying to show that you have to clone values that you hold a reference to if you want to move them? Because yes, you do. But your example also needlessly borrows them in the outer closure.