Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-write closures chapter #23568

Merged
merged 1 commit into from
Apr 2, 2015
Merged

Conversation

steveklabnik
Copy link
Member

the name: a closure "closes over its environment." What does that mean? It means
this:
```rust
let plus_one = |x: i32| -> i32 x + 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per rust-lang/rfcs#968 braces will be required here.

@mdinger
Copy link
Contributor

mdinger commented Mar 21, 2015

On the whole, I think this is very informative. It's use of Box, traits, and various dispatch types seems to reinforce the idea that in Rust, there are a few important ideas which extend to be very encompassing and cohesive. It's not just a disparate set of parts cobbled together in odd ways. Some parts of the language probably feel more this way than others.

Little was said about the differences between Fn, FnMut, FnOnce. That's the only other thought I had.


println!("The sum of 5 plus 1 is {}.", add_one(5));
```rust
let plus_one = |x| x + 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one warning: I expect that the fix for #23319 will cause this not to work unless you annotate the type of x (|x: i32|)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense. let's see which one lands first, I guess.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, it's still working

@steveklabnik
Copy link
Member Author

Added some commits to address some of the additional stuff. I think I'll wait till #23282 to land before I polish the rest off, since that changes some things.

@Manishearth
Copy link
Member

(#23282 landed)

interesting, but when you combine them with functions that take closures as
arguments, really powerful things are possible.
Rust not only has named functions, but anonymous functions as well. Anonymous
functions that have an associated environment are called 'closures', and Rust
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a comma splice in this sentence - how about:

Anonymous functions which have an associated environment are called 'closures' since they 'close' over their environment. Rust has a flexible implementation of closures that centers around overloading the calling operator: ().

You might want to drop the bit about (), but I just wanted to say something else in that sentence other than "the rust version is cool."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

introductions are hard. I re-worded this slightly, but don't know what exactly to add. I'm not sure describing it as () overloading really captures what I love about closures.

the enclosing stack frame. Moving closures are most useful with Rust's
concurrency features, and so we'll just leave it at this for
now. We'll talk about them more in the "Concurrency" chapter of the book.
# Closure implementation
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section comes far too late in my opinion. If you don't know about these traits, it significantly hampers your ability to form a clear mental model while reading the beginning of this guide.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You show use, then you show implementation.

@steveklabnik
Copy link
Member Author

Okay, updated to address feedback.

@nikomatsakis , with the new subtyping relationship, how do I specify the associated type? The 'this is what Rust expands your code to' section is incorrect, but I'm not sure how to make it right.

@nikomatsakis
Copy link
Contributor

@steveklabnik let's touch base on this!


You'll notice a few things about closures that are a bit different than regular
functions defined with `fn`. The first of which is that we did not need to
annotate the types of arguments the closure takes or the values it returns. We
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One problem is that, in your example, you did need to annotate the type of the argument (but not the return). This is ... frequently but not always necessary if there is no expected type (that is, if the || expression does not appear in a context that implies the type of the arguments, such as foo(|| ..)).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem of course is that to include a caller, you must explain that part, which I know you're trying to avoid. Maybe just a note saying something like "you can elide the argument types too, when the closure is used as part of a call expression. we'll see that later."

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've tweaked some things, this shoudl be good now

```rust
fn plus_1 ( x: i32 ) -> i32 { x + 1 }
let plus_2 = |x: i32 | -> i32 { x + 1 };
let plus_3 = |x: i32 | x + 1 ;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit, plus_2 should probably be x + 2 in the body

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh, so this is because it's the second plus_ function, unfortuante clash. lemme tweak it

@nikomatsakis
Copy link
Contributor

r+ -- seems like this can be improved over time, but it's pretty good

@steveklabnik
Copy link
Member Author

@bors: r=nikomatsakis rollup

@bors
Copy link
Contributor

bors commented Apr 1, 2015

📌 Commit eac94fa has been approved by nikomatsakis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.