macros: rename some sections, cover macro expansion (WIP)
diff --git a/examples/staging/macros/arguments/designators.rs b/examples/staging/macros/arguments/designators.rs
index 0b88855..9e9f78a 100644
--- a/examples/staging/macros/arguments/designators.rs
+++ b/examples/staging/macros/arguments/designators.rs
@@ -1,28 +1,28 @@
 #![feature(macro_rules)]
 
 macro_rules! create_function {
-    // this macro takes an argument of "type" `ident`
-    // the `ident` designator is used for variable/function names
+    // This macro takes an argument of "type" `ident`
+    // The `ident` designator is used for variable/function names
     ($func_name:ident) => {
-        // this macro creates a function with name `$func_name`
+        // This macro creates a function with name `$func_name`
         fn $func_name() {
-            // the stringify! macro converts an `ident` into a string
-            println!("You called {}()",
-                     stringify!($func_name))
+            // The `stringify!` macro converts an `ident` into a string
+            println!("You called {}()", stringify!($func_name))
         }
     }
 }
 
 create_function!(foo)
 create_function!(bar)
+// Designators provide type safety in macros
+//create_function!(0)
+// TODO ^ Try uncommenting this line
 
 macro_rules! print_result {
-    // the `expr` designator is used for expressions
+    // The `expr` designator is used for expressions
     ($expression:expr) => {
-        // stringify! will convert the expression *as it is* into a string
-        println!("{} = {}",
-                 stringify!($expression),
-                 $expression)
+        // `stringify!` will convert the expression *as it is* into a string
+        println!("{} = {}", stringify!($expression), $expression)
     }
 }
 
@@ -32,7 +32,7 @@
 
     print_result!(1u + 1);
 
-    // remember that blocks are expressions
+    // Remember that blocks are expressions too
     print_result!({
         let x = 1u;
 
diff --git a/examples/staging/macros/arguments/input.md b/examples/staging/macros/arguments/input.md
index 93f7efa..ba2e8e3 100644
--- a/examples/staging/macros/arguments/input.md
+++ b/examples/staging/macros/arguments/input.md
@@ -9,10 +9,10 @@
 * `expr` is used for expressions
 * `ident` is used for variable/function names
 * `item`
-* `matchers` (lhs of the => in macro rules)
+* `matchers`
 * `pat`
 * `path`
 * `stmt`
-* `tt` (*token tree*) is used for operators and tokens
+* `tt` (*token tree*) is used for operators (`+`, `-`, etc)
 * `ty` (*type*)
 
diff --git a/examples/staging/macros/arity/input.md b/examples/staging/macros/arity/input.md
new file mode 100644
index 0000000..f8c954f
--- /dev/null
+++ b/examples/staging/macros/arity/input.md
@@ -0,0 +1,15 @@
+Macros can have different implementations depending on their arity (number of
+arguments), this can be used to implement some form of function overloading.
+Here we implement a macro similar to Python's overloaded
+[range](https://docs.python.org/3/library/stdtypes.html?highlight=range#range)
+function:
+
+```rust
+// Here is how it should work
+range!(10i)       // Returns 0..9
+range!(3i, 10)    // Returns 3..9
+range!(3i, 10, 2) // Returns 3, 5, 7, 9 (3..9 in increments of 2)
+```
+
+{range.play}
+
diff --git a/examples/staging/macros/arity/range.rs b/examples/staging/macros/arity/range.rs
new file mode 100644
index 0000000..98a7025
--- /dev/null
+++ b/examples/staging/macros/arity/range.rs
@@ -0,0 +1,32 @@
+#![feature(macro_rules)]
+
+use std::iter::range_step;
+
+// `macro_rules` behaves like a `match` expression
+macro_rules! range (
+    // The left side of the fat arrow is the `pattern` side, and the right side
+    // is the `expansion` side
+    ($end:expr) => {
+        range(0, $end)
+    };
+    // The macro can have a different expansion for each arity
+    ($start:expr, $end:expr) => {
+        range($start, $end)
+    };
+    // ^ Each pattern-match arm must be terminated by a semicolon
+    ($start:expr, $end:expr, $step:expr) => {
+        range_step($start, $end, $step)
+    };
+    // The semicolon on the last arm is optional (is a trailing semicolon)
+)
+
+fn main() {
+    for i in range!(10i) { print!("{}", i) }
+    println!("");
+
+    for i in range!(3i, 10) { print!("{}", i) }
+    println!("");
+
+    for i in range!(3i, 10, 2) { print!("{}", i) }
+}
+
diff --git a/examples/staging/macros/test_suite/dry.rs b/examples/staging/macros/dry/dry.rs
similarity index 100%
rename from examples/staging/macros/test_suite/dry.rs
rename to examples/staging/macros/dry/dry.rs
diff --git a/examples/staging/macros/test_suite/input.md b/examples/staging/macros/dry/input.md
similarity index 100%
rename from examples/staging/macros/test_suite/input.md
rename to examples/staging/macros/dry/input.md
diff --git a/examples/staging/macros/expand/input.md b/examples/staging/macros/expand/input.md
new file mode 100644
index 0000000..0b967d1
--- /dev/null
+++ b/examples/staging/macros/expand/input.md
@@ -0,0 +1,30 @@
+You can check the expansion of any macro by running the
+`rustc --pretty expanded` command over your source file.
+
+Let's see what the `vec!` macro expands to:
+
+{vec.rs}
+
+``` rust
+$ rustc --pretty expanded vec.rs
+#![feature(phase)]
+#![no_std]
+#![feature(globs)]
+#[phase(plugin, link)]
+extern crate std;
+extern crate native;
+use std::prelude::*;
+fn main() {
+    let v1 =
+        { let mut _temp = ::std::vec::Vec::new(); _temp.push(1u); _temp };
+    let v2 =
+        {
+            let mut _temp = ::std::vec::Vec::new();
+            _temp.push(1u);
+            _temp.push(2);
+            _temp
+        };
+}
+```
+
+Soon you'll learn how to define macros that work like this one!
diff --git a/examples/staging/macros/expand/vec.rs b/examples/staging/macros/expand/vec.rs
new file mode 100644
index 0000000..21f5438
--- /dev/null
+++ b/examples/staging/macros/expand/vec.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let v1 = vec!(1u);
+    let v2 = vec!(1u, 2);
+}
diff --git a/examples/staging/macros/input.md b/examples/staging/macros/input.md
index 819a4a5..5d5b030 100644
--- a/examples/staging/macros/input.md
+++ b/examples/staging/macros/input.md
@@ -3,7 +3,7 @@
 ends with a bang `!`, but instead of generating a function call, macros are
 expanded into source code that gets compiled with the rest of the program.
 
-Macros are created using the `macro_rules!` macro.
+Macros are defined using the `macro_rules!` macro.
 
 {simple.play}
 
diff --git a/examples/staging/macros/repetition/input.md b/examples/staging/macros/repetition/input.md
index bcc71bb..f1cce1d 100644
--- a/examples/staging/macros/repetition/input.md
+++ b/examples/staging/macros/repetition/input.md
@@ -1,51 +1,32 @@
-Macros can also match and return repeated patterns. This is similar but
-different from a regex. `$($x:expr),+` is a matching example. It uses the
-`$()` grouping operator to mark `x` as repeatable. `+` or `*` denotes
-repetition amount; one or more and zero or more respectively. `,`
-is the only separator token available.
+Macros can be defined to handle indefinite arity (any number of arguments).
+This can be accomplished using the *repetition* syntax and the `+`
+and `*` operators. This is what the syntax looks like:
 
-```rust
-// The separator only checks separation; this is
-// not a regex.
-$($x:expr),+ // matches `1, 2, 3` but not `1, 2,`
-```
+On the pattern side:
 
-When returned, it uses a similar notation: `$($x:expr),+` => `$($x),+`
-however, a returned list will not be re-expanded whereas, matching
-will find the whole thing.
+* `($($x:expr),+)`: matches a list (with at least one element) of `expr`s
+  separated by commas. Examples: `('a', 'b')` and `(1 + 2, 3 * 4, 5 - 6)`
 
-```rust
-#![feature(macro_rules)]
+* `($($y:ident),*)`: matches a list of `ident`s separated by commas, but also
+  handles the zero arity case. Examples: `()` and `(foo, bar)`
 
-macro_rules! echo_broken {
-    // Attempt to match and return with one compact expression
-    ($($x:expr),+) => { $($x),+ };
-}
+* Neither of these two patterns will match a list that has a trailing comma. To
+  allow trailing commas, you can use this pattern: `($($z:expr),+,)`
 
-macro_rules! echo_works {
-    ($x:expr) => { $x }; // one element list
-    // $x is the first element. `$($y:expr),+` is the tail
-    ($x:expr, $($y:expr),+) => {
-        // pass the tail to `echo_works` so it can be expanded
-        ($x, echo_works!($($y),+))
-    };
-}
+On the expansion side:
 
-fn main() {
-    println!("{}", echo_broken!(1u)); // Works for single elements
+* `[$($x),+]`: will expand the input arguments (the `$x`s) into an array.
+  Following the previous example: `['a', 'b']` and `[1 + 2, 3 * 4, 5 - 6]`
 
-    // Errors: `,` ignored. A list is never re-expanded so when
-    // the `,` is reached, the rest of the line is ignored.
-    // Rust does not allow incomplete expansion, so it errors. To
-    // handle this, recursion is needed.
-    //println!("{}", echo_broken!(1u, 2u));
+For our example, we'll make a `min!` macro that can take any number of
+arguments and will return the smallest one. Under the hood it will use the
+`min` function that compares *two* arguments.
 
-    println!("{}", echo_works!(1u));
-    // Would like it flat but it nests the results...
-    println!("{}", echo_works!(1u, 2u, 3u, 4u, 5u, 6u));
-}
-```
-
-Another example making a min macro:
 {repeat.play}
 
+If you check the expansion you'll see this expression in the place of the last
+macro:
+
+``` rust
+std::cmp::min(5u, std::cmp::min(2u * 3, 4u))
+```
diff --git a/examples/staging/macros/repetition/repeat.rs b/examples/staging/macros/repetition/repeat.rs
index dbe6258..a9a1780 100644
--- a/examples/staging/macros/repetition/repeat.rs
+++ b/examples/staging/macros/repetition/repeat.rs
@@ -1,16 +1,16 @@
 #![feature(macro_rules)]
 
-// min! will calculate the minimum of any number of arguments
+// It's common to use recursion to handle indefinite arity
 macro_rules! min {
     // base case
     ($x:expr) => {
         $x
     };
-    // `$x` followed by at least one `$y,`
+    // `$x` followed by at least another `expr`
     ($x:expr, $($y:expr),+) => {
-        // call min! on the tail `$y`
+        // Recursion! Call `min!` on the tail
         std::cmp::min($x, min!($($y),+))
-    }
+    };
 }
 
 fn main() {
diff --git a/examples/staging/macros/separators/input.md b/examples/staging/macros/separators/input.md
index 82fb09b..8644cdd 100644
--- a/examples/staging/macros/separators/input.md
+++ b/examples/staging/macros/separators/input.md
@@ -1,4 +1,20 @@
-Macros can be overloaded to accept different combinations of arguments.
+So far we have been using a comma to separate the arguments fed into a macro,
+but macros are more flexible than that! You are free to use symbols or words to
+separate the input arguments of the macro.
 
-{overload.play}
+Let's create a sugary macro to initialize hash maps:
 
+{separators.play}
+
+The expansion of the `map!` macro looks like this:
+
+``` rust
+let alphabet =
+        {
+            let mut _temp = std::collections::HashMap::new();
+            _temp.insert('a', "apple");
+            _temp.insert('b', "banana");
+            _temp.insert('c', "carrot");
+            _temp
+        };
+```
diff --git a/examples/staging/macros/separators/overload.rs b/examples/staging/macros/separators/overload.rs
deleted file mode 100644
index e1e04b2..0000000
--- a/examples/staging/macros/separators/overload.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-#![feature(macro_rules)]
-
-// macro_rules! is similar to a match block
-macro_rules! test {
-    // the arguments don't need to be separated by a comma
-    // any template can be used
-    ($left:expr and $right:expr) => {
-        println!("{} and {} is {}",
-                 stringify!($left),
-                 stringify!($right),
-                 $left && $right)
-    };
-    // ^ each arm must be ended with a semicolon
-    ($left:expr or $right:expr) => {
-        println!("{} or {} is {}",
-                 stringify!($left),
-                 stringify!($right),
-                 $left || $right)
-    };
-}
-
-fn main() {
-    test!(1i + 1 == 2i and 2i * 2 == 4i);
-    test!(true or false);
-}
diff --git a/examples/staging/macros/separators/separators.rs b/examples/staging/macros/separators/separators.rs
new file mode 100644
index 0000000..3d38c2e
--- /dev/null
+++ b/examples/staging/macros/separators/separators.rs
@@ -0,0 +1,26 @@
+#![feature(macro_rules)]
+
+macro_rules! map {
+    ($($key:expr => $value:expr),*) => ({
+        let mut _temp = std::collections::HashMap::new();
+
+        $(_temp.insert($key, $value);)*
+
+        _temp
+    });
+    // Handle trailing commas
+    ($($key:expr => $value:expr),+,) => (
+        map!($($key => $value),+)
+    );
+}
+
+fn main() {
+    let alphabet = map! {
+        'a' => "apple",
+        'b' => "banana",
+        'c' => "carrot",
+    };
+
+    println!("{}", alphabet);
+}
+
diff --git a/examples/staging/macros/simple.rs b/examples/staging/macros/simple.rs
index 648bc07..ac8fb9b 100644
--- a/examples/staging/macros/simple.rs
+++ b/examples/staging/macros/simple.rs
@@ -1,16 +1,16 @@
-// macros are behind a feature gate
+// Macros are behind a "feature gate", because they are considered experimental
 #![feature(macro_rules)]
 
 // This is the simplest macro, `say_hello` is the name of the macro
 macro_rules! say_hello {
     // `()` indicates that the macro takes no argument
     () => {
-        // the macro will expand into the contents of this block
+        // The macro will expand into the contents of this block
         println!("Hello!");
     }
 }
 
 fn main() {
-    // this call will expand into `println!("Hello");`
-    say_hello!()
+    // This call will expand into `println!("Hello");`
+    say_hello!();
 }
diff --git a/examples/staging/macros/variable_args/input.md b/examples/staging/macros/variable_args/input.md
deleted file mode 100644
index d8d0b20..0000000
--- a/examples/staging/macros/variable_args/input.md
+++ /dev/null
@@ -1,13 +0,0 @@
-Variadic (variable number of arguments) functions can be implemented via
-macros. Here we implement a macro similar to Python's overloaded
-[range](https://docs.python.org/3/tutorial/controlflow.html#the-range-function) function:
-
-```rust
-// Here is how it should work
-range!(10i)       // Returns 0..9
-range!(3i, 10)    // Returns 3..9
-range!(3i, 10, 2) // Returns 3, 5, 7, 9 (3..9 in increments of 2)
-```
-
-{range.play}
-
diff --git a/examples/staging/macros/variable_args/range.rs b/examples/staging/macros/variable_args/range.rs
deleted file mode 100644
index 5eb4205..0000000
--- a/examples/staging/macros/variable_args/range.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-#![feature(macro_rules)]
-
-use std::iter::range_step;
-
-// range! will take up to 3 inputs and call range
-// function depending on inputs
-macro_rules! range (
-    ($end:expr) => {
-        range(0, $end)
-    };
-    ($start:expr, $end:expr) => {
-        range($start, $end)
-    };
-    ($start:expr, $end:expr, $step:expr) => {
-        range_step($start, $end, $step)
-    };
-)
-
-fn main() {
-    for i in range!(10i) { print!("{}", i) }
-    println!("");
-
-    for i in range!(3i, 10) { print!("{}", i) }
-    println!("");
-
-    for i in range!(3i, 10, 2) { print!("{}", i) }
-}
-
diff --git a/examples/structure.json b/examples/structure.json
index 207823a..6247e8a 100644
--- a/examples/structure.json
+++ b/examples/structure.json
@@ -104,11 +104,13 @@
     { "id": "bench", "title": "Benchmarking", "children": null  },
     { "id": "ffi", "title": "Foreign Function Interface", "children": null  },
     { "id": "macros", "title": "macro_rules!", "children": [
-      { "id": "arguments", "title": "Arguments and designators", "children": null },
-      { "id": "variable_args", "title": "Variadic macros", "children": null },
-      { "id": "separators", "title": "Variable separator options", "children": null },
-      { "id": "repetition", "title": "Repetition and expansion", "children": null },
-      { "id": "test_suite", "title": "Generating generic test suite implementations", "children": null }
+      { "id": "expand", "title": "Expansion", "children": null },
+      { "id": "arguments", "title": "Designators", "children": null },
+      { "id": "arity", "title": "Arity", "children": null },
+      { "id": "repetition", "title": "Repetition", "children": null },
+      { "id": "separators", "title": "Separators", "children": null },
+      { "id": "dry", "title": "DRY", "children": null },
+      { "id": "export", "title": "Export", "children": null }
   ] },
     { "id": "rand", "title": "Random", "children": null  },
     { "id": "simd", "title": "SIMD", "children": null  },