Priorities after 1.0

I think Rust next should at a minimum try to include 2-3 new nifty features because users love new features. On top of the improved infrastructure (improved build times or whatever), this should by default meet the suck less criteria.

I mean speed and such is always nice but when looking at release notes to decide if you should upgrade (especially if it’s already satisfactory), new features always tend to look cool and :sparkles: sparkly :sparkles:.

[EDIT] I’m not picky currently about which features get included though. A lot of things would be nice I’m sure.

1 Like

How about extending std::process functionality re: stdio (i.e… setting file descriptors in the child & daemonizing)? It’s not listed in the library stabilization metabug. https://github.com/rust-lang/rfcs/issues/941

2 Likes

I think the ability for Cargo to specify required Rust version is very important in long term. This feature have been requested many times[0] and require language level consideration, not third party tools’s hack. Millions of programmers hours have been poured into constructing and debugging rbenv, virtualenv and pyenv things. I hope rust will save that time.

[0] https://github.com/rust-lang/cargo/issues/1214

3 Likes

My vote:

  1. Borrow checker improvements. Lexical borrows are really frustrating and leave a bad impression for newcomers.
  2. Compile time improvements. The compile times from my small-ish applications are way too long, and I’ve given up trying to add improvements to rustc because of the build times.
  3. Library APIs (specifically libraries outside of the standard library). I’d like to see the libraries that started in std, i.e. num, time, etc, get some love. Not only is there not really any improvement from the maintainers, but it’s hard to even suggest and discuss improvements for these crates. I remember I made multiple comments on an issue that I was willing to work on for one of these libraries (I just wanted the go ahead from the maintainers so it wouldn’t get rejected later on), but I got no response, so I just dropped it.

I definitely think that compilation times and compiler refactoring/cleanup should receive as much as attention as possible after 1.0. Consider that faster compile times and easier to understand internals means that work on the distribution, including for these other desired features and enhancements, will get done faster. It also means Bors can get through the queue and land changes more quickly.

2 Likes

It would be a good thing to extend the function traits with something like FnAsync to be able to get safe reentrant functions.

A Rust (exact) specification would be awesome with grammar tests and proof.

I'm surprised by this being an important story while "easier integrations into existing FFI solutions" is not. I expect calling into Rust code to be very important in a short run. Rust has a high chance of being used for things C is a classic for: one of them being shared libraries. Considering that ARM support is a another story listed here, if you think about mobile devices, smooth calling into Rust seems very important for me. Something with a similar statement - calling into simple Rust traits - might be very interesting here.

It's not the same as having an ABI, emitting symbols in a certain format for the C-ABI should be enough.

2 Likes

For me the order would be:

  • Borrow checker improvements - this is one of the key selling points of Rust, (memory safety), therefore we should make sure that it works correctly in most situations, including ifs.
  • Faster compilation times - Besides being memory unsafe, one of the biggest drawbacks of C++ is compilation times, (in fact that’s at least half of the reason why a whole new language (Go) was invented), improving this would definitely be another major selling point on Rust’s “specsheet”.
1 Like

Why would this be a useful goal? There's the philosophical matter of GCC being an Open Source toolchain, which I appreciate some may not care for, but pragmatically the MinGW-w64 toolchain brings C runtime compatibility that MSVC doesn't. What benefits are you looking to achieve here?

There’s no perf hit there, you don’t have to Box your iterator, just create a struct that impl’s Iterator and return that. It’s ugly, but no slower than impl Trait.

Only if you can name the type though. For example it’s impossible to name the type of iter.map(|x| x).

I would love to see keyword arguments for functions sooner rather than later, as it will dramatically change the way some APIs are designed. Using the builder pattern is a workaround for now, but it adds a lot of boilerplate for no real benefit.

4 Likes

Shortly, I would like to link with MSVC binaries. More broadly, there is more than one C++ compiler in the world, different compilers have different advantages, it is not great to depend on one solution, especially when it is not the default one on the platform.

That’s not what I meant. You can define a new type which does what your anonymous closure does (and holds any neccessary state). For instance iter.map(|n| n + x) becomes http://is.gd/xrXbon . Due to inlining this a zero-overhead workaround for lack of impl Trait. This is how all the std iter adapters are implemented.

Also in cases with no state, like your |x| x, example, you can also use fn(T) -> T as the function type i.e. type Identity<I: Iterator> = iter::Map<I, fn(I::Item) -> I::Item>

impl Trait is nice sugar, nothing else.

To be honest, I really meant that as a placeholder for "improved FFI story" in many dimensions, one of which is calling out, but I agree that calling is equally important. I'm curious, what precisely are you looking for? We do have the ability to define Rust fns that use the C abi and so forth. (Best would probably be to open an RFC issue describing what it is you would like to do.)

You’re right, you can simply create your own struct and implement Iterator on it (but let me say that this is very very verbose and inconvenient – e.g. nobody would use closures if you’d need to jump through hoops and create a custom struct each time you want to pass a closure).

The other example with “no state” isn’t the same, fn(T) -> T has a performance impact as it is a function pointer which isn’t necessarily optimized away by the optimizer.

1 Like

I’d add “support for the C preprocessor when writing C wrappers” to the list.

You touched the most important ones for me (integers at the type level, variadics, HKTs, memory allocators, …).

About await/yield/async: there is a current theme in C++ about “avoiding future islands”. I really like the latests Kohlhoff proposal “Resumable expressions” which unifies stackless and stackfull coroutines and allows things like implementing constexpr stack allocated futures: http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4453.pdf

1 Like

I don’t think my ideas/wishes about this are RFC ready, but I’ll open a topic later tonight. (CEST)

I completely agree, it’s a pain and I was hoping for it to be higher priority too—though I sympathize with all the arguments given by other people. I only meant to point out that in the meantime, when perf matters, you can avoid boxing it; I end up doing that a lot in my code.

Re: First I also don’t like over relying on an optmizing compiler—I want my perf to be predictable.

But for the sake of the conversation for an fn pointer, if it’s in the same crate, LLVM seems to do a decent job: http://is.gd/hthlFG . Check out the LLVM IR, it gets expanded directly into 11, 12, 13, 14, inline-ing through the fn ptr.

If you make the iterator returning function inline/generic (which it probably should be), then it should work cross crate too. contain-rs relies on this a lot.