From the historical sources I could find online, it appears that Rust's borrow system was independently invented, or at least they don't mention linear logic or anything substructural. This is kind of interesting to me, especially given the reactions in this thread, and ties into the general difficulty of PL research to find acceptance among practitioners, especially when presented by researchers (which I think is regretful, I like the ideas in the article!). Perhaps we really should stick to terminology like "function colors" to make effect systems more popular (or not, because the color framing makes it sound bad to have different colors in a program, IIRC).
This may be too much advanced type theory for a useful language.
You can go all the way to formal verification. This is not enough for that.
Or you can stop at the point all memory error holes have been plugged. That's more useful.
You can go way overboard with templates/macros/traits/generics. Remember C++ and Boost. I understand that Boost is now deprecated.
I should work some more on my solution to the back-reference problem in Rust. The general idea is that Rc/Weak/upgrade/downgrade provide enough expressive power for back references, but the ergonomics are awful. That could be fixed, and some of the checking moved to compile time for the single owner/multiple users case.
Thanks for posting this! As a long-time Rust user (and contributor, in the good old days), the thing that has always fascinated me about Rust is the healthy balance it strikes between academic brilliance and industry pragmatism. Radical changes like the ones suggested by the OP risk damaging that balance IMO. I'd rather put up with some language quirks and see Rust achieve "boring technology" status...
But who knows, maybe the "academic brilliance" from the article is more pragmatic than I give it credit for. I sure hope for it if these changes ever go through.
> You can go way overboard with templates/macros/traits/generics.
You can go overboard on any language concept imaginable, but conflating all these mechanisms makes it sound like you haven't interacted much with non-C++ languages—particularly since rust doesn't have templates or anything like templates, traits are an entirely unrelated composition mechanism, and macros are entirely unrelated to the type discussion in the article.
This isn't really "advanced type theory" so much as picking up programming language developments from the 90s. I suppose it's "advanced" in the sense that it's a proper type system and not a glorified macro ala templating, but how is that a bad thing?
This sounds insane at this point. The language already has too many features. Would be cool if all these people with amazing visions could move it elsewhere.
Rust is fast tracking being as bad as c++ in terms of just garbage in it.
IMO the worst thing about c++ isn't that it is unsafe but it is extemely difficult to learn to a satisfying degree.
This is already kind of feels true for Rust and it will be surely true if people just keep shoving their amazing ideas into it.
IMO even async/tokio/error-handling aren't that well though out in rust. So much for keeping things out of the language.
Maybe Rust just wasn't what I wanted and I am salty about it but it feels a bit annoying when I see posts like this and considering where Rust is now after many years of shoving stuff into it
That's actually the point. Many of these additions can be phrased as unifying existing features and allowing them to be used in previously unusable ways and contexts. There's basically no real increase in user-perceived complexity. The Rust editions system is a key enabler of this, and C++ has nothing comparable.
It doesn't have too many features, it arguably does not have enough. The issue is that the current features don't play nicely with each other, so much of the work has been in making sure they do, such as with async traits as an example: there is no reason why you can make a function async but not inside a trait, and this was the case until very recently.
Beyond that, what the article shows is exactly what I want, I want as much type safety as possible especially for critical systems code which is increasingly what Rust is being used for.
This inevitably happens when the approach to language design is "try it and see". I know people here hate design-by-committee, but historically it's led to some very cohesive languages.
I don't think it is about having committee, but rather having a spec. And I mean spec, not necessarily ISO standard. There should be a description of how specific features work, what is expected behavior, what is unexpected and should be treated as bug, and what is rationale behind specific decision.
Coincidentally people here hate specs as well, and that explains some things.
I know there is some work on Rust spec, but it doesn't seem to progress much.
Well ok ... experiment but maybe unlike c++ we could have added N keywords removed M keywords for arguably net-simpler language.
Geez I'd hate to be in rust dev shoes if I can't remove something later when I have a better better min/max. I guess this could be done off main, stable.
> Rust's development process is also design by committee, interestingly enough.
Sure, but it's still quite informal and they just add things as they go instead of writing a complete standard and figuring out how everything interacts before anything is added to the language. Design-by-committee was probably not the best term to use.
After working with Rust for half a decade I‘m afraid I have to agree. A lot of the newer features have weird edge cases with promises for fixes stuck in bikeshedding hell for years (looking at you const generics). Alternatively feature authors wait on dependecies that will never ship.
The main problem I see is adding things slowly instead of automatic rewrites.
I remember adding lifetimes in some structs and then wanted to use generics and self pointing with lifetimes because that made sense, and then it didn't work because the composition of some features was not yet part of Rust.
Another thing: there are annotations for lifetimes in function signatures, but not inside the functions where there is a lot of magic happening that makes understanding them and working with them really hard: after finally the borrow checking gave me errors, that's when I just started to getting lots of lifetime errors, which were not shown before.
Rust should add these features but take out the old ones with guaranteed automatic update path.
You're not wrong here. Not that I'm entirely up-to-speed on all of the deep Rust discussions, but the sense I have of the language evolution is that while there is definitely a loud contingent of people pushing for a lot of the complexity of full effect systems or linear types, these sorts of proposals aren't actually all that likely to actually move forward in the language.
(I should note that of all of the features mentioned in this blog post, the only one I actually expect to see in Rust someday is pattern types, and that's largely because it partially exists already in unstable form to use for things like NonZeroU32.)
Yoshua works directly on developing the language, and mentions he is working on these features specifically (he is part of the effects initiative), I'm not sure you won't see these features in Rust.
I had some Scala 3 feelings when reading the vision, I hope Rust doesn't gets too pushy with type systems ideas.
That is how we end with other ecosystems doubling down in automatic memory management with a good enough ownership model for low level coding, e.g. Swift 6, OxCaml, Chapel, D, Linear Haskel, OCaml effects,...
Where the goal is that those features are to be used by experts, and everyone else stays on the confort zone.
I doubt those languages would have the same level of traction as Rust, especially now that Rust has already gotten said traction over the past decade with even the Linux kernel using them. It's more likely that Rust will be written as today and then these extra features are added for more type safety in certain functions as like I said in another comment I doubt people are going to write type contracts for every single function (maybe LLMs will, but that's an orthogonal discussion).
Finally seeing more movement on effects or what started as keyword generics, there was a big blog post a few years ago but not much public facing news although of course they've been working on it as Yoshua says in the post.
I truly do wish we get closer to Ada and even Lean in terms of safety, would be great to see all these theoretical type system features become reality. I use the `anodized` crate right now for refinement type features, and who knows, maybe we get full fledged dependent types too as there aren't many production languages with them and certainly not popular languages.
I couldn’t disagree more. Most of my company’s backend code is written in Scala, and most of our engineers dislike it because the language is difficult to understand, has way too many features, and has many ways to solve the same problem. I don’t want Rust to continue down this path, and I already worry with some of the syntactic sugar and type system additions being discussed that it already has.
A language’s type system doesn’t need to model every possible type of guarantee. It just needs to provide a type safe way to do 95% of things and force its users to conform to use the constructs it provides. Otherwise it becomes a buggy hodge podge of features that interact in poor and unpredictable ways. This is already the case in Scala; we’ve discovered almost 20 bugs in the compiler in the past year.
There is a middle ground. People seem to use Haskell and OCaml just fine and both are as expressive, so maybe it is just Scala having shoved in too many things. Based on what the article shows, it doesn't seem like they're making ten different ways to do the same thing but rather one way to (optionally) get more type safety out. I doubt everyone will be writing dependent type contracts for every single function, it's more for certain pieces of the codebase.
I would love to have a use case to learn and write rust today. But i am deep in node and go services for my employer. Previously wrote java and c#. What are people writing in rust today?
I'm working on a multisig sign-off solution, with the first use case being file downloads like GitHub releases authentication: https://github.com/asfaload/asfaload
I'm coming from F# and find rust a good compromise: great type safety (though I prefer the F# language) with an even better ecosystem. It can also generate decently sized statically compiled executables, useful for CLI tools, and the library code I wrote should be available to mobile apps (to be developed).
I find that CLI is a great way to model problems. When I find myself doing something that has graduated beyond a comfortable amount of PowerShell, Rust is there for me.
I have a template I've been evolving so it's super easy to get started with something new; I just copy the template and slam Copilot with some rough ideas on what I want and it works out.
Decomposes the problem very nicely into incrementally achievable steps
1. `fetch <username>` to get info from github into a cache location
2. `generate <username> <output.svg>` to load stats and write an svg
3. `serve` to run a webserver to accept GET requests containing the username to do the above
Means that my stuff always has `--help` and `--version` behaviours too
I'm having fun using it to make websites. Rust→WASM works really well. Definitely a very enjoyable way to make web apps. I've been trying to think how I can contribute to the ecosystem, seeing as I enjoy it so much. Rust gives you a control over memory that is impossible to replicate in javascript, and which allows much more performant code
Whatever I used to use Node for, like web servers, I now use Rust. It's pretty nice, with a strong OCaml-like type system which I've used before (better than TypeScript even in some cases), plus it's much faster and more memory efficient such that I can run way more services on my 5 dollar Hetzner box with Dokploy compared to Node or Java or C#.
You can go all the way to formal verification. This is not enough for that. Or you can stop at the point all memory error holes have been plugged. That's more useful.
You can go way overboard with templates/macros/traits/generics. Remember C++ and Boost. I understand that Boost is now deprecated.
I should work some more on my solution to the back-reference problem in Rust. The general idea is that Rc/Weak/upgrade/downgrade provide enough expressive power for back references, but the ergonomics are awful. That could be fixed, and some of the checking moved to compile time for the single owner/multiple users case.
But who knows, maybe the "academic brilliance" from the article is more pragmatic than I give it credit for. I sure hope for it if these changes ever go through.
You can go overboard on any language concept imaginable, but conflating all these mechanisms makes it sound like you haven't interacted much with non-C++ languages—particularly since rust doesn't have templates or anything like templates, traits are an entirely unrelated composition mechanism, and macros are entirely unrelated to the type discussion in the article.
This isn't really "advanced type theory" so much as picking up programming language developments from the 90s. I suppose it's "advanced" in the sense that it's a proper type system and not a glorified macro ala templating, but how is that a bad thing?
Also the way nowadays is with constexpr, templates, and around the corner, static reflection.
Rust is fast tracking being as bad as c++ in terms of just garbage in it.
IMO the worst thing about c++ isn't that it is unsafe but it is extemely difficult to learn to a satisfying degree.
This is already kind of feels true for Rust and it will be surely true if people just keep shoving their amazing ideas into it.
IMO even async/tokio/error-handling aren't that well though out in rust. So much for keeping things out of the language.
Maybe Rust just wasn't what I wanted and I am salty about it but it feels a bit annoying when I see posts like this and considering where Rust is now after many years of shoving stuff into it
That's actually the point. Many of these additions can be phrased as unifying existing features and allowing them to be used in previously unusable ways and contexts. There's basically no real increase in user-perceived complexity. The Rust editions system is a key enabler of this, and C++ has nothing comparable.
Rust editions don't cover all use cases that one can think of regarding language evolution, and requires full access to source code.
Beyond that, what the article shows is exactly what I want, I want as much type safety as possible especially for critical systems code which is increasingly what Rust is being used for.
I don't think it is about having committee, but rather having a spec. And I mean spec, not necessarily ISO standard. There should be a description of how specific features work, what is expected behavior, what is unexpected and should be treated as bug, and what is rationale behind specific decision.
Coincidentally people here hate specs as well, and that explains some things.
I know there is some work on Rust spec, but it doesn't seem to progress much.
Geez I'd hate to be in rust dev shoes if I can't remove something later when I have a better better min/max. I guess this could be done off main, stable.
C++ is not cohesive at all
Examples of cohesive languages designed by committees would be Ada and Haskell.
Rust's development process is also design by committee, interestingly enough.
Sure, but it's still quite informal and they just add things as they go instead of writing a complete standard and figuring out how everything interacts before anything is added to the language. Design-by-committee was probably not the best term to use.
I remember adding lifetimes in some structs and then wanted to use generics and self pointing with lifetimes because that made sense, and then it didn't work because the composition of some features was not yet part of Rust.
Another thing: there are annotations for lifetimes in function signatures, but not inside the functions where there is a lot of magic happening that makes understanding them and working with them really hard: after finally the borrow checking gave me errors, that's when I just started to getting lots of lifetime errors, which were not shown before.
Rust should add these features but take out the old ones with guaranteed automatic update path.
(I should note that of all of the features mentioned in this blog post, the only one I actually expect to see in Rust someday is pattern types, and that's largely because it partially exists already in unstable form to use for things like NonZeroU32.)
I had some Scala 3 feelings when reading the vision, I hope Rust doesn't gets too pushy with type systems ideas.
That is how we end with other ecosystems doubling down in automatic memory management with a good enough ownership model for low level coding, e.g. Swift 6, OxCaml, Chapel, D, Linear Haskel, OCaml effects,...
Where the goal is that those features are to be used by experts, and everyone else stays on the confort zone.
Linux kernel adoption of Rust hasn't been a smooth ride, exactly because of its type system among C folks.
It is only happening because the likes of Google and Microsoft want to see it through.
I truly do wish we get closer to Ada and even Lean in terms of safety, would be great to see all these theoretical type system features become reality. I use the `anodized` crate right now for refinement type features, and who knows, maybe we get full fledged dependent types too as there aren't many production languages with them and certainly not popular languages.
A language’s type system doesn’t need to model every possible type of guarantee. It just needs to provide a type safe way to do 95% of things and force its users to conform to use the constructs it provides. Otherwise it becomes a buggy hodge podge of features that interact in poor and unpredictable ways. This is already the case in Scala; we’ve discovered almost 20 bugs in the compiler in the past year.
https://news.ycombinator.com/item?id=47259148
I'm coming from F# and find rust a good compromise: great type safety (though I prefer the F# language) with an even better ecosystem. It can also generate decently sized statically compiled executables, useful for CLI tools, and the library code I wrote should be available to mobile apps (to be developed).
I find that CLI is a great way to model problems. When I find myself doing something that has graduated beyond a comfortable amount of PowerShell, Rust is there for me.
I have a template I've been evolving so it's super easy to get started with something new; I just copy the template and slam Copilot with some rough ideas on what I want and it works out.
https://github.com/teamdman/teamy-rust-cli
Just today used it to replace a GitHub stats readme svg generator thing that someone else made that was no longer working properly.
https://github.com/TeamDman/teamy-github-readme-stats
Decomposes the problem very nicely into incrementally achievable steps
1. `fetch <username>` to get info from github into a cache location 2. `generate <username> <output.svg>` to load stats and write an svg 3. `serve` to run a webserver to accept GET requests containing the username to do the above
Means that my stuff always has `--help` and `--version` behaviours too