15 ms·
Rust 1.46
- est31 6y agoThe most exciting component of this release is the const fn improvements. With loops and if available, you can now do non-trivial computation in const fn for the first time. It reduces the gap between Rust's const fn and C++'s constexpr to a large degree. Ultimately, the miri execution engine that this feature builds upon, supports a much larger set of features that even constexpr supports. It's been a project spanning years to get it merged into the compiler, used for const fn evaluation, and stabilize it's features (this part is far from over). In addition to the linked examples, I have some code of my own which is made simpler due to this feature: https://github.com/RustAudio/ogg/commit/b79d65dced32342a5f9313960856114d88d50f4a https://github.com/RustAudio/ogg/commit/b79d65dced32342a5f93... Previously, the table was present as an array literal in C-style, now I can remove it once I decide for the library to require the 1.46 compiler or later versions. Link to the old/current generation code: https://github.com/RustAudio/ogg/blob/master/examples/crc32-table-generate.rs https://github.com/RustAudio/ogg/blob/master/examples/crc32-...
- tines 6y ago> supports a much larger set of features that even constexpr supports This sounds promising. Can you give examples? I don't know Rust at all, and the reason I like C++ is its metaprogrammability.
- tobz1000 6y agoI believe in a talk[1] it was mentioned that Rust's const eval will support heap-allocated values (accessed as references). A quick search suggests that C++20 will also support this, although it may be safer in Rust as it can give a stronger guarantee that the static memory won't be written to. [1]https://youtu.be/wkXNm_qo8aY?t=888 https://youtu.be/wkXNm_qo8aY?t=888
- steveklabnik 6y agoBasically, 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.
- tines 6y agoThat 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?
- steveklabnik 6y agoI 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.
- dodobirdlord 6y agoIt has been a while, and I’m remembering from a discussion of new features in C++20, but I recall that constexpr isn’t capable of fully supporting memory allocations made during evaluation, while Rust’s const fn will eventually be able to.
- kibwen 6y agoI think some clarification is warranted here, because Miri is intended to be used for more than just constant evaluation. In particular, Miri wants to be able to dynamically verify `unsafe` code in order to detect undefined behavior, which means that it will eventually want to support the entire Rust language. However, just because Miri supports any given Rust feature does not necessarily mean that that feature will be made available for constant evaluation; consider features that are non-deterministic (like RNG) or architecture-dependent/nonportable (like floating-point operations), and how const-evaluating such things could potentially cause memory-unsafety to occur when runtime output and const output differ.
- marricks 6y agoI 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?
- Rusky 6y agoThat 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.)
- est31 6y ago> (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 https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html
- phire 6y agoShort 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.
- marricks 6y agoAhh 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?
- kibwen 6y agoFor the history of this feature request, see https://github.com/rust-lang/rust/issues/29608 https://github.com/rust-lang/rust/issues/29608 as a starting point.
- crazypython 6y agoDlang has had CTFE for a long time. The engine just needs to be rewritten to reduce memory usage. https://tour.dlang.org/tour/en/gems/compile-time-function-evaluation-ctfe https://tour.dlang.org/tour/en/gems/compile-time-function-ev...
- thomasahle 6y agoIf anyone wants to know more about const fns, see https://doc.rust-lang.org/reference/items/functions.html#const-functions 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.
- ko27 6y agoNever worked with Rust, but I am pretty sure that having a function be pure is not enough to evaluate it at compile time.
- deleted 6y ago[deleted]
- steveklabnik 6y agoYes, we don't actually use the "pure" terminology for this reason.
- mijamo 6y agoWhy not? By definition the output does not depend on runtime property so you should be able to compute it at compile time right?
- eloff 6y agoPure functions are functions where the return value only depends on the function arguments. If the function arguments are not known at compile time, obviously you can't evaluate it at compile time. It would only be possible to do that when all the arguments are also known at compile time (constants).
- tgb 6y agoBut a const fn can also do that: if given non-constant parameters it will be evaluated at run-time. So I (having never used Rust before) still haven't see the distinction between pure and const. What's an example of a function that is pure but cannot be evaluated at compile time with constant parameters?
- cordite 6y agoThese const fn’s are cool, but won’t this also lead to long compile times down the road?
- Verdex 6y agoYeah, but only if you use them to compute significant items during compilation. The upside of course is that any computation you compute at compile time is a computation that you don't compute at runtime. For some applications this trade off is definitely worth the cost of admission. At the end of the day it's a trade off that will have to be made in light of the scenario it's being used in. Being able to make that decision is a good thing.
- steveklabnik 6y agoYes, any time you move computation to compile time, it makes the compile time take longer. As always it is a tradeoff. One thing that people may not realize, especially now that we have loop. You may expect this to hang the compiler: const fn forever() -> ! { loop { } } static FOO: u32 = forever(); But it won't: error[E0080]: could not evaluate static initializer --> src/lib.rs:2:5 | 2 | / loop { 3 | | 4 | | } | | ^ | | | | |_____exceeded interpreter step limit (see `#[const_eval_limit]`) | inside `forever` at src/lib.rs:2:5 This does place an upper limit on any given const fn.
- LEARAX 6y agoThe quality of life improvements to cargo look very nice, and I feel that rust wouldn't be remotely as successful without such a tool. I'm very glad I won't have to be manually picking target directories out of my borg backups anymore when I'm running out of disk space.
- sfvisser 6y agoI’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 them is tricky. Especially in a combinator world with lots of higher order functions/closures it’s often completely unclear who should own what. It often feels my library/dsl code needs to make ownerships decisions that actually depend on the usage. Anyways, I guess this gets easier over time, right? Should I avoid using closures all over the place? Should my code look more like C and less like Haskell? [edit] great answers all, providing useful context, thanks
- ragnese 6y ago> 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 generic ones, is difficult. Rust is very much procedural. Java-style OOP doesn't work because of the borrowing/ownership. And FP style function composition doesn't work without Boxing everything. But then you'd need to be careful about reference cycles.
- vmchale 6y ago> how many function types does Rust have again? Three? It has to, right? ATS has many function types as well, plus stack-allocated closures (I think Rust has that too??)
- steveklabnik 6y agoRust's closures do not heap allocate unless you box them, like any other struct, because closures are sugar for a struct + a function, that's correct. (and yes, there are three types of closures, because they need to know if they take said struct by reference, by mutable reference, or by owner.)
- scott31 6y agoNote that entire rust team was recently fired from Mozilla, so it is unclear how the future looks like for the language. Especially since it does not have a spec and only have single reference implementation
- adamch 6y agoThe Rust teams discusses their post-Mozilla future here: https://blog.rust-lang.org/2020/08/18/laying-the-foundation-for-rusts-future.html https://blog.rust-lang.org/2020/08/18/laying-the-foundation-... TLDR: they're feeling pretty good.
- AsyncAwait 6y agoThey're moving to a Rust Foundation with corporate sponsorship model. I think Rust will be fine, even Amazon expressed interest in sponsoring development.
- Verdex 6y agoHear 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 waiting for someone to swoop in and buy them for fire sale prices.
- hu3 6y agoWhat'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.
- steveklabnik 6y agoIt'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.
- kumarvvr 6y agoSo, I want to learn Rust. I am a C# / Python programmer, experienced. Are there any particular set of problems that I can solve systematically, so that I can learn all the features of Rust?
- xvedejas 6y agoTrying to implement anything in Rust will set you up for a crash-course. Even the simplest non-trivial programs will introduce you to the Rust borrow checker, a major feature absent in C# / Python.
- steveklabnik 6y agohttps://doc.rust-lang.org/stable/book/ https://doc.rust-lang.org/stable/book/ is not purely problems, but does have some problem chapters. (I am a co-author.) https://doc.rust-lang.org/stable/rust-by-example/ https://doc.rust-lang.org/stable/rust-by-example/ is the "by example" introduction, which is all about sample programs, but feels a bit dated, IMHO. Still not incorrect, but not up-to-date. You may also like the O'Reilly book, or Rust In Action, which use more fully-featured example programs more heavily than The Book does.
- jxcl 6y agoI was super impressed by the O’Reilly book, which throws you right in to writing a multithreaded Mandelbrot set plotter. It also goes through writing a multithreaded HTTP server. Pretty neat!
- somurzakov 6y agotry to write ETL in rust
- adamnemecek 6y agoTry to do some graphics programing with thr backend of your choice. There is also this cool nanovg port https://github.com/cytecbg/gpucanvas https://github.com/cytecbg/gpucanvas. Run the demo in examples to see the nanovg demo.
- deleted 6y ago
- orthecreedence 6y agoAwesome! Any idea when relative links will be available in rustdoc? Seems like it's just on the edge of stabilizing (https://github.com/rust-lang/rust/pull/74430 https://github.com/rust-lang/rust/pull/74430) but I'm curious how long it takes to see in a release after this happens.
- steveklabnik 6y agoThere can be fuzziness here depending on exactly when it lands, but generally, if something lands in nightly, it'll be in stable two releases after the current stable.
- kevinastone 6y agoGlad to see `Option::zip` stabilized. I tend to write such a helper in many of my projects to collect optional variables together when they're coupled. Really improves the ergonomics doing more railroad-style programming.
- borgel 6y agoDo you have an example? I'm having trouble understanding how zip would be used in practice.
- Arnavion 6y agoYou sometimes have two Options that must both be Some to have any effect, but other reasons prevent you from making an Option of a tuple of those two fields. Eg think of deserializing a JSON that contains optional username and password strings, but you need both if you are to use them to authenticate to some remote. In that case, you currently have to write code like: if let (Some(username), Some(password)) = (username, password) { /* both are set */ } else { /* at least one is not set */ } With zip this can be written as `if let Some((username, password)) = username.zip(password) {` In this case it doesn't look like a big difference, but it does allow you to chain other Option combinators more easily if you were doing that instead of writing if-let / match. Using combinators is the "railroad-style programming" that kevinastone was talking about. For example, you can more easily write: let (username, password) = username.zip(password).ok_or("one or more required parameters is missing")?; You could of course still do this without .zip(), but it would be clunkier: let (username, password) = username.and_then(|username| password.map(|password| (username, password))).ok_or("one or more required parameters is missing")?; The zip form does lose the information of which of the two original Options was None, so if you do need that information (say the error message needs to specify which parameter is missing) you'd still use the non-zip form with a match.
- Matthias247 6y agoThe zip solution however requires any reviewer to look up on what it actually does, whereas the "if let" is more of a language fundamental and known to most reviewers. Therefore I would actually prefer the long/verbose form without the zip.
- echelon 6y ago`const fn` improvements are amazing! I can't wait for when we'll be able to `const fn` all the things. Regex, expensive constants that feel as though they should be literals, etc.
- djhworld 6y agoIs there a resource that explains what const functions are and why you would use them?
- steveklabnik 6y agohttps://doc.rust-lang.org/edition-guide/rust-next/const-fn.html https://doc.rust-lang.org/edition-guide/rust-next/const-fn.h...
- fmakunbound 6y ago> if, if let, and match > while, while let, and loop > the && and || operators Common Lisp user here. Why just that? How come you can’t have the entire language as well as all your language customizations available at compile time for evaluation?
- pthariensflame 6y agoYou can! Just not through `const fn`. Rust has macros, which at their limit are capable of running arbitrary Rust code that manipulates syntax and communicates with the compilation process, just like in a good old Lisp. Why isn’t `const fn` like this too? One word answer: determinism. Rust takes type/memory/access/temporal safety very seriously, and consequentially you can’t use anything in a `const fn` that isn’t fully deterministic and doesn’t depend in any way on platform-specific behavior. This includes, for example, any floating-point computation, or any random number generation, or any form of I/O, or handling file paths in an OS-specific way, or certain kinds of memory allocation. The span of things possible in `const fn`s has been expanding over time, and will in the nearish future largely overtake C++’s direct counterpart of it (`constexpr` functions) in capability. But some things will intentionally never be possible in `const fn`s, for the reasons given above.
- daitangio 6y agoCan Mozilla layoffs (on Servo team) impact Rust future? It is just s question to understand if there are others big rust project healty out of there. Just curious
- steveklabnik 6y agohttps://blog.rust-lang.org/2020/08/18/laying-the-foundation-for-rusts-future.html https://blog.rust-lang.org/2020/08/18/laying-the-foundation-...