From f8eb62f7a370e3a3a96ddecb750a9c09b13ba52c Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Tue, 11 Mar 2014 10:25:11 +0100 Subject: [PATCH 01/14] Initial mess. --- src/doc/new-tutorial.md | 131 ++++++++++++++++++++++++++++++++++++++++ src/doc/syntax.md | 20 ++++++ 2 files changed, 151 insertions(+) create mode 100644 src/doc/new-tutorial.md create mode 100644 src/doc/syntax.md diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md new file mode 100644 index 0000000000000..03fa4a5030b74 --- /dev/null +++ b/src/doc/new-tutorial.md @@ -0,0 +1,131 @@ +% Rust Tutorial + +# Stack vs. heap, values, copying + +## Variables + + + +~~~~ +struct Point { x: int, y: int } +fn main() { + let mut p = Point { x: 1, y: 2}; + let q = p; // copies p deeply + p.x += 1; // legal because p is mutable + println!(q.x); // still prints 1 +} +~~~~ + +* difference of stack vs heap +* values of aggregate type (Point is not a pointer to a Point) +* more examples of types inline with other types + - e.g. Line { p1, p2 } + - show efficiency of inline struct layout +* how to write a function +* do basic I/O `println!` +* copying (not compared to moving) +* to modify p.x, you make p mutable + - don't explain inherited mutability in depth + +## Using Functions + +Functions in Rust are introduced with the `fn` keyword, optional parameters are specified within brackets as comma separated `name: type` pairs, and `->` indicates the return type. You can ommit the return type for functions that do not return a value. Functions return the top level expression (note the return expression is not terminated with a semi colon). + +~~~~ +fn main() { + let i = 7; + + fn increment(i:int) -> (int) { + i + 1 + } + + let k = increment(i); // k=8 +} +~~~~ + +## Printing + +This small program prints "hello?" to the console. Use `println` instead of `print` to add a newline to the end of the output. + +~~~~ +fn main() { + print("hello?"); +} +~~~~ + +To add variables and formatting to the printed output, use `print!` or `println!`. The variables are inserted into the output at the `{}` placeholders. + +~~~~ +fn main() { + let n = 3; + let l = 'b'; + + println!("hello? the number is {} and the letter is {}.", n, l); +} +~~~~ + +For more information on formatting strings look at [`std::fmt`][fmt]. We explain what the `::` syntax means at FIXME. + +[fmt]: http://static.rust-lang.org/doc/0.9/std/fmt/index.html + +### Enums and matching (???) + +Introduce enums and matching here? Or after ownership? After 3.3? + +## Ownership (front and center) + +~~~~ +struct Point { ... } +fn main() { + let mut p = ~Point { x: 1, y: 2 }; + let q = p; + p.x += 1; // error, huh? +} +~~~~~ + +* heap allocation (~) +* moving +* freeing + +## Borrowing + +Ownership is not the right tool when you just want temporary access to data: + +~~~~ +fn main() { + let p = ~Point { x: 1, y: 2}; + let r = inc_allocated_point(p); +} +fn inc_allocated_point(mut p: ~Point) -> ~Point { + p.x += 1; + p // final expression is returned +} +~~~~~ + +* final expression is returned (syntax note) +* writing a function with arguments +* mutability on function arguments + +~~~~ +struct Point { ... } +fn main() { + let mut p = ~Point { ... }; + inc_allocated_point(&mut p); +} +fn inc_allocated_point(p: &mut ~Point) { + p.x += 1; +} +~~~~ + +## Immutable borrow + +~~~~ +fn get_point(p: &Point) -> int { + p.x + p.y +} +~~~~ + +* only talking about using borrowed pointers in parameters +* make it explicit we're not talking about returning borrowed pointers +* don't introduce lifetime parameters yet +* don't put pointers into structs diff --git a/src/doc/syntax.md b/src/doc/syntax.md new file mode 100644 index 0000000000000..da70fc2680fce --- /dev/null +++ b/src/doc/syntax.md @@ -0,0 +1,20 @@ +Rust Syntax Primer +================== + +Variables + +Conditionals + +Looping + +Expressions + +Statements + +Functions + +Paramters + +Return values + + From d81a403dc023b1a7ea260feaba86931fc787a8c0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Mon, 10 Mar 2014 14:41:02 -0700 Subject: [PATCH 02/14] Add new-tutorial.md and guide-syntax.md, some intial content. --- mk/docs.mk | 6 +++--- src/doc/guide-syntax.md | 20 ++++++++++++++++++++ src/doc/new-tutorial.md | 2 +- src/doc/syntax.md | 20 -------------------- 4 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 src/doc/guide-syntax.md delete mode 100644 src/doc/syntax.md diff --git a/mk/docs.mk b/mk/docs.mk index 5b9e8407a5822..d8fb0aa368bb8 100644 --- a/mk/docs.mk +++ b/mk/docs.mk @@ -27,9 +27,9 @@ # translated. ###################################################################### DOCS := index tutorial guide-ffi guide-macros guide-lifetimes \ - guide-tasks guide-container guide-pointers guide-testing \ - guide-runtime complement-bugreport complement-cheatsheet \ - complement-lang-faq complement-project-faq rust rustdoc + guide-tasks guide-container guide-pointers \ + complement-cheatsheet guide-runtime \ + rust rustdoc new-tutorial guide-syntax PDF_DOCS := tutorial rust diff --git a/src/doc/guide-syntax.md b/src/doc/guide-syntax.md new file mode 100644 index 0000000000000..17eb6d6ce9214 --- /dev/null +++ b/src/doc/guide-syntax.md @@ -0,0 +1,20 @@ +% The Guide to Rust Syntax + +The Guide to Rust Syntax +========================= + +Variables + +Conditionals + +Looping + +Expressions + +Statements + +Functions + +Paramters + +Return values diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 03fa4a5030b74..4f278cc1f18da 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -1,4 +1,4 @@ -% Rust Tutorial +% The (New) Rust Language Tutorial # Stack vs. heap, values, copying diff --git a/src/doc/syntax.md b/src/doc/syntax.md deleted file mode 100644 index da70fc2680fce..0000000000000 --- a/src/doc/syntax.md +++ /dev/null @@ -1,20 +0,0 @@ -Rust Syntax Primer -================== - -Variables - -Conditionals - -Looping - -Expressions - -Statements - -Functions - -Paramters - -Return values - - From 6c2215ab6040cc98cf107e79403c820a2b6c2942 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Fri, 14 Mar 2014 17:03:14 +0100 Subject: [PATCH 03/14] Examples now pass code tests. --- src/doc/new-tutorial.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 4f278cc1f18da..d243e68448ef5 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -12,7 +12,7 @@ fn main() { let mut p = Point { x: 1, y: 2}; let q = p; // copies p deeply p.x += 1; // legal because p is mutable - println!(q.x); // still prints 1 + println!("{}", q.x); // still prints 1 } ~~~~ @@ -49,6 +49,8 @@ This small program prints "hello?" to the console. Use `println` instead of `pri ~~~~ fn main() { + use std::io::print; + print("hello?"); } ~~~~ @@ -74,8 +76,8 @@ Introduce enums and matching here? Or after ownership? After 3.3? ## Ownership (front and center) -~~~~ -struct Point { ... } +~~~~ {.notrust} +struct Point {x: int, y: int} fn main() { let mut p = ~Point { x: 1, y: 2 }; let q = p; @@ -92,6 +94,7 @@ fn main() { Ownership is not the right tool when you just want temporary access to data: ~~~~ +struct Point {x: int, y: int} fn main() { let p = ~Point { x: 1, y: 2}; let r = inc_allocated_point(p); @@ -107,9 +110,9 @@ fn inc_allocated_point(mut p: ~Point) -> ~Point { * mutability on function arguments ~~~~ -struct Point { ... } +struct Point {x: int, y: int} fn main() { - let mut p = ~Point { ... }; + let mut p = ~Point {x: 1, y: 2}; inc_allocated_point(&mut p); } fn inc_allocated_point(p: &mut ~Point) { @@ -120,6 +123,7 @@ fn inc_allocated_point(p: &mut ~Point) { ## Immutable borrow ~~~~ +struct Point {x: int, y: int} fn get_point(p: &Point) -> int { p.x + p.y } From 232eb3913039cc28b4061a2065b54f64b7154503 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Thu, 20 Mar 2014 16:02:21 +0100 Subject: [PATCH 04/14] Some more text. --- src/doc/guide-syntax.md | 64 ++++++++++++++--- src/doc/new-tutorial.md | 147 +++++++++++++++++++++++++++++----------- 2 files changed, 161 insertions(+), 50 deletions(-) diff --git a/src/doc/guide-syntax.md b/src/doc/guide-syntax.md index 17eb6d6ce9214..10ab52a5a8b0b 100644 --- a/src/doc/guide-syntax.md +++ b/src/doc/guide-syntax.md @@ -1,20 +1,64 @@ % The Guide to Rust Syntax -The Guide to Rust Syntax -========================= +A *very* brief guide to Rust syntax. It assumes you are already familar with programming concepts. -Variables +# Arguments -Conditionals +# Conditions -Looping +# `enum` -Expressions +# Expressions -Statements +# Functions -Functions +Functions in Rust are introduced with the `fn` keyword, optional parameters are specified within brackets as comma separated `name: type` pairs, and `->` indicates the return type. You can ommit the return type for functions that do not return a value. Functions return the top level expression (note the return expression is not terminated with a semi colon). -Paramters +~~~~ +fn main() { + let i = 7; -Return values + fn increment(i:int) -> (int) { + i + 1 + } + + let k = increment(i); // k=8 +} +~~~~ + +# Loops + +## `if` + +## `loop` + +## `while` + +# Operators + +# Patterns + +# Return values + +# Statements + +# Structs and Tuples: `struct` + +# Variables + +There are two types of variable in Rust: + +* `immutable` - the value cannot be changed. Introduced with `let mut`. +* `mutable` - the value of can be changed. Introduced with `let`. + +~~~~ +fn main() { + + let i = 7; // i Cannot be changed + + let mut j = i +1; // j = 8 + + j = 9; // j can be changed + +} +~~~~ diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index d243e68448ef5..88ac9e08d3575 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -1,95 +1,162 @@ % The (New) Rust Language Tutorial -# Stack vs. heap, values, copying +An introductory tutorial to the Rust programming language. The tutorial focuses on the strengths and unique aspects of the Rust language, and is intentionally brief. -## Variables +You should already be already familiar with programming concepts and a programming language from the C-family. The [syntax guide][syntax] is a reference to the nuts and bolts of the language, essentials such as [variables][guide-var], [functions][guide-fn], etc. +[syntax]: guide-syntax.html +[guide-var]: guide-syntax.html#variables +[guide-fn]: guide-syntax.html#functions +# Output and Input + +Output to the console using `print`. Use the `println` convenience function instead of `print` to add a newline to the end of the output. Note the `use std::io::print` syntax to include the `print` function from the standard `io` library. + +~~~~ +fn main() { + use std::io::print; + + print("hello?"); +} +~~~~ + +To add variables and formatting to the printed output, use `print!` or `println!`. The variables are inserted into the output at the `{}` placeholders. FIXME second println to show decimal places formatting? + +~~~~ +fn main() { + let n = 3.0; + let l = 'b'; + + println!("hello? the number is {} and the letter is {}.", n, l); + +} +~~~~ + +For more information on formatting strings, read [`std::fmt`][fmt]. + +[fmt]: http://static.rust-lang.org/doc/0.9/std/fmt/index.html + +Getting user input is slightly more involved, the following code takes each line of input, and prints it back after the string "You wrote:". Note the bracketed `use` on line one to include two different functions on the same line. + +~~~~ +use std::io::{stdin, BufferedReader}; +fn main() { + let mut stdin = BufferedReader::new(stdin()); + for line in stdin.lines() { + println!("You wrote: {}", line); + } +} +~~~~ + +# `struct` + +Structures are groupings of types, and are introduced by the `struct` keyword. For example, a structure that represents a point on a two dimensional grid is composed of two integers, `x` and `y`. Access the types within the `struct` using the name of the structure instance, a dot `.` and the name of the type inside the structure. In the following example, `p` is the instance of the `Point` structure and `p.x` and `p.y` are the coordinates, with values 1 and 2 respectively. ~~~~ struct Point { x: int, y: int } +fn main() { + let p = Point { x: 1, y: 2}; + println!("{}", p.x); // prints 1 + +} +~~~~ + +FIXME: Should talk about Pointers first. + +Structures in Rust contain the values of the instances, not pointers to the values like most other languages in the C-family. If you copy a structure, you copy the entire structure, not just a pointer to the original structure. + +~~~~ +struct Point { x: int, y: int } + fn main() { let mut p = Point { x: 1, y: 2}; - let q = p; // copies p deeply - p.x += 1; // legal because p is mutable + let q = p; + p.x += 1; println!("{}", q.x); // still prints 1 } ~~~~ + + + -Functions in Rust are introduced with the `fn` keyword, optional parameters are specified within brackets as comma separated `name: type` pairs, and `->` indicates the return type. You can ommit the return type for functions that do not return a value. Functions return the top level expression (note the return expression is not terminated with a semi colon). - -~~~~ -fn main() { - let i = 7; +Tuples are structures of types without names, such a point composed of two unnamed integers `struct Point(int,int)`. See [tuples][guide-tup] for more information. - fn increment(i:int) -> (int) { - i + 1 - } +[guide-tup]: guide-syntax.html/tuples - let k = increment(i); // k=8 -} -~~~~ +# Stack vs. Heap -## Printing +Rust [variables][guide-var] are allocated on the stack by default. Rust also lets you allocate variables on the heap, using the `~` symbol. To access the variable use the `*` symbol. Heap memory is freed when the variable goes out of scope. -This small program prints "hello?" to the console. Use `println` instead of `print` to add a newline to the end of the output. + ~~~~ fn main() { - use std::io::print; - - print("hello?"); + let mut x = 3; // allocated on the stack + x = x + 1; + + let mut y = ~5; // allocated on the heap + // y = y + 1; // Does not work + *y = *y + 1; + } ~~~~ -To add variables and formatting to the printed output, use `print!` or `println!`. The variables are inserted into the output at the `{}` placeholders. + + +Many modern languages represent values as pointers to heap memory by default. In contrast, Rust, like C and C++, represents such types directly. Another way to say this is that aggregate data in Rust are unboxed. * more examples of types inline with other types + - e.g. Line { p1, p2 } + - show efficiency of inline struct layout ~~~~ -fn main() { - let n = 3; - let l = 'b'; +struct Point { x: int, y: int } - println!("hello? the number is {} and the letter is {}.", n, l); +fn main() { + let mut p = Point { x: 1, y: 2}; + let q = p; // copies p deeply + p.x += 1; // legal because p is mutable + println!("{}", q.x); // still prints 1 } ~~~~ -For more information on formatting strings look at [`std::fmt`][fmt]. We explain what the `::` syntax means at FIXME. +# Move Vs Copy -[fmt]: http://static.rust-lang.org/doc/0.9/std/fmt/index.html + + +# Ownership -~~~~ {.notrust} +~~~~ struct Point {x: int, y: int} fn main() { let mut p = ~Point { x: 1, y: 2 }; let q = p; - p.x += 1; // error, huh? + + // p.x += 1; // error, huh? + } ~~~~~ -* heap allocation (~) -* moving * freeing -## Borrowing +# Borrowing Ownership is not the right tool when you just want temporary access to data: From a7c478a77e07a1d3b62547bb7996c134e75821d8 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Sat, 29 Mar 2014 16:25:10 +0100 Subject: [PATCH 05/14] WIP --- src/doc/guide-syntax.md | 2 +- src/doc/new-tutorial.md | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/doc/guide-syntax.md b/src/doc/guide-syntax.md index 10ab52a5a8b0b..8ca03f38d04ed 100644 --- a/src/doc/guide-syntax.md +++ b/src/doc/guide-syntax.md @@ -12,7 +12,7 @@ A *very* brief guide to Rust syntax. It assumes you are already familar with pro # Functions -Functions in Rust are introduced with the `fn` keyword, optional parameters are specified within brackets as comma separated `name: type` pairs, and `->` indicates the return type. You can ommit the return type for functions that do not return a value. Functions return the top level expression (note the return expression is not terminated with a semi colon). +Functions in Rust are introduced with the `fn` keyword, optional arguments are specified within parenthesis as comma separated `name: type` pairs, and `->` indicates the return type. You can ommit the return type for functions that do not return a value. Functions return the top level expression (note the return expression is not terminated with a semi colon). ~~~~ fn main() { diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 88ac9e08d3575..e9d1a45aa4ec8 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -12,6 +12,17 @@ You should already be already familiar with programming concepts and a programmi Output to the console using `print`. Use the `println` convenience function instead of `print` to add a newline to the end of the output. Note the `use std::io::print` syntax to include the `print` function from the standard `io` library. + + + ~~~~ fn main() { use std::io::print; @@ -50,7 +61,7 @@ fn main() { # `struct` -Structures are groupings of types, and are introduced by the `struct` keyword. For example, a structure that represents a point on a two dimensional grid is composed of two integers, `x` and `y`. Access the types within the `struct` using the name of the structure instance, a dot `.` and the name of the type inside the structure. In the following example, `p` is the instance of the `Point` structure and `p.x` and `p.y` are the coordinates, with values 1 and 2 respectively. +Structures are groupings of types, and are introduced by the `struct` keyword. For example, a structure that represents a point on a two dimensional grid is composed of two integers, `x` and `y`. Access the types within the `struct` using the name of the Point object, a dot `.` and the name of the type inside the structure. In the following example, `p` is the `Point` object, and `p.x` and `p.y` are the coordinates, with values 1 and 2 respectively. ~~~~ struct Point { x: int, y: int } @@ -63,7 +74,7 @@ fn main() { FIXME: Should talk about Pointers first. -Structures in Rust contain the values of the instances, not pointers to the values like most other languages in the C-family. If you copy a structure, you copy the entire structure, not just a pointer to the original structure. +Structures in Rust contain the values of the types the structure contains, not pointers to the values like most other languages in the C-family. If you copy a structure, you copy the entire structure, not just a pointer to the original structure. ~~~~ struct Point { x: int, y: int } @@ -111,6 +122,8 @@ fn main() { } ~~~~ + + Many modern languages represent values as pointers to heap memory by default. In contrast, Rust, like C and C++, represents such types directly. Another way to say this is that aggregate data in Rust are unboxed. * more examples of types inline with other types From e02bb45afaef1f376be82214a865a10e6b4667b7 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Sat, 5 Apr 2014 15:32:49 +0200 Subject: [PATCH 06/14] WIP --- src/doc/new-tutorial.md | 96 ++++++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 16 deletions(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index e9d1a45aa4ec8..7e2f350eb5aef 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -1,16 +1,22 @@ % The (New) Rust Language Tutorial -An introductory tutorial to the Rust programming language. The tutorial focuses on the strengths and unique aspects of the Rust language, and is intentionally brief. +An introductory tutorial to the Rust programming language. The tutorial focuses on Rust's strengths and unique design, and is intentionally brief. -You should already be already familiar with programming concepts and a programming language from the C-family. The [syntax guide][syntax] is a reference to the nuts and bolts of the language, essentials such as [variables][guide-var], [functions][guide-fn], etc. +You should already be already familiar with programming concepts, in particular pointers, and a programming language from the C-family. The [syntax guide][syntax] is a reference to the nuts and bolts of the language, essentials such as [variables][guide-var], [functions][guide-fn], [structs][guide-struct] etc. + + [syntax]: guide-syntax.html [guide-var]: guide-syntax.html#variables [guide-fn]: guide-syntax.html#functions +[guide-struct]: guide-syntax.html#struct + # Output and Input -Output to the console using `print`. Use the `println` convenience function instead of `print` to add a newline to the end of the output. Note the `use std::io::print` syntax to include the `print` function from the standard `io` library. +Output to the console using `print`. Use the `println` convenience function instead of `print` to add a newline to the end of the output. Note the `use std::io::print` syntax to include the `print` function from the standard `io` library. You can find more information on [use::][guide-use] in the [syntax guide][syntax]. + +[guide-use]: guide-syntax.html#use + +Storing aggregate data inline (ie, one the stack, with no pointer indirection) is critical for improving performance, because cache, malloc/free expensive, pointer chasing and cache invalidation require a complex runtime with garbage collector. + +Rust does not introduce pointers unless you specifically specify them. If we define a type `Line` that consists of two `Point`s: + +``` +struct Line { + p1: Point, + p2: Point +} +``` + +The two `Point`s are laid out inline inside the `Line` struct. + + + +~~~~ ++------+ +| ... | --+ +| 1 | | p.x +| 2 | | p.y ++------+ --+ ++------+ +| ... | --+ +| 1 | | p.x +| 2 | | p.y ++------+ --+ +~~~~ + + + + + + [guide-tup]: guide-syntax.html/tuples # Stack vs. Heap @@ -124,11 +188,9 @@ fn main() { - + + # Move Vs Copy + [syntax]: guide-syntax.html [guide-var]: guide-syntax.html#variables @@ -18,17 +18,6 @@ Output to the console using `print`. Use the `println` convenience function inst [guide-use]: guide-syntax.html#use - - - ~~~~ fn main() { use std::io::print; @@ -37,23 +26,29 @@ fn main() { } ~~~~ -To add variables and formatting to the printed output, use `print!` or `println!`. The variables are inserted into the output at the `{}` placeholders. FIXME second println to show decimal places formatting? +To add variables and formatting to the printed output, use `print!` or `println!`. Variables are introduced with the `let` keyword, and unlike in most other languages are not changeable (or in Rust terms, mutable) by default. To make a variable mutable, use `let mut`. More information on [variables][guide-var]. + +The variables are inserted into the output at the `{}` placeholders. + + ~~~~ fn main() { - let n = 3.0; + let n = 3.5; let l = 'b'; - println!("hello? the number is {} and the letter is {}.", n, l); + println!("hello? the number is {} and the letter is {}.", n as int, l); } ~~~~ -For more information on formatting strings, read [`std::fmt`][fmt]. +For more information on formatting strings, read [`std::fmt`][fmt]. [fmt]: http://static.rust-lang.org/doc/0.9/std/fmt/index.html -Getting user input is slightly more involved, the following code takes each line of input, and prints it back after the string "You wrote:". Note the bracketed `use` on line one to include two different functions on the same line. +Getting user input is slightly more involved, the following code takes each line of input, and prints it back after the string "You wrote:". Note the bracketed `use` on line one to include two different functions on the same line. ~~~~ use std::io::{stdin, BufferedReader}; @@ -65,24 +60,26 @@ fn main() { } ~~~~ -# `struct` +# Stack and Heap, `struct` -So far we've look at simple variables and strings. To represent compound data, use structures, which are groupings of types, and are introduced by the `struct` keyword. For example, a structure that represents a point on a two dimensional grid is composed of two integers, `x` and `y`. You can access the types within the `struct` using dot notation. +So far we've looked at simple variables and strings. To represent compound data use structures, which are groupings of data types, and are introduced by the `struct` keyword. For example, a structure that represents a point on a two dimensional grid is composed of two integers, `x` and `y`. You can access the types within the `struct` using dot notation. Create a point using a *struct literal* expression `let p = Point { x: 1, y: 2 };`, which assigns the point into the local variable `p`. The data for the point is stored directly on the stack, there is no heap allocation or pointer indirection, which improves performance. + + ~~~~ struct Point { x: int, y: int } fn main() { let p = Point { x: 1, y: 2}; println!("{}", p.x); // prints 1 - + } ~~~~ -In other words, if you look at the stack frame for the function `main()`, it looks like this: +If you look at the stack frame for the function `main()`, it looks like this: -~~~~ +~~~~{.notrust} +------+ | ... | --+ | 1 | | p.x @@ -93,7 +90,7 @@ In other words, if you look at the stack frame for the function `main()`, it loo -Storing aggregate data inline (ie, one the stack, with no pointer indirection) is critical for improving performance, because cache, malloc/free expensive, pointer chasing and cache invalidation require a complex runtime with garbage collector. - -Rust does not introduce pointers unless you specifically specify them. If we define a type `Line` that consists of two `Point`s: +Storing aggregate data inline is critical for improving performance, because cache, malloc/free, pointer chasing and cache invalidation require a complex runtime with garbage collector. If we define a type `Line` that consists of two `Point`s: -``` +~~~~{.notrust} struct Line { p1: Point, p2: Point } -``` +~~~~ -The two `Point`s are laid out inline inside the `Line` struct. +The two `Point`s are similarly laid out inline inside the `Line` struct, which avoids the memory overhead of multiple headers and pointers to objects in different locations. +~~~~{.notrust} ++------------------+ +|+------+ | +|| ... | --+ | +|| 1 | | p1.x | +|| 2 | | p1.y | +|+------+ --+ | +|+------+ | +|| ... | --+ | +|| 1 | | p2.x | +|| 2 | | p2.y | +|+------+ --+ | ++------------------+ ~~~~ -+------+ -| ... | --+ -| 1 | | p.x -| 2 | | p.y -+------+ --+ -+------+ -| ... | --+ -| 1 | | p.x -| 2 | | p.y -+------+ --+ + +## Stack vs. Heap + +Rust does not introduce pointers to the heap unless you specify that you require them, using the `~` symbol. To access the contents of the pointer, use the `*` symbol. Heap memory is freed when the variable goes out of scope. + ~~~~ +fn main() { + let mut x = 3; // allocated on the stack + x = x + 1; - - [guide-tup]: guide-syntax.html/tuples -# Stack vs. Heap - -Rust [variables][guide-var] are allocated on the stack by default. Rust also lets you allocate variables on the heap, using the `~` symbol. To access the variable use the `*` symbol. Heap memory is freed when the variable goes out of scope. - - - -~~~~ -fn main() { - let mut x = 3; // allocated on the stack - x = x + 1; - - let mut y = ~5; // allocated on the heap - // y = y + 1; // Does not work - *y = *y + 1; - -} -~~~~ +--> - -# Ownership +# Ownership -~~~~ +~~~~ struct Point {x: int, y: int} fn main() { let mut p = ~Point { x: 1, y: 2 }; let q = p; - + // p.x += 1; // error, huh? - + } ~~~~~ From 6528addfedf2e11403edaf46d202cff5a8dd4047 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Mon, 7 Apr 2014 22:18:19 +0200 Subject: [PATCH 08/14] Iterating --- src/doc/new-tutorial.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 3955f946d90b7..b4f031e9c3a03 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -133,7 +133,9 @@ The two `Point`s are similarly laid out inline inside the `Line` struct, which a ## Stack vs. Heap -Rust does not introduce pointers to the heap unless you specify that you require them, using the `~` symbol. To access the contents of the pointer, use the `*` symbol. Heap memory is freed when the variable goes out of scope. + + +Rust does not introduce pointers to the heap unless you specify that you require them, using the `~` symbol. To access the contents of the pointer, use the `*` symbol to dereference it. Heap memory is freed when the variable goes out of scope. ~~~~ fn main() { From e88d274a729de368d622a053dbb02a82edbd26ad Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Mon, 21 Apr 2014 20:06:32 +0200 Subject: [PATCH 09/14] Philosophy rewrite. --- src/doc/new-tutorial.md | 260 ++++++++++++++++++++++------------------ 1 file changed, 143 insertions(+), 117 deletions(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index b4f031e9c3a03..fd8b86c139d86 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -1,83 +1,36 @@ -% The (New) Rust Language Tutorial +% The Philosophy of Rust (provisional title) -An introductory tutorial to the Rust programming language. The tutorial focuses on Rust's strengths and unique design, and is intentionally brief. +An introduction to the Rust programming language that focuses on Rust's design choices and strengths. You should already be already familiar with programming concepts, in particular pointers, and a programming language from the C-family. The [syntax guide][syntax] is a reference to the nuts and bolts of the language, essentials such as [variables][guide-var], [functions][guide-fn], [structs][guide-struct] etc. - - [syntax]: guide-syntax.html [guide-var]: guide-syntax.html#variables [guide-fn]: guide-syntax.html#functions [guide-struct]: guide-syntax.html#struct +# Stack, Heap and inline structures -# Output and Input - -Output to the console using `print`. Use the `println` convenience function instead of `print` to add a newline to the end of the output. Note the `use std::io::print` syntax to include the `print` function from the standard `io` library. You can find more information on [use::][guide-use] in the [syntax guide][syntax]. - -[guide-use]: guide-syntax.html#use - -~~~~ -fn main() { - use std::io::print; - - print("hello?"); -} -~~~~ - -To add variables and formatting to the printed output, use `print!` or `println!`. Variables are introduced with the `let` keyword, and unlike in most other languages are not changeable (or in Rust terms, mutable) by default. To make a variable mutable, use `let mut`. More information on [variables][guide-var]. - -The variables are inserted into the output at the `{}` placeholders. - - - -~~~~ -fn main() { - let n = 3.5; - let l = 'b'; - - println!("hello? the number is {} and the letter is {}.", n as int, l); - -} -~~~~ - -For more information on formatting strings, read [`std::fmt`][fmt]. - -[fmt]: http://static.rust-lang.org/doc/0.9/std/fmt/index.html - -Getting user input is slightly more involved, the following code takes each line of input, and prints it back after the string "You wrote:". Note the bracketed `use` on line one to include two different functions on the same line. +To show how Rust semantics take maximum advantage of modern machine architecture to optimize runtime, we use a structure that represents a two dimensional point: ~~~~ -use std::io::{stdin, BufferedReader}; -fn main() { - let mut stdin = BufferedReader::new(stdin()); - for line in stdin.lines() { - println!("You wrote: {}", line); - } +struct Point { + x: int, + y: int } ~~~~ -# Stack and Heap, `struct` - -So far we've looked at simple variables and strings. To represent compound data use structures, which are groupings of data types, and are introduced by the `struct` keyword. For example, a structure that represents a point on a two dimensional grid is composed of two integers, `x` and `y`. You can access the types within the `struct` using dot notation. +Create a point using a *struct literal* expression which assigns the point into the local variable `p`, in this case specifying `x=1` and `y=2`. -Create a point using a *struct literal* expression `let p = Point { x: 1, y: 2 };`, which assigns the point into the local variable `p`. The data for the point is stored directly on the stack, there is no heap allocation or pointer indirection, which improves performance. - - - -~~~~ +```` struct Point { x: int, y: int } fn main() { let p = Point { x: 1, y: 2}; - println!("{}", p.x); // prints 1 } -~~~~ +```` -If you look at the stack frame for the function `main()`, it looks like this: +The data for the point is stored directly on the stack, there is no heap allocation or pointer indirection, which improves performance. The stack frame for the function `main()` looks like this: ~~~~{.notrust} +------+ @@ -87,11 +40,11 @@ If you look at the stack frame for the function `main()`, it looks like this: +------+ --+ ~~~~ - ```{.notrust} -(TODO: Make me not look like vomit) ----------------- ----------------------------- | struct p | 1 | x: ---------------| @@ -101,18 +54,22 @@ Those of you who are familiar with C and C++ will find this behavior familiar. I ----------------------------- ``` ---> +Storing aggregate data inline is critical for improving performance, because malloc/free, pointer chasing and cache invalidation require a complex runtime with garbage collector. -Storing aggregate data inline is critical for improving performance, because cache, malloc/free, pointer chasing and cache invalidation require a complex runtime with garbage collector. If we define a type `Line` that consists of two `Point`s: +Rust does not introduce pointers unless you specifically request them. If we define a type `Line` that consists of two `Point`s: -~~~~{.notrust} +~~~~ +struct Point { + x: int, + y: int +} struct Line { p1: Point, p2: Point } ~~~~ -The two `Point`s are similarly laid out inline inside the `Line` struct, which avoids the memory overhead of multiple headers and pointers to objects in different locations. +The two `Point`s are laid out inline inside the `Line` struct, which avoids the memory overhead of multiple headers and pointers to objects in different locations. @@ -131,105 +88,170 @@ The two `Point`s are similarly laid out inline inside the `Line` struct, which a +------------------+ ~~~~ -## Stack vs. Heap + - - -Rust does not introduce pointers to the heap unless you specify that you require them, using the `~` symbol. To access the contents of the pointer, use the `*` symbol to dereference it. Heap memory is freed when the variable goes out of scope. +Function parameters are laid out inline in the same way. A function that takes two points as arguments: +~~~~{.notrust} +fn draw_line(from: Point, to: Point) { // Draw the line } ~~~~ -fn main() { - let mut x = 3; // allocated on the stack - x = x + 1; - let mut y = ~5; // allocated on the heap - // y = y + 1; // Does not work - *y = *y + 1; +reserves space on the stack for the two point arguments. -} -~~~~ +## Heap Allocation +The stack is very efficient but it is also limited in size, so can't be used to store arbitrary amounts of data. To do that you need to allocate memory on the heap. - -[guide-tup]: guide-syntax.html/tuples +# Ownership and Moving ---> + + +In other languages, manually freeing memory carries the risk that if you use a pointer after it has been freed, you are using memory that no longer belongs to you, which might have been reused elsewhere in the system. The results are unpredicable, leading to errors, crashes, and security vulnerabilities. - +The last line, which attempts to use `points` after it has been *given* to `draw_polygon()` is flagged as an error by the Rust compiler. Because `draw_polygon()` has already freed the array's memory when it returned, this access would be reading from freed memory, which is not allowed. + +Ownership can also be transferred by returning a value or by storing it an array or the field of a struct. For example, we can modify the `draw_polygon()` function to return the array of points at the end, so that the caller can go on using it -# Move Vs Copy + - -### Enums and matching (???) +In Rust, owned pointers are called owned boxes, as they represent pointers to 'boxes' of memory. Ownership is not just about owned boxes. By default, whenever you declare a new type, values of that type are *moved* from place to place when you use them. By *move*, we mean that ownership of the value is transferred to its new location. -Introduce enums and matching here? Or after ownership? After 3.3? +Ownership is a powerful tool for working with values that require some sort of cleanup or which have some sort of destructor. Examples are owned boxes, which need to be freed, or file handles, which need to be closed. Ownership tells us who will perform this cleanup. ---> +For simple data types, however, this sort of tracking is inconvenient. The `Point` type that we introduced earlier is simply a pair of integers and requires no cleanup, so we might prefer that it be implicitly copied each time we use it rather than transferring ownership. To indicate that, we annotate the `Point` type with an attribute, `#[deriving(Copy)]`: + -# Ownership +``` +#[deriving(Copy)] +struct Point { + x: int, + y: int, +} +``` -~~~~ -struct Point {x: int, y: int} -fn main() { - let mut p = ~Point { x: 1, y: 2 }; - let q = p; +This annotation is an example of a Rust *attribute*. Rust attributes generally have the form `#[...]` and can be attached to any declaration. There are detailed guides on [attributes][attributes] in general and the [deriving][deriving] attribute in particular. - // p.x += 1; // error, huh? +[attributes]: FIXME +[deriving]: FIXME -} -~~~~~ +Now that we have indicated that `Point` values should be copied and not moved, we can continue using them even after they have been passed as parameters or stored into data structures: -* freeing +~~~~ +# struct Point { +# x: int, +# y: int +# } +fn main() { + let point1 = Point { x:1, y:2 }; + let point2 = Point { x:5, y:6 }; + + // Passing copies of some points to a function + draw_line(point1, point2); + + // Inserting copies of the same points into a boxed array. + // If `Point` were not declared as `#[deriving(Copy)]`, + // the compiler would flag an error + let points = ~[point1, point2]; + draw_polygon(points); +} +~~~~ # Borrowing Ownership is not the right tool when you just want temporary access to data: + ## Immutable borrow + + * only talking about using borrowed pointers in parameters * make it explicit we're not talking about returning borrowed pointers * don't introduce lifetime parameters yet From 22a3b0e4337df934f9a69e1c60b2d2f93064f1f1 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Mon, 21 Apr 2014 20:24:48 +0200 Subject: [PATCH 10/14] Typo fixes --- src/doc/new-tutorial.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index fd8b86c139d86..1e74c0dc52fd5 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -9,9 +9,9 @@ You should already be already familiar with programming concepts, in particular [guide-fn]: guide-syntax.html#functions [guide-struct]: guide-syntax.html#struct -# Stack, Heap and inline structures +# Stack, Heap and Inline Structures -To show how Rust semantics take maximum advantage of modern machine architecture to optimize runtime, we use a structure that represents a two dimensional point: +To show how Rust semantics take maximum advantage of modern machine architecture to optimize runtime, we use a structure that represents a point in 2 dimensions: ~~~~ struct Point { @@ -90,21 +90,22 @@ The two `Point`s are laid out inline inside the `Line` struct, which avoids the -Function parameters are laid out inline in the same way. A function that takes two points as arguments: +Function parameters are laid out inline in the same way. A function that takes two points as arguments reserves space on the stack for the two point arguments: ~~~~{.notrust} fn draw_line(from: Point, to: Point) { // Draw the line } ~~~~ -reserves space on the stack for the two point arguments. ## Heap Allocation The stack is very efficient but it is also limited in size, so can't be used to store arbitrary amounts of data. To do that you need to allocate memory on the heap. + + In Rust, the `~` operator allocates memory, so `~expr` allocates space on the heap, evaluates `expr` and stores the result on the heap. For example, `p=~Point { x: 1, y: 2 }`. `p` is not of type `Point` but of type `~Point`, the `~` indicates that it is a pointer to a heap allocation. -One very common use for heap allocation is to store [arrays][arrays]. For example, a function to draw an a polygon of an arbitrary list of points: +One very common use for heap allocation is to store [arrays][arrays]. For example, a function to draw a polygon of an arbitrary list of points: [arrays]: FIXME @@ -119,7 +120,9 @@ fn draw_polygon(points: ~[Point]) { } ~~~~ -The type `~[...]` in Rust indicates a heap-allocated array, in this case that means a variable number of points. You can create a `~[...]` array using a `~[...]` expression. Calling `draw_polygon` might look like: +The type `~[...]` in Rust indicates a heap-allocated array containing an unknown number of points. Calling `draw_polygon`: + + ~~~~ # struct Point { x: int, y: int } @@ -146,7 +149,7 @@ In Rust, whenever a heap pointer (that is, a variable of type `~T`) goes out of -In other languages, manually freeing memory carries the risk that if you use a pointer after it has been freed, you are using memory that no longer belongs to you, which might have been reused elsewhere in the system. The results are unpredicable, leading to errors, crashes, and security vulnerabilities. +In other languages, manually freeing memory carries the risk that if you use a pointer after it has been freed, you are using memory that no longer belongs to you, which might have been reused elsewhere. The results are unpredictable, leading to errors, crashes, and security vulnerabilities. Rust is designed to guarantee that once a pointer is freed, it can never be used again. Every heap pointer has an *owner*, and only the owner of a pointer may use it. When a pointer is first allocated, the owner is the function that allocated it. But when the pointer is passed as an argument, ownership is transferred to the callee. This means that the caller can no longer access the pointer or the memory it points at. @@ -185,7 +188,6 @@ Ownership can also be transferred by returning a value or by storing it an array # } fn draw_polygon(points: ~[Point]) -> ~[Point] { - ... return points; } From b5e88a17c81ddd6b695246a5df8cbdd246e8fc0e Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Wed, 30 Apr 2014 12:18:44 +0200 Subject: [PATCH 11/14] Where we're headed --- src/doc/new-tutorial.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 1e74c0dc52fd5..0c7450f13a9a2 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -11,7 +11,7 @@ You should already be already familiar with programming concepts, in particular # Stack, Heap and Inline Structures -To show how Rust semantics take maximum advantage of modern machine architecture to optimize runtime, we use a structure that represents a point in 2 dimensions: +To show how Rust semantics take maximum advantage of modern machine architecture to optimize runtime, we use a structure that represents a point in two dimensions: ~~~~ struct Point { @@ -298,3 +298,11 @@ fn get_point(p: &Point) -> int { * make it explicit we're not talking about returning borrowed pointers * don't introduce lifetime parameters yet * don't put pointers into structs + +# Mutability + +# Lifetimes + +# Vectors vs. Slices + +# Structs, enums, and pattern matching From 4fcb05d37ed8c22445ac076cb3b3541918874fe0 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Wed, 7 May 2014 19:14:39 +0200 Subject: [PATCH 12/14] Editing --- src/doc/new-tutorial.md | 67 +++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 0c7450f13a9a2..d8a6bba49d8c3 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -1,17 +1,59 @@ -% The Philosophy of Rust (provisional title) +% The Rust Tutorial -An introduction to the Rust programming language that focuses on Rust's design choices and strengths. +Rust is a compiled programming language with a focus on type safety, memory safety, concurrency and performance. It has a sophisticated memory model that encourages efficient data structures and safe concurrency patterns, forbidding invalid memory accesses that would otherwise cause segmentation faults. -You should already be already familiar with programming concepts, in particular pointers, and a programming language from the C-family. The [syntax guide][syntax] is a reference to the nuts and bolts of the language, essentials such as [variables][guide-var], [functions][guide-fn], [structs][guide-struct] etc. +This brief introduction to Rust focuses on Rust's design choices, strengths and 'philosophy'. You should already be already familiar with programming concepts, in particular pointers, and a programming language from the C-family. The [syntax guide][syntax] is a reference to the nuts and bolts of the language, essentials such as [variables][guide-var], [functions][guide-fn], [structs][guide-struct] etc. [syntax]: guide-syntax.html [guide-var]: guide-syntax.html#variables [guide-fn]: guide-syntax.html#functions [guide-struct]: guide-syntax.html#struct +# Running the Example Code + +Before we get started, lets show you how to compile the code examples shown in the tutorial. + +## Installing Rust + +To install Rust on Windows: + +1. Download and run the latest stable installer (.exe) from the [Rust website][install]. + +To install Rust on OS X: + +1. Download and run the latest stable installer (.pkg) from the [Rust website][install]. + +To install Rust on Linux: + +1. Download and extract the latest stable binaries (tar.gz) from the [Rust website][install]. +2. Run the `./install.sh` inside the directory. + +There are more complete [installation intructions][install-wiki] on the wiki. + +[install]: http://www.rust-lang.org/install.html +[install-wiki]: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools + + + +## Compiling and Running Rust Examples + +1. Copy and paste the following source into an empty text file and save it as `example.rs`. By convention Rust source files have the `.rs` extension. + + ~~~~ + fn main() { + println!("Hello world!"); + } + ~~~~ + +2. Run `rustc example.rs` +3. If there are no compiler errors, you can run `./example`. + + + + # Stack, Heap and Inline Structures -To show how Rust semantics take maximum advantage of modern machine architecture to optimize runtime, we use a structure that represents a point in two dimensions: +To show how Rust semantics take maximum advantage of machine architecture to optimize runtime, we use a structure that represents a point in two dimensions: ~~~~ struct Point { @@ -30,7 +72,11 @@ fn main() { } ```` -The data for the point is stored directly on the stack, there is no heap allocation or pointer indirection, which improves performance. The stack frame for the function `main()` looks like this: + + +The stack frame for the function `main()` looks like this: ~~~~{.notrust} +------+ @@ -44,7 +90,7 @@ Those of you who are familiar with C and C++ will find this behavior familiar. I -```{.notrust} +~~~~{.notrust} ----------------- ----------------------------- | struct p | 1 | x: ---------------| @@ -52,9 +98,12 @@ Those of you who are familiar with C and C++ will find this behavior familiar. I ----------------------------- | 2 ----------------------------- -``` +~~~~ + + Rust does not introduce pointers unless you specifically request them. If we define a type `Line` that consists of two `Point`s: @@ -120,9 +169,9 @@ fn draw_polygon(points: ~[Point]) { } ~~~~ -The type `~[...]` in Rust indicates a heap-allocated array containing an unknown number of points. Calling `draw_polygon`: +The type `~[...]` in Rust indicates a heap-allocated array containing a variable number of points. Calling `draw_polygon`: - + ~~~~ # struct Point { x: int, y: int } From 05af4100c4c2043acde7859e4fd2c9ab4230cc8f Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Thu, 8 May 2014 20:21:40 +0200 Subject: [PATCH 13/14] Edits --- src/doc/guide-syntax.md | 8 +++---- src/doc/new-tutorial.md | 52 ++++++++++++++++++++++++++++++----------- 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/src/doc/guide-syntax.md b/src/doc/guide-syntax.md index 8ca03f38d04ed..8ae9c30e20064 100644 --- a/src/doc/guide-syntax.md +++ b/src/doc/guide-syntax.md @@ -15,13 +15,13 @@ A *very* brief guide to Rust syntax. It assumes you are already familar with pro Functions in Rust are introduced with the `fn` keyword, optional arguments are specified within parenthesis as comma separated `name: type` pairs, and `->` indicates the return type. You can ommit the return type for functions that do not return a value. Functions return the top level expression (note the return expression is not terminated with a semi colon). ~~~~ +fn increment(i:int) -> (int) { + i + 1 +} + fn main() { let i = 7; - fn increment(i:int) -> (int) { - i + 1 - } - let k = increment(i); // k=8 } ~~~~ diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index d8a6bba49d8c3..5b7a148c833c4 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -39,11 +39,11 @@ There are more complete [installation intructions][install-wiki] on the wiki. 1. Copy and paste the following source into an empty text file and save it as `example.rs`. By convention Rust source files have the `.rs` extension. - ~~~~ - fn main() { - println!("Hello world!"); - } - ~~~~ + ~~~~ + fn main() { + println!("Hello world!"); + } + ~~~~ 2. Run `rustc example.rs` 3. If there are no compiler errors, you can run `./example`. @@ -64,13 +64,13 @@ struct Point { Create a point using a *struct literal* expression which assigns the point into the local variable `p`, in this case specifying `x=1` and `y=2`. -```` +~~~~ struct Point { x: int, y: int } + fn main() { let p = Point { x: 1, y: 2}; - } -```` +~~~~ + ~~~~{.notrust} ----------------- ----------------------------- @@ -159,6 +164,13 @@ One very common use for heap allocation is to store [arrays][arrays]. For exampl [arrays]: FIXME ~~~~ +struct Point { + x: int, + y: int +} + +fn draw_line(from: Point, to: Point) { // Draw the line } + fn draw_polygon(points: ~[Point]) { let mut i = 0; while i < points.len() - 1 { @@ -175,6 +187,15 @@ The type `~[...]` in Rust indicates a heap-allocated array containing a variable ~~~~ # struct Point { x: int, y: int } +# fn draw_line(from: Point, to: Point) { // Draw the line } +fn draw_polygon(points: ~[Point]) { + let mut i = 0; + while i < points.len() - 1 { + draw_line(points[i], points[i+1]); + i += 1; + } + draw_line(points[i], points[0]); +} fn main() { let p1 = Point { x: 0, y: 0 }; @@ -187,9 +208,11 @@ fn main() { + --> # Ownership and Moving @@ -210,7 +233,7 @@ struct Point { y: int } -fn draw_polygon(points: ~[Point]) { // Draw the line} +fn draw_polygon(points: ~[Point]) { // Draw the line } fn main() { // `points` is initially owned by `main()` @@ -262,13 +285,13 @@ Ownership is a powerful tool for working with values that require some sort of c For simple data types, however, this sort of tracking is inconvenient. The `Point` type that we introduced earlier is simply a pair of integers and requires no cleanup, so we might prefer that it be implicitly copied each time we use it rather than transferring ownership. To indicate that, we annotate the `Point` type with an attribute, `#[deriving(Copy)]`: -``` +~~~~ #[deriving(Copy)] struct Point { x: int, y: int, } -``` +~~~~ This annotation is an example of a Rust *attribute*. Rust attributes generally have the form `#[...]` and can be attached to any declaration. There are detailed guides on [attributes][attributes] in general and the [deriving][deriving] attribute in particular. @@ -282,6 +305,7 @@ Now that we have indicated that `Point` values should be copied and not moved, w # x: int, # y: int # } + fn main() { let point1 = Point { x:1, y:2 }; let point2 = Point { x:5, y:6 }; From cf72c6401bae689201bb5f9fef22f1570a2556a7 Mon Sep 17 00:00:00 2001 From: Samuel Wright Date: Tue, 13 May 2014 16:15:44 +0200 Subject: [PATCH 14/14] Minor fixes for issues raised in https://github.com/mozilla/rust/pull/14017 --- src/doc/guide-syntax.md | 10 +++++----- src/doc/new-tutorial.md | 16 ++++++---------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/doc/guide-syntax.md b/src/doc/guide-syntax.md index 8ae9c30e20064..649757f35b1af 100644 --- a/src/doc/guide-syntax.md +++ b/src/doc/guide-syntax.md @@ -1,10 +1,12 @@ % The Guide to Rust Syntax +<-- We're still figuring out exactly what to do with this, so don't waste much time checking it. --> + A *very* brief guide to Rust syntax. It assumes you are already familar with programming concepts. # Arguments -# Conditions +# Conditional Statements # `enum` @@ -28,8 +30,6 @@ fn main() { # Loops -## `if` - ## `loop` ## `while` @@ -48,8 +48,8 @@ fn main() { There are two types of variable in Rust: -* `immutable` - the value cannot be changed. Introduced with `let mut`. -* `mutable` - the value of can be changed. Introduced with `let`. +* `immutable` - the value cannot be changed. Introduced with `let`. +* `mutable` - the value of can be changed. Introduced with `let mut`. ~~~~ fn main() { diff --git a/src/doc/new-tutorial.md b/src/doc/new-tutorial.md index 5b7a148c833c4..1d006922d070e 100644 --- a/src/doc/new-tutorial.md +++ b/src/doc/new-tutorial.md @@ -25,7 +25,7 @@ To install Rust on OS X: To install Rust on Linux: -1. Download and extract the latest stable binaries (tar.gz) from the [Rust website][install]. +1. Download and extract the latest stable binaries (.tar.gz) from the [Rust website][install]. 2. Run the `./install.sh` inside the directory. There are more complete [installation intructions][install-wiki] on the wiki. @@ -33,8 +33,6 @@ There are more complete [installation intructions][install-wiki] on the wiki. [install]: http://www.rust-lang.org/install.html [install-wiki]: https://github.com/mozilla/rust/wiki/Doc-packages,-editors,-and-other-tools - - ## Compiling and Running Rust Examples 1. Copy and paste the following source into an empty text file and save it as `example.rs`. By convention Rust source files have the `.rs` extension. @@ -46,10 +44,7 @@ There are more complete [installation intructions][install-wiki] on the wiki. ~~~~ 2. Run `rustc example.rs` -3. If there are no compiler errors, you can run `./example`. - - - +3. If there are no compiler errors, run `"./example"` and see "Hello world!" printed to screen. # Stack, Heap and Inline Structures @@ -72,7 +67,8 @@ fn main() { } ~~~~ - @@ -105,7 +101,7 @@ https://github.com/mozilla/rust/pull/14017#discussion_r12404628 ----------------------------- ~~~~ - @@ -157,7 +153,7 @@ The stack is very efficient but it is also limited in size, so can't be used to -In Rust, the `~` operator allocates memory, so `~expr` allocates space on the heap, evaluates `expr` and stores the result on the heap. For example, `p=~Point { x: 1, y: 2 }`. `p` is not of type `Point` but of type `~Point`, the `~` indicates that it is a pointer to a heap allocation. +In Rust, the box operator (`~`) allocates memory, so `~expr` allocates space on the heap, evaluates `expr` and stores the result on the heap. For example, `p=~Point { x: 1, y: 2 }`. `p` is not of type `Point` but of type `~Point`, the `~` indicates that it is a pointer to a heap allocation. One very common use for heap allocation is to store [arrays][arrays]. For example, a function to draw a polygon of an arbitrary list of points: