[HN Gopher] Rust 1.63
       ___________________________________________________________________
        
       Rust 1.63
        
       Author : todsacerdoti
       Score  : 270 points
       Date   : 2022-08-11 15:03 UTC (7 hours ago)
        
 (HTM) web link (blog.rust-lang.org)
 (TXT) w3m dump (blog.rust-lang.org)
        
       | baby wrote:
       | so const Mutex means you can do this IIUC:
       | const THING: Mutex<u64> = Mutex::new(4);
       | 
       | without using the once_cell crate. This is pretty cool! Also I
       | realize that the Rust playground is still using 1.62.0
       | 
       | https://play.rust-lang.org/?version=beta&mode=debug&edition=...
        
         | shepmaster wrote:
         | Wouldn't you want to use static instead of const, otherwise you
         | might get a new unique mutex at each usage? I think there's a
         | Clippy lint for that.
         | 
         | The playground rebuilds overnight (roughly after the nightly is
         | released); releases don't have as fixed timing so I tend to
         | trigger a rebuild when I notice. This HN post was delivered
         | before the git tag was published even, so I've started it.
         | 
         | Playground is updated now.
        
           | tialaramex wrote:
           | Yes. If I say FOUR is a const Mutex with a 4 in it, whenever
           | I talk about FOUR I get a completely new unlocked Mutex with
           | a 4 in it, unrelated to any other Mutex regardless of whether
           | it was made the same way.
           | 
           | This might be what you want if you, for some reason, need to
           | make different Mutexes with a 4 in them all the time. But, if
           | you actually meant one Mutex, which intially has a 4 in it,
           | then that's a static variable not a constant.
           | 
           | https://play.rust-
           | lang.org/?version=beta&mode=debug&edition=...
           | 
           | Change FOUR to be static instead of const, and now when we
           | print y each time it's gone up by ten because we're using the
           | same Mutex which is what we presumably intended.
        
             | baby wrote:
             | What's the difference between CONST and STATIC
             | fundamentally?
        
               | CryZe wrote:
               | If those terms mean anything to you: const is an rvalue,
               | static is an lvalue.
        
               | notpopcorn wrote:
               | A const is like a `#define` in C or C++, while a static
               | is a global variable.
        
       | aendruk wrote:
       | It's a small thing, but array::from_fn makes me happy.
        
         | brundolf wrote:
         | Something I can't figure out is how it infers the length in
         | this example:                 let array =
         | core::array::from_fn(|i| i);       assert_eq!(array, [0, 1, 2,
         | 3, 4]);
         | 
         | Is it because of the assert_eq? Can it use the length of the
         | second argument to infer the length all the way back up in the
         | from_fn call?
        
           | aendruk wrote:
           | Yep, you could change the asserted length and it would
           | succeed:                 assert_eq!(array, [0, 1, 2]);
           | 
           | If you tried both--                 assert_eq!(array, [0, 1,
           | 2]);       assert_eq!(array, [0, 1, 2, 3, 4]);
           | 
           | --the assertions would never run because it wouldn't even
           | compile:                 error[E0277]: can't compare `[usize;
           | 3]` with `[{integer}; 5]`
        
           | dymk wrote:
           | Yes, it's inferring that `array` must be an `[i32; 5]`
           | because there exists an impl of `PartialEq` for `[T; N]`
           | against another `[T; N]`, so `N` in `::from_fn` must be 5.
        
             | sophacles wrote:
             | nit: wouldn't it be usize since the only way to get T is
             | from the bare numbers which default to usize?
        
               | [deleted]
        
               | steveklabnik wrote:
               | "bare numbers" don't default to usize; integers default
               | to i32 and floats to f64.
        
               | orlp wrote:
               | In this case the "bare numbers" do get inferred to be
               | usize due to the signature of from_fn.
        
               | steveklabnik wrote:
               | Yes, I realize that I may have read these words slightly
               | differently than the parent meant them! I just said the
               | same thing in a reply to your sibling.
        
               | aendruk wrote:
               | It does seem to be choosing [usize; 5] in this case
               | though.
               | 
               | https://rust.godbolt.org/z/qasxnrTf9
        
               | steveklabnik wrote:
               | Yes, that is true. If you use a literal array, you get
               | i32 for the element type.
               | 
               | I _believe_ this is because of the signature:
               | pub fn from_fn<T, const N: usize, F>(cb: F) -> [T; N]
               | where           F: FnMut(usize) -> T,
               | 
               | While T is unconstrained, N is a usize, which is used in
               | the closure, which we then re-use as the element.
        
               | sophacles wrote:
               | OK this is just kinda funny - I was right, but only by
               | accident. For some reason I thought that the literal
               | defaulted to usize not i32. The fact that this path makes
               | my assertion of usize correct is pretty cool though.
               | Thanks for diving into it!
        
             | orlp wrote:
             | Sorry but the typing part is incorrect. Look at the
             | signature of from_fn:                   pub fn from_fn<T,
             | const N: usize, F>(cb: F) -> [T; N]          where
             | F: FnMut(usize) -> T,
             | 
             | It takes a function with signature f(usize) -> T. So |i| i
             | gets inferred to be a function taking a usize, and
             | returning a usize (since we just give the argument straight
             | back). So it infers [usize; 5] in the end.
             | 
             | For example core::array::from_fn(|i| i) == [0i32] wouldn't
             | even compile.
        
               | wongarsu wrote:
               | You are right. The parameter given to the closure is the
               | array index, which is usize. Since that's returned
               | straight back the returned value is also of type usize,
               | and the integers in the array in the assert are inferred
               | to also be usize.
               | 
               | Which is in a way an even stronger showcase of Rust's
               | type inference: the length of the variable is inferred
               | from the constant array, but the type of the content of
               | the constant array is inferred by the type of the content
               | of the variable, which is inferred from the type of the
               | closure.
        
               | dymk wrote:
               | Good catch. The parent comment is interested in how the
               | array length is inferred though, so I'm going to consider
               | the explanation close enough (that it's an i32 or usize
               | isn't particularly relevant).
        
             | zerr wrote:
             | What's a sane/legit use case of such inferring in general?
        
               | game-of-throws wrote:
               | let numbers = [0, 1, 2];       let doubled =
               | numbers.map(|x| x * 2);
               | 
               | You wouldn't want to have to explicitly type out the
               | length of the second array.
        
               | tomjakubowski wrote:
               | That isn't really inferring the size of the array though.
               | [T; N]::map(impl FnMut(T) -> U) defines its return type
               | as [U; N]. N is fixed at the original array literal.
               | 
               | https://doc.rust-lang.org/std/primitive.array.html
        
               | brundolf wrote:
               | It's inferring it from the array literal in the first
               | place, but it is a different kind of inference from the
               | original one. But I think that's what the question was
               | asking for:
               | 
               | > What's a sane/legit use case of such inferring in
               | general?
               | 
               | Depends how you interpret "such inferring"
        
               | dymk wrote:
               | It's inferring the size of `doubled`
        
               | [deleted]
        
               | PoignardAzur wrote:
               | A few use cases:                   let foobar =
               | Default::default();         do_something_with(foobar); //
               | where do_something_with takes a FooBar param
               | 
               | One I often use in unit tests:                   fn
               | generate_ids<const N: usize>() -> [Id; N] { ... }
               | let [id_button, id_label, id_thing, id_other_thing] =
               | generate_ids();
               | 
               | (before const generics were stabilized, the above code
               | instead had multiple utility functions, eg
               | generate_2_ids, generate_3_ids, etc)
        
               | brundolf wrote:
               | I think the one here is legit (perhaps more realistic
               | would be where you're passing the new array to an actual
               | function that requires a certain array length).
               | 
               | People always complain about Rust's type system being
               | verbose- well, this makes it less verbose. It knows what
               | you need from the function call, so it doesn't make you
               | say it. And as an added benefit, if the required type
               | ever changes in a way that can still be generated by the
               | provided code (eg. the function you're passing to needs a
               | different length), you won't need to update any explicit
               | type annotations at the call-site.
               | 
               | If that's ever undesirable - you want to be very precise
               | about your code - well, then you can do that too by
               | specifying the generic parameters explicitly.
        
               | kibwen wrote:
               | It's not anything specific to arrays, it's just how type
               | inference works. Here's another example:
               | let mut x = HashMap::new();         x.insert(1, 2);
               | 
               | Note that nowhere did we need to specify the concrete
               | type of the HashMap; the compiler sees that you
               | eventually insert numbers into the map so it uses that
               | information to fill in the generic type parameters for
               | the key and value.
        
               | Ar-Curunir wrote:
               | You general type inference, or inferring the array
               | length? The latter follows from the former, so it would
               | be kind of a weird hole in the language if type inference
               | worked everywhere except array lengths.
        
               | zerr wrote:
               | "Scattered through multiple lines" inference :) Such code
               | makes another programmer analyze multiple lines to deduce
               | types in the head.
        
               | brundolf wrote:
               | In practice, type inference works best when paired with
               | editor integration. Most languages/editors will give you
               | hover-overs with inferred types, but some like rust-
               | analyzer have started going further (the greyed-out text
               | here is all inlaid by the editor): https://user-
               | images.githubusercontent.com/3971413/96668192-1...
        
               | dymk wrote:
               | The tooling ecosystem, for instance rust-analyzer, make
               | this not an issue if you're reading the code in an
               | environment that supports it. I have rust-analyzer to
               | display inferred types when I hold `control+command`.
               | 
               | In other languages, this can be a brittle/expensive
               | operation due to meh tooling. But with Rust, it tends to
               | "just work".
               | 
               | Online viewers of source e.g. Github and such don't have
               | all this information exposed yet, but they're
               | incrementally getting there. For instance, "go to
               | definition" works for Rust code in Github.
               | 
               | One could imagine a generic file format included as an
               | artifact in source control, that online viewers could
               | consume, to annotate spans of source code. Go to
               | definition, show expanded type, etc.
        
             | brundolf wrote:
             | That rocks
        
         | svnpenn wrote:
         | Why does it arbitrarily choose length 5?
         | 
         | https://doc.rust-lang.org/core/array/fn.from_fn.html
        
           | aendruk wrote:
           | In that example N is inferred from the assertion; observing
           | the output has affected it.
        
             | svnpenn wrote:
             | Wow that is stupid. That is way too much assumption.
        
               | sophacles wrote:
               | Exactly 0 assumptions are made - how is that too much?
        
               | surewe wrote:
               | Sure, it's a lot of assumption, but the type system would
               | prevent an invalid assumption from compiling (arrays are
               | typed [T; N] where T is the type they hold and N is the
               | number of elements), and you can always override it with
               | a turbofish.
        
               | dymk wrote:
               | https://en.wikipedia.org/wiki/Hindley%E2%80%93Milner_type
               | _sy...
               | 
               | It's a dream once you understand it. You don't need to
               | understand the math, just the general concept of type
               | unification, and that type inference can flow in "both
               | directions", as opposed to in e.g. C++ where `auto`
               | inference only works in one direction.
               | 
               | Rust is not exactly HM type inference, but it's something
               | close to it. http://smallcultfollowing.com/babysteps/blog
               | /2014/07/09/an-e...
        
               | chrismorgan wrote:
               | No, it's just the right amount, and makes perfect sense.
               | This is the whole point of type inference: where there
               | are multiple possibilities, determine types based on how
               | you use them, and if you still have ambiguity after that,
               | complain.
               | 
               | If you tried comparing it to something that wasn't an
               | array, or if you tried comparing it to multiple
               | different-sized arrays, it would complain.
        
           | shepmaster wrote:
           | Is likely based on what you compare it to. For example, this
           | passes as well                   let array =
           | core::array::from_fn(|i| i);         assert_eq!(array, [0, 1,
           | 2, 3, 4, 5]);
           | 
           | The magic of type inference
        
       | ydnaclementine wrote:
       | What is everyone building in rust, and how do the killer rust
       | features (mentioned in other comments) help you?
       | 
       | I'm not anti rust in any way, it's more of having limited time
       | and so many languages problem. But I'm interested in the types of
       | problems rust is good for, so I could consider it if/when I
       | encounter them
        
         | pjmlp wrote:
         | Only hobby coding.
         | 
         | Java, .NET languages and C++ are what pay the bills for me.
        
         | gattr wrote:
         | I wrote a video acquisition tool for astrophotography [1] (and
         | I dogfood it). Uses GTK3 for GUI.
         | 
         | [1] https://github.com/GreatAttractor/vidoxide
        
         | ostenning wrote:
         | I'm building commercial hardware products using embedded Rust,
         | I love it. I cant really imagine going back to C. I haven't dug
         | too deep into the offerings with this update, but none of the
         | standard library stuff is relevant for me
        
         | dymk wrote:
         | I've written no code professionally in Rust, but a fair amount
         | of personal project code. I've written C++ both professionally
         | and as a hobby. At least for hobby use, comparing the two, Rust
         | is wonderful.
         | 
         | - It's easy to set up cross compilation.
         | 
         | - Cargo makes dependencies easy.
         | 
         | - Building is almost always just `cargo build` except for very
         | exceptional projects, same with `cargo test`.
         | 
         | - `cargo fmt` makes formatting easy and built in.
         | 
         | - Clippy gives actually useful lints and can automate most
         | refactorings.
         | 
         | - Rust-analyzer is fast to index decently large projects, works
         | with almost all language features (even complex ones like proc
         | macros), and has some real time-saver automation built in.
         | 
         | Working with the borrow checker can feel like a pain, but in
         | many cases, feels like a fun puzzle (writing hobby code, I'm
         | not under time pressure, so it's 'solve a puzzle' and not 'oh
         | fuck deadline coming up').
         | 
         | But really, the tooling of the language is where it shines.
        
         | CJefferson wrote:
         | Personally, I use Rust as a "better C++".
         | 
         | Ways in which it is better:
         | 
         | * A decent package manager
         | 
         | * "Safe by default" (you have to use 'unsafe' to turn off the
         | safety features), unlike C++ which is "unsafe by default" (v[i]
         | is undefined behaviour if i is out of bounds, for all of C
         | arrays, std::arrays and std::vectors).
         | 
         | * Really easy to do multithreading -- I had reached the point
         | with C and C++ where I was of the opinion it is "almost
         | impossible" to write large thread-safe programs, and all
         | communication should be between processes with pipes, wherever
         | reasonable. In Rust I again feel I can safely and productively
         | write multi-threaded code.
         | 
         | The things Rust doesn't let you do (throw pointers around
         | everywhere) can get a little annoying, but I find the extra
         | safety increases my productivity enough that it's worth the
         | tradeoff.
        
           | tialaramex wrote:
           | You didn't say otherwise, but this is such a frequent
           | misunderstanding from people who don't write Rust, or write
           | only safe Rust (which is fine) that it's worth pointing out
           | the unsafe keyword and Rust's choice to be "safe by default"
           | are not directly related. Culturally obviously they come from
           | the same place, but for example:
           | 
           | v[i] is bounds checked in Rust _even in unsafe_. The unsafe
           | "super powers" don't include "magically now indexing has no
           | bounds checks" but because Rust's get function
           | v.get_unchecked(i) is marked unsafe++ you would need to mark
           | code unsafe to use that function and _that_ function doesn 't
           | have bounds checks.
           | 
           | If you write:                 unsafe {
           | println!("{}", v[i]);       }
           | 
           | The compiler will point out that unsafe isn't doing anything
           | for you here, v[i] is safe, marking it unsafe is just a waste
           | of everybody's time.
           | 
           | C++ doesn't have bounds checked array access for its
           | abandoned built-in arrays, but it does (these days) have
           | bounds checked access for std::array and std::vector as a
           | separate member function, however because they aren't the
           | default few C++ programmers use them even where they
           | undoubtedly should. This is an ergonomics issue, it's just
           | easier to write needlessly unsafe C++.
           | 
           | ++ This said just get() before I edited it, but Steve
           | corrected me, see below.
        
             | steveklabnik wrote:
             | Teeeny tiny note
             | 
             | > because Rust's get function v.get(i) is marked unsafe
             | 
             | You mean get_unchecked. get is safe, and returns an Option,
             | so that None can be returned if something is out of bounds.
        
               | tialaramex wrote:
               | Doh! I even had the "get_unchecked()" function in front
               | of me on the screen and wrote get() anyway. Thanks Steve.
        
               | steveklabnik wrote:
               | No problem. Thanks for explaining what unsafe does and
               | doesn't do; you're 100% right that this is a common
               | misconception that comes up often.
        
             | CJefferson wrote:
             | You are right, I did know this but it's worth clarifying.
             | Thanks.
        
           | dralley wrote:
           | >(you have to use 'unsafe' to turn off the safety features)
           | 
           | "unsafe" doesn't turn off any safety features, it just allows
           | you to do additional things which the base language does not,
           | like:
           | 
           | * use raw pointers
           | 
           | * use mutable static globals
           | 
           | * access fields of unions
           | 
           | https://doc.rust-lang.org/book/ch19-01-unsafe-
           | rust.html#unsa...
           | 
           | All the rules of safe Rust still apply inside of unsafe
           | blocks. The borrow checker still works, etc.
        
         | shpongled wrote:
         | I'm building scientific software in Rust.
         | 
         | Phenomenal performance, drop-in concurrency support (`iter()`
         | -> `par_iter()` with Rayon), and a great ML-based type system
         | that makes writing correct code easy.
         | 
         | It also has some of the best developer UX/tooling out of any
         | language I've used.
        
         | nynx wrote:
         | I've written a bunch of embedded software in rust.
        
         | pornel wrote:
         | Cloudflare is using Rust for network stacks, proxies, caches,
         | compression, and image processing. Basically everything that
         | you would use C or C++ for, but where security is also
         | incredibly important.
        
         | kibwen wrote:
         | I work on a project that's basically a mini-OS designed to host
         | WebAssembly applications.
         | 
         | The OS parts need to run on bare metal and do all sorts of
         | cursed shenanigans, where Rust's separation of safe and unsafe
         | code lets us better focus on proving to ourselves that the
         | unsafe bits are working as intended (we also test our unsafe
         | code under Rust's Miri interpreter/sanitizer for extra
         | confidence). IOW, the killer feature is low-level control plus
         | a reasonable expectation of safety.
         | 
         | The actual WebAssembly interpreter is also written in Rust,
         | which is a good fit because inefficiency in an interpreter
         | leads to inefficiency in anything running in the interpreter.
         | The killer feature here is performance plus safety.
         | 
         | The overall package is bundled up into a CLI app that lets you
         | deploy an instance of our OS with your application running
         | within. Rust has a fairly nice wealth of libraries that make
         | this pleasant, from CLI argument parsers to cryptography to
         | OIDC and beyond. And it all gets packaged up into a single
         | binary for easy distribution (even the OS and interpreter
         | parts, which get embedded directly in the binary via
         | `include_bytes!`). The killer feature here is great platform
         | support (including cross-compilation) and small binaries
         | (though you may reasonably disagree on "small"; altogether the
         | binary (again, including the OS and interpreter) comes out to
         | 25 MB).
         | 
         | Finally, Rust's lack of a pervasive runtime and great
         | WebAssembly tooling means that it's easy to compile Rust
         | applications to run on top of all this as well.
        
           | cultureulterior wrote:
           | This OS seems interesting! Link?
        
             | kibwen wrote:
             | Keep in mind that I'm using "OS" here loosely; it's a bare-
             | metal program that exposes a subset of Linux syscalls so
             | that the interpreter (which itself is compiled for Linux)
             | can run in the extremely specific context that we target.
             | It's still early days so I won't spend too much time
             | shilling it, but all the code is open source and lives
             | under the umbrella of the Linux Foundation:
             | https://enarx.dev/
        
         | cliffcrosland wrote:
         | We are using Rust to build a fast log event database. The
         | workload includes a lot of asynchronous networking I/O and
         | parallelized CPU-intensive work, like indexing and SIMD-
         | accelerated string search. There are great libraries for what
         | we need. The performance and low memory footprint are quite
         | useful.
        
         | Hamuko wrote:
         | I've written a small automatic file organiser in Rust that I
         | run in a Docker container on my NAS. Docker reports that the
         | container is using 1.5 MiB of memory, so that's pretty nice.
         | Pretty sure I wouldn't have achieved that if I wrote it in
         | Python like I normally do.
        
         | jackmott42 wrote:
         | I've done some hobby projects in Rust. One was a SIMD
         | abstraction library, where you could write code that looks more
         | or less like SIMD intrinsics, but it would either at compile
         | time or runtime select the SIMD instruction set for the target
         | cpu.
         | 
         | The traits/generics/macro system made that feasible, though
         | messy. You can do similar things with templates in C++
        
         | ekidd wrote:
         | I've built a fair amount of production software in Rust. The
         | best features are:
         | 
         | - Rust is naturally pretty fast, on the rough order of C++ in
         | many cases. Even unoptimized programs tend to be very snappy
         | (as long as you remember to compile in release mode and buffer
         | I/O).
         | 
         | - Rust tends to warn me if I make a dumb mistake, rather than
         | having my program mysteriously corrupt memory at run-time.
         | 
         | - Rust has very nice support for portable CLI applications,
         | both in the standard library and in third-party libraries.
         | 
         | - With a bit of extra work, I can usually deliver a single,
         | statically-linked Linux binary. Go is even better at this, but
         | Rust does it well.
         | 
         | - It turns out the "algebraic data types", what Rust calls
         | "enum" and "match", are just a really nice way to write down
         | every possible "case" or "state" of some value. If a piece of
         | software involves hundreds of special cases, Rust allows me to
         | think about them clearly.
         | 
         | - Rust has surprisingly good third-party libraries for many
         | things. (Not everything.)
         | 
         | - Multithreaded Rust apps are a dream.
         | 
         | Cons:
         | 
         | - Rust forces me to keep track of whether things live on the
         | heap or the stack, whether I'm passing them by value or
         | reference, and so on. This is good when I want performance, but
         | for other kinds of code, it's just a "cognitive tax."
         | 
         | - Rust's learning curve is higher than Go, but arguably lower
         | than C++. This is especially true if you've either never worked
         | with stack/heap/pointers before.
         | 
         | - Rust tends to favor "mostly functional" architectures over
         | "mutable objet soup" architectures. This pushes you to use
         | less-familiar designs for games and GUI libraries, for example.
        
           | wiseowise wrote:
           | > Rust tends to favor "mostly functional" architectures over
           | "mutable objet soup" architectures. This pushes you to use
           | less-familiar designs for games and GUI libraries, for
           | example.
           | 
           | How is that a con?
        
             | ikawe wrote:
             | One example would be the lack of pragmatic rust native GUI
             | libraries. There are wrappers for GTK and Qt, which are
             | probably your best option.
             | 
             | The most popular pure rust ones are based on somewhat
             | esoteric patterns and seem prone to being abandoned.
             | 
             | Within that there are some interesting options, like for
             | functionally reactive programming and immediate mode guis,
             | but these paradigms aren't all encompassing and in fact
             | cover a pretty minority use case based on what GUIs are
             | being created today.
             | 
             | Maybe one day we'll all only ever create purely functional
             | GUIs and speak Esperanto, but until then, we're a little
             | hamstrung in rust.
        
               | game-of-throws wrote:
               | I think that's more a function of the newness of the
               | language than anything else. Golang is (I say this as a
               | Rust developer) more popular, has been around longer, yet
               | still has the same dearth of GUI libs.
        
             | oconnor663 wrote:
             | It's a big piece of the learning curve, and one that
             | usually only shows up when you try to write larger
             | programs. Plus there's very little the compiler can do to
             | point you in the right direction when your object soup
             | needs major refactoring. From what I've seen, a lot of
             | folks either give up on Rust or start writing blatantly
             | unsound unsafe code when they hit this.
             | 
             | On the upside, a lot of C++ game programming uses an ECS-
             | style architecture, which does work well in Rust.
        
           | iopq wrote:
           | When I tried to be more functional, it was really awkward in
           | Rust
           | 
           | I wanted to write some helper functions that applied an
           | argument to a closure and I got this code
           | fn apply<A, B, C, G>(mut f: impl FnMut(B) -> G, a: A) -> impl
           | FnMut(&B) -> C         // must still be `for<'r> impl
           | FnMut(&'r B) -> C`, because that's what filter requires
           | where         G: FnMut(A) -> C,         B: Copy, // for
           | dereferencing         A: Clone,         {             move
           | |b| f(*b)(a.clone()) // this must do any bridging necessary
           | to satisfy the requirements         }
           | 
           | needless to say, Rust doesn't do automatic currying or any
           | advanced functional language tricks so it's just painful to
           | write the same type of code
        
         | teknopurge wrote:
         | security. I dabble with system programs and it's nice to get
         | the speed/portability of native optimized code and know most
         | memory issues won't occur.
        
         | di4na wrote:
         | NIFs for particular casting of numbers to other binary formats
         | in erlang. NIFS for embedded database and data format in
         | erlang.
         | 
         | Main reason ? It works. The compiler has real error messages
         | that are helpful making the onboarding of anyone having to fix
         | problems a far far better situation than any of the
         | competitors. It has a proper modern toolchain.
         | 
         | All of these would be killer features. All together ? No
         | competition.
         | 
         | I also write cli tool and all kind of parsers for embedded
         | language. The libraries here, in particular if you want good
         | error messages and UX, are simply the best in all other
         | environment i know of.
        
         | allisdust wrote:
         | I use it to write backend web services. Some how it doesn't
         | appear to be any less productive than typescript +nodejs
         | combination. Library support used to be a mess but now a lot of
         | good libraries exist to get the job done.
        
         | bsnnkv wrote:
         | I've built the most popular[1] actively maintained tiling
         | window manager for Windows that is available today.[2]
         | 
         | It would have been impossible for me to build this in any other
         | language. I knew absolutely 0 about developing for Windows when
         | I started this, but I quickly realized that the Win32 API is a
         | very old beast with a lot of footguns that Rust saves me from
         | on a daily basis.
         | 
         | On top of that, with parking_lot I can quickly and easily
         | detect incredibly rare instances of deadlocks, and in general
         | have to worry very little about concurrency. All of this allows
         | me to stop worrying about the noise and focus on the real work
         | of how the window manager should behave.
         | 
         | 1. Based on Github Stars
         | 
         | 2. https://github.com/LGUG2Z/komorebi
        
         | Macha wrote:
         | Rust has replaced Python for me in my personal CLI tools where
         | I expect to use them as an ongoing basis. At this stage I am
         | almost as fast writing Rust as Python, find the Rust projects
         | much easier in terms of environment setup than the whole
         | pipenv/poetry/pyenv world, and enjoy the instant response of
         | not having to wait for a python interpreter startup.
         | 
         | I also have some side projects like a gameboy emulator, where
         | it's nice to have what is effectively a lower level language
         | with the safety and features of higher level language.
         | 
         | My day job is mostly Java/Javascript though, rewriting the
         | world isn't yet worth it, but there's certainly one or two of
         | our systems where if a rewrite in another language was on the
         | table I'd make the case for Rust
        
           | Scarbutt wrote:
           | _At this stage I am almost as fast writing Rust as Python_
           | 
           | By generously use of copying?
        
             | oconnor663 wrote:
             | The "One Simple Trick" that lets you port most Python code
             | straight to Rust is to take all the aliasing "object soup"
             | references that Rust doesn't like, shove those objects in a
             | Vec or a HashMap, and use indexes/keys instead of Rust
             | references. This does require plumbing the Vec/HashMap
             | around through different functions, but if you do it this
             | way from the beginning it's not much extra work.
        
         | kylebarron wrote:
         | I'm building WebAssembly bindings to existing Rust libraries
         | [0] and lower-dependency geospatial tools [1]. Rust makes it
         | very easy to bind rust code to both WebAssembly and Python. And
         | by avoiding some large C geospatial dependencies we can get
         | reliable performance in both wasm and Python using the exact
         | same codebase.
         | 
         | [0]: https://github.com/kylebarron/parquet-wasm
         | 
         | [1]: https://github.com/kylebarron/geopolars
        
           | theptip wrote:
           | Oh, that's really cool. Rust noob here, and I hadn't seen the
           | tooling for building Python bindings. That looks like it
           | could be a very powerful way to speed up your Python programs
           | (much easier than the "just replace the slow bits in C"
           | advice that was standard.)
           | 
           | The mappings in
           | https://github.com/kylebarron/geopolars/blob/master/py-
           | geopo... for example look very easy to follow.
        
         | solar-ice wrote:
         | I write video streaming software in Rust. Rust helps us make
         | sure we've got concurrency correct, has a very solid type
         | system to help us make sure we've got general application
         | properties correct, and seriously reduces the space where we
         | have to go looking for segfaults and suchlike (primarily third-
         | party C libraries and bindings to them).
        
         | __david__ wrote:
         | For me the killer feature of Rust is its nice broad scope. I've
         | done:
         | 
         | - embedded programs on avr hardware, which is impressive that
         | something like rust can compile down to an 8 bit micro. Doing
         | some sort of crazy map/iterator filter closures and finding the
         | resulting assembly being nice and tight makes me super happy.
         | 
         | - web servers and clients (a scraper that collects scores from
         | a web page and serves its own page of aggregated scores to my
         | family).
         | 
         | - a low level opengl tmux/terminal client (Rust's Enums were a
         | killer feature here)
         | 
         | - a windows GUI program for installing a PC game mod (99%
         | developed on a mac and cross-compiled)
         | 
         | - a cli app to "compile" svgs down to png sprites for a web
         | based game
         | 
         | - a launcher for Emacs that uses native cocoa apis to display a
         | dialog on error
         | 
         | Each of these cases ended up pushing different parts of Rust
         | for me. I would say the killer feature that spans all of those
         | is Cargo and the crates.io registry. There are a ton of very
         | good libraries out there--it feels like the heyday of CPAN or
         | RubyGems to me.
         | 
         | I also quite enjoy how many programming errors Rust finds at
         | compile time. With Rust code I spend _way_ more time fixing
         | compiler errors, but when it compiles I typically don 't find a
         | ton of major logic errors. I personally find it extremely
         | rewarding when I get something to compile and then it just
         | works. This happens more in Rust than in other languages I've
         | heavily used.
        
         | emadda wrote:
         | https://table.dog (a CLI to download Stripe to SQLite).
         | 
         | I considered Node.js, C#.
         | 
         | I went with Rust for a few reasons:
         | 
         | - Easy to build small portable binaries (as a primary language
         | feature).
         | 
         | - The type checker ensures type consistency when writing out to
         | SQL tables (SQLite is loosely typed). Code that reads from the
         | SQLite database implicitly benefits from Rusts strong type
         | checks.
         | 
         | - Macros to convert structs to SQL insert/updates.
         | 
         | - Reduce the chance of errors at runtime.
         | 
         | - Leverage as much as SQLite's write throughput as possible.
         | 
         | - When converting Stripes Open API JSON spec into Rust code
         | (using another Node.js program), the Rust type checker ensures
         | I have a well formed HTTP client - the strict compiler makes it
         | a good target for generated programs. Read more about this idea
         | at (https://willcrichton.net/notes/rust-the-new-llvm/).
        
         | huyage wrote:
         | I'm building an HTTP CRUD app on top of PostgreSQL. I have
         | previously used Go for various CRUD apps. The experience is
         | better except for compile time. My favorites:
         | 
         | 1. Much more expressive type system: no more `interface{}`.
         | 
         | 2. Algebraic data type with `enum`. Exhaustive check.
         | 
         | 3. `serde` crate is lightyears ahead of Go's `json:"wtf"`.
         | 
         | 4. Compile-time checks against DB with `sqlx` crate.
         | 
         | 5. Logging is a breeze with `tracing::instrument`.
         | 
         | 6. Using macros to reduce boilerplate has better UX than Go
         | codegen.
         | 
         | What these give me is more confidence in
         | development/refactoring because the compiler can guide me most
         | of the way.
         | 
         | Low lights:
         | 
         | 1. Build time.
         | 
         | 2. Async is still clunky. e.g. Try to implement an `actix-web`
         | extractor or middleware.
         | 
         | 3. Please just stablize nightly rustfmt features already.
        
           | mjb8086 wrote:
           | I'm looking to do a bit of CRUD on top of PostgreSQL as well.
           | Currently mid-way through learning the language.
           | 
           | Would you mind sharing some of your experiences? Do you find
           | the 'stubbornness' of the compiler frustrating at all? How do
           | you find the tooling?
           | 
           | Also, I've considered Diesel for ORM, so was wondering if
           | you've been using that too.
        
             | huyage wrote:
             | > Do you find the 'stubbornness' of the compiler
             | frustrating at all?
             | 
             | I actually love it. The more work I can offload to compiler
             | the better. One simple example that frustrated me in Go was
             | adding a field to a struct. You add the field the the whole
             | thing still compiles even though the zero-initialized value
             | probably broke your app logic. In Rust if I add a field to
             | a struct, the compiler warns me about all the places that I
             | need to double check.
             | 
             | > Would you mind sharing some of your experiences?
             | 
             | I highly recommend zero2prod book which is well-written,
             | practical, but still teaches the essential principles
             | (https://www.zero2prod.com/). You basically deploy a CRUD
             | app to DigitalOcean from scratch. The best way to ramp up
             | IMHO.
             | 
             | > How do you find the tooling?
             | 
             | Cargo is sweet. rust-analyzer is all I need. I need less
             | extraneous tooling to be effective. For example, in Go I
             | might use a task runner to watch the repo and run tests
             | when I change a file. But in Rust I can just follow the
             | rust-analyzer highlights and manually compile less-
             | frequently.
             | 
             | > Also, I've considered Diesel for ORM, so was wondering if
             | you've been using that too.
             | 
             | I was not happy with GORM (https://gorm.io/index.html) and
             | never had a satisfactory experience with any ORM. I'm a fan
             | of writing plain SQL, even in Go. It's just that with Rust
             | sqlx I can get compile-time checks against the schema. It's
             | not anything new (see Haskell), but it tightens the
             | feedback loop and I have full control of the performance.
        
         | orthecreedence wrote:
         | I do a lot of cryptography stuff in rust that is ported to
         | various platforms and embedded in larger apps so I don't have
         | to write the same logic over and over (desktop/mobile mainly).
         | 
         | Also, lately working on some identity/p2p stuff.
        
         | api wrote:
         | ZeroTier version 2 is being built in Rust, with the main
         | reasons being safety (it's a network protocol!), easier cross
         | platform compilation, easier dependency management, and an all
         | around better language than C++. It should help us greatly
         | boost developer velocity while also be much safer from a
         | security point of view.
        
           | mwcampbell wrote:
           | That will also make it more attractive to other developers
           | using Rust who want to embed the SDK. Speaking of which, I've
           | emailed ZeroTier a couple of times now about licensing the
           | SDK (the first email was last week), and haven't yet heard
           | back.
        
         | marcosdumay wrote:
         | I am currently writing a kinda complex GUI application intended
         | to run on a browser. So it's in webassembly.
         | 
         | Compared to Javascript, Rust safety features allow me to
         | iterate quickly and improves my productivity from "I won't be
         | able to complete this project" to "it's trivial, just some
         | work". Compared to Typescript, Rust gives me some performance
         | and types that actually represent the data I use, but I am not
         | sure if I lost a bit of productivity (the TS tooling is
         | horrible, so programing a bit slower isn't the entire story).
         | 
         | I don't consider this a problem Rust is good for, but one that
         | all the more suitable languages still don't support.
        
       | rvcdbn wrote:
       | How come the first example isn't a race on a since it's accessed
       | from two threads?
        
         | jcranmer wrote:
         | Both threads are only reading the array. For it to be a race,
         | at least one of the accesses must be a write.
        
           | theptip wrote:
           | The second usage is a mut borrow and I think would be
           | incompatible with a read only borrow if they were run in
           | parallel.
           | 
           | As the comment eludes to, each spawned thread is implicitly
           | joined if you drop the join handle returned by s::spawn().
           | 
           | So in this case the spawned threads run serially.
        
             | DenseComet wrote:
             | Nope, the threads run in parallel. The variable x is
             | mutably borrowed only once by the second thread. The
             | variable a is immutably borrowed twice, so there is no
             | issue.
        
               | theptip wrote:
               | Are you certain?
               | 
               | From the docs on https://doc.rust-
               | lang.org/stable/std/thread/struct.Scope.htm...,
               | 
               | > If the join handle is dropped, the spawned thread will
               | implicitly joined at the end of the scope.
               | 
               | Plus the comment says
               | 
               | > // We can even mutably borrow `x` here, // because no
               | other threads are using it.
               | 
               | Which doesn't line up with another thread having a read-
               | only borrow on it.
               | 
               | Anyway not at my machine to test right now, I could be
               | wrong.
        
               | theptip wrote:
               | Oh never mind, I'm completely misreading. Thanks for the
               | pointer.
        
               | [deleted]
        
             | tomjakubowski wrote:
             | The second use is a mutable borrow of x, not the array. x
             | is borrowed read-only later, after the scoped threads are
             | joined.
        
           | rvcdbn wrote:
           | ah, that makes sense thanks
        
         | nextaccountic wrote:
         | If one thread tries to mutate the variable a instead of just
         | reading from it, the compiler will output a compile-time error
         | saying you can't do that. (But, if you wrap a into a mutex and
         | add the required methods to lock the mutex, you suddenly can)
        
       | Lvl999Noob wrote:
       | Awesome update! It's good to see scoped threads here. Btw, can
       | someone explain how these are safe when the initial
       | implementation wasn't? The problem was that someone could put a
       | reference to a local variable inside an `Rc` or `Arc` and leak it
       | with reference cycles, right? How is that case prevented now?
        
         | duckerude wrote:
         | The original implementation gave out a handle that waited for
         | all the threads to end when it was dropped (i.e. went out of
         | scope). That would prevent premature cleanup. But it was
         | possible to leak the handle so that it would never be dropped
         | even at the end of the block, and then it wouldn't wait for the
         | threads.
         | 
         | The new implementation calls a closure and waits for the
         | threads when that closure returns. Unlike the destructor here's
         | no way to stop that code from running when it should.
        
         | [deleted]
        
         | game-of-throws wrote:
         | Side note: since memory leaks were deemed safe, there are
         | easier ways to deliberately leak than using reference cycles.
         | The most straightforward are `mem::forget` and `Box::leak`.
        
         | [deleted]
        
         | kam wrote:
         | `std::thread::scope` takes a closure, and joins the threads
         | after the call to the closure returns, rather than relying on
         | `Drop`.
        
       | chmod600 wrote:
       | With the "try_reserve" stabilizations, does that mean the
       | "allocator_api" is closer to stabilization?
        
         | kibwen wrote:
         | I think that is less about the general allocator API than it is
         | about the fallible allocation for collections RFC (
         | https://github.com/rust-lang/rust/issues/48043 ), which is
         | something that the Rust-in-Linux folks have been pushing for
         | recently.
        
       | brundolf wrote:
       | Wow this is a juicy one
        
       | joshsyn wrote:
        
       | GolDDranks wrote:
       | Scoped threads are something that really showcases Rust's
       | features around thread-safety, lifetimes, sharing and mutability.
       | I'm glad it's finally back in the standard library!
        
         | davidatbu wrote:
         | I would be very interested in hearing from experienced folks
         | about how important this is/what useful patterns it unlocks.
         | 
         | I ask because I remember when trying to learn Kotlin, the docs
         | made a big deal of structured concurrency[0], and golang of
         | course is known for its concurrency story.
         | 
         | [0] https://kotlinlang.org/docs/coroutines-
         | basics.html#structure...
        
           | klabb3 wrote:
           | Sadly, this is only lexical scoping which means you can only
           | borrow from the outer scope and not ad-hoc the normal way
           | borrowing works in Rust.
           | 
           | In short, this means that thread pools and async runtimes
           | cannot use this feature to provide borrowing across tasks.
           | We're still stuck with Arc-ing everything that crosses task
           | boundaries.
           | 
           | Prior to 1.0, there were "true" scoped threads (with a
           | lifetime 'a on the join handle), which let you borrow from
           | the parent thread. (This could have extended to tasks as
           | well, had they been around.) unfortunately it wasn't safe
           | together with the much more popular Arc/Rc, which wasn't
           | 'static restricted, despite it's ability to cause cycles and
           | leak. So those powerful scoped threads were removed and
           | "destructors are not guaranteed to run in safe Rust" was
           | formalized instead.
           | 
           | Seeing how popular async became, I wonder if this was the
           | only and right way to move forward. I'm not against Arcs,
           | they have their place. But if you can use normal RAII it's
           | much preferable.
        
             | oconnor663 wrote:
             | > async runtimes cannot use this feature to provide
             | borrowing across tasks
             | 
             | They can't use this function, but with some duplicated
             | unsafe code they can still provide similar APIs for their
             | callers, right? Things like this:
             | https://github.com/jaboatman/tokio-scoped
        
               | klabb3 wrote:
               | I just checked quickly so may be wrong, but it looks like
               | they're pulling the same trick as with the new scoped
               | threads, ie only lexical scoping. Note also that the
               | scope function is blocking and called from within an
               | async fn, which is normally not great for composability
               | with other async code.
               | 
               | That said, taking a step back it has crossed my mind that
               | bringing back true scoping with unsafe in the impl might
               | be an acceptable way forward, despite how upsetting this
               | is to a lot of rustaceans. I _think_ that the failure
               | modes (ie triggering UB) for this case can be simply
               | enumerated in a short list of  "DON'Ts" (such as putting
               | a scoped join handle in an Arc).
               | 
               | OTOH, since leaking was formalized and explicitly allowed
               | (heck, even borderline encouraged through mem::forget),
               | god knows if people have exploited that for other cases
               | in true Hyrum's law fashion, that breaks the
               | abovementioned idea. They certainly had the right to.
        
               | thramp wrote:
               | the problem with this approaches like these that it
               | requires blocking the runtime:
               | https://github.com/jaboatman/tokio-
               | scoped/blob/master/src/li....
        
           | masklinn wrote:
           | > I would be very interested in hearing from experienced
           | folks about how important this is/what useful patterns it
           | unlocks.
           | 
           | For Rust it allows thread to play better with lifetimes,
           | which means there are scenarios where you don't need the
           | overhead of a lock (and usually the Arc that does with it,
           | unless you go with a global) or queue, you can just work with
           | on-stack "unsynchronised" borrows and it's thread safe.
           | 
           | That means lower syntactic _and_ runtime overhead in the
           | cases where it's an option.
           | 
           | It was already available in crossbeam so it's not _novel_
           | novel, but not needing a dependency for it is useful still.
        
             | davidatbu wrote:
             | Thanks! I didn't know that it was already available in
             | crossbeam, that helps a lot in understanding the
             | significance of this feature.
        
       | csomar wrote:
       | This is a huge update! At least, for me, I can see several things
       | on my code base that could be changed because of this. (The first
       | one is the lazy initialization of sync primitives; and the second
       | one is BorrowedFd/OwnedFd.
        
       | ActorNightly wrote:
       | I wish they would stop adding features and just to lock down the
       | language, and focus on more maintainability and use. Adding
       | features is nice but its one of the biggest issues that slows
       | down adoption. More people care about learning a language and
       | being able to read code without trying to figure out what some
       | latest feature does rather than some syntactical sugar.
        
         | funklute wrote:
         | Rust is a pretty young language though.... if now is not the
         | time to add features, then when is?
        
         | oxff wrote:
         | I wish they'd break their current backwards compat. promises to
         | fix some accidental complexity that has been introduced. Let
         | legacy langs provide this kind of maintainability
        
           | brundolf wrote:
           | They have the Editions mechanism for unavoidable breaking
           | changes, but their target market is people who care a whole
           | lot about stability and maintainability, so it wouldn't make
           | any sense for them to jettison that design goal.
        
           | tialaramex wrote:
           | It's not worth it.
           | 
           | For example, it seems as though
           | "Word".contains(char::is_ascii_lowercase) should work,
           | because after all "Word".contains(char::is_lowercase) works
           | and char::is_ascii_lowercase exists and does what you expect,
           | the same but for ASCII only.
           | 
           | However, for compatibility reasons char::is_lowercase takes a
           | char, while char::is_ascii_lowercase takes a _reference_ to a
           | char, and so you can 't just pass it to contains() and will
           | need to write a closure to pass to contains to do ASCII
           | instead.
           | 
           | Writing the closure is ugly, but it's nowhere close to how
           | awful a compatibility break would be so even a million things
           | like this (and so far maybe I can think of a dozen) aren't
           | worth it.
        
           | cercatrova wrote:
           | It's a systems language so they're not gonna break BC.
           | Although if there's a really great feature that comes out
           | that requires BC breaking, then they should do so.
        
         | game-of-throws wrote:
         | Literally every single thing in the post is generalizing a
         | feature that already exists. Don't you think removing these
         | special cases makes the language simpler and easier to use?
         | 
         | You might have a point though in a few releases when GATs are
         | stabilized. I'll keep an eye out for your username complaining
         | about that release ;)
        
         | Macha wrote:
         | There's no new syntax here?
         | 
         | The first is a new library function that takes a closure as the
         | parameter. This function has existed for as long as Rust has
         | been 1.0 in the crossbeam library, it's just now also in std.
         | 
         | The second change is a new api type.
         | 
         | The third change is a library change to increase flexibility of
         | that library.
         | 
         | The fourth is arguably a bugfix, where existing syntax could
         | not be used in an edge case.
         | 
         | The fifth is unifying the compiler implementations so that some
         | types of patterns now work in code using the oldest
         | compatibility mode that previously only worked in more current
         | modes.
        
         | pas wrote:
         | there are a lot of work-in-progress features that are important
         | so we can write more maintainable code, like GAT.
         | 
         | but it's also true that there are quite a few threads that are
         | conceptually simpler than GAT and are just left unfinished.
         | 
         | and there is a very serious push (or pushback with regards to
         | GAT) to keep those promises.
         | 
         | https://github.com/rust-lang/rust/pull/96709#issuecomment-11...
        
         | ekidd wrote:
         | Almost everything in Rust 1.63.0 appears to be an improvement
         | in the standard library. Scoped threads no longer require a
         | third-party library, some types support "const" better, and a
         | bunch of existing types got some useful new methods. The only
         | real language change here is the "impl / turbofish" one, which
         | allows something that _should_ work, but which wasn 't allowed
         | before.
         | 
         | I'm not sure it would be realistic to totally stop adding
         | features to the standard library, or to stop making existing
         | syntax work the way a Rust user would expect. I would hope that
         | any actively maintained language does things like these.
        
         | brundolf wrote:
         | Most of the features here (and in Rust updates in general these
         | days) are just the loosening of constraints on what you could
         | already do. If anything, these types of changes make the
         | language conceptually simpler.
         | 
         | This gets pointed out by somebody in the comment section under
         | every Rust update. The trope that Rust is getting harder to use
         | is tired, and not really based in reality.
        
           | ActorNightly wrote:
           | Different syntax = different ways of doing things = codebases
           | that diverge in implementation. It doesn't matter if the new
           | way doing things is conceptually simpler, you are now
           | creating 2 ways to do things based on what version of the
           | compiler you use, which people will have to know, therefore
           | increasing complexity, not reducing it. I don't understand
           | how people don't get this by now. Saying "oh just learn and
           | use the latest version" is completely unrealistic guidance.
           | 
           | And while its fine for high level scripting languages like
           | Python, because the whole idea is to abstract a lot of the
           | functionality into the syntax, the issue with Rust is that
           | its trying to be the next C and be applicable for writing
           | critically important pieces of software like parts of the
           | linux kernel. You absolutely must have a locked down language
           | set for this. The reason C is still used for the kernel isn't
           | because of circumstances, its specifically because there is
           | very few ambiguities in the core language.
        
             | brundolf wrote:
             | > you are now creating 2 ways to do things based on what
             | version of the compiler you use
             | 
             | Which of the features in Rust 1.63 adds a divergent way of
             | doing something you could already do?
             | 
             | > The reason C is still used for the kernel isn't because
             | of circumstances, its specifically because there is very
             | few ambiguities in the core language
             | 
             | What are some ambiguities in the core Rust language?
        
             | game-of-throws wrote:
             | C was used because it existed 30 years ago, and is full of
             | ambiguities (undefined behavior), and Rust curtails UB
             | quite a bit by defining many semantics that are left
             | unspecified in C.
             | 
             | You don't need a "locked down" language to build an OS. In
             | fact Linux just upgraded the version of C they use to C11.
             | Time always marches forward, my friend.
        
               | sophacles wrote:
               | And C is about to get C23 with additionaly syntax and
               | features.
        
             | mbrubeck wrote:
             | Which "different syntax" are you talking about? I don't see
             | any changes in this release that add new syntax to the
             | language.
        
       | superkuh wrote:
        
         | dboreham wrote:
         | It's a fine line. Python world spent 10 years not using Python
         | 3 features.
        
           | throwaway894345 wrote:
           | Python is interpreted--you have to write code that works on
           | all of your target platforms. Rust is compiled. You don't
           | have to care (much) about what is installed on your target
           | platforms.
        
             | hojjat12000 wrote:
             | Except for Libc. I compiled a rust program on Ubuntu 20.04
             | and tried to run it on Ubuntu 18.04, and bam.... a piano
             | fell on my head! Consequences.
        
               | sophacles wrote:
               | How is this any different from C?
        
               | throwaway894345 wrote:
               | Yeah, that was the "(much)" in my comment. Pretty sure
               | you can statically link some libc or another though.
        
         | nazgulsenpai wrote:
         | This sounds more like an argument against the package manager
         | maintainer for a Linux distribution rather than a Rust problem.
        
         | cies wrote:
         | > Bash developers
         | 
         | Yeah those always seem to crowd my views on conferences, hordes
         | of Bash developers /s
         | 
         | Nitpick: Bash is interpreted, Rust is compiled. The executable
         | rustc produces may well run on a machine that was not updated
         | in the last 15 years.
        
         | oxff wrote:
         | Maybe the package managers for Linux distributions need to
         | rethink their package distribution model :)
        
         | mcronce wrote:
         | There's nothing stopping you from installing using rustup.
         | There are also _tons_ of projects that have much older MSRVs
         | than simply  "latest stable".
        
         | jeroenhd wrote:
         | Ask your OS package maintainers to update their packages if you
         | want a more modern toolkit. Or stick to the one your package
         | maintainers decided on if you can live without those features.
         | 
         | I don't think a tool that receives regular updates should
         | necessarily come from standard OS repos, they should be stable.
         | Perhaps the Rust people could host their own repositories but
         | the fact they don't do it suggests that it's not worth the
         | hassle. This stuff is handed out for free, take it or leave it.
         | 
         | As Rust is open source software, you're free to grab each Rust
         | release, package it up, and offer it as a package on your own
         | repository, or you could probably pay someone to do it for you
         | if you find the right people. I'd much prefer a repository as
         | well, but I accept that the Rust devs don't work for me and I
         | don't pay for any services that would entitle me to such
         | requests.
        
         | msbarnett wrote:
         | My distro gets updated software when it's available; sounds
         | like your beef is with your distro insisting that the entire
         | world should work on its timelines instead of vice-versa.
        
         | kbd wrote:
         | > This contrasts with say, Bash developers [who] will write for
         | what is actually available on the OSes people are running.
         | 
         | This is obvious, right? Rust is compiled with what you have on
         | _your_ machine, while Bash is interpreted and so depends on the
         | capabilities on the _target_ machine.
        
         | nu11ptr wrote:
         | Not true for most of the big hitter crates. MSRV is a big thing
         | and I never understood why, but it was recently explained to me
         | it was so the old tool chains in distros could keep compiling,
         | so the big crates tend to bump MSRV very slowly. Obviously,
         | each project owner decides this on their own, so it isn't
         | universally true, but is common practice.
        
           | epage wrote:
           | Theres also talk of improving the situation, including
           | 
           | - Depencency MSRV errors explaining how to downgrade (merged)
           | 
           | - The dependency resolver skipping versions that need newer
           | Rust. To have reasonable errors, this will require the new
           | pubgrub resolver. The main question is opt-in vs opt-out
           | 
           | - Warnings when using functions newer than your MSRV
           | 
           | Among other ideas
        
         | [deleted]
        
         | orthecreedence wrote:
         | And why haven't the rust developers backported the latest
         | versions of rust to Slackware 3.3??
        
         | bilkow wrote:
         | > Want to use your system repo rust toolchain instead?
         | 
         | If you want to use your system toolchain, just install your
         | software from there, it will be compatible with the available
         | toolchains, if it's a library, you don't even need the
         | toolchain if its an application. The software is obviously also
         | gonna be "outdated", because that's the point of Debian, stable
         | software that has been well tested with the system.
         | 
         | > This is because Rust devs, for now, are the type that will
         | immediately beginning putting the new code features
         | 
         | There is the concept of MSRV (Minimum Supported Rust Version)
         | that a great fraction of the community follows. You just
         | specify publicly the minimum version that your library supports
         | and enforce it with CI. This is not as good as having an
         | official standard (say, in Cargo.toml), but a lot better than
         | just implicitly depending on what you think is currently
         | available in bash for most users.
         | 
         | > without consideration that it's not available in any OS
         | repository toolchains
         | 
         | Arch's package has been available on the same day in the last
         | Rust's release. We'll probably have 1.63.0 available today or
         | tomorrow.
        
           | shepmaster wrote:
           | > This is not as good as having an official standard (say, in
           | Cargo.toml)
           | 
           | It's present now: https://doc.rust-
           | lang.org/cargo/reference/manifest.html#the-...
        
             | bilkow wrote:
             | Oh, incredible! How have I missed that, thought it was
             | still just a proposal...
        
             | pavon wrote:
             | Yeah, I was very excited when that was added. I prefer to
             | use use the system Rust as well, and my primary complaint
             | was the hassle of having to manually resolve dependency
             | versions (for packages not in the OS package manager)
             | because Cargo hasn't had great support for restricting
             | packages to ones compatible with your version of Rust.
             | 
             | There will always be some issues with package maintainers
             | using new features without realizing it, and/or forgetting
             | to bump the minimum version. But now that there is a
             | standard for how it should be done, I can submit patches to
             | these projects to fix the problems when I encounter them.
        
         | [deleted]
        
         | dietr1ch wrote:
         | Using nix I ended up realizing that I want my system to be
         | almost empty, providing not much more than a shell to any
         | project I'm working on. Anything that's comes from my system is
         | something that might bite anyone else or myself when using the
         | project, and allow the classical "works on my machine"
         | scenarios, luckily here at least the issue is that it won't
         | build.
        
         | loeg wrote:
         | For those missing the context; this guy wants new Rust software
         | on Debian stable's old Rust toolchain. And complains about it
         | in every Rust thread on HN.
         | 
         | A similar problem afflicts other software in Debian stable;
         | Rust is not unique. The reasonable solution is to stop using
         | Debian stable if you want updates.
        
           | pavon wrote:
           | To clarify, without weighing in on the merits of his
           | complaint, what he is saying is that he _wants_ to use Debian
           | Stable 's toolchain and is complaining that the ecosystem
           | (crates on cargo.io) move to use the latest features so
           | quickly, and don't have stable backport releases, which makes
           | this difficult to do.
           | 
           | Edit: Reworded to remove disagreement.
        
             | loeg wrote:
             | I think you're agreeing with me, but framing it as
             | disagreement.
             | 
             | > the ecosystem (crates on cargo.io) move to use the latest
             | features so quickly
             | 
             | They use the new features in new software -- implying he
             | wants to use that new software. If he uses the old versions
             | that predate the new features, this wouldn't be a problem
             | for him.
        
               | pavon wrote:
               | Yes, I did misread your post, sorry. Reworded mine to be
               | a clarification rather than a contradiction.
        
             | Macha wrote:
             | I'm not saying now that's opposed.
             | 
             | If you want Debian to curate your compiler version, then
             | use the Debian curated versions of your Rust software for
             | compatibility.
        
           | baby wrote:
           | Wait can't you just use rustup?
        
             | krastanov wrote:
             | `rustup` is awesome for me as a developer. It is not
             | convenient if I am a sysadmin that wants everything to be
             | stable and consistent: I can not afford to use special
             | version/package manager for every single language. It is
             | fair to complain that rust (or python, or julia, or any
             | other language with built-in environment/package/version
             | manager) do not play nice with OS package managers. OS
             | package managers are starting to take "vendoring" a bit
             | more seriously because of this.
        
               | rascul wrote:
               | The OS package managers seem to be figuring it out,
               | though. I've noticed that both opensuse and debian have a
               | number of rust programs in their repos.
        
               | pornel wrote:
               | Debian does it the hard way, by making a Debian package
               | for every crates-io dependency used and patching Rust
               | programs to use Debian's forked deps instead. It's seems
               | like a massive pain for them, and has zero value for Rust
               | end users, since normal Cargo won't use any of this.
               | 
               | Rust often carries its own bugfixes to its LLVM version
               | (before they're accepted upstream). Debian unbundles LLVM
               | from Rust and makes Rust use Debian's LLVM, which creates
               | a risk of undoing Rust's bugfixes and causing
               | miscompilations.
               | 
               | I don't think anyone should be using Debian-packaged
               | Rust. Debian's and Rust's policies are fundamentally
               | incompatible. This results in Debian having a hopelessly
               | outdated inferior package that is a pain for both Debian
               | users and the rest of the Rust ecosystem.
        
               | troutwine wrote:
               | At the most recent RustConf William Brown spoke about how
               | OpenSUSE deals with Rust[1]. If I remember correctly from
               | his talk they started doing something very similar to
               | Debian and then eventually settled on "just use rustup".
               | I wish I had taken better notes because there was more
               | nuance to the history there but I think they'll release
               | the videos of the talks soon.
               | 
               | [1]: https://rustconf.com/schedule#how-we-ship-rust-in-
               | opensuse
        
               | pas wrote:
               | you want stability (aka reproducibility across a fleet of
               | workstations/servers), but also security updates too,
               | right? but what do you mean by consistency?
               | 
               | and you don't want to create & distribute a new OS image
               | for every security update, right?
               | 
               | ... anyway, the whole problem is that only upstream can
               | provide these kind of security updates. it's a big (and
               | very very convenient) lie what stable distros are doing,
               | but many times packages have to work their asses off to
               | maintain this illusion. (when they have to
               | patch/backport/hack packages.)
               | 
               | Rust as language and compiler provides the tools for this
               | (stability guarantee, editions, etc), but the various
               | devs that provide Rust crates might not.
               | 
               | sure, if Rust would artificially hold back new features
               | that would definitely provide this "stability", but it's
               | no wonder devs adopt new features fast. because they want
               | them, it makes their life easier, and it usually makes
               | users happier too.
               | 
               | what the Rust ecosystem is doing (and NodeJS and
               | TypeScript and quite a few high-velocity newish ones) is
               | providing updates to users faster.
               | 
               | of course there are some users that might not care about
               | this, hence debian oldstable, and so on.
        
               | baby wrote:
               | I could understand any other languages, but rustup is
               | kind of flawless from my point of view, so I'm still
               | wondering what doesn't work exactly : o
        
           | malkia wrote:
           | or find ways to override and install latest, for example
           | latest LLVM that would work on debian stable -
           | https://apt.llvm.org/ (maybe similar for rust?). I've
           | switched to this on my debian stable so that I can compile
           | carbonlang (it needs llvm12, debian stable had only llvm11) -
           | with above I've actually got llvm15, and then week ago
           | switched to llvm16 (I can adjust that back to say llvm14 if I
           | want).
        
             | lvass wrote:
             | I assume the issue here is not getting the Rust toolchain
             | on a developer system, but Rust packages in APT.
        
               | baby wrote:
               | Use nix instead then?
        
           | superkuh wrote:
           | The Debian example you're referring to was back from the
           | release of 11. It's rustc was only 3 months old and already
           | couldn't compile. That's not a "Debian is old" problem and it
           | was only one instance. I've run into the same problem on
           | other OSes as well. No OS hosted repo can keep up with rust
           | and it's particular selection of bleeding edge types.
           | 
           | And it's hardly every Rust thread. There are far too many
           | rust threads to even count, let alone comment on.
        
             | pas wrote:
             | > No OS hosted repo can keep up with rust and it's
             | particular selection of bleeding edge types.
             | 
             | what? why? someone has to click the approve on the
             | update+build+publish pipeline.. and that's in most repos
             | anyway.
        
           | fweimer wrote:
           | Debian packages rustc-mozilla for building Firefox. Firefox
           | ESR 102 will need Rust 1.59.0, and that version has already
           | been uploaded to stable-proposed-updates. 1.59 is not _that_
           | old (it 's from February 2022), and this actually builds
           | after installing rustc-mozilla (with cargo even):
           | use std::arch::asm;                  fn main() {
           | unsafe {                 asm!(                     "syscall",
           | in("eax") 60,                     in("edi") 0,
           | out("rcx") _,                     out("r11") _,             }
           | }
           | 
           | I guess for the same reason, there's now an LLVM and Clang 13
           | build in Debian stable, too.
           | 
           | I'm not entirely happy how Mozilla forced Debian's hand here.
           | But it means that there is a relatively current, Debian-
           | blessed Rust compiler, and you can use it for your own builds
           | if you are willing to upgrade from time to time.
        
         | game-of-throws wrote:
         | Why are you here flaming the Rust devs for having the audacity
         | to dare release a new version of their software, instead of
         | talking to the packagers that distribute years-old versions?
        
         | matthews2 wrote:
         | Gentoo got Rust 1.62.1 (the previous release) only three days
         | after it was announced on rust-lang.org.
        
       | kibwen wrote:
       | Having the new borrow checker finally on in all cases is nifty.
       | For valid programs the behavior is the same as the previous
       | version, but in the event of a compiler error, previous versions
       | would still show you the output of the old borrow checker. I've
       | already had one case where someone came asking about a confusing
       | borrow checker error message and I just had to suggest that they
       | try compiling with 1.63 and the new error message was clear
       | enough that it answered their question immediately.
       | 
       | Now we just need to do it all over again once Polonius finally
       | arrives. :P
        
         | brundolf wrote:
         | Migrations aren't ideal, but I'm excited to see continued
         | innovation in borrow-checking. This is a major area where Rust
         | is exploring truly new territory as a language, so growing
         | pains are to be expected, and it's encouraging to me that
         | Rust's semantics allow borrow checking to keep getting better
         | without breaking changes
        
           | cwzwarich wrote:
           | > it's encouraging to me that Rust's semantics allow borrow
           | checking to keep getting better without breaking changes
           | 
           | Just to be clear, these are breaking changes. If the new
           | borrow checker didn't break existing code, they would have
           | removed the old one long ago. They've just decided that the
           | observable effects of the breaking change in the ecosystem
           | are small enough (especially after warning about them for
           | years) that they are okay making the breaking change without
           | a semver-incrementing Rust 2.0.
           | 
           | To be fair, the reason for the breaking changes is generally
           | to fix soundness issues (of course, not every example of code
           | now banned will exhibit unsoundness), but that doesn't cover
           | all of them. There were some completely sound (albeit
           | useless) examples of partial initialization that broke with
           | NLL:
           | 
           | https://github.com/rust-
           | lang/rust/issues/21232#issuecomment-...
           | 
           | https://github.com/rust-lang/rust/issues/54987
           | 
           | Strict adherence to semver would require still accepting this
           | code.
        
             | brundolf wrote:
             | Sure, I guess all I meant was that the fundamental
             | semantics of borrowing and lifetimes that were chosen at
             | the beginning have continued to scale up to a better and
             | better borrow-checker experience. They haven't found deep
             | limitations of the language that prevented innovation
             | without going back to the drawing board.
        
         | pavon wrote:
         | I'm probably mixing different things up, but I thought the non-
         | lexical lifetime changes made the borrow checker more
         | permissive in the sense that some code that the compiler would
         | reject using the lexical borrow checker, would be allowed using
         | the non-lexical borrow checker.
         | 
         | If this is so, how are they maintaining edition compatibility?
         | It seems like you could write code for the 2015 edition that
         | would build with the new compiler, but not an older (2015
         | edition compliant) compiler.
        
           | [deleted]
        
           | kibwen wrote:
           | The new borrow checker both allows more to compile (by being
           | more precise about tracking control flow, allowing it to
           | prove more advanced things about lifetime usage) and also
           | less code to compile (again, by being more precise about
           | tracking control flow, allowing bugs in the old borrow
           | checker to be fixed (see https://github.com/rust-
           | lang/rust/issues?q=is%3Aissue+label%... for examples)).
           | 
           | The edition compatibility story here is interesting. When the
           | 2018 edition came out, the new borrow checker was only turned
           | on for code on the 2018 edition. Meanwhile, in the 2015
           | edition, it would run both borrow checkers and yield a
           | warning if your code passed the old borrow checker but not
           | the new one. After a migration period, the new borrow checker
           | was eventually made the default on the 2015 edition as well.
           | Because of the aforementioned soundness bugs fixed by the new
           | borrow checker, this was seen as acceptable (soundness fixes
           | are explicitly allowed by the stability policy, although the
           | Rust developers still try to provide migration periods to
           | make them less painful).
        
           | kam wrote:
           | Editions only guarantee that old code builds with new
           | compilers, not vice versa. New features are added to all
           | editions unless they require e.g. new keywords that are
           | available only in new editions.
        
             | pavon wrote:
             | Ah, that is right. I apologize, I think I've learned that
             | three times now, but for some reason my brain refuses to
             | accept it.
             | 
             | I like that previous editions get new features when
             | possible, unlike say C++, but I wish they'd gone with
             | semantic versioning for the language version, like python
             | did when both 2 and 3 were active. Oh well, I just need to
             | remember that the edition is like the major version, and
             | compiler version is sort of like minor version, and both
             | are needed to specify forwards compatibility.
        
               | game-of-throws wrote:
               | It might make more sense to think of editions as optional
               | changes to the surface syntax, and nothing more. They are
               | not nearly as important as the name makes them sound.
        
               | brundolf wrote:
               | They are often small, but it's a mistake to say they're
               | surface-level. Changes to syntax or semantics only get
               | made when absolutely necessary to allow for essential
               | features or fixes.
        
               | brundolf wrote:
               | I'm not sure semver would really do it here, because then
               | you could have say:                 2.17       1.17
               | 
               | What would you call the compiler binary that could
               | compile both language v1 and language v2, with (shared)
               | minor-version .17?
               | 
               | The issue is that semantic versions are a hierarchy,
               | whereas Rust edition x compiler version are a matrix
        
           | game-of-throws wrote:
           | Editions are orthogonal to compiler versions. It is perfectly
           | fine if code builds with a new compiler but not an old one.
           | Another example of this: you can write code in a 2015 edition
           | crate that calls the new `std::thread::scope` function.
        
           | Macha wrote:
           | Editions promise old code works with new compilers.
           | 
           | They do not promise new code works with old compilers
        
       | jmartin2683 wrote:
       | Rust is the greatest. It's my go-to for virtually anything that
       | it could reasonably be used for (a lot). After using it
       | exclusively for a while and getting comfortable and fast with it,
       | I can't see any good reason to use anything else for most
       | purposes.
        
         | pjmlp wrote:
         | GUI programming at the same level as MAUI, SwiftUI, Jetpack
         | Compose, Qt, WPF,...
        
           | sebzim4500 wrote:
           | Yeah GUI is really the biggest missing part of the ecosystem.
           | To be fair it is an extremely difficult problem; there is a
           | reason there are so many electron apps out there.
        
             | pjmlp wrote:
             | Not really, the reason is laziness and seeing nails
             | everywhere, instead of picking the right tool.
             | 
             | Coding GUI/TUIs since MS-DOS and Amiga 500 days, and Web
             | since 1996.
        
               | pas wrote:
               | A lot of times a cross platform non-native GUI is the
               | right tool. Same UX on every platform. What's not to
               | like? Allows faster iteration for small teams, you can
               | use TS and doesn't even have to think about
               | Swift/ObjC/Java/Kotlin/C++, and you can use whatever you
               | like for the backend.
        
               | pjmlp wrote:
               | PWA then.
        
           | debug-desperado wrote:
           | Probably a lost cause at this point since most GUI toolsets
           | are too object-oriented to comfortably wrap and call with
           | Rust. Do a web view with Tauri instead.
        
             | pjmlp wrote:
             | Or chose a better tool for the job, picking languages based
             | on platforms, not picking an hammer and then trying to find
             | a nail that fits.
        
         | felipellrocha wrote:
         | I am on the same boat. It's just too good. There are flaws, for
         | sure, but it seems like the language itself is going on an
         | incredibly good direction.
        
         | monkmartinez wrote:
         | I have some serious FOMO with Rust... I have been using JS and
         | Python for everything the last few years. Will you please
         | recommend some Primers/Resources/Tutorials for Rust for someone
         | like me? That is, basically a script basher that glues
         | everything together with Python.
        
           | lawn wrote:
           | The Rust Programming Language book is usually the first thing
           | people recommend.
           | 
           | https://doc.rust-lang.org/book/
        
       | mkaic wrote:
       | I'm a junior programmer who never went to college and writes
       | Python for a living (ML researcher). I've been itching to learn
       | another programming language, ideally something fast and low-
       | level, and have had my eye on Rust now for some time. But in my
       | brief experiments trying some of the docs' hello-world projects,
       | I'm already finding myself a little out of my depth.
       | 
       | I'm realizing I don't know anything about compilers and very
       | little about how languages work on a technical level -- stuff
       | like "strong" vs. "weak" typing, memory management, stacks and
       | heaps and garbage collection -- I've _seen_ all those terms
       | before but have no intuition for what they mean. I never have to
       | think about these concepts because Python is such a high-level
       | "it just works" scripting language.
       | 
       | Could anyone recommend some online resources for learning about
       | the computer science of programming for someone with little prior
       | experience? I'm not quite sure where to even start, but I'm eager
       | to learn because at the moment I don't really feel like a "real
       | programmer", more like a script kiddie. Heck, I only learned to
       | use Git properly like 6 months ago!
        
         | whb07 wrote:
         | CS50X is a great starting point as they talk about the intro
         | into bits/heap/stack etc. In the first half they have the work
         | using C which will show you how to think about all this.
         | 
         | I'd suggest doing the C parts and stopping at the python side.
         | Once you stop, step into Rust and you'll see how much easier it
         | is to perform all the things you were doing in C.
        
         | Scarbutt wrote:
         | 'The C programming language' and then 'Operating Systems: Three
         | Easy Pieces'
        
       ___________________________________________________________________
       (page generated 2022-08-11 23:01 UTC)