Live data from Hacker News

Some notes on Rust

lambda-the-ultimate.org

91–100 of 113 posts

Re: Some notes on Rust

#91

Earlier quoted context omitted.

> But I don't know if technical details such as this are high enough on the priority list. There are actual features which still have no documentation. It's hard being a single person trying to keep up with changes from tons of other people, many full time and some community. I may be the person who is most looking forward to Rust being stable...

And I should say, for the record, that you deserve a ton of credit for being a nearly superhuman job. The doc may be lacking, but it would be far worse off without you. Still, I wish the team/community could find a way to shore up the coverage of this kind of information. I think we've given beginners enough for now, that the focus should shift to "details you need to know about what the compiler does."

Thank you, I appreciate it. These kinds of comments are the ones I try to re-read when I'm feeling down about stuff.

Yes, I agree, I'd love more help :) I think you'll see a shift after 1.0.0-beta happens, since then, the focus will be on polish, rather than shipping every breaking change.

Re: Some notes on Rust

#92
post #71

Earlier quoted context omitted.

> Why aren't they consistent? So, I went back to do a bit of research, and it's gotten better since this first bothered me, my apologies. My beef was with the `let x = vet::Vector::New:: ()` vs `let x: Vec = vec::Vec::New()`. Perhaps not the best way to word it, so consider this objection retracted. :) > the idea that we intentionally made the type inference less powerful than it could have been is totally false Exce…

The default types for bare literals is described in RFC #212 ( https://github.com/rust-lang/rfcs/pull/212 ) To summarize: bare FP literals default to f64, bare integral literals default to isize. (NOTE: isize is recently renamed from int. It is a pointer-sized integer.) (EDIT: The default for integer literals may be superseded by a later RFC. I seem to recall that the default is actually i32 now, but I can't find a P…

You are right that this changed, but I can't find it in the RFCs either. https://github.com/rust-lang/rust/pull/20189 implemented it. And it is what everyone agreed upon.... hmm

Re: Some notes on Rust

#93
post #46

> There's a macro called "try!(e)", which, if e returns a None value, returns from the enclosing function via a return you can't see in the source code. Such hidden returns are troubling. Strikes me as simply a very appropriate use of macros. Get tired of writing the same syntactic fragment again and again? Write a macro. Want to see what some macro is "hiding"? Look it up or expand it.

The issue is it makes it difficult to notice that a function might return when scanning through a function. Especially as it's in places that are looking for a value (e.g. assignment).

At the moment it's just return and try!, but people look to the standard library for what is acceptable. When the standard library contains a macro that can return, people will write their own macros that return. It could potentially be half a dozen different macros you need to keep in your head.

Personally, I go back and forth on it. Hopefully it will turn out fine.

Re: Some notes on Rust

#94
post #88
post #85

Earlier quoted context omitted.

Overall, I think Rust is easier to use than C++ but not easier to write than C++. Writability is a specific facet of usability, which is hurt by strict upfront checks. Writability is a worthy thing to improve: GHC's -fdefer-type-errors feature is a good example. I hope Rust improves its writability in the future.

I think just like other languages, writing Rust leads to a familiarity with what the compiler wants. Then you spend more time thinking about design and the problem at hand, and less fighting the compiler. I think Rust will ultimately be easier than C++ to write because while there are tricky concepts to master, there should be much fewer of them than C++ has.

I disagree. While you get familiar with what the compiler wants (certainly I did, after using Rust for more than 2 years now), it's just that Rust compiler wants more from you than C++ compiler does.

The number of tricky concepts largely do not affect writability, because you don't have to use them. The number of mandatory compile time checks do, because you have to pass them.

One way to improve writability is a mode to turn off some of checks while you are exploring. I already gave a good example from Haskell. When you are done exploring, you can turn on all the checks.

Re: Some notes on Rust

#95
post #85

Earlier quoted context omitted.

Not easier than C++? I dunno, C++ looks like a clusterfuck of complicatedness. I'm mostly coming from F#, with some C. Rust's ownership system just makes sense and seems to perfectly answer the questions I have when using C APIs. Rust, for me, looks a lot like what I've wanted when writing performance F#. I'd commit atrocities to have optional ownership in F#. Every time I've fought with the borrow checker, it's beca…

Overall, I think Rust is easier to use than C++ but not easier to write than C++. Writability is a specific facet of usability, which is hurt by strict upfront checks. Writability is a worthy thing to improve: GHC's -fdefer-type-errors feature is a good example. I hope Rust improves its writability in the future.

Thank you, you've managed to nicely express my feelings on Rust. For coming up with a polished end product that works, Rust is easier, but for bashing on your keyboard to get out your ideas it can be a little frustrating compared to even C++.

Re: Some notes on Rust

#96
post #48

> In particular, allocating a new object and returning a reference to it it from a function is common in C++ but difficult in Rust, because the function doing the allocation doesn't know the expected lifetime of what it returns. I'd like to see a code snippet explaining this problem.

Yeah, it's unclear what he's talking about there. Normally when a function allocates a new object, it would want to return it by move (transferring ownership), rather than by reference. That doesn't involve any lifetimes. fn make_a_foo() -> Box { Box::new(Foo { a: 5 }) } If the function allocated memory and only returned a borrowed reference, who would be responsible for freeing it? Yes, Rust will make you stop and t…

Any reason you would ever want to return a Box instead of just a Foo, which the caller can then put in a Box if so desired?

Re: Some notes on Rust

#97
post #94
post #88

Earlier quoted context omitted.

I think just like other languages, writing Rust leads to a familiarity with what the compiler wants. Then you spend more time thinking about design and the problem at hand, and less fighting the compiler. I think Rust will ultimately be easier than C++ to write because while there are tricky concepts to master, there should be much fewer of them than C++ has.

I disagree. While you get familiar with what the compiler wants (certainly I did, after using Rust for more than 2 years now), it's just that Rust compiler wants more from you than C++ compiler does. The number of tricky concepts largely do not affect writability, because you don't have to use them. The number of mandatory compile time checks do, because you have to pass them. One way to improve writability is a mode…

Hmm, so like a Rust flag like --allow-leaks or --corrupted-ownership?

It seems like editor support would totally dominate here. That is, realtime checking of lifetimes and autocomplete/inline errors should be a much bigger improvement in write times than some way to emit invalid code.

Re: Some notes on Rust

#98
post #87
post #78

Earlier quoted context omitted.

>Unlike C++, 1. Macros from one crate aren't imported into another unless > the user explicitly requests that they be. 2. Macro invocations are > clearly macro invocations. You never have to wonder if something is a > function or a macro. Given the reference to Boost, the author is almost certainly talking about template metaprogramming, not C macros. TMP is obviously a lot more limited in scope than Rust macros, but…

Boost has all kinds of preprocessor macro stuff, like a loop construct that works through recursive includes, and the foreach macro (hopefully obsoleted with C++11).

True, but since the context of the comment was about how crufty he worries Rust would get once the "Boost crowd" discovers Rust macros, I doubt that it's really the specific topic of "relative merits of language constructs given the name 'macro'" that's under discussion (the word 'macro' doesn't even appear until later in the post). Certainly C macros aren't the main source of cruft in Boost.

Re: Some notes on Rust

#99
post #96
post #48

Earlier quoted context omitted.

Yeah, it's unclear what he's talking about there. Normally when a function allocates a new object, it would want to return it by move (transferring ownership), rather than by reference. That doesn't involve any lifetimes. fn make_a_foo() -> Box { Box::new(Foo { a: 5 }) } If the function allocated memory and only returned a borrowed reference, who would be responsible for freeing it? Yes, Rust will make you stop and t…

Any reason you would ever want to return a Box instead of just a Foo, which the caller can then put in a Box if so desired?

I can think of a case: when you want to return a type whose size is not known at runtime (a "dynamically-sized type" a.k.a. DST), then you need to stuff it behind something else whose size is known so that the compiler can statically determine how much memory to allocate before calling your function. You could use a reference for this task, but only if, as per Rust's usual rules, you have a parameter to your function whose lifetime you can tie it to. If you don't have such a parameter, then a Box is your next best bet.

Somewhat related to this, there's also currently a language deficiency where you can be forced to use Box when returning a closure from a function. This will be addressed shortly after 1.0.

Re: Some notes on Rust

#100
post #46

> There's a macro called "try!(e)", which, if e returns a None value, returns from the enclosing function via a return you can't see in the source code. Such hidden returns are troubling. Strikes me as simply a very appropriate use of macros. Get tired of writing the same syntactic fragment again and again? Write a macro. Want to see what some macro is "hiding"? Look it up or expand it.

The issue is it makes it difficult to notice that a function might return when scanning through a function. Especially as it's in places that are looking for a value (e.g. assignment). At the moment it's just return and try!, but people look to the standard library for what is acceptable. When the standard library contains a macro that can return, people will write their own macros that return. It could potentially b…

> The issue is it makes it difficult to notice that a function might return when scanning through a function.

What other solutions are there? The only other approach to error handling I've seen is exceptions (e.g., C++, Java, C#, JS…), and if you don't like `try!` because it is a "hidden return", you certainly won't like exceptions. At least with Rust's macros, I know that in the absence of one, there is no return; in the presence, there might be. Exceptions in most languages make no guarantee.

Post reply on HN