Live data from Hacker News

Rust 1.46

blog.rust-lang.org

51–60 of 157 posts

Re: Rust 1.46

#51

If anyone wants to know more about const fns, see https://doc.rust-lang.org/reference/items/functions.html#con... It is the Rust way of specifying a function as being _pure_. In other words the output is dependent only on the function arguments, and not on any external state. This means they can be evaluated at compile time. I suppose in the future, it could also allow better compiler optimizations.

An interesting history note: Rust used to have an effects system which included actually being able to annotate a function as pure.

From way back in 2013, a HN thread https://news.ycombinator.com/item?id=6940624

Sadly it looks like the wayback machine does not have a copy of the original. Does anyone know how to get one?

Re: Rust 1.46

#52
post #46
post #26

Earlier quoted context omitted.

Hear hear. System languages don't grow on trees. Rust has had a lot of non-trivial effort put into it and is very usable right now . Somebody is going to see the value just lying around and is going to pick up the financial slack. I see it as vaguely analogous to the current movie theater situation in the US. A lot of companies are seeing the end of their business, but all of those buildings are still sitting around…

What's baffling to me is how scott's comment is [flagged] and [dead]. You trully can't have unconfortable opinions about Rust here. That's blatant censorship. Replying to you since I don't see a reply button to his comment.

It's a factually incorrect comment: the entire Rust team was not fired from Mozilla.

Does that mean it deserves to be flagged? I didn't flag it. But to be clear, while it does have some opinions, it is also plain incorrect in the facts it asserts.

You can also find, many, many, many comments critical of Rust that are upvoted, let alone not flagged. I wouldn’t extrapolate from a single comment.

Re: Rust 1.46

#53
post #47

Earlier quoted context omitted.

Basically, the interpreter interpret's rustc's internal IR, so it can theoretically support the entire language. That's not a good idea for various reasons, though, so its capabilities are effectively on an allowlist, that we expand over time as we're sure we want to enable a given feature.

That seems like a really good design, as opposed to having an AST interpreter like I might do otherwise. But would this indeed support a "much larger set of features" than constexpr as was claimed?

I think that the earlier const evaluator was an AST interpreter? It's been a long time and I don't work on this code, so I'm not 100% sure.

I don't know constexpr well enough to comment on that claim.

Re: Rust 1.46

#54
post #17
post #7

Earlier quoted context omitted.

Never worked with Rust, but I am pretty sure that having a function be pure is not enough to evaluate it at compile time.

Why not? By definition the output does not depend on runtime property so you should be able to compute it at compile time right?

Well, that is not the definition. Output of a pure functions can depend on input arguments, and those arguments can definitely depend on runtime properties.

https://en.wikipedia.org/wiki/Pure_function

Re: Rust 1.46

#55
post #44

Earlier quoted context omitted.

I wonder why && and || are not allowed in const functions? > All boolean operators except for && and || which are banned since they are short-circuiting. I guess I'm missing something obvious but why does the short circuiting break const-ness?

That was a restriction from before 1.46 stabilized control flow in const functions. Now that we have worked out the details around `if`, we can also stabilize `&&` and `||`. (I'm a little surprised they weren't stabilized at the same time! Edit: they were! I just didn't look closely enough.)

> (I'm a little surprised they weren't stabilized at the same time!)

They were stabilized at the same time, see the release announcement.

https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html

Re: Rust 1.46

#56
post #6

I’m learning rust right now and there is a lot to like. Steady updates like this are also very motivating. The ecosystem feels very sane - especially compared to npm. Top notch Wasm support, cross compiling is a breeze. That said, coming from a FP background (mostly Haskell/JS, now TS) Rust is... hard. I do understand the basic rules of the borrow checker, I do conceptually understand lifetimes, but actually using th…

> the borrow checker, I do conceptually understand lifetimes, but actually using them is tricky. I've been using Rust for a little over year, almost daily at work, and for several projects. I have a pretty good intuition about how the borrow checker works and what needs to be done to appease it. That said, I don't think I'm any closer to understanding lifetimes. I know conceptually how they are supposed to work (I ne…

As someone in a similar description as you - i find my lifetime understanding... moderate. Complex lifetime usage still can tweak my brain - notably how i can design it. But simple lifetime usage is intuitive.

A simple example i often run into is wanting to do something with a string, without taking owned parts of the string. Very intuitive how the str matches the lifetime of the owned value.

On the otherhand, the other day i was trying to write a piece of software where:

1. I wanted to deserialize a large tree of JSON nodes. I had the potential to deserialize these nodes without owning the data - since Serde supports lifetimes, i could deserialize strings as strs and hypothetically not allocate a lot of strings.

2. In doing that, because a tree could be infinitely large i couldn't keep all of the nodes together. Nodes could be kept as references, but eventually would need to be GC'd to prevent infinite memory.

3. To do this, i _think_ lifetimes would have to be separate between GC'd instances. Within a GC'd instance, you could keep all the read bytes, and deserialize with refs to those bytes. When a GC took place, you'd convert the remainder partial nodes to owned values (some allocation) to consume the lifetime and restart the process with the owned node as the start of the next GC lifetime. ... or so my plan was.

I have, i think, just enough understanding of lifetimes to _almost_ make that work. I _think_ some allocations would be required due to the GC behavior, but it would still reduce ~90% of allocations in the algorithm.

Unfortunately, i got tired of designing this complex API and just wrote a simple allocation version.

Conceptualizing allocations and the lifetimes to make it work are.. interesting. Especially when there is some data within the lifetime that you want to "break out of" the lifetime, as in my example (where i had a partial node, and i made it owned).

I still think i understand enough to do it - it'll just take a fair bit of thinking and working through the problem.

Re: Rust 1.46

#57
post #45

Earlier quoted context omitted.

Short circuiting introduces conditional branching. If you call a function on the right hand side of a || or && it might or might not be executed depending on the value of the left hand side. Until this version of rust, all conditional branches were banned from const functions. I guess to keep things simple they just banned any feature that might cause branching.

Ahh that makes a lot of sense, if you're going to have a compiler insert the result of a function having conditional branching seems a bit gnarly I guess?

For the history of this feature request, see https://github.com/rust-lang/rust/issues/29608 as a starting point.

Re: Rust 1.46

#58
post #6

I’m learning rust right now and there is a lot to like. Steady updates like this are also very motivating. The ecosystem feels very sane - especially compared to npm. Top notch Wasm support, cross compiling is a breeze. That said, coming from a FP background (mostly Haskell/JS, now TS) Rust is... hard. I do understand the basic rules of the borrow checker, I do conceptually understand lifetimes, but actually using th…

I don't have time for an exhaustive answer, so I'll give you some rules of thumb when using Functional-style combinators: * If you need to keep unchanged the input, you must either use a reference-to (.iter()) or copy-of (.iter().cloned()) of each item * If you don't need the input ever again, you should move the items (.into_iter()) These rules follow for each step of the chain. I very very often write very Function…

I've been using .to_owned() liberally, that often does the trick in the first instance, albeit at the potential cost of a copy.

Re: Rust 1.46

#59
post #15
post #6

I’m learning rust right now and there is a lot to like. Steady updates like this are also very motivating. The ecosystem feels very sane - especially compared to npm. Top notch Wasm support, cross compiling is a breeze. That said, coming from a FP background (mostly Haskell/JS, now TS) Rust is... hard. I do understand the basic rules of the borrow checker, I do conceptually understand lifetimes, but actually using th…

> Anyways, I guess this gets easier over time, right? Yes. > Should I avoid using closures all over the place? Not necessarily. > Should my code look more like C and less like Haskell? Yes. Others sometimes don't like to hear this, but IMO, Rust is not at all functional. Passing functions around is not ergonomic (how many function types does Rust have again? Three?). Even making heavy use of Traits, especially generi…

> how many function types does Rust have again? Three?).

Depending on what you meant, there are more than three:

  * There are 3 traits, used by closures depending on their needs:
    * Fn(Args) -> Output
    * FnMut(Args) -> Output
    * FnOnce(Args) -> Output
  * *Every* `fn` is its own type (`fn() {foo}`)
  * Function pointers (`fn()`), which is how you pass the above around in practice
> Rust is very much procedural.

I think this is like saying Python is very much procedural: true, but loses some nuance. Rust has some attributes of OOP, some attributes of FP. Some constructs from OOP and FP are made harder once you involve borrowing. Saying it is procedural conjures images of Pascal and K&R C in people's minds. To bolster your argument, though, I mostly use method chaining for iterators but every now and then I need to turn it into a `for` loop to keep the lifetimes understandable for the compiler, myself and others.

Re: Rust 1.46

#60
post #6

I’m learning rust right now and there is a lot to like. Steady updates like this are also very motivating. The ecosystem feels very sane - especially compared to npm. Top notch Wasm support, cross compiling is a breeze. That said, coming from a FP background (mostly Haskell/JS, now TS) Rust is... hard. I do understand the basic rules of the borrow checker, I do conceptually understand lifetimes, but actually using th…

This echoes my experience with learning Rust over the past few weeks (coming from Elixir). There is a lot to like, understand lifetimes conceptually, but it's hard.

If you're coming from elixir, and not doing this for work, I highly suggest zig; zig feels like elixir since both have the comptime concept.
Post reply on HN