Fair enough for the original author, but if I'd been submitting this to HN, I would probably have included this information in the text field or something.
Note that the thing Rust is doing here doesn't break backwards compatibility, because of the edition mechanism. C++ doesn't have that (I don't know if they've considered adding it), so they can't do anything about language footguns without compatibility breaks.
Rust idioms do of course change over time, such that if you come back to the language after a while you'll have some catching up to do, but that's just as true of C++.
Editions for the time being don't cover all language evolution scenarios, e.g. breaking changes on the standard library, and having incompatible crates on the same build talking to each other.
Is anybody contemplating nontrivial breaking changes to the standard library? When env::set_var and env::remove_var were marked unsafe, that was done across an edition boundary even though it's unsound to leave them as-is in older editions.
Do you have a particular scenario in mind for incompatible crates? This doesn't seem like a language evolution problem.
The paper you want to look up is “epochs” (the OG name for editions) but there were questions that never got resolved, and so the proposals are dead for now at least.
It came pretty close to happening in Rust 2024, but it was determined that there just wasn't enough time left before the end-of-year deadline to roll out such a big change.
Mythos is dramatically better specifically at finding zero-day vulnerabilities and developing exploits for them, that being what it was designed to do. On other cybersecurity tasks, GPT-5.5 is at least as good, but finding and exploiting zero-days is a particularly scary capability, which is why Mythos is a big deal. See, e.g., https://forum.effectivealtruism.org/posts/8yztpbjuPkyXsmA6n/....
We did not explicitly train Mythos Preview to have these capabilities. Rather, they emerged as a downstream consequence of general improvements in code, reasoning, and autonomy. The same improvements that make the model substantially more effective at patching vulnerabilities also make it substantially more effective at exploiting them.
I've been assuming that Mythos is just a big jump in model size, and that's where the jump in capabilities comes from. Hence I expect OpenAI not to be able to catch up without scaling up the model and hence significantly raising the API prices.
Anthropic frames this as something emergent. Not 100% but in a way they always phrase it as like, it’s a great model, but our breaths were swept and taken with its approach to security.
Probably more importantly, in browser JavaScript locking up the main thread means making the page unresponsive. If your script needs to make a network call, there may be nothing for it to do but wait until that call returns, but the user still needs to be able to scroll, click, etc., while that's happening.
This is why asynchronous I/O APIs became prevalent in JavaScript (initially with callbacks, with promises and then async/await syntax added later to make things nicer). Ryan Dahl then realized that this could also be used in a server-side context and would thereby solve the C10K problem, and so Node.js was initially designed with that same discipline (which was later relaxed a little with APIs like fs.readFileSync).
If Brendan Eich had realized in 1995 that this was how things were going to work, perhaps he'd have added green threads and browser events would spawn new ones (and so could block without locking up the page), but that's not the order things happened in.
The problem with checked exceptions is that they don't compose with the rest of the type system. Hence the infamous problems with things like Streams. Result types have basically all the virtues of checked exceptions without the problems.
Result types do have one problem that checked exceptions don’t. Checked exceptions automatically combine into union types in a throws or catch clause. I haven’t seen a language that lets you be generic like that.
T fn() throws E, F, G
vs
Result<T, E | F | G> // not even Rust lets you do this.
That's more a consequence of Rust needing its tagged unions declared up front so it can lay them out consistently in memory without runtime type information. Python and TypeScript have untagged unions (that are discriminated at runtime by the RTTI attached to all objects in the underlying dynamic language); they don't happen to have an equivalent of Rust's ? operator, but if they did it'd work like you're describing.
People often call Python/TypeScript unions "untagged unions" even though they're a very different creature from C/Rust unions. Ideally there'd be a term specifically for them but I'm not aware of one.
C# already has second-class references; this is essentially what the ref keyword does. It's actually a bit more expressive than what Hoare suggests he'd have done (you can return ref structs and you can store them in other ref structs), but it doesn't have full-blown Rust-style lifetime annotations.
Rust doesn't have this behavior (sometimes called "life before main"). Code to initialize a static variable runs either at compile time, or lazily on first access, depending on which mechanism you use.
Yeah, I don't think that "precompute something at compile-time" is really comparable to "every import literally executes code as a script". Rust imports are actually about as far from this as I can imagine, because modules can circularly reference each other, which unless I'm misunderstanding would be an infinite loop in Python without manually breaking the chain with some form of conditional.
I'm actually kind of surprised to see comments like that one, because compile-time logic feels like the opposite end of the spectrum from what Python imports do, with "regular" code being compiled without any precomputation sitting somewhere in the middle. It seems like I didn't articulate my thoughts clearly enough though, since several people seemed to read what I was saying as being comparable.
reply