From d58a9c73464133f95663bf5e78bb693ffb5de284 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 2 Nov 2011 13:49:37 +0100 Subject: [PATCH] Expand the tutorial section on functions --- doc/tutorial/func.md | 22 +++++++++++++++++++- doc/tutorial/lib/codemirror-rust.js | 3 ++- doc/tutorial/syntax.md | 32 ++++++++++++++--------------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/doc/tutorial/func.md b/doc/tutorial/func.md index b0e5dd793ab..c174b904fb9 100644 --- a/doc/tutorial/func.md +++ b/doc/tutorial/func.md @@ -40,6 +40,11 @@ not see changes made to these variables after the `lambda` was evaluated. `lambda`s can be put in data structures and passed around without limitation. +The type of a closure is `lambda(args) -> type`, as opposed to +`fn(args) -> type`. The `fn` type stands for 'bare' functions, with no +closure attached. Keep this in mind when writing higher-order +functions. + A different form of closure is the block. Blocks are written like they are in Ruby: `{|x| x + y}`, the formal parameters between pipes, followed by the function body. They are stack-allocated and properly @@ -55,10 +60,25 @@ stored in data structures or returned. } map_int({|x| x + 1 }, [1, 2, 3]); +The type of blocks is spelled `block(args) -> type`. Both closures and +bare functions are automatically convert to `block`s when appropriate. +Most higher-order functions should take their function arguments as +`block`s. + A block with no arguments is written `{|| body(); }`—you can not leave off the pipes. -FIXME mention bind +## Binding + +Partial application is done using the `bind` keyword in Rust. + + let daynum = bind std::vec::position(_, ["mo", "tu", "we", "do", + "fr", "sa", "su"]); + +Binding a function produces a closure (`lambda` type) in which some of +the arguments to the bound function have already been provided. +`daynum` will be a function taking a single string argument, and +returning the day of the week that string corresponds to (if any). ## Iteration diff --git a/doc/tutorial/lib/codemirror-rust.js b/doc/tutorial/lib/codemirror-rust.js index 70091470e80..5ab964c107e 100644 --- a/doc/tutorial/lib/codemirror-rust.js +++ b/doc/tutorial/lib/codemirror-rust.js @@ -8,7 +8,8 @@ CodeMirror.defineMode("rust", function() { "lambda": "fn", "type": "type", "tag": "tag", "mod": "mod", "as": "op", "true": "atom", "false": "atom", "assert": "op", "check": "op", "claim": "op", "native": "ignore", "unsafe": "ignore", "import": "else-style", - "export": "else-style", "copy": "op", "log": "op", "log_err": "op", "use": "op" + "export": "else-style", "copy": "op", "log": "op", "log_err": "op", + "use": "op", "bind": "op" }; var typeKeywords = function() { var keywords = {"fn": "fn", "block": "fn", "obj": "obj"}; diff --git a/doc/tutorial/syntax.md b/doc/tutorial/syntax.md index aa53932c382..acef5163a59 100644 --- a/doc/tutorial/syntax.md +++ b/doc/tutorial/syntax.md @@ -130,31 +130,31 @@ annotation: The basic types are written like this: `()` -: Nil, the type that has only a single value. +: Nil, the type that has only a single value. `bool` -: Boolean type.. +: Boolean type.. `int` -: A machine-pointer-sized integer. +: A machine-pointer-sized integer. `uint` -: A machine-pointer-sized unsigned integer. +: A machine-pointer-sized unsigned integer. `i8`, `i16`, `i32`, `i64` -: Signed integers with a specific size (in bits). +: Signed integers with a specific size (in bits). `u8`, `u16`, `u32`, `u64` -: Unsigned integers with a specific size. +: Unsigned integers with a specific size. `f32`, `f64` -: Floating-point types. +: Floating-point types. `float` -: The largest floating-point type efficiently supported on the target machine. +: The largest floating-point type efficiently supported on the target machine. `char` -: A character is a 32-bit Unicode code point. +: A character is a 32-bit Unicode code point. `str` : String type. A string contains a utf-8 encoded sequence of characters. @@ -163,22 +163,22 @@ These can be combined in composite types, which will be described in more detail later on (the `T`s here stand for any other type): `[T]` -: Vector type. +: Vector type. `[mutable T]` -: Mutable vector type. +: Mutable vector type. `(T1, T2)` -: Tuple type. Any arity above 1 is supported. +: Tuple type. Any arity above 1 is supported. `{fname1: T1, fname2: T2}` -: Record type. +: Record type. -`fn(arg1: T1, arg2: T2) -> T3` -: Function type. +`fn(arg1: T1, arg2: T2) -> T3`, `lambda()`, `block()` +: Function types. `@T`, `~T`, `*T` -: Pointer types. +: Pointer types. `obj { fn method1() }` : Object type.