diff --git a/ch13/closures/src/main.rs b/ch13/closures/src/main.rs
index 0616cd7..727dbca 100644
--- a/ch13/closures/src/main.rs
+++ b/ch13/closures/src/main.rs
@@ -167,13 +167,22 @@ fn main() {
     println!("{list:#?}");
 
     // closures must name captured lifetimes
-
-    // Stopped here:
-    // https://rust-book.cs.brown.edu/ch13-01-closures.html#closures-must-name-captured-lifetimes
+    // let s_own = String::from("Hello world");
+    // let cloner = make_a_cloner(&s_own);
+    // drop(s_own);
+    // cloner();
 }
 
 // from closures must name captured lifetimes
-fn make_a_cloner(s_ref: &str) -> impl Fn() -> String {
+// Need to add a lifetime to tell Rust that the closure
+// returned from make_a_cloner must not live longer than s_ref.
+// The `+ 'a` in the return type indicates that the closure
+// must live no longer than 'a.
+// fn make_a_cloner<'a>(s_ref: &'a str) -> impl Fn() -> String + 'a {
+// move || s_ref.to_string()
+// }
+// Can make this function more concise with the lifetime elision rules
+fn make_a_cloner(s_ref: &str) -> impl Fn() -> String + '_ {
     move || s_ref.to_string()
 }
 
diff --git a/ch13/iterators/Cargo.lock b/ch13/iterators/Cargo.lock
new file mode 100644
index 0000000..712f210
--- /dev/null
+++ b/ch13/iterators/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "iterators"
+version = "0.1.0"
diff --git a/ch13/iterators/Cargo.toml b/ch13/iterators/Cargo.toml
new file mode 100644
index 0000000..2652a8a
--- /dev/null
+++ b/ch13/iterators/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "iterators"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/ch13/iterators/src/lib.rs b/ch13/iterators/src/lib.rs
new file mode 100644
index 0000000..31c8b90
--- /dev/null
+++ b/ch13/iterators/src/lib.rs
@@ -0,0 +1,27 @@
+#[cfg(test)]
+mod tests {
+    // use super::*;
+
+    #[test]
+    fn iterator_demonstration() {
+        let v1 = vec![1, 2, 3];
+
+        let mut v1_iter = v1.iter();
+
+        assert_eq!(v1_iter.next(), Some(&1));
+        assert_eq!(v1_iter.next(), Some(&2));
+        assert_eq!(v1_iter.next(), Some(&3));
+        assert_eq!(v1_iter.next(), None);
+    }
+
+    // methods that consume the iterator
+    // aren't allowed to use v1_iter after sum call
+    // because sum takes ownership of v1_iter
+    #[test]
+    fn iterator_sum() {
+        let v1 = vec![1, 2, 3];
+        let v1_iter = v1.iter();
+        let total: i32 = v1_iter.sum();
+        assert_eq!(total, 6);
+    }
+}
diff --git a/ch13/iterators/src/main.rs b/ch13/iterators/src/main.rs
new file mode 100644
index 0000000..ed5ed1f
--- /dev/null
+++ b/ch13/iterators/src/main.rs
@@ -0,0 +1,29 @@
+fn main() {
+    let v1 = vec![1, 2, 3];
+    let v1_iter = v1.iter(); // iterator are lazy
+
+    for val in v1_iter {
+        println!("Got: {val}");
+    }
+
+    // methods that produce other iterators
+    // iterator adaptors are methods defined on Iterator trait
+    // that don't consume the iterater; instead, they produce
+    // different iterators by changing some aspect of the
+    // original iterator.
+    let v1: Vec<i32> = vec![1, 2, 3];
+    v1.iter().map(|x| x + 1);
+
+    // stopped here:
+    // https://rust-book.cs.brown.edu/ch13-02-iterators.html#methods-that-produce-other-iterators
+}
+
+// the iterator trait and the next method
+// in the std library
+pub trait Iterator {
+    // This is an associated type with this trait
+    // Will learn more about these in chapter 20
+    type Item;
+
+    fn next(&mut self) -> Option<Self::Item>;
+}