about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSteve Klabnik <steve@steveklabnik.com>2015-10-07 18:18:36 -0400
committerSteve Klabnik <steve@steveklabnik.com>2015-10-07 18:18:36 -0400
commitf688c0e71153a4ee6ca936076cbad1bb08d3c52c (patch)
tree3cc2213872658d650471bc2ee3b450dfc8f21bf2
parent18c66b5afff6b1ba860357c07fac963ea9b50b6e (diff)
parent7895ec2d5752c5a5dacd17d463e401d9e85fac13 (diff)
downloadrust-f688c0e71153a4ee6ca936076cbad1bb08d3c52c.tar.gz
rust-f688c0e71153a4ee6ca936076cbad1bb08d3c52c.zip
Rollup merge of #28856 - chills42:master, r=steveklabnik
This is to address issue #28803 by improving some of the references to closures, to explain what they are more clearly, while hopefully still being concise.

r? @steveklabnik
-rw-r--r--src/doc/trpl/closures.md45
1 files changed, 24 insertions, 21 deletions
diff --git a/src/doc/trpl/closures.md b/src/doc/trpl/closures.md
index 983af4a0efe..7d4452a4c84 100644
--- a/src/doc/trpl/closures.md
+++ b/src/doc/trpl/closures.md
@@ -1,9 +1,10 @@
 % Closures
 
-Rust not only has named functions, but anonymous functions as well. Anonymous
-functions that have an associated environment are called ‘closures’, because they
-close over an environment. Rust has a really great implementation of them, as
-we’ll see.
+Sometimes it is useful to wrap up a function and _free variables_ for better
+clarity and reuse. The free variables that can be used come from the
+enclosing scope and are ‘closed over’ when used in the function. From this, we
+get the name ‘closures’ and Rust provides a really great implementation of
+them, as we’ll see.
 
 # Syntax
 
@@ -34,7 +35,7 @@ assert_eq!(4, plus_two(2));
 ```
 
 You’ll notice a few things about closures that are a bit different from regular
-functions defined with `fn`. The first is that we did not need to
+named functions defined with `fn`. The first is that we did not need to
 annotate the types of arguments the closure takes or the values it returns. We
 can:
 
@@ -44,14 +45,15 @@ let plus_one = |x: i32| -> i32 { x + 1 };
 assert_eq!(2, plus_one(1));
 ```
 
-But we don’t have to. Why is this? Basically, it was chosen for ergonomic reasons.
-While specifying the full type for named functions is helpful with things like
-documentation and type inference, the types of closures are rarely documented
-since they’re anonymous, and they don’t cause the kinds of error-at-a-distance
-problems that inferring named function types can.
+But we don’t have to. Why is this? Basically, it was chosen for ergonomic
+reasons. While specifying the full type for named functions is helpful with
+things like documentation and type inference, the full type signatures of
+closures are rarely documented since they’re anonymous, and they don’t cause
+the kinds of error-at-a-distance problems that inferring named function types
+can.
 
-The second is that the syntax is similar, but a bit different. I’ve added spaces
-here for easier comparison:
+The second is that the syntax is similar, but a bit different. I’ve added
+spaces here for easier comparison:
 
 ```rust
 fn  plus_one_v1   (x: i32) -> i32 { x + 1 }
@@ -63,8 +65,8 @@ Small differences, but they’re similar.
 
 # Closures and their environment
 
-Closures are called such because they ‘close over their environment’. It
-looks like this:
+The environment for a closure can include bindings from its enclosing scope in
+addition to parameters and local bindings. It looks like this:
 
 ```rust
 let num = 5;
@@ -197,9 +199,10 @@ frame.  Without `move`, a closure may be tied to the stack frame that created
 it, while a `move` closure is self-contained. This means that you cannot
 generally return a non-`move` closure from a function, for example.
 
-But before we talk about taking and returning closures, we should talk some more
-about the way that closures are implemented. As a systems language, Rust gives
-you tons of control over what your code does, and closures are no different.
+But before we talk about taking and returning closures, we should talk some
+more about the way that closures are implemented. As a systems language, Rust
+gives you tons of control over what your code does, and closures are no
+different.
 
 # Closure implementation
 
@@ -288,9 +291,9 @@ isn’t interesting. The next part is:
 #   some_closure(1) }
 ```
 
-Because `Fn` is a trait, we can bound our generic with it. In this case, our closure
-takes a `i32` as an argument and returns an `i32`, and so the generic bound we use
-is `Fn(i32) -> i32`.
+Because `Fn` is a trait, we can bound our generic with it. In this case, our
+closure takes a `i32` as an argument and returns an `i32`, and so the generic
+bound we use is `Fn(i32) -> i32`.
 
 There’s one other key point here: because we’re bounding a generic with a
 trait, this will get monomorphized, and therefore, we’ll be doing static
@@ -452,7 +455,7 @@ autogenerated name.
 The error also points out that the return type is expected to be a reference,
 but what we are trying to return is not. Further, we cannot directly assign a
 `'static` lifetime to an object. So we'll take a different approach and return
-a "trait object" by `Box`ing up the `Fn`. This _almost_ works:
+a ‘trait object’ by `Box`ing up the `Fn`. This _almost_ works:
 
 ```rust,ignore
 fn factory() -> Box<Fn(i32) -> i32> {