Skip to content

Commit 39acb06

Browse files
committed
Copyedit sections 11-13 of the tutorial. That's all, folks!
1 parent 6d25051 commit 39acb06

File tree

1 file changed

+103
-85
lines changed

1 file changed

+103
-85
lines changed

doc/tutorial.md

+103-85
Original file line numberDiff line numberDiff line change
@@ -1807,10 +1807,13 @@ fn contains(v: &[int], elt: int) -> bool {
18071807
18081808
# Generics
18091809

1810-
Throughout this tutorial, we've been defining functions that act only on
1811-
specific data types. With type parameters we can also define functions whose
1812-
arguments represent generic types, and which can be invoked with a variety
1813-
of types. Consider a generic `map` function.
1810+
Throughout this tutorial, we've been defining functions that act only
1811+
on specific data types. With type parameters we can also define
1812+
functions whose arguments have generic types, and which can be invoked
1813+
with a variety of types. Consider a generic `map` function, which
1814+
takes a function `function` and a vector `vector` and returns a new
1815+
vector consisting of the result of applying `function` to each element
1816+
of `vector`:
18141817

18151818
~~~~
18161819
fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
@@ -1824,17 +1827,18 @@ fn map<T, U>(vector: &[T], function: fn(v: &T) -> U) -> ~[U] {
18241827

18251828
When defined with type parameters, as denoted by `<T, U>`, this
18261829
function can be applied to any type of vector, as long as the type of
1827-
`function`'s argument and the type of the vector's content agree with
1830+
`function`'s argument and the type of the vector's contents agree with
18281831
each other.
18291832

18301833
Inside a generic function, the names of the type parameters
1831-
(capitalized by convention) stand for opaque types. You can't look
1832-
inside them, but you can pass them around. Note that instances of
1833-
generic types are often passed by pointer. For example, the
1834-
parameter `function()` is supplied with a pointer to a value of type
1835-
`T` and not a value of type `T` itself. This ensures that the
1836-
function works with the broadest set of types possible, since some
1837-
types are expensive or illegal to copy and pass by value.
1834+
(capitalized by convention) stand for opaque types. All you can do
1835+
with instances of these types is pass them around: you can't apply any
1836+
operations to them or pattern-match on them. Note that instances of
1837+
generic types are often passed by pointer. For example, the parameter
1838+
`function()` is supplied with a pointer to a value of type `T` and not
1839+
a value of type `T` itself. This ensures that the function works with
1840+
the broadest set of types possible, since some types are expensive or
1841+
illegal to copy and pass by value.
18381842

18391843
Generic `type`, `struct`, and `enum` declarations follow the same pattern:
18401844

@@ -1852,15 +1856,16 @@ enum Maybe<T> {
18521856
}
18531857
~~~~
18541858

1855-
These declarations produce valid types like `Set<int>`, `Stack<int>`
1856-
and `Maybe<int>`.
1859+
These declarations can be instantiated to valid types like `Set<int>`,
1860+
`Stack<int>` and `Maybe<int>`.
18571861

1858-
Generic functions in Rust are compiled to very efficient runtime code
1859-
through a process called _monomorphisation_. This is a fancy way of
1860-
saying that, for each generic function you call, the compiler
1861-
generates a specialized version that is optimized specifically for the
1862-
argument types. In this respect Rust's generics have similar
1863-
performance characteristics to C++ templates.
1862+
The Rust compiler compiles generic functions very efficiently by
1863+
*monomorphizing* them. *Monomorphization* is a fancy name for a simple
1864+
idea: generate a separate copy of each generic function at each call
1865+
site where it is called, a copy that is specialized to the argument
1866+
types and can thus be optimized specifically for them. In this
1867+
respect, Rust's generics have similar performance characteristics to
1868+
C++ templates.
18641869

18651870
## Traits
18661871

@@ -1869,15 +1874,19 @@ are very limited. After all, since the function doesn't know what
18691874
types it is operating on, it can't safely modify or query their
18701875
values. This is where _traits_ come into play. Traits are Rust's most
18711876
powerful tool for writing polymorphic code. Java developers will see
1872-
in them aspects of Java interfaces, and Haskellers will notice their
1873-
similarities to type classes.
1874-
1875-
As motivation, let us consider copying in Rust. Perhaps surprisingly,
1876-
the copy operation is not defined for all Rust types. In
1877-
particular, types with user-defined destructors cannot be copied,
1878-
either implicitly or explicitly, and neither can types that own other
1879-
types containing destructors (the actual mechanism for defining
1880-
destructors will be discussed elsewhere).
1877+
them as similar to Java interfaces, and Haskellers will notice their
1878+
similarities to type classes. Rust's traits are a form of *bounded
1879+
polymorphism*: a trait is a way of limiting the set of possible types
1880+
that a type parameter could refer to.
1881+
1882+
As motivation, let us consider copying in Rust. The `copy` operation
1883+
is not defined for all Rust types. One reason is user-defined
1884+
destructors: copying a type that has a destructor could result in the
1885+
destructor running multiple times. Therefore, types with user-defined
1886+
destructors cannot be copied, either implicitly or explicitly, and
1887+
neither can types that own other types containing destructors (see the
1888+
section on [structs](#structs) for the actual mechanism for defining
1889+
destructors).
18811890

18821891
This complicates handling of generic functions. If you have a type
18831892
parameter `T`, can you copy values of that type? In Rust, you can't,
@@ -1890,8 +1899,8 @@ fn head_bad<T>(v: &[T]) -> T {
18901899
}
18911900
~~~~
18921901

1893-
We can tell the compiler though that the `head` function is only for
1894-
copyable types with the `Copy` trait.
1902+
However, we can tell the compiler that the `head` function is only for
1903+
copyable types: that is, those that have the `Copy` trait.
18951904

18961905
~~~~
18971906
// This does
@@ -1903,14 +1912,17 @@ fn head<T: Copy>(v: &[T]) -> T {
19031912
This says that we can call `head` on any type `T` as long as that type
19041913
implements the `Copy` trait. When instantiating a generic function,
19051914
you can only instantiate it with types that implement the correct
1906-
trait, so you could not apply `head` to a type with a destructor.
1915+
trait, so you could not apply `head` to a type with a
1916+
destructor. (`Copy` is a special trait that is built in to the
1917+
compiler, making it possible for the compiler to enforce this
1918+
restriction.)
19071919

19081920
While most traits can be defined and implemented by user code, three
19091921
traits are automatically derived and implemented for all applicable
19101922
types by the compiler, and may not be overridden:
19111923

1912-
* `Copy` - Types that can be copied, either implicitly, or using the
1913-
`copy` expression. All types are copyable unless they are classes
1924+
* `Copy` - Types that can be copied: either implicitly, or explicitly with the
1925+
`copy` operator. All types are copyable unless they are classes
19141926
with destructors or otherwise contain classes with destructors.
19151927

19161928
* `Send` - Sendable (owned) types. All types are sendable unless they
@@ -1957,7 +1969,7 @@ impl ~str: Printable {
19571969
# (~"foo").print();
19581970
~~~~
19591971

1960-
Methods defined in an implementation of a trait may be called just as
1972+
Methods defined in an implementation of a trait may be called just like
19611973
any other method, using dot notation, as in `1.print()`. Traits may
19621974
themselves contain type parameters. A trait for generalized sequence
19631975
types might look like the following:
@@ -1979,14 +1991,14 @@ impl<T> ~[T]: Seq<T> {
19791991
The implementation has to explicitly declare the type parameter that
19801992
it binds, `T`, before using it to specify its trait type. Rust
19811993
requires this declaration because the `impl` could also, for example,
1982-
specify an implementation of `Seq<int>`. The trait type -- appearing
1983-
after the colon in the `impl` -- *refers* to a type, rather than
1994+
specify an implementation of `Seq<int>`. The trait type (appearing
1995+
after the colon in the `impl`) *refers* to a type, rather than
19841996
defining one.
19851997

19861998
The type parameters bound by a trait are in scope in each of the
19871999
method declarations. So, re-declaring the type parameter
1988-
`T` as an explicit type parameter for `len` -- in either the trait or
1989-
the impl -- would be a compile-time error.
2000+
`T` as an explicit type parameter for `len`, in either the trait or
2001+
the impl, would be a compile-time error.
19902002

19912003
Within a trait definition, `self` is a special type that you can think
19922004
of as a type parameter. An implementation of the trait for any given
@@ -2006,16 +2018,17 @@ impl int: Eq {
20062018
}
20072019
~~~~
20082020

2009-
Notice that in the trait definition, `equals` takes a `self` type
2010-
argument, whereas, in the impl, `equals` takes an `int` type argument,
2011-
and uses `self` as the name of the receiver (analogous to the `this` pointer
2012-
in C++).
2021+
Notice that in the trait definition, `equals` takes a parameter of
2022+
type `self`. In contrast, in the `impl`, `equals` takes a parameter of
2023+
type `int`, and uses `self` as the name of the receiver (analogous to
2024+
the `this` pointer in C++).
20132025

20142026
## Bounded type parameters and static method dispatch
20152027

2016-
Traits give us a language for talking about the abstract capabilities
2017-
of types, and we can use this to place _bounds_ on type parameters,
2018-
so that we can then operate on generic types.
2028+
Traits give us a language for defining predicates on types, or
2029+
abstract properties that types can have. We can use this language to
2030+
define _bounds_ on type parameters, so that we can then operate on
2031+
generic types.
20192032

20202033
~~~~
20212034
# trait Printable { fn print(); }
@@ -2026,14 +2039,14 @@ fn print_all<T: Printable>(printable_things: ~[T]) {
20262039
}
20272040
~~~~
20282041

2029-
By declaring `T` as conforming to the `Printable` trait (as we earlier
2030-
did with `Copy`), it becomes possible to call methods from that trait
2031-
on values of that type inside the function. It will also cause a
2042+
Declaring `T` as conforming to the `Printable` trait (as we earlier
2043+
did with `Copy`) makes it possible to call methods from that trait
2044+
on values of type `T` inside the function. It will also cause a
20322045
compile-time error when anyone tries to call `print_all` on an array
20332046
whose element type does not have a `Printable` implementation.
20342047

20352048
Type parameters can have multiple bounds by separating them with spaces,
2036-
as in this version of `print_all` that makes copies of elements.
2049+
as in this version of `print_all` that copies elements.
20372050

20382051
~~~
20392052
# trait Printable { fn print(); }
@@ -2083,10 +2096,10 @@ fn draw_all(shapes: &[@Drawable]) {
20832096
}
20842097
~~~~
20852098

2086-
In this example there is no type parameter. Instead, the `@Drawable`
2087-
type is used to refer to any managed box value that implements the
2088-
`Drawable` trait. To construct such a value, you use the `as` operator
2089-
to cast a value to a trait type:
2099+
In this example, there is no type parameter. Instead, the `@Drawable`
2100+
type denotes any managed box value that implements the `Drawable`
2101+
trait. To construct such a value, you use the `as` operator to cast a
2102+
value to a trait type:
20902103

20912104
~~~~
20922105
# type Circle = int; type Rectangle = bool;
@@ -2104,10 +2117,12 @@ let r: @Rectangle = @new_rectangle();
21042117
draw_all(&[c as @Drawable, r as @Drawable]);
21052118
~~~~
21062119

2107-
Note that, like strings and vectors, trait types have dynamic size
2108-
and may only be used via one of the pointer types. In turn, the
2109-
`impl` is defined for `@Circle` and `@Rectangle` instead of for
2110-
just `Circle` and `Rectangle`. Other pointer types work as well.
2120+
We omit the code for `new_circle` and `new_rectangle`; imagine that
2121+
these just return `Circle`s and `Rectangle`s with a default size. Note
2122+
that, like strings and vectors, trait types have dynamic size and may
2123+
only be referred to via one of the pointer types. That's why the `impl` is
2124+
defined for `@Circle` and `@Rectangle` instead of for just `Circle`
2125+
and `Rectangle`. Other pointer types work as well.
21112126

21122127
~~~{.xfail-test}
21132128
# type Circle = int; type Rectangle = int;
@@ -2123,13 +2138,13 @@ let owny: ~Drawable = ~new_circle() as ~Drawable;
21232138
let stacky: &Drawable = &new_circle() as &Drawable;
21242139
~~~
21252140

2126-
> ***Note:*** Other pointer types actually _do not_ work here. This is
2141+
> ***Note:*** Other pointer types actually _do not_ work here yet. This is
21272142
> an evolving corner of the language.
21282143
21292144
Method calls to trait types are _dynamically dispatched_. Since the
21302145
compiler doesn't know specifically which functions to call at compile
2131-
time it uses a lookup table (vtable) to decide at runtime which
2132-
method to call.
2146+
time it uses a lookup table (also known as a vtable or dictionary) to
2147+
select the method to call at runtime.
21332148

21342149
This usage of traits is similar to Java interfaces.
21352150

@@ -2170,17 +2185,18 @@ fn chicken_farmer() {
21702185
~~~
21712186

21722187
These farm animal functions have a new keyword, `pub`, attached to
2173-
them. This is a visibility modifier that allows item to be accessed
2174-
outside of the module in which they are declared, using `::`, as in
2175-
`farm::chicken`. Items, like `fn`, `struct`, etc. are private by
2176-
default.
2188+
them. The `pub` keyword modifies an item's visibility, making it
2189+
visible outside its containing module. An expression with `::`, like
2190+
`farm::chicken`, can name an item outside of its containing
2191+
module. Items, such as those declared with `fn`, `struct`, `enum`,
2192+
`type`, or `const`, are module-private by default.
21772193

21782194
Visibility restrictions in Rust exist only at module boundaries. This
2179-
is quite different from most object-oriented languages that also enforce
2180-
restrictions on objects themselves. That's not to say that Rust doesn't
2181-
support encapsulation - both struct fields and methods can be private -
2182-
but it is at the module level, not the class level. Note that fields
2183-
and methods are _public_ by default.
2195+
is quite different from most object-oriented languages that also
2196+
enforce restrictions on objects themselves. That's not to say that
2197+
Rust doesn't support encapsulation: both struct fields and methods can
2198+
be private. But this encapsulation is at the module level, not the
2199+
struct level. Note that fields and methods are _public_ by default.
21842200

21852201
~~~
21862202
mod farm {
@@ -2220,7 +2236,7 @@ fn main() {
22202236

22212237
## Crates
22222238

2223-
The unit of independent compilation in Rust is the crate - rustc
2239+
The unit of independent compilation in Rust is the crate: rustc
22242240
compiles a single crate at a time, from which it produces either a
22252241
library or executable.
22262242

@@ -2294,38 +2310,40 @@ fn main() { bar::baz(); }
22942310
22952311
## Using other crates
22962312

2297-
Having compiled a crate into a library you can use it in another crate
2298-
with an `extern mod` directive. `extern mod` can appear at the top of
2299-
a crate file or at the top of modules. It will cause the compiler to
2300-
look in the library search path (which you can extend with `-L`
2301-
switch) for a compiled Rust library with the right name, then add a
2302-
module with that crate's name into the local scope.
2313+
The `extern mod` directive lets you use a crate (once it's been
2314+
compiled into a library) from inside another crate. `extern mod` can
2315+
appear at the top of a crate file or at the top of modules. It will
2316+
cause the compiler to look in the library search path (which you can
2317+
extend with the `-L` switch) for a compiled Rust library with the
2318+
right name, then add a module with that crate's name into the local
2319+
scope.
23032320

23042321
For example, `extern mod std` links the [standard library].
23052322

23062323
[standard library]: std/index.html
23072324

2308-
When a comma-separated list of name/value pairs is given after `extern
2309-
mod`, these are matched against the attributes provided in the `link`
2310-
attribute of the crate file, and a crate is only used when the two
2311-
match. A `name` value can be given to override the name used to search
2312-
for the crate.
2325+
When a comma-separated list of name/value pairs appears after `extern
2326+
mod`, the compiler front-end matches these pairs against the
2327+
attributes provided in the `link` attribute of the crate file. The
2328+
front-end will only select this crate for use if the actual pairs
2329+
match the declared attributes. You can provide a `name` value to
2330+
override the name used to search for the crate.
23132331

23142332
Our example crate declared this set of `link` attributes:
23152333

23162334
~~~~ {.xfail-test}
23172335
#[link(name = "farm", vers = "2.5", author = "mjh")];
23182336
~~~~
23192337

2320-
Which can then be linked with any (or all) of the following:
2338+
Which you can then link with any (or all) of the following:
23212339

23222340
~~~~ {.xfail-test}
23232341
extern mod farm;
23242342
extern mod my_farm (name = "farm", vers = "2.5");
23252343
extern mod my_auxiliary_farm (name = "farm", author = "mjh");
23262344
~~~~
23272345

2328-
If any of the requested metadata does not match then the crate
2346+
If any of the requested metadata do not match, then the crate
23292347
will not be compiled successfully.
23302348

23312349
## A minimal example
@@ -2361,7 +2379,7 @@ a hash representing the crate metadata.
23612379

23622380
## The core library
23632381

2364-
The Rust [core] library acts as the language runtime and contains
2382+
The Rust [core] library is the language runtime and contains
23652383
required memory management and task scheduling code as well as a
23662384
number of modules necessary for effective usage of the primitive
23672385
types. Methods on [vectors] and [strings], implementations of most

0 commit comments

Comments
 (0)