Re: `mod`, `use`, and `extern crate`: My preferred solution so far has been to have one file that has the `extern crate` and `mod` statements (usually projectname.rs), and then my other files (e.g. main.rs) have only `use` statements.
On Wed, Oct 8, 2014 at 1:36 PM, Nathan Vegdahl <[email protected]> wrote: > 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 > [email protected] > https://mail.mozilla.org/listinfo/rust-dev >
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
