13 ms·
I have what I thought was a broad knowledge base of rust an experience in it over many domains, but I haven't heard of most of those. Have been getting by with
by the__alchemist 10mo ago
I have what I thought was a broad knowledge base of rust an experience in it over many domains, but I haven't heard of most of those. Have been getting by with `&`, and `&mut` only from those tables!
Incidentally, I think this is one of Rust's best features, and I sorely miss it in Python, JS and other languages. They keep me guessing whether a function will mutate the parent structure, or a local copy in those languages!
Incidentally, I recently posted in another thread here how I just discovered the 'named loop/scope feature, and how I thought it was great, but took a while to discover. A reply was along the effect of "That's not new; it's a common feature". Maybe I don't really know rust, but a dialect of it...
- mring33621 10mo agoI'm just learning Rust but so far, it looks like the author is proposing some of these ref types, like &own and &uninit. I don't know 100% for sure. It's a bit confusing...
- jojomodding 10mo agoThe part of the blog post where it says > What’s with all these new reference types? > All of these are speculative ideas makes it pretty clear to me that they are indeed not yet part of Rust but instead something people have been thinking about adding. The rest of the post discusses how these would work if they were implemented.
- whytevuhuni 10mo agoRight. The &pin, &own, and &uninit in the article (or rather everything except & and &mut in that table) do not exist in Rust. I have seen &pin being proposed recently [1], first time I'm seeing the others. [1] https://blog.rust-lang.org/2025/11/19/project-goals-update-october-2025/ https://blog.rust-lang.org/2025/11/19/project-goals-update-o...
- VorpalWay 10mo agoOwn and uninit have been in discussions wrt in place construction. The Rust in the Linux kernel project seems to be the motivating use case for this that really got the effort going recently.
- GardenLetter27 10mo agoRust gives you no guarantees that a function won't allocate or panic though.
- MaulingMonkey 10mo agoThis is something I do wish Rust could better support. A `#![no_std]` library crate can at least discourage allocation (although it can always `extern crate alloc;` in lib.rs or invoke malloc via FFI...)
- maxbond 10mo agoIs the juice worth the squeeze to introduce two new function colors? What would you do if you needed to call `unreachable!()`? It's a shame that you can't quite do this with a lint, because they can't recurse to check the definitions of functions you call. That would seem to me to be ideal, maintain it as an application-level discipline so as not to complicate the base language, but automate it.
- MaulingMonkey 10mo ago> Is the juice worth the squeeze to introduce two new function colors? Typically no... which is another way of saying occasionally yes. > What would you do if you needed to call `unreachable!()`? Probably one of e.g.: unsafe { core::hint::unreachable_unchecked() } loop {} Which are of course the wrong habits to form! (More seriously: in the contexts where such no-panic colors become useful, it's because you need to not call `unreachable!()`.) > It's a shame that you can't quite do this with a lint, because they can't recurse to check the definitions of functions you call. That would seem to me to be ideal, maintain it as an application-level discipline so as not to complicate the base language, but automate it. Indeed. You can mark a crate e.g. #![deny(clippy::panic)] and isolate that way, but it's not quite the rock solid guarantees Rust typically spoils us with.
- VorpalWay 10mo ago> Typically no... which is another way of saying occasionally yes. You might be able to avoid generating panic handling landing pads if you know that a function does not call panic (transitively). Inlining and LTO often help, but there is no guarantee that it will be possible to elide, it depends on the whims of the optimiser. Knowing that panicking doesn't happen can also enable other optimisations that wouldn't have been correct if a panic were to happen. All of that is usually very minor, but in a hot loop it could matter, and it will help with code size and density. (Note that this is assuming SysV ABI as used by everyone except Windows, I have no clue how SEH exceptions on Windows work.) > Indeed. You can mark a crate e.g. #![deny(clippy::panic)] and isolate that way, but it's not quite the rock solid guarantees Rust typically spoils us with. Also, there are many things in Rust which can panic apart from actual calls to panic or unwrap: indexing out of bounds, integer overflow (in debug), various std functions if misused, ...
- goku12 10mo agoI doubt that anybody truly knows Rust. And this is aggravated by the fact that features keep getting added. But here are two simple strategies that I found very effective in keeping us ahead of the curve. 1. Always keep the language reference with you. It's absolutely not a replacement for a good introductory textbook. But it's an unusually effective resource for anybody who has crossed that milestone. It's very effective in spontaneously uncovering new language features and in refining your understanding of the language semantics. What we need to do with it is to refer it occasionally for even constructs that you're familiar with - for loops, for example. I wish that it was available as auto popups in code editors. 2. Use clippy, the linter. I don't have much to add here. Your code will work without it. But for some reason, clippy is an impeccable tutor into idiomatic Rust coding. And you get the advantage of the fact that it stays in sync with the latest language features. So it's yet another way to keep yourself automatically updated with the language features.
- VorpalWay 10mo agoI feel like other languages also have the issue of complexity and changing over time. I doubt I know all of C++ post C++14 for example (even though that is my day job). Keeping up with all the things they throw into the standard library of Python is also near impossible unless you write python every day. Rust has an unusually short release cycle, but each release tends to have fewer things in it. So that is probably about the same when it comes to new features per year in Python or C++. But sure, C moves slower (and is smaller to begin with). If that is what you want to compare against. But all the languages I work with on a daily basis (C++, Python and Rust) are sprawling. I don't have enough experience to speak about other languages in depth, but as I understand it Haskell for example has a lot of extensions. And the typescript/node ecosystem seems to move crazy fast and require a ton of different moving pieces to get anything done (especially when it comes to the build system with bundlers, minifiers and what not).
- jacquesm 10mo agoLanguages should be small, not large. I find that every language I've ever used that tries to throw everything and the kitchensink at you eventually deteriorates into a mess that spills over into the projects based on that language in terms of long term instability. You should be able to take a 10 year old codebase, compile it and run it. Backwards compatibility is an absolute non-negotiable for programming languages and if you disagree with that you are building toys, not production grade systems.
- the8472 10mo ago> All of these are speculative ideas, but at this point they’ve been circulating a bunch so should be pretty robust.
- VorpalWay 10mo agoMany of the things like "&own" are ideas being discussed, they don't exist in the language yet. As far as I know only &, &mut and raw pointers (mut and const) exist in stable rust at this point. The standard library has some additional things like NonNull, Rc, etc.
- jibal 10mo ago> I sorely miss it in Python, JS and other languages. They keep me guessing whether a function will mutate the parent structure, or a local copy in those languages! Python at least is very clear about this ... everything, lists, class instances, dicts, tuples, strings, ints, floats ... are all passed by object reference. (Of course it's not relevant for tuples and scalars, which are immutable.)
- mrkeen 10mo agoEverything being passed by object reference just means every case is equally unclear. answer = frobnicate(foo) Will frobnicate destroy foo or not?
- kstrauser 10mo agoNo. It can’t. It can only destroy its own reference to foo, not the calling scope’s reference.
- mrkeen 10mo agoRight, but I don't care about the reference to foo (that's a low-level detail that should be confined to systems languages, not application languages) I was asking about the foo.
- kstrauser 10mo agoRight, but that reference is all the function has. It can’t destroy another scope’s reference to the foo, and the Python GC won’t destroy the foo as long as a reference to it exists. The function could mutate foo to be empty, if foo is mutable, but it can’t make it not exist.
- mrkeen 10mo ago>> I sorely miss it in Python, JS and other languages. They keep me guessing whether a function will mutate the parent structure, or a local copy in those languages! No mention of references! I don't care about references to foo. I don't care about facades to foo. I don't care about decorators of foo. I don't care about memory segments of foo. "Did someone eat my lunch in the work fridge?" "Well at least you wrote your name in permanent marker on your lunchbox, so that should help narrow it down"
- kibwen 10mo ago> Incidentally, I recently posted in another thread here how I just discovered the 'named loop/scope feature, and how I thought it was great, but took a while to discover. A reply was along the effect of "That's not new; it's a common feature". Maybe I don't really know rust, but a dialect of it... I assume I'm the one who taught you this, and for the edification of others, you can do labeled break not only in Rust, but also C#, Java, and JavaScript. An even more powerful version of function-local labels and break/continue/goto is available in Go (yes, in Go!), and a yet more powerful version is in C and C++. The point being, the existence of obscure features does not a large or complex language make, unless you're willing to call Go a large and complex language. By this metric, anyone who's never used a goto in Go is using a dialect of Go, which would be silly; just because you've never had cause to use a feature of a language does not a dialect make.
- morcus 10mo agoWow, I had no idea JavaScript has labeled break! Thanks for the comment.
- jacquesm 10mo agoIt's a terrible feature, really. If you need a labeled break what you really need is more decomposition. I'm pretty sure that Dijkstra would have written a nice article about it, alas, he is no longer with us.
- dwattttt 10mo agoIt depends on how big or trivial the loops you need are. If they're only 3 or 4 lines, extracting their body into a function doesn't improve anything.
- cyberax 10mo agoDijkstra was wrong on this one. Breaks and continues help to keep the code more readable by reducing the amount of state that needs to be tracked. Yes, from the purely theoretical standpoint, you can always rewrite the code to use flags inside the loop conditions. And it even allows formal analysis by treating this condition as a loop invariant. But that's in theory. And we all know the difference between the theory and practice.
- nextaccountic 10mo agoOf that table, only & and &mut actually exist, the rest are hypothetical syntax
- Sytten 10mo agoAnother one that is missing in the article is &raw mut/const but it is purely for unsafe usage when you need a pointer to an unaligned field of a struct.
- steveklabnik 10mo ago&raw T/&raw mut T aren't pointer types, they're syntax for creating *const T/*mut T. These aren't included in the article because they are not borrow checked, but you're right that if someone was trying to cover 100% of pointer types in Rust, raw pointers would be missing.
- gpm 10mo agoIf we start creating more `&... T` ptr types I wonder if a future edition changes `*const T` to `&raw T` for consistency...
- kibwen 10mo agoI'm hoping that languages move away from the sigil-ified legacy of C treating pointers as special syntax and just start calling these `Ref<T>`, `PtrConst<T>`, etc.
- steveklabnik 10mo agoEhhh it’s already consistent: ones with & borrow, ones without do not.
- sesm 10mo agoTypeScript has `Readonly<T>` for this purpose.
- jaen 10mo ago`Readonly<T>` in TypeScript is almost useless, unsound and completely unsafe (as are most other things in TypeScript), and in no way equivalent to the Rust affine type system. In particular, Readonly only prevents writing to the immediate fields of the object, but doing eg `const x: Readonly<X>; x.a.b = ...` is completely fine (ie. nested mutability is allowed). If you want transitive immutability, you need a type-level function (such as `ReadonlyDeep` from `type-fest`), but then that gives terrible error messages. Also due to the bivariance of the TypeScript type system, using Readonly in combination with generics can silently and automatically cast it away, making it largely pointless for actual safety...
- FpUser 10mo ago>"...and other languages" Many "other languages", particularly ones that compile to native code in traditional way have fairly explicit ways of specifying how said parameters to be treated
- adrian_b 10mo agoFor your problem, i.e. "guessing whether a function will mutate the parent structure", the solution used by Rust is far from optimal and I actually consider it as one of the ugliest parts of Rust. The correct solution for the semantics of function parameters is the one described in the "DoD requirements for high order computer programming languages: IRONMAN" (January 1977, revised in July 1977), which have been implemented in the language Ada and in a few other languages inspired by Ada. According to" IRONMAN", the formal parameters of a function must be designated as belonging to one of 3 classes, input parameters, output parameters and input-output parameters. This completely defines the behavior of the parameters, without constraining in any way the implementation, i.e. any kind of parameters may be passed by value or by reference, whichever the compiler chooses for each individual case. (An input-output parameter where the compiler chooses to pass it by value will be copied twice, which can still be better than passing it by reference, e.g. when the parameter is passed in a register.) When a programming language of the 21st century still requires for the programmer to specify whether it is passed by value or by reference, that is a serious defect for the language, because in general the programmer does not have the information needed to make a correct choice and this is an implementation detail with which the programmer should not be burdened. The fact that C++ lacks this tripartite classification of the formal parameters of a function has lead to the ugliest complications of C++, which have been invented as bad workarounds for this defect, i.e. the fact that constructors are not normal functions, the fact that there exist several kinds of superfluous constructors which would not have been needed otherwise (e.g. the copy constuctor), the fact that C++ 2011 had to add some features like the "move" semantics to fix performance problems of the original C++. (The problems of C++ are avoided when you are able to differentiate "out" parameters from "inout" parameters, because in the former case the function parameter uses a "raw" area of memory with initially invalid content, where an object will be "constructed" inside the function, while in the latter case the function receives an area of memory that has already been "constructed", i.e. which holds a valid object. In C++ only "constructors" can have a raw memory area as parameter, and not the normal functions.)
- scuff3d 10mo agoI suspect this is fairly common. The reality is most developers don't need a lot of the features a language provides. Python for example has a ton of stuff that can be done with classes using sunder methods and other magic. I'm aware of it, but in all the years I've been writing Python I've never actually needed it. The only time I've had to directly interact with it was when trying to figure out how the fuck OpenAPI generates FastAPI server code. Which fairly deep into a framework and code generation tool.