diff --git a/doc/tutorial-tasks.md b/doc/tutorial-tasks.md
index 320385c89a652..8c574e539febf 100644
--- a/doc/tutorial-tasks.md
+++ b/doc/tutorial-tasks.md
@@ -284,7 +284,7 @@ let result = ports.foldl(0, |accum, port| *accum + port.recv() );
 # fn some_expensive_computation(_i: uint) -> int { 42 }
 ~~~
 
-## Futures
+## Backgrounding computations: Futures
 With `extra::future`, rust has a mechanism for requesting a computation and getting the result
 later.
 
@@ -329,6 +329,77 @@ fn main() {
 }
 ~~~
 
+## Sharing immutable data without copy: ARC
+
+To share immutable data between tasks, a first approach would be to only use pipes as we have seen
+previously. A copy of the data to share would then be made for each task. In some cases, this would
+add up to a significant amount of wasted memory and would require copying the same data more than
+necessary.
+
+To tackle this issue, one can use an Atomically Reference Counted wrapper (`ARC`) as implemented in
+the `extra` library of Rust. With an ARC, the data will no longer be copied for each task. The ARC
+acts as a reference to the shared data and only this reference is shared and cloned.
+
+Here is a small example showing how to use ARCs. We wish to run concurrently several computations on
+a single large vector of floats. Each task needs the full vector to perform its duty.
+~~~
+use extra::arc::ARC;
+
+fn pnorm(nums: &~[float], p: uint) -> float {
+    (vec::foldl(0.0, *nums, |a,b| a+(*b).pow(p as float) )).pow(1f / (p as float))
+}
+
+fn main() {
+    let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
+    println(fmt!("Inf-norm = %?",  numbers.max()));
+
+    let numbers_arc = ARC(numbers);
+
+    for uint::range(1,10) |num| {
+        let (port, chan)  = stream();
+        chan.send(numbers_arc.clone());
+
+        do spawn {
+            let local_arc : ARC<~[float]> = port.recv();
+            let task_numbers = local_arc.get();
+            println(fmt!("%u-norm = %?", num, pnorm(task_numbers, num)));
+        }
+    }
+}
+~~~
+
+The function `pnorm` performs a simple computation on the vector (it computes the sum of its items
+at the power given as argument and takes the inverse power of this value). The ARC on the vector is
+created by the line
+~~~
+# use extra::arc::ARC;
+# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
+let numbers_arc=ARC(numbers);
+~~~
+and a clone of it is sent to each task
+~~~
+# use extra::arc::ARC;
+# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
+# let numbers_arc = ARC(numbers);
+# let (port, chan)  = stream();
+chan.send(numbers_arc.clone());
+~~~
+copying only the wrapper and not its contents.
+
+Each task recovers the underlying data by
+~~~
+# use extra::arc::ARC;
+# let numbers=vec::from_fn(1000000, |_| rand::random::<float>());
+# let numbers_arc=ARC(numbers);
+# let (port, chan)  = stream();
+# chan.send(numbers_arc.clone());
+# let local_arc : ARC<~[float]> = port.recv();
+let task_numbers = local_arc.get();
+~~~
+and can use it as if it were local.
+
+The `arc` module also implements ARCs around mutable data that are not covered here.
+
 # Handling task failure
 
 Rust has a built-in mechanism for raising exceptions. The `fail!()` macro