Settings

Theme

Functional Language Features in Rust – Iterators and Closures

rust-lang.github.io

72 points by nanxor 9 years ago · 41 comments

Reader

bigger_cheese 9 years ago

That was really well written. As I was reading through the example code in the section about closures

    let add_one = |x| x + 1;
    let five = add_one(4);
I thought to myself "hmm I wonder what happens if I were to call the code with a float rather than an int?"

Answered my question a few paragraphs down. Kudos.

Is it possible to write a generic closure? i.e something that would add 1 to any numeric type.

  • Manishearth 9 years ago

    > Answered my question a few paragraphs down. Kudos.

    I absolutely love it when a blog post, talk, or docs like these do that.

    Especially during talks. Often the speaker will say something and it will immediately pop up questions in my mind which I really really want to ask but of course I should wait till the end. And then they answer it in the next slide. Perfect :)

  • steveklabnik 9 years ago

    Thanks!

    To answer your last question, not yet. There was an RFC for this, but it was recently postponed; closures rely heavily on traits and we are in the process of re-doing the internals of the trait system. If I remember the reason correctly.

    • eddyb 9 years ago

      Indeed, the way you would be generic over generic closures would be "type HRTB" (e.g. F: for<T: Clone> Fn(&T) -> T), which depends on the trait system overhaul, just like ATC.

  • TheCycoONE 9 years ago

    The whole new Rust Book is quite well written. It was my first resource when I read it a few months ago and I found it easy to understand everything it covered - even lifetimes which I completely failed to get from the original book or other online resources. I look forward to the rest of the chapters being filled in.

computerphage 9 years ago

For context: there's a rewrite of the rust book in progress for a while now. This is a chapter of that book.

  • steveklabnik 9 years ago

    Yes. Co-author here, happy to answer any questions or hear feedback on the text, as usual.

    Incidentally, I just finished the build system stuff today to get the new book shipped on doc.rust-lang.org; that slates it to land in Rust 1.18. It will still be a draft, but this is one more step towards it being finished.

theossuary 9 years ago

Please don't take over my Cmd+Left arrow key for going back, Chrome already took away my backspace :(

curun1r 9 years ago

Under the "Improving our I/O Project" section, there's this little paragraph:

  It would be nice if we could use ? on the Option
  returned from next, but ? only works with Result
  values currently. Even if we could use ? on Option
  like we can on Result, the value we would get would
  be borrowed, and we want to move the String from
  the iterator into Config.
It seems remiss to not mention that Option/Result have combinators/adapters too, no?

  let search = match args.next() {
      Some(arg) => arg,
      None => return Err("Didn't get a search string"),
  };
becomes:

  let search = args.next().ok_or("Didn't get a search string")?;
I'm not the most fluent in Rust, so please tell me whether the above two snippets are not equivalent in some way.

It might actually be a nice segue into a page on the combinators of Option and Result, since functional-style Rust seems to benefit from liberal use of them.

  • steveklabnik 9 years ago

    This is a great suggestion! I'm on mobile right now, but I'll file an issue when I get home, or if you feel like it, please do!

  • pitaj 9 years ago

    Please don't quote with code blocks.

    • curun1r 9 years ago

      Umm...If I don't quote the entire code snippet, I'll end up with just the indented lines being quoted...the joys of HN formatting.

      • pitaj 9 years ago

        I was speaking with reference to "It would be nice..." which you quoted using a pre/code block (prepending four spaces). Please only use that for actual code, and use `>` at the start of the line to signify a quote, like so:

        > Umm...If I don't quote the entire code snippet, I'll end up with just the indented lines being quoted...the joys of HN formatting.

        This allows for responsive formatting on different screen sizes, and is especially beneficial for mobile users.

bmh100 9 years ago

This is beautiful. Higher order functions and closures are a big reason why I enjoy functional programming languages. To see these applied with method chaining is very exciting in a systems programming language.

wahern 9 years ago

How would one explicitly allocate space for a closure? (That is, in such a way that one could handle allocation failure.) I can't find any examples nor any hints about what the syntax might look like.

  • steveklabnik 9 years ago

    Closures are stack allocated unless you wrap them in something like a Box, so it's up to you. They're no different than any other value.

Dowwie 9 years ago

very well written

dozzie 9 years ago

Iterators of this form are not functional construct, they are a pattern from object-oriented programming.

  • steveklabnik 9 years ago

    This is why we say

    > We're going to sidestep the issue of what, exactly, functional programming is or is not, and instead show off some features of Rust that are similar to features in many languages referred to as functional.

    Many people think of "programming with higher order functions" to be a feature of functional languages, and that may be wrong, but it's also okay. The goal is to teach the stuff, not worry about what exacty "functional" means.

    • dozzie 9 years ago

      OK, but if you avoided calling non-functional patterns part of functional programming, you would avoid invoking the topic of "what constitutes functional programming" altogether.

      • Rusky 9 years ago

        OK, but if you avoided disputing the definition of a word the author explicitly said was irrelevant, you would avoid invoking the topic of "what constitutes functional programming" altogether.

        • dozzie 9 years ago

          Thank you for pointing out that the word was irrelevant (and thus should not have been used in the first place).

      • hexane360 9 years ago

        "OK, but if you just asked me what constitutes functional programming, you could avoid me complaining about what constitutes functional programming"

      • steveklabnik 9 years ago

        What specifically does "functional programming" mean to you and why do these features not qualify?

        • frankmcsherry 9 years ago

          > In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.

          from https://en.wikipedia.org/wiki/Functional_programming

          I totally agree that neither iterators nor 2/3s of closures are "functional programming". That's fine, though, because I really enjoy the sane way that it all was done.

          If you check out

          https://doc.rust-lang.org/std/iter/trait.Iterator.html

          and search for `FnMut`, you see that most of the iterator methods are side-effectful. That is cool and fun and very useful, but it isn't functional programming.

          Edit. The term you are probably looking for (guessing) is "higher-order programming":

          https://en.wikipedia.org/wiki/Higher-order_programming

          • steveklabnik 9 years ago

            Yeah that is one way of doing it, but I'm not sure how practically useful it actually is; many functional languages do allow for mutation and/or side effects too. Often in a controlled way, of course, but then again, so does Rust. That said, I wouldn't argue that Rust is a functional language exactly, mostly that I find essentialist FP definitions to be lacking, like most essentialist definitions.

            That said, you're right that "higher order" is a better description of these features, but my counter would be that most people perceive higher order programming as an aspect of functional programming, bringing it full circle again :)

            • frankmcsherry 9 years ago

              Most people perceive structs and fields as an aspect of object-oriented programming, but you probably wouldn't write about them under the heading of "Object-oriented programming".

              Maybe change the title to "Functional Language Idioms"?

              • steveklabnik 9 years ago

                The "oh no OOP" chapter is later :)

                That's a good suggestion, I'll think about it, thanks :)

          • ben0x539 9 years ago

            `FnMut` just means that the iterator methods don't artificially restrict the user-supplied closures. `map` itself doesn't become impure just because you can map `|x| { counter += x; x+1 }` over your list if you really want to.

            I think it's fair to say that iterator methods are typically used as combinators to build computations out of pure functions to avoid having to manage mutable state.

        • dozzie 9 years ago

          Certainly functional programming is not making the data containers to fulfil a separately defined interface. This comes from OOP paradigm (its form that is implemented in most languages).

          And then, what specifically does "functional programming" mean to you that makes implementing an interface a feature from functional paradigm?

          But this all misses the point of my comment. If you knew it would invoke the unnecessary discussion to call the iterator "functional feature" (as the quoted comment signifies), you should have rephrased the title of the chapter in the first place, rendering the disclaimer unnecessary.

          • steveklabnik 9 years ago

            You didn't answer my question.

            • dozzie 9 years ago

              I did, at least the relevant parts of your question. And it still stands that you missed my point that you just created a contention point fully knowing that it is useless contention (your quoted remark from the chapter prooves both that you knew it will be problematic and that you didn't need it there).

          • sixbrx 9 years ago

            No OO style interfaces here, Ierator and IntoIterator are traits, which are more akin to a type class from Haskell than an interface as seen in OO languages

  • ben0x539 9 years ago

    The way iterators are used in Rust is reminiscent of the use of lazy lists in, like, Haskell, enabling a distinctly functional-ish style.

  • WatchDog 9 years ago

    If you are thinking of the Iterator class in Java, a rust iterator is more akin to a Java stream.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection