The time is soon. I as much as anyone want error handling to be flawless, but I don't think that's enough of a reason to hold back the rest of the language. If we have to evolve our approach to error handling a ways down the road, so be it. Other languages have endured similar paradigm shifts.
However, this issue will be inherently subjective... all I can say for sure is, if nobody at all were saying "no, it's too early!", it would certainly be too late. :)
Ultimately I do appreciate reaching 1.0 is a difficult set of tradeoffs and everyone has their pet feature they're sad isn't going to make it in. Bring on 2.0!
> while the same is not necessarily true for HKT
By far the biggest demand for HKT is from people who are requesting Haskell-like do-notation for error handling. HKT would affect everything! Given this, I absolutely agree with the notion that HKT is a 2.0 feature rather than a 1.0 feature.That hasn't been my experience -- we are constantly running into cases in the libraries where we need HKT to express signatures in traits. The simplest example is talking about iterator return types, which often need to depend on a lifetime. See the collections reform RFC (https://github.com/aturon/rfcs/blob/collections-conventions/...) for details on that example. There are many, many others.
I suspect that HKT's role in Rust will be much more about extending the trait system for generic programming, rather than full-blown monadic programming.
In my opinion it is a pity that HKT wasn't there from day one. I had high hopes for Rust, because in comparison with languages like Go, it didn't take a stance like generics are hard, lets go shopping. And personally I can see problems with such pragmatic approaches, because such features have to be baked in, otherwise they'll either never make it or they'll suck.
And then we are back to square one - C++ and Java forever.
> In my opinion it is a pity that HKT wasn't there from
> day one.
I think this shows a misunderstanding of the genesis of Rust. :P Literally the only feature of early Rust that has survived to the present day has been the use of `unsafe` blocks to cordon off bits of code that cannot be statically checked for safety (I don't count things like generics as having survived from early Rust, because early Rust used Java-style virtual dispatch for generics rather than C++-style monomorphization (nor did it have typeclasses, because traits weren't conceived until later)). From day one, the goal has simply been to make a systems language that was safer than C++, and it's taken years to figure out how to do that effectively. And as a goal-oriented language, features are cheap: Rust has thrown out more features than most languages will ever have. The fact that HKT aren't there yet is because they're merely a nice-to-have rather than strictly necessary (in the way that lifetimes are strictly necessary), and because Rust has never particularly valued maximal expressivity in the way that e.g. Scala has. In the meantime, just because generic monads aren't possible doesn't mean that monads can't be approximated for specific types like Result and Option, and the lack of them isn't going to prevent Rust from its goal of being a replacement for C++.It's possible that we will add at least the `?` notation to replace `try!` before 1.0 final; it remains to be seen.
I wouldn't really consider a language without a standard library "complete", and a good standard library is important to me in a language. (As it's going to help you get stuff done.)
¹Python, for example, doesn't specify iterator invalidation rules AFAICT; you just have to look at what CPython does. And in CPython, there are ways to make an iterator return a sequence of items that does not make any sense. (e.g., the same item twice, or skipping items…) In C++, invalidation is well-specified, but the compiler doesn't really help catch errors.
You shouldn't read much into the "experimental" tags right now; they're part of an API stability tracking system that is heavily in flux at the moment. In particular, for most of the modules you mentioned, only the module name itself has not been marked "stable", while the contents have been. For example, if you look at the Vec type itself:
http://static.rust-lang.org/doc/master/std/vec/struct.Vec.ht...
you'll see that most methods are unstable or stable, rather than experimental. (The "experimental" status is currently the default, to help us keep track of API "stabilization" progress.)
This stability tracking is part of our general story about API compatibility; you can read more at
http://blog.rust-lang.org/2014/10/30/Stability.html
These markers won't take on their full meaning until we ship 1.0.
For 1.0, all of the APIs you mentioned will be "stable", and indeed most of their internals already are. Over the next few weeks, we'll be updating stability markers to reflect the API scrutiny and design work that we've been doing.
More generally, for all but a couple of the modules listed at
http://static.rust-lang.org/doc/master/std/index.html?search...
we have already performed a detailed scrutiny of the API, and have either landed changes needed for 1.0 or will do so very soon. Most truly experimental APIs have already been deprecated or removed.
For IO in particular, you can read a very recent RFC that proposes the final set of API changes for 1.0:
https://github.com/rust-lang/rfcs/pull/517
Hope that helps!
2) this means Rust will have a small standard library. But we already have Cargo. So you end up getting lots of packages, they just aren't built-in: they require adding one line to a config file instead.
3) iterator invalidation is a compile-time error in Rust. Rust relies on Iterators quite heavily.
> I haven't seen any confidence that HKT can be implemented
> in a backwards compatible way
Because nobody has ever managed to propose a design for HKT. How can you possibly future-proof against a feature with no clear idea as to its shape?For example, see https://github.com/rust-lang/rfcs/pull/213#issuecomment-6575...
Then "nothing" happens. The default, correct, behaviour for "unhandled" errors is to abort the program. Rust apparently thinks it doesn't need this, because "poisoning". Which is a great thing, except it still doesn't excuse silently swallowing errors. It's one way to end up with a half-dead process. And considering Rust's overall strict handling of errors, it seems bizarrely counter-intuitive to go with the silent route here.
The .NET team went through the exact same process and ended up taking a breaking change in v2 to fix their handling of background exceptions (so now they crash the app unless you opt-in to handling them).
I described it here: https://github.com/rust-lang/rust/issues/19610
But it's closed pending writing an RFC and I haven't had time to figure that out yet.
Edit: I added the RFC: https://github.com/rust-lang/rfcs/pull/519
With the new, threads-only system, I think the only way out is abort.
Rust has been going as a project for five years.
There are many, many people who have been waiting literally years for Rust to stabilize to start using it. (Just look at the comments in any other HN thread about Rust.)
Rough edges in the macro system (which can be fixed post-1.0 and doesn't need to be completely rewritten) and error handling changes aren't enough reason to force them to keep waiting. It would take years to get every single feature in that people want and it'd be doing a disservice to our community to force that huge group of people to wait even longer. And I feel it too—as someone who uses Rust every day, the issues that keep coming up are minor annoyances compared to the major pain caused by lack of stability.
https://github.com/rust-lang/rfcs/pull/243