about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-10-11 15:46:16 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-10-11 18:18:53 -0700
commitfd85a0000a542a52f0fda3bd2f941fba452e0698 (patch)
treee2cd4dbf5822c2a5d3282876f9daf9852ab77055
parent693866d75e25425053c61dc16adcc12b977d86f0 (diff)
downloadrust-fd85a0000a542a52f0fda3bd2f941fba452e0698.tar.gz
rust-fd85a0000a542a52f0fda3bd2f941fba452e0698.zip
manual: add section on do-expressions.
-rw-r--r--doc/rust.md46
1 files changed, 46 insertions, 0 deletions
diff --git a/doc/rust.md b/doc/rust.md
index 628cb137061..1dfeaddc1a2 100644
--- a/doc/rust.md
+++ b/doc/rust.md
@@ -2071,6 +2071,52 @@ the loop.
 A `loop` expression is only permitted in the body of a loop.
 
 
+### Do expressions
+
+~~~~~~~~{.ebnf .gram}
+do_expr : "do" expr [ '|' ident_list '|' ] ? '{' block '}' ;
+~~~~~~~~
+
+A _do expression_ provides a more-familiar block-syntax for a [lambda expression](#lambda-expressions),
+including a special translation of [return expressions](#return-expressions) inside the supplied block.
+
+The optional `ident_list` and `block` provided in a `do` expression are parsed as though they constitute a lambda expression;
+if the `ident_list` is missing, an empty `ident_list` is implied.
+
+The lambda expression is then provided as a _trailing argument_
+to the outermost [call](#call-expressions) or [method call](#method-call-expressions) expression
+in the `expr` following `do`.
+If the `expr` is a [path expression](#path-expressions), it is parsed as though it is a call expression.
+If the `expr` is a [field expression](#field-expressions), it is parsed as though it is a method call expression.
+
+Additionally, any occurrence of a [return expression](#return-expressions)
+inside the `block` of a `do` expression is rewritten
+as a reference to an (anonymous) flag set in the caller's environment,
+which is checked on return from the `expr` and, if set,
+causes a corresponding return from the caller.
+In this way, the meaning of `return` statements in language built-in control blocks is preserved,
+if they are rewritten using lambda functions and `do` expressions as abstractions.
+
+Therefore the two calls to `f` in this example are equivalent.
+Both cause an early return from the caller's frame:
+
+~~~~
+# fn f(f: fn(int)) { }
+# fn g(i: int) { }
+
+{
+  let mut _early_ret = false;
+  f(|j| { g(j); _early_ret = true; });
+  if early_ret { return; }
+}
+
+do f |j| {
+    g(j);
+    return;
+}
+~~~~
+
+
 ### For expressions
 
 ~~~~~~~~{.ebnf .gram}