Recent submissions

Comment · 4 years ago
> That single passing reference to him as King of Assyria, was everything that was known of him for 2500 years, until the ruins of Dur-Sharrukin, his capital (destroyed during the mentioned wars) were excavated in the 19th century.

I only have a layman's knowledge of this part of history, but this strikes me as unlikely. Surely something was known of him for some time in other sources, probably hundreds of years at least, before those source were also lost? The loss of knowledge is also second-order: we have lost knowledge of what was known to our predecessors.

Comment · 4 years ago
Comment · 4 years ago
You're begging the question when you say that GATs are "not comprehensible for a mortal like myself." My entire point is that they were designed not to be incomprehensible.

What is "not comprehensible for a mortal" in this situation is why adding a generic to an associated type is a long-anticipated feature that took years of development to support. This is related to the "incomprehensible" discussion that occurs around this feature, talking about type functions and higher kindedness and all of these mathematical formalisms. But this discussion is just happening among practitioners and enthusiasts schooled in a certain jargon and area of arcane knowledge. It doesn't mean you need to understand any of this to just use the feature.

It's like people saying the internet is "not comprehensible for a mortal like myself" because most people do not have the background to properly understand IP/TCP/HTTP and how things like this undergirdle the technology that they use. And yet they use the internet just fine. If the design has succeeded, you should not need to even hear words like "higher kindedness" before you can make your associated type generic.

Possibly the system design is imperfect and the abstractions leaks and you as a user have to learn more than one would hope in order to successfully use the tool to accomplish your goals. Rust doesn't have a perfect track record here.

Comment · 4 years ago
I hope you don't. To establish my credentials for this comment - GATs were my idea.

The entire point of GATs was to carve out a design space that solved peoples' problems without being so high-minded as monads and HKT and so on. Unfortunately, a lot of people who like monads like to talk about GATs in the same way. But its really as simple as this: when you add an associated type to a trait, you can make that type generic, the same way you can make a type alias generic when its not in a trait. The whole point of specifying GATs and not a more general "HKT" is that it's an obvious extension of the existing language.

There are lots of useful traits that you can't define if you can't make an associated type generic, so people are excited to have this feature.

It turned out that implementing this in rustc took a very long time, because refactoring the typechecker of rustc to support this was challenging. But that doesn't mean the feature itself is complicated or difficult to use. The whole point of GATs is that it shouldn't really feel like a feature once it's done: naturally, if you are writing a trait with a method that returns `Self::Foo`, but you need it to be `Self::Foo<T>` or `Self::Foo<'a>`, you can just do that, rather than the compiler telling you that it's not supported.

Comment · 4 years ago
That's not why I stopped working on Rust. Given that Amazon, Google, Microsoft and others all employ people to work on Rust, lack of money is certainly not the problem. There has never been more money in Rust development.
Comment · 4 years ago
> Async support is incredibly half-baked. It was released as an MVP, but that MVP has not improved notably in almost three years.

As the primary mover of the MVP (who stopped working on Rust shortly after it was launched), I'm really sad to see this. I certainly didn't imagine that 3 years later, none of the next steps past the MVP would have even made it into nightly. I don't want to speculate as to why this is.

I also recommend avoiding async if you don't need. Unfortunately for people who don't need it but do want to do a bit of networking, a huge part of the energy behind Rust is in cloud data plane applications, which do need it.

Comment · 5 years ago
Java's NPE is not at all the same thing as the undefined behavior of dereferencing a null pointer in C (or Zig in release mode). In fact its the same exact thing as calling unwrap. Your Java server's NPE is not bringing down the entire server because the exception is caught somewhere. The same can be done in Rust (and is, by many frameworks), where panics are caught before they crash the entire application.
Comment · 5 years ago
This is the opposite of reality: in Rust, the safe syntax `?` exists and there is no short syntax for the panicking form (`.unwrap()`). Users are not incentivized to unwrap in Rust, users are as disincitivized as possible to unwrap.

The uses of unwrap in the projects the GP cited are overwhelmingly in tests and examples, which are not expected to handle errors in the same way as application code. The remainder are mainly lock poisoning unwrapping, which is a completely endorsed idiom.

Comment · 5 years ago
It is not at all like Rust; it is a garbage collection system based on reference counting, pretty similar to Swift. This is obscured by the documentation for each using similar terminology (like "move semantics" and "ownership") to refer to systems with different characteristics.
Comment · 5 years ago
I hope your book does well.
Comment · 5 years ago
It doesn't really matter to me what you, an internet stranger, are "excited to consider as something you want to work with." Instead, what you should consider is how incredibly boorish it is to post that "async is broken by design" in reply to the person who designed async.
Comment · 5 years ago
As others have written, there's basically no connection between Rust's six week release cycle & the rate of actual change to Rust. If Rust switched to a 12 week release cycle, all that would change is that it would take twice as long for features to reach users on stable once they were decided to be released. Feature development is neither release driven nor release constrained.

However, the ground truth is that the design of significant new language features basically stopped in 2018. The work now is shepherding through the language extensions the project already committed to in the first few years after 1.0. For example, const generics, which will have a stable MVP in the next release, was first begun in 2017. Generic associated types, which are still not near stable, in 2016.

And my own view, these remaining features are a nearly "feature complete" Rust. Future extensions will be either more niche (a lot of attention in the last few years has been aimed at features to make writing unsafe code less error prone, which wouldn't visibly impact users who write only safe code) or less substantial (such as a syntactic sugar that would improve a lot of users lives, but not deeply change how they write code). And that's actually very good.

Comment · 5 years ago
> But then, in a typical use of select, you don't actually want to cancel the I/O operations represented by the other futures. Rather, you're running select in a loop in order to handle each completed operation as it comes.

You often do want to cancel them in some branches of the code that handles the result (for example, if they error). It indeed may be prohibitively expensive to wait until cancellation is complete - because io-uring cancellation requires a full round trip through the interface, the IORING_OP_ASYNC_CANCEL op is just a hint to the kernel to cancel any blocking work, you still have to wait to get a completion back before you know the kernel will not touch the buffer passed in.

And this doesn't even get into the much better buffer management strategies io-uring has baked into it, like registered buffers and buffer pre-allocation. I'm really skeptical of making those work with AsyncRead (now you need to define buffer types that deref to slices that are tracking these things independent of the IO object), but since AsyncBufRead lets the IO object own the buffer, it is trivial.

Moving the ecosystem that cares about io-uring to AsyncBufRead (a trait that already exists) and letting the low level IO code handle the buffer is a strictly better solution than requiring futures to run until they're fully, truly cancalled. Protocol libraries should already expose the ability to parse the protocol from an arbitrary stream of buffers, instead of directly owning an IO handle. I'm sure some libraries don't, but that's a mistake that this will course correct.

Comment · 5 years ago
Of course I was more gracious to pornel - that remark was uncharacteristically flippant from a contributor who is normally thoughtful and constructive. pornel is not in the habit of posting that my work is fatally flawed because I did not pursue some totally unviable vaporware proposal.
Comment · 5 years ago
That is not a correct reading of the situation. async/await was not rushed, and does not have flaws that could have been solved with more time. async/await will continue to improve in a backward compatible way, as it already has since it was released in 2019.

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton