@@ -381,7 +381,7 @@ more detail later on (the `T`s here stand for any other type):
381381` {field1: T1, field2: T2} `
382382 : Record type.
383383
384- ` fn(arg1: T1, arg2: T2) -> T3 ` , ` lambda ()` , ` block ()`
384+ ` fn(arg1: T1, arg2: T2) -> T3 ` , ` fn@ ()` , ` fn~() ` , ` fn& ()`
385385 : Function types.
386386
387387` @T ` , ` ~T ` , ` *T `
@@ -824,32 +824,36 @@ functions that can access variables in the scope in which they are
824824created.
825825
826826There are several forms of closures, each with its own role. The most
827- common type is called a 'block', this is a closure which has full
828- access to its environment.
827+ common type is called a 'stack closure'; this is a closure which has
828+ full access to its environment.
829829
830830~~~~
831- fn call_block_with_ten (b: block (int)) { b(10); }
831+ fn call_closure_with_ten (b: fn (int)) { b(10); }
832832
833833let x = 20;
834- call_block_with_ten ({|arg|
834+ call_closure_with_ten ({|arg|
835835 #info("x=%d, arg=%d", x, arg);
836836});
837837~~~~
838838
839- This defines a function that accepts a block , and then calls it with a
840- simple block that executes a log statement, accessing both its
841- argument and the variable ` x ` from its environment.
839+ This defines a function that accepts a closure , and then calls it with
840+ a simple stack closure that executes a log statement, accessing both
841+ its argument and the variable ` x ` from its environment.
842842
843- Blocks can only be used in a restricted way, because it is not allowed
844- to survive the scope in which it was created. They are allowed to
845- appear in function argument position and in call position, but nowhere
846- else.
843+ Stack closures are called stack closures because they directly access
844+ the stack frame in which they are created. This makes them very
845+ lightweight to construct and lets them modify local variables from the
846+ enclosing scope, but it also makes it unsafe for the closure to
847+ survive the scope in which it was created. To prevent them from being
848+ used after the creating scope has returned, stack closures can only be
849+ used in a restricted way: they are allowed to appear in function
850+ argument position and in call position, but nowhere else.
847851
848852### Boxed closures
849853
850- When you need to store a closure in a data structure, a block will not
851- do, since the compiler will refuse to let you store it. For this
852- purpose, Rust provides a type of closure that has an arbitrary
854+ When you need to store a closure in a data structure, a stack closure
855+ will not do, since the compiler will refuse to let you store it. For
856+ this purpose, Rust provides a type of closure that has an arbitrary
853857lifetime, written ` fn@ ` (boxed closure, analogous to the ` @ ` pointer
854858type described in the next section).
855859
@@ -879,14 +883,14 @@ fn main() {
879883
880884A nice property of Rust closures is that you can pass any kind of
881885closure (as long as the arguments and return types match) to functions
882- that expect a ` block ` . Thus, when writing a higher-order function that
886+ that expect a ` fn() ` . Thus, when writing a higher-order function that
883887wants to do nothing with its function argument beyond calling it, you
884- should almost always specify the type of that argument as ` block ` , so
888+ should almost always specify the type of that argument as ` fn() ` , so
885889that callers have the flexibility to pass whatever they want.
886890
887891~~~~
888- fn call_twice(f: block ()) { f(); f(); }
889- call_twice({|| "I am a block" ; });
892+ fn call_twice(f: fn ()) { f(); f(); }
893+ call_twice({|| "I am a stack closure ; });
890894call_twice(fn@() { "I am a boxed closure"; });
891895fn bare_function() { "I am a plain function"; }
892896call_twice(bare_function);
@@ -903,9 +907,9 @@ them. Unique closures mostly exist to for spawning new
903907
904908### Shorthand syntax
905909
906- The compact syntax used for blocks (` {|arg1, arg2| body} ` ) can also
907- be used to express boxed and unique closures in situations where the
908- closure style can be unambiguously derived from the context. Most
910+ The compact syntax used for stack closures (` {|arg1, arg2| body} ` ) can
911+ also be used to express boxed and unique closures in situations where
912+ the closure style can be unambiguously derived from the context. Most
909913notably, when calling a higher-order function you do not have to use
910914the long-hand syntax for the function you're passing, since the
911915compiler can look at the argument type to find out what the parameter
@@ -941,12 +945,12 @@ returning the day of the week that string corresponds to (if any).
941945
942946## Iteration
943947
944- Functions taking blocks provide a good way to define non-trivial
948+ Functions taking closures provide a good way to define non-trivial
945949iteration constructs. For example, this one iterates over a vector
946950of integers backwards:
947951
948952~~~~
949- fn for_rev(v: [int], act: block (int)) {
953+ fn for_rev(v: [int], act: fn (int)) {
950954 let i = vec::len(v);
951955 while (i > 0u) {
952956 i -= 1u;
@@ -958,7 +962,7 @@ fn for_rev(v: [int], act: block(int)) {
958962To run such an iteration, you could do this:
959963
960964~~~~
961- # fn for_rev(v: [int], act: block (int)) {}
965+ # fn for_rev(v: [int], act: fn (int)) {}
962966for_rev([1, 2, 3], {|n| log(error, n); });
963967~~~~
964968
@@ -967,7 +971,7 @@ moved outside of the parentheses permits the following, which
967971looks quite like a normal loop:
968972
969973~~~~
970- # fn for_rev(v: [int], act: block (int)) {}
974+ # fn for_rev(v: [int], act: fn (int)) {}
971975for_rev([1, 2, 3]) {|n|
972976 log(error, n);
973977}
@@ -1387,7 +1391,7 @@ Here we know for sure that no one else has access to the `x` variable
13871391in ` main ` , so we're good. But the call could also look like this:
13881392
13891393~~~~
1390- # fn myfunc(a: int, b: block ()) {}
1394+ # fn myfunc(a: int, b: fn ()) {}
13911395# fn get_another_record() -> int { 1 }
13921396# let x = 1;
13931397myfunc(x, {|| x = get_another_record(); });
@@ -1408,7 +1412,7 @@ to pessimistically assume a value will get mutated, even though it is
14081412not sure.
14091413
14101414~~~~
1411- fn for_each(v: [mutable @int], iter: block (@int)) {
1415+ fn for_each(v: [mutable @int], iter: fn (@int)) {
14121416 for elt in v { iter(elt); }
14131417}
14141418~~~~
@@ -1431,7 +1435,7 @@ with the `copy` operator:
14311435
14321436~~~~
14331437type mutrec = {mutable x: int};
1434- fn for_each(v: [mutable mutrec], iter: block (mutrec)) {
1438+ fn for_each(v: [mutable mutrec], iter: fn (mutrec)) {
14351439 for elt in v { iter(copy elt); }
14361440}
14371441~~~~
@@ -1509,23 +1513,23 @@ defining such functions again and again for every type they apply to.
15091513Thus, Rust allows functions and datatypes to have type parameters.
15101514
15111515~~~~
1512- fn for_rev<T>(v: [T], act: block (T)) {
1516+ fn for_rev<T>(v: [T], act: fn (T)) {
15131517 let i = vec::len(v);
15141518 while i > 0u {
15151519 i -= 1u;
15161520 act(v[i]);
15171521 }
15181522}
15191523
1520- fn map<T, U>(v: [T], f: block (T) -> U) -> [U] {
1524+ fn map<T, U>(v: [T], f: fn (T) -> U) -> [U] {
15211525 let acc = [];
15221526 for elt in v { acc += [f(elt)]; }
15231527 ret acc;
15241528}
15251529~~~~
15261530
15271531When defined in this way, these functions can be applied to any type
1528- of vector, as long as the type of the block 's argument and the type of
1532+ of vector, as long as the type of the closure 's argument and the type of
15291533the vector's content agree with each other.
15301534
15311535Inside a parameterized (generic) function, the names of the type
@@ -1635,7 +1639,7 @@ by value based on their type. There is one situation in which this is
16351639difficult. If you try this program:
16361640
16371641~~~~
1638- # fn map(f: block (int) -> int, v: [int]) {}
1642+ # fn map(f: fn (int) -> int, v: [int]) {}
16391643fn plus1(x: int) -> int { x + 1 }
16401644map(plus1, [1, 2, 3]);
16411645~~~~
@@ -1650,7 +1654,7 @@ pass to a generic higher-order function as being passed by pointer,
16501654using the ` && ` sigil:
16511655
16521656~~~~
1653- # fn map<T, U>(f: block (T) -> U, v: [T]) {}
1657+ # fn map<T, U>(f: fn (T) -> U, v: [T]) {}
16541658fn plus1(&&x: int) -> int { x + 1 }
16551659map(plus1, [1, 2, 3]);
16561660~~~~
@@ -2027,11 +2031,11 @@ generalized sequence types:
20272031~~~~
20282032iface seq<T> {
20292033 fn len() -> uint;
2030- fn iter(block (T));
2034+ fn iter(fn (T));
20312035}
20322036impl <T> of seq<T> for [T] {
20332037 fn len() -> uint { vec::len(self) }
2034- fn iter(b: block (T)) {
2038+ fn iter(b: fn (T)) {
20352039 for elt in self { b(elt); }
20362040 }
20372041}
@@ -2112,7 +2116,7 @@ to leave off the `of` clause.
21122116# type currency = ();
21132117# fn mk_currency(x: int, s: str) {}
21142118impl int_util for int {
2115- fn times(b: block (int)) {
2119+ fn times(b: fn (int)) {
21162120 let i = 0;
21172121 while i < self { b(i); i += 1; }
21182122 }
0 commit comments