Hello Rust devs! I've been following Rust off-and-on for about a year, but in the last month I actually started trying to do some development in it. I haven't done a huge amount with Rust yet, but I'm hoping some first impressions from a newbie like myself might be useful. I come from a C++ and Python background. My github is here: https://github.com/cessen
Disclaimer: please take all of this with a huge grain of salt. This feedback is meant with the humility of someone who surely doesn't fully understand the language yet and hasn't invested enough time into yet to be taken seriously. Much of what I say may have little bearing on anything. This is purely just to give my "fresh new user" perspective, in the hopes that it might be helpful somehow. So, first off, I absolutely love Rust over-all. The constrained generics with Traits feels really nice, and just glows with a sense of expressiveness and power. Rust's ownership model and move semantics are a great way to handle memory safety/management (it feels like C++11 move semantics "done right"). Rust is definitely a language I plan to continue learning, and hopefully use for a real project in not too long. But enough of that! You guys already know how awesome Rust is. # Modules and Crates # One of the first things that tripped me up was 'mod' declarations in a multi-file project. I wrote code like this the first time: mod my_other_file; use my_other_file::{Thing, OtherThing}; But this didn't end up working. It took me a stupidly long time to figure out that the 'mod' statement had to go after the 'use' statement. And this was made worse by the fact that 'extern crate' statements have to come _before_ 'use' statements. My intuition is that I need to tell Rust about the existence of code outside of the current source file before I can refer to that code. So having the "mod" statement come after the use statement feels backwards to me. In any case, once I figured out the order to put these things in, everything else worked as I expected. Modules and Crates are awesome! # The 'box' Keyword # It feels awkward to me that Box and Rc have different ways of initializing: let a = box 45i; let b = Rc::new(54i); Both Box and Rc are wrapped pointer types, and both are implemented in the standard library, and yet Box uses a language-level keyword to initialize it. That feels really inconsistent to me. I feel like Box should be: let a = Box::new(45i); I'm assuming there's a technical reason for using the 'box' operator, but surely any such technical reasons also apply to initializing e.g. Rc and Arc as well? Maybe this could be unified somehow with macros? let a = box!(45i); let b = rc!(45i); That would also be consistent with the initializing macro for Vec: let c = vec!(1i, 2, 3, 4, 5); # Can't Write to mut Vec # I was very surprised when I couldn't do this: let mut v = vec!(1i, 2, 3, 4, 5); v[2] = 7; // Not allowed Instead I had to do: *v.get_mut(2) = 7; Which feels awkward on multiple levels: not only can I not use square bracket syntax to access the element for writing, but I have to remember to do a dereference as well. And when reading code, it takes longer to mentally parse. # Lambdas vs Functions # The syntax for lambdas/closures feels weird to me. Currently there are two syntaxes (||{} and proc(){}) which have different semantics. My understanding is that these are already going to be unified into one syntax, and that addresses most of my feeling of weirdness with them. But I also wonder if it would be possible to unify them even further with regular functions. Function: fn add_five(x: int) -> int { x + 5 } Lambda/closure: fn(x: int) -> int { x + 5 } Maybe that's a terrible idea, and I'm sure there may be some important technical or semantic reasons to avoid that. And maybe it would cause confusion. But if it's reasonable, I think that would further enhance the feeling of consistency and unification, using the same keyword 'fn' to indicate "executable code that takes parameters and returns things". ---- Anyway, that's all I have. Other than these things--which are all largely ergonomic rather than semantic in nature--everything has felt really nice so far. And working with Cargo is fantastic. There is still a lot of Rust I haven't touched yet. I haven't played much at all with unsafe blocks, raw pointers, or named lifetimes among other things. As I dive further into Rust, would continued feedback like this be appreciated? Is this kind of feedback helpful? Thanks so much for everyone's hard work on Rust! It's becoming a really amazing language, and I look forward to continuing to work with it. --Nathan _______________________________________________ Rust-dev mailing list Rust-dev@mozilla.org https://mail.mozilla.org/listinfo/rust-dev