diff --git a/0033-protocol-witnesses-pt1/README.md b/0033-protocol-witnesses-pt1/README.md
new file mode 100644
index 00000000..0c2c9bc7
--- /dev/null
+++ b/0033-protocol-witnesses-pt1/README.md
@@ -0,0 +1,5 @@
+## [Point-Free](https://www.pointfree.co)
+
+> #### This directory contains code from Point-Free Episode: [Protocol Witnesses: Part 1](https://www.pointfree.co/episodes/ep33-protocol-witnesses-part-1)
+>
+> Protocols are a great tool for abstraction, but aren’t the only one. This week we begin to explore the tradeoffs of using protocols by highlighting a few areas in which they fall short in order to demonstrate how we can recover from these problems using a different tool and different tradeoffs.
diff --git a/0033-protocol-witnesses-pt1/Witness.xcworkspace/contents.xcworkspacedata b/0033-protocol-witnesses-pt1/Witness.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 00000000..d0003ede
--- /dev/null
+++ b/0033-protocol-witnesses-pt1/Witness.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/0033-protocol-witnesses-pt1/Witness.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/0033-protocol-witnesses-pt1/Witness.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 00000000..18d98100
--- /dev/null
+++ b/0033-protocol-witnesses-pt1/Witness.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/0033-protocol-witnesses-pt1/Witnesses.playground/Contents.swift b/0033-protocol-witnesses-pt1/Witnesses.playground/Contents.swift
new file mode 100644
index 00000000..822b9e92
--- /dev/null
+++ b/0033-protocol-witnesses-pt1/Witnesses.playground/Contents.swift
@@ -0,0 +1,155 @@
+
+protocol Describable {
+ var describe: String { get }
+}
+
+struct PostgresConnInfo {
+ var database: String
+ var hostname: String
+ var password: String
+ var port: Int
+ var user: String
+}
+
+let localhostPostgres = PostgresConnInfo(
+ database: "pointfreeco_development",
+ hostname: "localhost",
+ password: "",
+ port: 5432,
+ user: "pointfreeco"
+)
+
+//extension PostgresConnInfo: Describable {
+// var describe: String {
+// return "PostgresConnInfo(database: \"\(self.database)\", hostname: \"\(self.hostname)\", password: \"\(self.password)\", port: \"\(self.port)\", user: \"\(self.user)\")"
+// }
+//}
+
+//extension PostgresConnInfo: Describable {
+// var describe: String {
+// return """
+//PostgresConnInfo(
+// database: \"\(self.database)\",
+// hostname: \"\(self.hostname)\",
+// password: \"\(self.password)\",
+// port: \"\(self.port)\",
+// user: \"\(self.user)\"
+//)
+//"""
+// }
+//}
+
+extension PostgresConnInfo: Describable {
+ var describe: String {
+ return "postgres://\(self.user):\(self.password)@\(self.hostname):\(self.port)/\(self.database)"
+ }
+}
+
+print(localhostPostgres.describe)
+
+extension Int: Describable {
+ var describe: String {
+ return "\(self)"
+ }
+}
+
+2.describe
+
+protocol EmptyInitializable {
+ init()
+}
+
+extension String: EmptyInitializable {
+}
+extension Array: EmptyInitializable {
+}
+extension Int: EmptyInitializable {
+ init() {
+ self = 1
+ }
+}
+extension Optional: EmptyInitializable {
+ init() {
+ self = nil
+ }
+}
+
+[1, 2, 3].reduce(0, +)
+
+extension Array {
+ func reduce(_ accumulation: (Result, Element) -> Result) -> Result {
+ return self.reduce(Result(), accumulation)
+ }
+}
+
+[1, 2, 3].reduce(+)
+[[1, 2], [], [3, 4]].reduce(+)
+["Hello", " ", "Blob"].reduce(+)
+
+protocol Combinable {
+ func combine(with other: Self) -> Self
+}
+
+struct Combining {
+ let combine: (A, A) -> A
+}
+
+extension Int: Combinable {
+ func combine(with other: Int) -> Int {
+ return self * other
+ }
+}
+extension String: Combinable {
+ func combine(with other: String) -> String {
+ return self + other
+ }
+}
+extension Array: Combinable {
+ func combine(with other: Array) -> Array {
+ return self + other
+ }
+}
+extension Optional: Combinable {
+ func combine(with other: Optional) -> Optional {
+ return self ?? other
+ }
+}
+
+extension Array where Element: Combinable {
+ func reduce(_ initial: Element) -> Element {
+ return self.reduce(initial) { $0.combine(with: $1) }
+ }
+}
+
+extension Array /* where Element: Combinable */ {
+ func reduce(_ initial: Element, _ combining: Combining) -> Element {
+ return self.reduce(initial, combining.combine)
+ }
+}
+
+[1, 2, 3].reduce(1)
+[[1, 2], [], [3, 4]].reduce([])
+[nil, nil, 3].reduce(nil)
+
+let sum = Combining(combine: +)
+[1, 2, 3, 4].reduce(0, sum)
+
+let product = Combining(combine: *)
+[1, 2, 3, 4].reduce(1, product)
+
+
+extension Array where Element: Combinable & EmptyInitializable {
+ func reduce() -> Element {
+ return self.reduce(Element()) { $0.combine(with: $1) }
+ }
+}
+
+[1, 2, 3, 4].reduce()
+[[1, 2], [], [3, 4]].reduce()
+[nil, nil, 3].reduce()
+
+//extension Int: Combinable {
+// func combine(with other: Int) -> Int {
+// return self * other
+// }
+//}
diff --git a/0033-protocol-witnesses-pt1/Witnesses.playground/contents.xcplayground b/0033-protocol-witnesses-pt1/Witnesses.playground/contents.xcplayground
new file mode 100644
index 00000000..63b6dd8d
--- /dev/null
+++ b/0033-protocol-witnesses-pt1/Witnesses.playground/contents.xcplayground
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index ba3834e6..f96c70e5 100644
--- a/README.md
+++ b/README.md
@@ -33,4 +33,6 @@ This repository is the home of code written on episodes of
1. [An HTML DSL](0028-html-dsl)
1. [DSLs vs. Templating Languages](0029-dsls-vs-templating-languages)
1. [Composable Randomness](0030-composable-randomness)
-1. [Decodable Randomness](0031-arbitrary-pt1)
+1. [Decodable Randomness: Part 1](0031-arbitrary-pt1)
+1. [Decodable Randomness: Part 2](0032-arbitrary-pt2)
+1. [Protocol Witnesses: Part 1](0033-protocol-witnesses-pt1))