Live data from Hacker News

Some notes on Rust

lambda-the-ultimate.org

41–50 of 113 posts

Re: Some notes on Rust

#41
post #7

I don't have an account there so I'll comment here: > 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. This is what boxes are for. A Box is a unique pointer to a value on the heap and can be used without knowing compile-time lifetimes. Refere…

> References and lifetimes allow you to safely return pointers to stack allocated objects. This is explicitly called out as non-idiomatic behavior in the documentation, however. The preferred action is to allocate on the caller's heap and pass a mutable reference down to the callee. In fact, in general it's recommended not to use Box, because it complicates human reasoning about the code. And while it gets around a l…

> In fact, in general it's recommended not to use Box, because it complicates human reasoning about the code.

Really? I've always understood it was because when possible that decision should be left to the caller and boxing by default just made the interface less flexible/convenient for callers. How does Box complicate reasoning about the code?

Re: Some notes on Rust

#42

Earlier quoted context omitted.

> What? C++11/14 solves these issues. You're right that C++ provides a solution to the first two, but C++ locking via std::mutex isn't done in the same way as Rust: in Rust the mutex owns the data and prevents you from getting access to it unless you lock. std::mutex, however, is a separate value from the data it protects and it's up to you to coordinate access to that data. I would also argue that Rust is a better s…

Fair points Rust’s synchronization primitives are immature — they’ve been rewritten once or twice in the past year or so — but cool from a usability perspective. edit: oh, hello pcwalton. I suspect you knew this already. :P

[Citation needed]

Re: Some notes on Rust

#43

Earlier quoted context omitted.

> Explicit returns are not frowned upon. I don't know where you got that idea From the docs: http://doc.rust-lang.org/book/functions.html > Using a `return` as the last line of a function works, but is considered poor style

Yes. Which is what I said. "Using a `return` as the last line of a function works" is not the same as "don't use explicit returns."

So I should use `return` except when I shouldn't? This is the cognitive overhead problem I'm talking about.

The original context of my concern is the instance where the match statement makes up the last statement in the function (frequently the only statement in the function's immediate scope). Since the individual cases are not terminating the function early, to get a value out of a match statement you simply leave the last expression bare.

i.e.

    fn something... {
      match input {
      Ok(input_val) => {/* several lines of semicolon terminated code*/
                        output}
      Err(errval) => {/* several more lines of semicolon terminated code */
              output}
    } 
is correct, but

    fn something... {
      match input {
      Ok(input_val) => {/* several lines of semicolon terminated code*/
                        return output;}
      Err(errval) => {/* several more lines of semicolon terminated code */
              return output;}
    } 
is poor style, and

    fn something... {
      match input {
      Ok(input_val) => {/* several lines of semicolon terminated code*/
                        output;}
      Err(errval => {/* several more lines of semicolon terminated code */
              output;}
    } 
is an error.

Re: Some notes on Rust

#44

Earlier quoted context omitted.

Yes. Which is what I said. "Using a `return` as the last line of a function works" is not the same as "don't use explicit returns."

So I should use `return` except when I shouldn't? This is the cognitive overhead problem I'm talking about. The original context of my concern is the instance where the match statement makes up the last statement in the function (frequently the only statement in the function's immediate scope). Since the individual cases are not terminating the function early, to get a value out of a match statement you simply leave…

> So I should use `return` except when I shouldn't? This is the cognitive overhead problem I'm talking about.

No. Use `return` only when you must. If you want an early return in a function, then you need to use `return`. If you don't need an early return, then don't use `return` at all.

I can't remember if this was ever a cognitive load for me personally. I don't think it was.

Re: Some notes on Rust

#45
> 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.

Re: Some notes on Rust

#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.

Re: Some notes on Rust

#47
post #4

Rust's error handling looks like the Maybe monad. That seems pretty reasonable in Haskell. I'm a little surprised by the criticism in the article — is the author saying there isn't enough syntactic sugar?

It's similar. We don't have HKT, so we can't get fully generic monads, but you can implement specific instances, like we have with Option/Result.

Steve, what's the reason that Rust doesn't have HKTs (higher-kinded types). Is there a technical barrier, e.g. to do with life-time inference, or is it a philosophical choice not to have them?

Re: Some notes on Rust

#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 think there, as it enforces memory safety.

In cases where it does make sense to return a reference to a new object, like allocating from an arena, the lifetime ('a) of the returned reference will be the same as the lifetime of the arena.

    fn new_from_arena(arena: &'a TypedArena) -> &'a mut Foo {
        arena.alloc(Foo { a: 5 })
    }
But Rust can infer the lifetime, so that can be shortened to:

    fn new_from_arena(arena: &TypedArena) -> &mut Foo {
        arena.alloc(Foo { a: 5 })
    }

Re: Some notes on Rust

#49
post #47

Earlier quoted context omitted.

It's similar. We don't have HKT, so we can't get fully generic monads, but you can implement specific instances, like we have with Option/Result.

Steve, what's the reason that Rust doesn't have HKTs (higher-kinded types). Is there a technical barrier, e.g. to do with life-time inference, or is it a philosophical choice not to have them?

It's one of our most requested features (and would be really good for collections) but it should be backwards compatible and therefore was postponed until after 1.0.

Nobody has put in the work to actually make a formal RFC yet either, which is required.

Re: Some notes on Rust

#50
post #37

Earlier quoted context omitted.

Maybe? I was addressing your “I don’t see the opportunity where to use C++14 outside hobby projects.” Compilers, games, and operating system components are archetypical systems software.

How many Fortune 500 do you see writing those?

Microsoft, Apple, IBM, Amazon?
Post reply on HN