diff --git a/examples/generics.rs b/examples/generics.rs
index f575c559a6ebdd9cfe9962150bdd2368b97752d8..54e2e2bf540b8bb57eb251918b39b01ed27b119a 100644
--- a/examples/generics.rs
+++ b/examples/generics.rs
@@ -4,6 +4,8 @@ struct P<T> {
     y: T,
 }
 
+// We can implement functions for
+// instances of our generic type
 impl P<u32> {
     fn double(&mut self) {
         self.x += self.x;
@@ -11,6 +13,7 @@ impl P<u32> {
     }
 }
 
+// Another implementation
 impl P<u64> {
     fn double(&mut self) {
         self.x += self.x;
@@ -26,10 +29,19 @@ fn main() {
     let mut p2 = P { x: 1u64, y: 2 };
     p2.double();
     println!("x {} y {}", p2.x, p2.y);
+
+    let mut p3: P<u8> = P { x: 1u8, y: 2 };
+    // p3.double(); // we don't have an implementation (yet)
+    println!("x {} y {}", p3.x, p3.y);
 }
 
 // The types of p1 and p2 is known at compile time
-// (See that rust analyses derives the types)
+// (See that rust analyzer derives the types.)
 //
 // The compiler will "specialize" the call
 // to double (as cheap as an ordinary call)
+//
+// We have a zero-cost abstraction.
+//
+// (We cannot do double on p3, as we don't have any
+// implementation of double for P<u8>.)
diff --git a/examples/traits.rs b/examples/traits.rs
new file mode 100644
index 0000000000000000000000000000000000000000..beac5d8e532124fab7104cab6e339224cf169a1f
--- /dev/null
+++ b/examples/traits.rs
@@ -0,0 +1,46 @@
+// a struct with generics
+// a trait for double
+
+use std::fmt::Debug;
+
+#[derive(Debug)]
+struct P<T> {
+    x: T,
+    y: T,
+}
+
+// Declare an "interface", for double.
+trait Double {
+    fn double(&mut self);
+}
+
+// Implement Double for some types.
+impl Double for P<u32> {
+    fn double(&mut self) {
+        self.x += self.x;
+        self.y += self.y;
+    }
+}
+
+impl Double for String {
+    fn double(&mut self) {
+        let s = self.clone();
+        self.push_str(&s);
+    }
+}
+
+fn main() {
+    let mut p1 = P { x: 1u32, y: 2 };
+    p1.double();
+    println!("{:?}", p1);
+
+    let mut s = "String, ".to_string();
+    s.double();
+    println!("{:?}", s);
+}
+
+// Types of p1 and s is known at compile time
+// Even if we now use Traits the compiler can
+// specialize the calls to double.
+//
+// We have a zero-cost abstraction.