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

Extraneous sigil patrol #3750

Closed
wants to merge 3 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 26 additions & 40 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -1502,9 +1502,9 @@ and [`core::str`]. Here are some examples.
# fn unwrap_crayon(c: Crayon) -> int { 0 }
# fn eat_crayon_wax(i: int) { }
# fn store_crayon_in_nasal_cavity(i: uint, c: Crayon) { }
# fn crayon_to_str(c: Crayon) -> ~str { ~"" }
# fn crayon_to_str(c: Crayon) -> &str { "" }

let crayons = &[Almond, AntiqueBrass, Apricot];
let crayons = [Almond, AntiqueBrass, Apricot];

// Check the length of the vector
assert crayons.len() == 3;
Expand Down Expand Up @@ -1569,7 +1569,7 @@ let bloop = |well, oh: mygoodness| -> what_the { fail oh(well) };
~~~~

There are several forms of closure, each with its own role. The most
common, called a _stack closure_, has type `fn&` and can directly
common, called a _stack closure_, has type `&fn` and can directly
access local variables in the enclosing scope.

~~~~
Expand All @@ -1591,7 +1591,7 @@ pervasively in Rust code.
When you need to store a closure in a data structure, a stack closure
will not do, since the compiler will refuse to let you store it. For
this purpose, Rust provides a type of closure that has an arbitrary
lifetime, written `fn@` (boxed closure, analogous to the `@` pointer
lifetime, written `@fn` (boxed closure, analogous to the `@` pointer
type described earlier). This type of closure *is* first-class.

A managed closure does not directly access its environment, but merely
Expand All @@ -1604,8 +1604,9 @@ returns it from a function, and then calls it:

~~~~
# extern mod std;
fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
return fn@(s: ~str) -> ~str { s + suffix };
fn mk_appender(suffix: ~str) -> @fn(~str) -> ~str {
// The compiler knows that we intend this closure to be of type @fn
return |s| s + suffix;
}

fn main() {
Expand All @@ -1614,22 +1615,9 @@ fn main() {
}
~~~~

This example uses the long closure syntax, `fn@(s: ~str) ...`. Using
this syntax makes it explicit that we are declaring a boxed
closure. In practice, boxed closures are usually defined with the
short closure syntax introduced earlier, in which case the compiler
infers the type of closure. Thus our managed closure example could
also be written:

~~~~
fn mk_appender(suffix: ~str) -> fn@(~str) -> ~str {
return |s| s + suffix;
}
~~~~

## Owned closures

Owned closures, written `fn~` in analogy to the `~` pointer type,
Owned closures, written `~fn` in analogy to the `~` pointer type,
hold on to things that can safely be sent between
processes. They copy the values they close over, much like managed
closures, but they also own them: that is, no other code can access
Expand All @@ -1649,12 +1637,10 @@ callers may pass any kind of closure.

~~~~
fn call_twice(f: fn()) { f(); f(); }
call_twice(|| { ~"I am an inferred stack closure"; } );
call_twice(fn&() { ~"I am also a stack closure"; } );
call_twice(fn@() { ~"I am a managed closure"; });
call_twice(fn~() { ~"I am an owned closure"; });
fn bare_function() { ~"I am a plain function"; }
call_twice(bare_function);
let closure = || { "I'm a closure, and it doesn't matter what type I am"; };
fn function() { "I'm a normal function"; }
call_twice(closure);
call_twice(function);
~~~~

> ***Note:*** Both the syntax and the semantics will be changing
Expand Down Expand Up @@ -1693,7 +1679,7 @@ structure.
~~~~
# fn each(v: &[int], op: fn(v: &int)) { }
# fn do_some_work(i: &int) { }
each(&[1, 2, 3], |n| {
each([1, 2, 3], |n| {
do_some_work(n);
});
~~~~
Expand All @@ -1704,7 +1690,7 @@ call that can be written more like a built-in control structure:
~~~~
# fn each(v: &[int], op: fn(v: &int)) { }
# fn do_some_work(i: &int) { }
do each(&[1, 2, 3]) |n| {
do each([1, 2, 3]) |n| {
do_some_work(n);
}
~~~~
Expand All @@ -1715,7 +1701,7 @@ parentheses, where it looks more like a typical block of
code.

`do` is a convenient way to create tasks with the `task::spawn`
function. `spawn` has the signature `spawn(fn: fn~())`. In other
function. `spawn` has the signature `spawn(fn: ~fn())`. In other
words, it is a function that takes an owned closure that takes no
arguments.

Expand Down Expand Up @@ -1765,9 +1751,9 @@ And using this function to iterate over a vector:
~~~~
# use each = vec::each;
# use println = io::println;
each(&[2, 4, 8, 5, 16], |n| {
each([2, 4, 8, 5, 16], |n| {
if *n % 2 != 0 {
println(~"found odd number!");
println("found odd number!");
false
} else { true }
});
Expand All @@ -1782,9 +1768,9 @@ to the next iteration, write `loop`.
~~~~
# use each = vec::each;
# use println = io::println;
for each(&[2, 4, 8, 5, 16]) |n| {
for each([2, 4, 8, 5, 16]) |n| {
if *n % 2 != 0 {
println(~"found odd number!");
println("found odd number!");
break;
}
}
Expand Down Expand Up @@ -1967,12 +1953,12 @@ impl int: Printable {
fn print() { io::println(fmt!("%d", self)) }
}

impl ~str: Printable {
impl &str: Printable {
fn print() { io::println(self) }
}

# 1.print();
# (~"foo").print();
# ("foo").print();
~~~~

Methods defined in an implementation of a trait may be called just like
Expand Down Expand Up @@ -2120,7 +2106,7 @@ impl @Rectangle: Drawable { fn draw() { ... } }

let c: @Circle = @new_circle();
let r: @Rectangle = @new_rectangle();
draw_all(&[c as @Drawable, r as @Drawable]);
draw_all([c as @Drawable, r as @Drawable]);
~~~~

We omit the code for `new_circle` and `new_rectangle`; imagine that
Expand Down Expand Up @@ -2162,8 +2148,8 @@ additional modules.

~~~~
mod farm {
pub fn chicken() -> ~str { ~"cluck cluck" }
pub fn cow() -> ~str { ~"mooo" }
pub fn chicken() -> &str { "cluck cluck" }
pub fn cow() -> &str { "mooo" }
}

fn main() {
Expand Down Expand Up @@ -2360,13 +2346,13 @@ these two files:
~~~~
// world.rs
#[link(name = "world", vers = "1.0")];
fn explore() -> ~str { ~"world" }
fn explore() -> &str { "world" }
~~~~

~~~~ {.xfail-test}
// main.rs
extern mod world;
fn main() { io::println(~"hello " + world::explore()); }
fn main() { io::println("hello " + world::explore()); }
~~~~

Now compile and run like this (adjust to your platform if necessary):
Expand Down