1. 54
  1.  

  2. 10

    I’m really excited about break values in loops. Before then, my way of setting a value at the end of a loop was to use this funky “let” syntax that doesn’t assign a value, e.g.

    let x;
    loop {
        if foo() {
            x = 5;
            break;
        }
    }
    

    I much more prefer the new method.

    1. [Comment removed by author]

      1. 15

        Lots of things are side-effecting in Rust; that’s not really an axis by which we design the language.

        1. [Comment removed by author]

          1. 4

            Until we get something like the becomes syntax for guaranteed TCO, we need real loops to keep from blowing out the stack in Rust.

            1. [Comment removed by author]

              1. 2

                Yeah! I’ve heard noise about it on the IRC before. Pretty sure there’s an RFC but I can’t find it at the moment…

            2. 3

              Why do you prefer recursion to loops?

        2. 1

          I remember wanting this feature well before 1.0.

        3. 3

          While reading these announcements and considering most of the developments to be rather smart, some of the updates (not necessarily in this one, earlier ones had more “short cuts”) I wonder whether some features geared towards making things easier come at a high price for readability and getting into the language.

          Is there experience on this? Do people consider it a lot harder or read and understand Rust code compared to Go or Python (when they know them and have worked with them of course)?

          I understand that expressiveness of course comes with some price, but I am wondering on how well reading Rust code from other people works, when it remains somewhat idiomatic.

          1. 6

            I write Go and Rust pretty much daily and I don’t really experience any amount of trouble reading code in either one. But I’ve been using both languages for many years now.

            1. 8

              I wonder whether some features geared towards making things easier come at a high price for readability and getting into the language.

              It depends on the feature, really. For example, I wrote this code recently:

              match item {
                  &Item::Module { ref name, ref docs } => {
              

              once https://github.com/rust-lang/rust/issues/42640 is implemented, this code will instead be

              match item {
                  Item::Module { name, docs } => {
              

              much, much easier to read. This is what I actually wrote, but the compiler yelled at me, so I had to add in the &s and refs to make it work. This is geared at usability, but definitely makes reading and getting into it easier.

              ? is another recent one that I think you’re thinking of, maybe; I was skeptical at first but it’s really grown on me. I find it easier to read than the old try!.

              As always, YMMV.

              1. 3

                Coming from the language design of Elm, which takes readability and ease of understanding as a priority, I found the types in Rust in particular to be very counter-productive. For example, imagine you want to split a string. Simple, right? It should just be something like split : String -> String -> List String. Not so in Rust. In Rust, you have to first figure out this type which looks this: <'a, P>(&'a self, pat: P) -> Split<'a, P>. Figuring out what ', & and <> are quite a big wall to run into early on. For this reason, I would not personally recommend Rust unless you specifically have an interest in it or need a language like it for work. I would definitely argue that

                Context: I have done a pretty large amount of Haskell and have written a decent of Idris. Types are not a scary thing to me, but when I run into types which are harder to read than they should be, it really frustrates me. That being said, Rust does do some really cool things, and complicated syntax can help complicated features exist. Different languages have different purposes :)

                1. 14

                  I appreciate what elm does, but the Elm type signature and the Rust type signature express different things.

                  Elm describes: “given a String and a String to split, return a List of new Strings”.

                  We could easily have fn split(&self, pattern: &str) -> Vec<String>. But that would mean that you immediately heap allocate a number of strings. (That’s directly readable from the signature)

                  Rusts split signature describes something very different: “Given a String and a pattern, return slices into the original string. These slices cannot be used after the original String is removed from memory.”

                  Generics aren’t the weirdest thing in the world, so are references. I’m a bit surprised that languages that have a notion of them are now seen as weird.

                  Finally, you make it seem like Strings are the easiest in the world and their APIs all have to be dead simple. The opposite is true: Strings are the nastiest data type. Their APIs might reflect that.

                  I give you that the split signature isn’t the easiest to read at first, that’s why it comes with a lot of examples, which use very easily. It reads very clearly once you know the lingo.

                  1. 5

                    I appreciate and understand the difference, and I also understand the goal. But please remember that I am answering a question from a perspective “How easy was Rust to learn?”, and not “Is Rust a useful language?”. In a world where you have to care about memory, this kind of representation is important. But that does not make is an easy to learn language.

                    I appreciate what elm does, but the Elm type signature and the Rust type signature express different things.

                    The point of the split comparison isn’t quite “this is what Elm does, this is what Rust does” – I was rather saying “This is what I would expect, but instead the type signature looks like that”. In particular, there’s several layers of complexity:

                    • The new Split type
                    • & syntax
                    • 'a syntax
                    • <'a, P> syntax

                    This is why the split type signature is confusing and offputting to newcomers. It does not work nor look as newcomers expect it to.

                    We could easily have fn split(&self, pattern: &str) -> Vec. But that would mean that you immediately heap allocate a number of strings. (That’s directly readable from the signature)

                    It is entirely feasible to have a lazy data structure in the form of an iterator. It does not need to be a custom Split type. It would be easier to understand with that small change – introducing new types instead of using familiar names can have a counter-productive effect on aiding learners.

                    I give you that the split signature isn’t the easiest to read at first, that’s why it comes with a lot of examples, which use very easily.

                    To you, as a user of Rust, it is very easy. To others coming to your language, it is not. The first place I look at when figuring out a function is the types if it has it. The examples come only to clarify the knowledge I gained from the type. split in Rust does not give me sufficient knowledge from the type signature to feel comfortable reading the rest of the document. Of course, given enough examples, I could understand how to use it, but for me, having clear type signatures is more important than having lots of examples. This is why I say that I could not recommend Rust as a language that is easy to pick up, unless you need it at work. Obviously, polyglots and people with an interest in language design will try it out anyway. And they should! It does some very different and interesting things. Please don’t take this as me saying “Rust is bad, don’t use it” :)

                    1. 10

                      Yet, you don’t address my most important point: the comparison doesn’t fit, we have opted for a vastly more powerful implementation at the cost of a harder type signature.

                      The whole rest of the String docs mostly has very with plain signatures.

                      I find your insistence that having all syntactic options of Rust in one signature still a little weird, you will always find functions like that in any language. There’s certainly a problem for people that absolutely want to grok the signature before use, but then, well - that’s the moment where those people must go out and learn them. There’s not much you can do. It’s not even like these are fringe concepts of the language, you will be able to reuse them for years to come :).

                      (By the way, due to the issue of rust not having anonymous return types, it is indeed not possible to avoid the custom Split type)

                      I do know the problems of newcomers quite well, I make part of my income with training Rust and founded the largest training group. split is only shortly among them.

                      I didn’t find your post dismissive, just picking a local maximum and hitting very hard on it also isn’t very useful criticism. Also, your conclusion doesn’t seem quite right: almost every user of Rust currently is a hobbyist, and many find it very interesting that they can finally encode those things in their signatures.

                      1. 2

                        Yet, you don’t address my most important point: the comparison doesn’t fit, we have opted for a vastly more powerful implementation at the cost of a harder type signature.

                        I address this with this:

                        The point of the split comparison isn’t quite “this is what Elm does, this is what Rust does” – I was rather saying “This is what I would expect, but instead the type signature looks like that”.

                        Please re-read my comment carefully. You are coming across fairly hostile, and I don’t want a flame war – like I’ve said, I am not saying that Rust is a bad language.

                        I find your insistence that having all syntactic options of Rust in one signature still a little weird, you will always find functions like that in any language

                        I’d love if you could point out any of such complexity in a language other than Rust, Haskell, Idris or Purescript. For example, if “any” is to be taken to be true, could you find one in Elm or Mypy or Typescript or even Java? There is a restricted set of symbols that you need to learn for each of those, and they tend to come it later, after you have written your first production code.

                        There’s certainly a problem for people that absolutely want to grok the signature before use, but then, well - that’s the moment where those people must go out and learn them

                        Here’s the funny thing about using symbols in type signatures: they are literally ungooglable. It’s hard to learn what 'a means, because you cannot Google it easily.

                        By the way, due to the issue of rust not having anonymous return types, it is indeed not possible to avoid the custom Split type

                        This is another area where Rust trades power for readability and accessibility. Languages can and should be improved constantly.

                        I do know the problems of newcomers quite well, I make part of my income with training Rust and founded the largest training group. split is only shortly among them.

                        If that is true, then I am very surprised that you yourself say in another comment.

                        I’m a little confused by this, as the docs come with a ton of examples and usage is really easy. Yet people get hung up on the type signature, which is admittedly “all in” at first, but easy to read once you are a little in.

                        If your job is literally training people to understand Rust, then I assume you also take time to learn why they see things that way. I am telling you that examples alone are not enough for me: perhaps some documentation that explains why split is the way it is is needed. Just showing what it does is not enough.

                        I didn’t find your post dismissive, just picking a local maximum and hitting very hard on it also isn’t very useful criticism

                        It’s interesting, as I do find your post dismissive and hostile. I’m simply giving my opinion on the language design of Rust from the perspective of how easy it is to learn. That was the original question. I’m answering it from the perspective of someone who works with a language that is easy to learn.

                        Edit: I originally phrased part in a negative manner, due to bad English skills. Rephrased to be less negative

                        1. 4

                          Your original comment said this:

                          but when I run into types which are harder to read than they should be

                          And you (seemed to) back this up by a false equivalence.

                          This is very different than saying, “these are things that are hard for a newcomer to learn,” which would be entirely reasonable. I think you shifted more towards this position in your follow up comments, but it was not at all clear from your first comment. Your first comment makes it seem like Rust introduces needless complexity into its type signature, instead of acknowledging the tradeoffs that skade pointed out.

                          In general, I do agree with you that the type signature is hard to read. I personally think it’s hard to read more because of the conceptual burden rather than specific pieces of syntax though, which makes it a much easier pill to swallow. The conceptual burden is there for a very good reason. Nevertheless, I do take this into account when designing library APIs. Failing that, I rely on writing clear documentation with examples to counteract the complexity in the type signature.

                          1. 4

                            That’s fair enough, I guess what I meant was that is harder to read than I, as the learned, expected it to be, rather than it being harder than it needs to be. I did not meant the complication is fully unwarranted – some of it is, and Rust represents some things in types few other languages do.

                            1. 4

                              Agreed. A big part of teaching Rust is managing expectations.

                  2. 2

                    As a beginner thinking “split” would be an easy, I tried reading the docs (i.e., parsing the type) and gave up. For things like these I bruteforced my way through the compiler errors or asked in #rust-beginners on irc.mozilla.org.

                    1. 6

                      I’m a little confused by this, as the docs come with a ton of examples and usage is really easy.

                      https://doc.rust-lang.org/std/string/struct.String.html#examples-52

                      Yet people get hung up on the type signature, which is admittedly “all in” at first, but easy to read once you are a little in.