+
+On the other hand, the compiler can usually infer both the argument
+and return types for a closure expression; therefore they are often
+omitted, since both a human reader and the compiler can deduce the
+types from the immediate context. This is in contrast to function
+declarations, which require types to be specified and are not subject
+to type inference. Compare:
+
+~~~~ {.ignore}
+// `fun` as a function declaration cannot infer the type of `x`, so it must be provided
+fn fun (x: int) { println!("{}", x) }
+let closure = |x | { println!("{}", x) }; // infers `x: int`, return type `()`
+
+// For closures, omitting a return type is *not* synonymous with `-> ()`
+let add_3 = |y | { 3i + y }; // infers `y: int`, return type `int`.
+
+fun(10); // Prints 10
+closure(20); // Prints 20
+closure(add_3(30)); // Prints 33
+
+fun("String"); // Error: mismatched types
+
+// Error: mismatched types
+// inference already assigned `closure` the type `|int| -> ()`
+closure("String");
+~~~~
+
+In cases where the compiler needs assistance, the arguments and return
+types may be annotated on closures, using the same notation as shown
+earlier. In the example below, since different types provide an
+implementation for the operator `*`, the argument type for the `x`
+parameter must be explicitly provided.
+
+~~~~{.ignore}
+// Error: the type of `x` must be known to be used with `x * x`
+let square = |x | -> uint { (x * x) as uint };
+~~~~
+
+In the corrected version, the argument type is explicitly annotated,
+while the return type can still be inferred.
+
+~~~~
+let square_explicit = |x: int| -> uint { (x * x) as uint };
+let square_infer = |x: int| { (x * x) as uint };
+
+println!("{}", square_explicit(20)); // 400
+println!("{}", square_infer(-20)); // 400