Does Rust have severe shortcomings?

Continuing the discussion from Rust beginner notes & questions:

The links here and the discussion that follows should go towards improving the learning curve, once the truth is uncovered and consensus reached here. Please try to move towards consensus here.

The main points as seen in the fourth linked post is shown below. Expand the links to read further.

In post below, read from What I would like to have seen in Rust, else branch to Stream API and types

Thread generates Are Rust crates secure thread.

It feels to me like one should separate out Rust the language from Rust's standard library. A lot of the earlier debate was focused on the standard library and fat/thin standard libraries.

Do people feel that rust's language has severe shortcomings (aside from not being able to do a [..-3] slice :wink: ?

2 Likes

As @leonardo pointed out before, it's not a bug, it's a feature :slight_smile:

Negative indices are a bad design from a performance point of view, because they essentially force extra checking and branching in the Index implementation, which costs performance even for those who do not use the feature!

A better fit for Rust would be some sort of "slice length placeholder", which is automatically replaced by slice.len() under the hood (think e.g. [..$-3]).

2 Likes

You can implement Index<RangeTo<isize>> if you want :wink:

Negative indices are a footgun anyways.

# my go-to example
def last_n_items(xs, n):
    return xs[-n:]

last_n_items(range(10), 3) # [7, 8, 9]
last_n_items(range(10), 2) # [8, 9]
last_n_items(range(10), 1) # [9]
last_n_items(range(10), 0) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

This was debated at length here. I don't mind D's solution (the $-1 mentioned by @HadrienG).

Sorry, can someone please explain what this post is asking? The OP is just a bunch of quotes and everyone's response is about slicing...

Also, negative indices are so 1989 - I use Euclidean modulo indices. No more out-of-bounds exceptions, and you get negative indices for free! /s

I'd be really interested in seeing what some will say to this. Personally, I'm not sure I've found anything I'd deem severe but there are definitely things beyond just papercuts. A few examples:

  1. Type inference. It's basically wonderful until it's not. I have a hard time analyzing some piece of generic code and guessing whether it'll definitely break some callsite code due to inference.
  2. Trait objects are not always easy to use (e.g. you must specify the associated type of the contained trait). There are also "edge cases" like "generic lifetime parameters in trait objects are invariant" - not easy to see/anticipate a priori until you know about it.
  3. There're some odd borrowck edge cases where code that seems like it should work doesn't. I'd like to see NLL and perhaps Polonius come through to see how things look with them.
  4. Coherence/orphan rules can be a pain, which has been discussed many a time in this forum (and elsewhere).
  5. It's very difficult to model/abstract borrows via trait methods. Perhaps virtual fields will help, or a first class notion of "borrow regions" (although not too hopeful about the latter).
  6. & vs &mut vs interior mutability "confusion". Normal mutation needs &mut, but mutation isn't really about & vs &mut afterall as witnessed by interior mutability. But interior mutability requires extra boilerplate. Not sure what a good solution to this is, but the dichotomy is noticeable.
  7. No good solution exists to the self-referential struct case; although rare/niche, they're not pretty when present themselves.

But, for the vast majority of it, Rust is superb.

4 Likes

Sorry, Github is blocking me from editing my comments (it says: Too many edits, wait 20hrs), otherwise, I would have added a summary. This thread collects all the posts in the continued-from thread about where Rust has (supposed) shortcomings. This thread is a bit of a meta-thread in that there are several shortcomings mentioned, but, some of the mentioned points should only require one or two refutations, while others with more merit are meant to be branched off to a new topic linked here.

Could a moderator perhaps re-set the timer for you? I've no idea if such a thing is possible, but, if it is and a moderator has the time....

I've added short comments as replies instead of edits to get around this. Best is for users to comment on specific parts of the linked posts with summaries/responses to give some direction to the discussion.

I can think of one particular shortcoming, maybe not severe but IMO still significant: how traits are implemented for arrays is pretty much a dirty hack. And the unfortunate consequence is that documentation is polluted. We only may hope that at some point in the future Rust will get shiny const generics and similar hacks will be deprecated or even removed altogether. I think, Rust 2.x, it's when we'll get a chance to bring breaking changes, is going to have a great leap forward in terms of productivity and usability.

I don't believe Rust has any severe shortcomings. Certainly it has shortcomings, particularly surrounding API design: const generics, arrays, GADTs, code sharing primitives ('delegation'/newtype boilerplate, diamond specialization), unsafe guidelines, keyword args & var args...

But a function is a very strong abstraction, and plenty of languages have lived on to solve great problems when the only API design available looks like a grab-bag of functions, and certainly Rust can do at least that. Rust's shortcomings have a bigger impact on the overall ecosystem, not the its capabilities as a programming language. (This is probably unavoidable for a new language, and quadruply so for an open-source, cross-platform, general-purpose, opinionated language.)

6 Likes