Priorities after 1.0

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.

To me, a stable way of doing async I/O would be very important. Right now, there doesn’t seem to be any good way to select() from multiple Readers in an event-driven way. Also, I’m wondering what happened to the Deadlines design that was brought up during std::io redesign. Currently, not being able to cleany stop listing on or reading from e.g. a socket is a complete deal-breaker when writing server applications.

3 Likes

There's an RFC for timeouts (rather than deadlines) that is pretty straightforward. I need to update it with some feedback, but otherwise I think we should be able to land this for 1.1 beta.

The hidden Drop flag. It makes C interoperability fragile and crashy (currently it’s really bad. Code that worked pre-1.0 crashes without warning)

This … potentially sounds like the sort of dependency on zeroing that filling-drop ( https://github.com/rust-lang/rust/pull/23535 ) was put in deliberately to expose?

Have you filed a bug about this?

I’d like to see some more minor features with already-accepted RFCs to be implemented; in particular, the box operator and the new array patterns would be nice to have soon after 1.0.

Non-lexical lifetimes and impl Trait are also pretty important in my opinion for newcomers to the language. A lot of lifetime problems that people learning Rust have are because of lexical lifetimes, and I’ve seen quite a few questions on Reddit and IRC about how to return closures. Also, being forced to use trait objects is really not cool, whereas impl Trait gives you the choice to use a trait object but doesn’t force you. Returning closures is definitely one of the messiest parts of the language at the moment in my opinion.

On the other hand, I think that HKT should probably not be prioritised very much. It’s a large expansion of the Rust type system that I personally haven’t needed very often.

I would like easier input (especially for code that simply wants to panic on input parsing error).

Some choices:

  • C style scanf
  • C++ style iostream
  • Java style Scanner
  • Haskell style Parsec
2 Likes

Oddly enough, Rust already has HKTs. * → * is basically just a trait with a type parameter and an associated type. You just have to coach the type system through the relationships involved and tell it that the HKT can be applied to a given type on a case-by-case basis, which makes it hackish and inconvenient, and thus probably shouldn’t be used in real code. Fixing that last problem just means being able to write T : for<U> Trait<U>. The rest could probably be handled by rewrite rules. It would still be non-trivial to specify it, though, and it might be better to design it as a completely separate feature rather than as sugar.

I suggest spending some time writing a spec – grammar, type system, static and dynamic semantics – and an accompanying conformance testsuite that checks the assumptions in the spec. And then correcting the inevitable set of underspecified, surprising, backwards or incoherent aspects of the language discovered along the way.

That and compiler performance / general compiler technical-debt repayment. Including dynamic drop. And exposing a stable syntax-extension interface: lean on token trees as much as possible, with an interface for building opaque AST-nodes and AST-matchers in TT-patterns. Don’t try to stabilize the AST representations themselves. Spliced ASTs are not multi-stage typesafe anyways, so even if they “fit together” at the AST level, they won’t necessarily parse or typecheck any more reliably than if they were built from token trees.

Personally I wouldn’t add any new language-language features for … a few years at this point. It’s got plenty.

(Sorry of saying so is too intrusive; I know this isn’t my project anymore, but you’re asking for observer-input)

34 Likes

I think it is important for you all to make sure that whatever you do, pick some mantra (e.g. “zero-cost abstraction”) and try to stay laser-focused on it. Do something very well rather than a bunch of random things sort of well (this is a vote against random language features that feel neat / smart; mostly stuff in the “longer term” section that feels a little like PL-envy).

My experience as a mid-term user (4-5 months?) is that what I like most about Rust is that once I understand what I need to do I can (usually) write it and it just works. I want more of that (meaning fewer cases where I can’t write what I want, and more “just working”).

My main pain points recently have been

  • Non-lexical borrows: fighting with the borrow checker is mostly a thing of the past, but not entirely, and this such an important part of Rust that making it work smooth feels critical for understanding whether it is progress or not. This is a case of “I could write it, but it didn’t work”.

  • Specialization: When this bites you it is really annoying. Having a story here would make (for me) lots of programs more general and easier/possible to write.

  • Generic functions for boxed trait objects: I don’t even understand if this is an object-safety thing or just a “whoa, you would need too many methods” thing, but it is a point where the JITed languages I used to use clearly win out, and (as far as I can tell) I just can’t write the thing I wanted to write.

  • Performance/Codegen/Fewer ICEs: This isn’t meant to be a dig, but to the extent that adding new features cuts in to the experience using current features, I’d almost rather you not do it. I think we all know what happens if you measure “progress” by number of features added.

  • Tooling: This is always good. Early pain points coming from Visual Studio were largely resolved, but I still type way more than I think I should. I’m also no good at using profilers yet, but I don’t know enough to understand if that is me or the offerings.

If Rust just literally stayed the same, modulo some bug fixes, I think I would be pretty happy. I wouldn’t rush to add crazy new features, but rather just take a breath, watch its use grow a bit, and see what people need (with caution against “faster horse” needs).

5 Likes

“Poor support for arrays” / “Type level integers”

Yes, this! I would really like to see Rust’s story for array math computation improve. The field of control systems is dominated by engineers using MATLAB to generate C code for their controllers. My gripes with that workflow are off-topic, but suffice it to say that I would love to see Rust get good enough at array math that it can be used to put control system design and implementation on a safer, more unified foundation.

1 Like

How about deprecating syntax extensions and procedural macros, focusing instead on compilation speed and tooling?

I think compilation speed and tooling will mainly be done by community, while language features are mainly done by the core team, so they don’t really conflict.

1 Like

I hope compilation speed is also a goal of the core team!

1 Like

I haven’t filed bugs about the crashy-Drop. I’ve asked on IRC about it and learned that Drop and #[repr(C)] are not supported together, so I’ve refactored my code to be less fancy and not use Drop on C types.

How about deprecating syntax extensions and procedural macros, focusing instead on compilation speed and tooling?

Why does deprecating support for these help with compilation speed? They aren’t even officially supported yet (since they’re not considered anywhere close to stable) so I’m not sure how they could be deprecated to begin with. Some compiler plugin machinery is also required to support features of the stable distribution like the built-in lints and rustdoc.

(To be absolutely clear here, I did not interpret “procedural macros” to mean macro_rules! macros; I believe that syntax extensions and procedural macros are supposed to be called “compiler plugins” now, to distinguish them from macro_rules! macros and similar future features which are not as powerful as compiler plugins)

1 Like