git » homepage.git » commit 7d11cdb

Preserve Cognicast interviews

author Alan Dipert
2026-08-09 19:59:24 UTC
committer Alan Dipert
2026-08-09 19:59:24 UTC
parent 2bb0e0729d82eaabc6d82d7d0629ad33c06087e2

Preserve Cognicast interviews

archive/techworks/SHA256SUMS +14 -0
archive/techworks/items/cognicast/052-cover.jpg +0 -0
archive/techworks/items/cognicast/052.headers +14 -0
archive/techworks/items/cognicast/052.html +801 -0
archive/techworks/items/cognicast/111-cover.jpg +0 -0
archive/techworks/items/cognicast/111.headers +14 -0
archive/techworks/items/cognicast/111.html +1507 -0
archive/techworks/items/cognicast/112-cover.jpg +0 -0
archive/techworks/items/cognicast/112.headers +14 -0
archive/techworks/items/cognicast/112.html +1748 -0
archive/techworks/manifest.tsv +14 -0
md/TechWorks/Cognicast111.html +664 -0
md/TechWorks/Cognicast112.html +904 -0
md/TechWorks/media/audio/cognicast-052.mp3 +3 -0
md/TechWorks/media/audio/cognicast-111.mp3 +3 -0
md/TechWorks/media/audio/cognicast-112.mp3 +3 -0
md/TechWorksArchive.md +8 -0
tools/extract_cognicast.py +67 -0

diff --git a/archive/techworks/SHA256SUMS b/archive/techworks/SHA256SUMS
index fb4c0d6..48e5d4c 100644
--- a/archive/techworks/SHA256SUMS
+++ b/archive/techworks/SHA256SUMS
@@ -8,12 +8,16 @@
 16c40b3f183bd656dda0303c53a56a85ec20e2426909b60b4b7904e920002208  md/TechWorks/flapjax-demo-b719782.tar.gz
 1e876de98c65f221e3b437892e93a5c1ef911b023e85e78975769e015d95152e  md/TechWorks/media/video/tSw3x0rVh88.info.json
 1e9951de2d98335c45976f7dce0b5429469343eab20a5c17e5d3ed597f1fd7b4  md/TechWorks/2018-12-17-CommonLispOrangeCombinator.pdf
+2058ab1dd1f4ce00ad2dc7df9c5bab0bb2fec352de7264bafb4066cf92d67cd5  archive/techworks/items/cognicast/111-cover.jpg
 23aa4b7e40ecb6f2cf4e3835ed2e0742361c247fc27b4b5c919ddf65215787e5  md/TechWorks/media/video/wVXjExRiFy0.jpg
 295dcd7f2ea293bb9e3bb46417d787a934e739739a98bccf7031276c6366a280  md/TechWorks/ocrug-2018-11-27-71dd0b1.tar.gz
 2a2b25998617233beb48a5e213dc22fe80a561f0d576c625beeb34f9feae1c4d  md/TechWorks/media/video/HGuTqsVh59w.mp4
 2fa46c61ffce23593ef18c65bdeea96bff452d233c0b75f348709ee58f85a040  md/TechWorks/media/video/wVXjExRiFy0.info.json
+33b3861b8d5deeb4596682207f44dbe534bcea015f25849d53f5d696c9decfec  archive/techworks/items/cognicast/052.html
+348263dc01b3b86799759f5bcbfce0afe32726a675580a520ddc7a39ca868d83  archive/techworks/items/cognicast/112-cover.jpg
 36efb38dd1f1fc8682b6f2e70e4ce21bad65e0b235bc236fb105d79911fd337b  md/TechWorks/barcamp2012-jsonscript-7e4dcf7.tar.gz
 37eb2a8885fae16fc6f45b7910a272d9564246cf140ecd72db756fbdc3efa852  md/TechWorks/oscon2012-clojure-5ac233f.tar.gz
+380d401a5861632a524375c92f278598dda20a84fd51110a394e5b8e56c95726  archive/techworks/items/cognicast/112.html
 39071c475b53ebb55c213f4dbb0cc731b9f9da31f7afe5591afbe8f59cd80789  md/TechWorks/OCRUGInterview/headshot.jpg
 39d6df4a9fa92d1c897cf40b79f79efaba56d0862ed8bcf80a7c7aa65ef73b63  md/TechWorks/media/audio/s4-e19-hoplon-with-alan-dipert-source.html
 3a1a72783cd199b05cfb3073931edba2742a3f45264af748d09142e4ff6a4e90  md/TechWorks/authored/wondr/posts/tail-recursion-in-r.html
@@ -23,6 +27,7 @@
 3ced799f7d1d7972530d496fd448c560d97e02f0654c266df205ebb20627e450  archive/techworks/items/2019-ocrug-interview/headshot.headers
 438ca7957efe63073364b69b0fecb6385d7b9ddcc9efdc0943198847927401cb  archive/techworks/items/2005-netbsd-workstation/linux-com-live.warc.gz
 446379435661cd8a75647936a7b4ca130dfdfffb7e5fcc4f767aa11d2f922d13  md/TechWorks/2020-01-28-RStudio-Conf-Integration-Testing-ePoster.pdf
+4562fcd751a5331289d86e3f40eb67870160e637b88b8ff3be0cf33524a1bc5a  md/TechWorks/media/audio/cognicast-111.mp3
 49b6ec526b72e3c2a8655557e715b51ca8c999b2ebef8bad5a0efb19fc69b94c  md/TechWorks/media/video/44Q9ew9JH_U.en-orig.vtt
 49b6ec526b72e3c2a8655557e715b51ca8c999b2ebef8bad5a0efb19fc69b94c  md/TechWorks/media/video/44Q9ew9JH_U.en.vtt
 4a2815c9d0b1cf0de5cba85b0b1cf22944a910fb28de1f90afb1e9c50717d987  md/TechWorks/Dipert-FRP_in_ClojureScript_with_Javelin.pdf
@@ -31,9 +36,11 @@
 4cee7dddb59d50de9c253f43481e2ce8c4f9db06280cb2dd7fadba7f782c2eed  archive/techworks/items/2019-ocrug-interview/cdx.json
 4fa2b18b4df657cc4fe0b1dcc61fac3a179bb7da636cf90c06de98b38efe7e6f  md/TechWorks/wombat-dbd34f4.tar.gz
 5330706e824804a97059a9ea78e04ec5b30f3b35cde21e51ca9c999fb9203854  md/TechWorks/media/video/bmHTFo2Rf2w.info.json
+592cd602f71f74cafbafc385156eaa90e1af01eb24373d4d53cb07642c2451f3  archive/techworks/items/cognicast/111.headers
 66326358232546ee1a467dc983d144d777d8f039f1b4377a140554fe3b527781  md/TechWorks/media/video/HGuTqsVh59w.en-orig.vtt
 66326358232546ee1a467dc983d144d777d8f039f1b4377a140554fe3b527781  md/TechWorks/media/video/HGuTqsVh59w.en.vtt
 718dea32362c630c4756f539298cddfdc7cb3f941ebd25e303c55e174edd5aa3  md/TechWorks/media/video/44Q9ew9JH_U.webp
+7355773d7c4efd3beefc0b75481b20722d33b75c5fb13a2802850eb493a24837  archive/techworks/items/cognicast/052-cover.jpg
 73c7a51dec9b771029efe866ccdc013dfdd6807b98e64b853c85e91c2858fe41  archive/techworks/items/2005-netbsd-workstation/linux-com-live.headers
 746135f37df7aa246fa753ce0a39d2e7f347424ee65e26eb1ec4343a1d13addd  md/TechWorks/authored/wondr/posts/assertions-and-postconditions.html
 76fe6f5dcebea899924ed50454fd1e8a83fc1ebcb3833a1996b14ac22d8d442f  md/TechWorks/media/video/xaxF5RDdVRE.en-orig.vtt
@@ -48,23 +55,29 @@
 934c2bd9997b9e6603f28308b6fccf0a72d2e30c3bb422effbcf4224ee8d7282  md/TechWorks/gherkin-76dc034.tar.gz
 935c7f008b22184aa5f2c494c3b4f085adc4091e400fd616b31d57e23d5cc7ac  archive/techworks/items/2019-ocrug-interview/2019-original.html
 94d65c64f26cc5ba9bfd7377b2ffa8dd7bdb27a93db1cf47a33fc013283312a0  md/TechWorks/media/video/vimeo-144696304.oembed.json
+9839ad172d31b2915e3eeb9cdf98830d4baf218fab8a5ff804ccedb17e6970d1  md/TechWorks/Cognicast111.html
 9b5b40432bc71b1da7aeb72a106c524136112e12be1da250e8b01a8d482a262b  md/TechWorks/media/video/tSw3x0rVh88.mp4
 9b5d26799ed7c9f6d78240a10c09f934444d393e506323b6e2320459f8474533  md/TechWorks/OCRUGInterview.html
 9bdd689419033e4120dad5da97c5da162614f4c13528a49f6e3955d692fed341  md/TechWorks/MyWorkstationOSNetBSD.html
 9ffc964563d278119bf8a0feec54ab7cd41c1dbb1c4e0de058d7d370603cc0d3  md/TechWorks/media/video/44Q9ew9JH_U.info.json
 a15dd034225897ddf87849d027c48c7d3ef0979b2bb17329172c5103e5b7e794  md/TechWorks/media/video/bmHTFo2Rf2w.en-orig.vtt
 a15dd034225897ddf87849d027c48c7d3ef0979b2bb17329172c5103e5b7e794  md/TechWorks/media/video/bmHTFo2Rf2w.en.vtt
+a36e25592798eb869f27aefea9fadaa00de5622ef5eb268edd335af69a03c36d  archive/techworks/items/cognicast/111.html
 a4f289f053abcdb02ac7ff433f4f1aacf279e4470c999cb5e292c31a1f28f4e8  md/TechWorks/2015-04-20_ClojureWestBoot.pdf
 a73794c8dd4a4550f2098db3a854959449c0adf623ea4877d3dc13e959b7cacc  md/TechWorks/media/video/xaxF5RDdVRE.webp
 a7d709bd9848acd265ee0a8837f1045cc29522ec544467b1922d926bbab7a0a7  md/TechWorks/media/video/wVXjExRiFy0.mp4
+a85d3c8db5b8b03b215d958101912af1ed776c780ba1a4fcc5a05f1c7819beed  archive/techworks/items/cognicast/052.headers
 a906f29ababff5e39751e14dcd9e14f74545dd3571d5a0f5c41a3c7641af25d2  md/TechWorks/authored/jlt/code_highlight.css
 a906f29ababff5e39751e14dcd9e14f74545dd3571d5a0f5c41a3c7641af25d2  md/TechWorks/authored/wondr/code_highlight.css
+ac5b60c328ac78786f03d96cf889ec4b236f5f0b5aa984e5d318ff6c644cc044  archive/techworks/items/cognicast/112.headers
+ace070cf982b935b701a28b767194b82a59b2322986c065e7159aefdfab3dc58  md/TechWorks/media/audio/cognicast-052.mp3
 b329888a9c0e528192cb24eb4a5dd7644b0e0126d975a8329c5a49fe7b7c0e14  archive/techworks/items/2019-ocrug-interview/2022-replay.html
 b439b4b8993805b0163a467d8f18090e3044526ed7e50cd97bb5a32b09cbbc8a  md/TechWorks/media/video/HGuTqsVh59w.info.json
 c0b942c1ec79ed851fc8810fc224b3e357c01bce98f957bf63786f4e467a2ed8  md/TechWorks/media/video/TcnzB2tB-8Q.mp4
 c318fdba4c6c5caa69baefa238a7b6ecd94afefc8d2c8826a7931028d989fa51  md/TechWorks/media/video/bmHTFo2Rf2w.mp4
 c44f5ca43719a56aa8b4146dac88674026912bef67d01f7f7661184cd0b470b9  archive/techworks/items/2019-ocrug-interview/timemap.json
 cbdb7e0a11b8566c73453ca401b7cc4ef9d2a424eff8d00dee4f1a6e435d89c3  md/TechWorks/media/SHA256SUMS
+cff200708de3e324faa0e5a7cd4fce4beaaa9100921c47ac4d81bcb698e151f6  md/TechWorks/media/audio/cognicast-112.mp3
 d04ff1f53296811517fd27fb2ed11b4092709558723c36d07f9719a9a4850ca4  md/TechWorks/media/video/bmHTFo2Rf2w.jpg
 d3bc604551b9f39837f4d619d8b61c324b95e6e26afed30a291092bc8d975d02  md/TechWorks/authored/wondr/posts/package-development-windows.html
 d82843df799752ff13fef3f75599bc683cf22ce5957590aa199a2bbbd018c315  md/TechWorks/authored/jlt/posts/collecting.html
@@ -72,6 +85,7 @@ d9feaebbf7dd5f8037be7b60226c1e773f304b479f331a2bea3c1a16338684d4  md/TechWorks/m
 d9feaebbf7dd5f8037be7b60226c1e773f304b479f331a2bea3c1a16338684d4  md/TechWorks/media/video/tSw3x0rVh88.en.vtt
 dbdf9ad5674803b9eb8537c17c7b8f2d4a97a00e9e2d83b6c614e1d91dc02643  archive/techworks/items/2019-ocrug-interview/2019-original.headers
 dd9a11ba5b00ffa08f88a10dce60f10eb61ac83d5439f0a95e7637a8f76d084b  md/TechWorks/media/video/TcnzB2tB-8Q.info.json
+e307e14633721e10ecdd576af6458d4b1409ddf6f9e42cf3daa4e15e7ffa9b8c  md/TechWorks/Cognicast112.html
 e5e57746ea11987744b1acacd6255d24951fddd939b57f1ceaf1b873a3b786bc  md/TechWorks/media/video/xaxF5RDdVRE.info.json
 ea6820d653957fcc86d231b37fab642418a9f8a8991003a30d2a4d70adbd6ce3  md/TechWorks/fast-shiny-da0ea10.tar.gz
 eb519fb5da6646d808dc1801803b3d8e35d5d90bf164775c10833cc43be9b340  md/TechWorks/authored/wondr/posts/shiny-inline-markdown.html
diff --git a/archive/techworks/items/cognicast/052-cover.jpg b/archive/techworks/items/cognicast/052-cover.jpg
new file mode 100644
index 0000000..a438c0f
Binary files /dev/null and b/archive/techworks/items/cognicast/052-cover.jpg differ
diff --git a/archive/techworks/items/cognicast/052.headers b/archive/techworks/items/cognicast/052.headers
new file mode 100644
index 0000000..8fe448e
--- /dev/null
+++ b/archive/techworks/items/cognicast/052.headers
@@ -0,0 +1,14 @@
+HTTP/2 200 
+content-type: text/html
+content-length: 38944
+date: Sun, 09 Aug 2026 19:54:30 GMT
+last-modified: Fri, 19 Sep 2025 18:37:57 GMT
+etag: "78dbb8cd6d8fcc3011b435245124c2da"
+x-amz-server-side-encryption: AES256
+accept-ranges: bytes
+server: AmazonS3
+x-cache: Miss from cloudfront
+via: 1.1 c40a611016f947a8da0f087fe5d2af84.cloudfront.net (CloudFront)
+x-amz-cf-pop: LAX53-P1
+x-amz-cf-id: SGy193u3nzVn1vhWuS3h-rr6ZUx1RoSq9pWk9vOFuayL8CnHb6NVRg==
+
diff --git a/archive/techworks/items/cognicast/052.html b/archive/techworks/items/cognicast/052.html
new file mode 100644
index 0000000..3ad85c3
--- /dev/null
+++ b/archive/techworks/items/cognicast/052.html
@@ -0,0 +1,801 @@
+<!DOCTYPE html>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+
+
+  <!-- Manually setup SEO for better results and smoother local dev experience  -->
+  <!-- Much better than the Jekyll SEO plugin -->
+
+  <title>
+    
+    Alan Dipert - Cognicast Episode 52
+    
+  </title>
+
+  <link rel="canonical" href="https://www.cognitect.com/cognicast/052-alan-dipert">
+
+  <meta content="width=device-width, initial-scale=1" name="viewport">
+  <meta itemprop="description" name="description"
+    content="We talk to Alan Dipert about Hoplon, a set of Clojure libraries for writing interactive browser applications." />
+  <meta property="og:locale" content="en_US">
+  <meta charset="utf-8">
+  <meta property="og:type" content="article">
+  <meta property="og:title" content="Alan Dipert - Cognicast Episode 52">
+  <meta property="og:url" content="https://www.cognitect.com/cognicast/052-alan-dipert">
+  <!-- Re-add if page thumbs become a thing <meta property="og:image" content="https://www.cognitect.com/thumbs/" /> -->
+  <meta property="og:site_name" content="Cognitect.com">
+  <meta property="article:publisher" content="https://www.cognitect.com" />
+  
+  <meta property="article:author" content="Craig Andera" />
+  
+  <meta property="article:published_time" content="2014-03-18 10:38:22 -0400" />
+  <meta property="og:description"
+    content="We talk to Alan Dipert about Hoplon, a set of Clojure libraries for writing interactive browser applications.">
+  <meta name="twitter:title" content="Alan Dipert - Cognicast Episode 52">
+  <meta name="twitter:description" content="We talk to Alan Dipert about Hoplon, a set of Clojure libraries for writing interactive browser applications.">
+  
+
+  <meta name="twitter:site" content="@cognitect" />
+  <meta name="twitter:card" content="summary">
+  
+  <meta name="twitter:image" content="/assets/content/v1/5372821be4b0aefc6719057e/1405694508397-HOH07K4E5EZHYS2KGSDF/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/image-asset.jpeg" />
+  
+
+  
+  
+
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+  <link rel="stylesheet" href="/assets/css/style.css?v=1.14">
+  <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
+  <link href="/assets/css/normalize.css" rel="stylesheet" type="text/css">
+  <link href="/assets/css/webflow.css" rel="stylesheet" type="text/css">
+  <link href="/assets/css/stripped-down.webflow.css" rel="stylesheet" type="text/css">
+  <!--[if lt IE 9]>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
+    <![endif]-->
+
+  <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
+  <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
+  <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
+  <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
+  <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
+  <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
+  <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
+  <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
+  <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
+  <link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png">
+  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
+  <link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
+  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
+  <link rel="manifest" href="/manifest.json">
+  <meta name="msapplication-TileColor" content="#ffffff">
+  <meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
+  <meta name="theme-color" content="#ffffff">
+  <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+  <link rel="shortcut icon" href="/favicon.ico?v=rMq4O6n057">
+  <style type="text/css">
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/l?subset_id=2&fvd=n1&v=3) format("woff2"), url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/d?subset_id=2&fvd=n1&v=3) format("woff"), url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/a?subset_id=2&fvd=n1&v=3) format("opentype");
+      font-weight: 100;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/l?subset_id=2&fvd=i1&v=3) format("woff2"), url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/d?subset_id=2&fvd=i1&v=3) format("woff"), url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/a?subset_id=2&fvd=i1&v=3) format("opentype");
+      font-weight: 100;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/l?subset_id=2&fvd=n3&v=3) format("woff2"), url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/d?subset_id=2&fvd=n3&v=3) format("woff"), url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/a?subset_id=2&fvd=n3&v=3) format("opentype");
+      font-weight: 300;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/l?subset_id=2&fvd=i3&v=3) format("woff2"), url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/d?subset_id=2&fvd=i3&v=3) format("woff"), url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/a?subset_id=2&fvd=i3&v=3) format("opentype");
+      font-weight: 300;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/l?subset_id=2&fvd=n4&v=3) format("woff2"), url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/d?subset_id=2&fvd=n4&v=3) format("woff"), url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/a?subset_id=2&fvd=n4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/l?subset_id=2&fvd=i4&v=3) format("woff2"), url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/d?subset_id=2&fvd=i4&v=3) format("woff"), url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/a?subset_id=2&fvd=i4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/l?subset_id=2&fvd=n5&v=3) format("woff2"), url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/d?subset_id=2&fvd=n5&v=3) format("woff"), url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/a?subset_id=2&fvd=n5&v=3) format("opentype");
+      font-weight: 500;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/l?subset_id=2&fvd=i5&v=3) format("woff2"), url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/d?subset_id=2&fvd=i5&v=3) format("woff"), url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/a?subset_id=2&fvd=i5&v=3) format("opentype");
+      font-weight: 500;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/l?subset_id=2&fvd=n6&v=3) format("woff2"), url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/d?subset_id=2&fvd=n6&v=3) format("woff"), url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/a?subset_id=2&fvd=n6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/l?subset_id=2&fvd=i6&v=3) format("woff2"), url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/d?subset_id=2&fvd=i6&v=3) format("woff"), url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/a?subset_id=2&fvd=i6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/l?subset_id=2&fvd=n7&v=3) format("woff2"), url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/d?subset_id=2&fvd=n7&v=3) format("woff"), url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/a?subset_id=2&fvd=n7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/l?subset_id=2&fvd=i7&v=3) format("woff2"), url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/d?subset_id=2&fvd=i7&v=3) format("woff"), url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/a?subset_id=2&fvd=i7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/l?subset_id=2&fvd=n8&v=3) format("woff2"), url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/d?subset_id=2&fvd=n8&v=3) format("woff"), url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/a?subset_id=2&fvd=n8&v=3) format("opentype");
+      font-weight: 800;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/l?subset_id=2&fvd=i8&v=3) format("woff2"), url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/d?subset_id=2&fvd=i8&v=3) format("woff"), url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/a?subset_id=2&fvd=i8&v=3) format("opentype");
+      font-weight: 800;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/l?subset_id=2&fvd=n9&v=3) format("woff2"), url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/d?subset_id=2&fvd=n9&v=3) format("woff"), url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/a?subset_id=2&fvd=n9&v=3) format("opentype");
+      font-weight: 900;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/l?subset_id=2&fvd=i9&v=3) format("woff2"), url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/d?subset_id=2&fvd=i9&v=3) format("woff"), url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/a?subset_id=2&fvd=i9&v=3) format("opentype");
+      font-weight: 900;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/l?subset_id=2&fvd=n4&v=3) format("woff2"), url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/d?subset_id=2&fvd=n4&v=3) format("woff"), url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/a?subset_id=2&fvd=n4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/l?subset_id=2&fvd=i4&v=3) format("woff2"), url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/d?subset_id=2&fvd=i4&v=3) format("woff"), url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/a?subset_id=2&fvd=i4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/l?subset_id=2&fvd=n6&v=3) format("woff2"), url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/d?subset_id=2&fvd=n6&v=3) format("woff"), url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/a?subset_id=2&fvd=n6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/l?subset_id=2&fvd=i6&v=3) format("woff2"), url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/d?subset_id=2&fvd=i6&v=3) format("woff"), url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/a?subset_id=2&fvd=i6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/l?subset_id=2&fvd=n7&v=3) format("woff2"), url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/d?subset_id=2&fvd=n7&v=3) format("woff"), url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/a?subset_id=2&fvd=n7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/l?subset_id=2&fvd=i7&v=3) format("woff2"), url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/d?subset_id=2&fvd=i7&v=3) format("woff"), url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/a?subset_id=2&fvd=i7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: italic;
+    }
+  </style>
+  <meta name="msapplication-TileColor" content="#ffffff">
+  <meta name="theme-color" content="#ffffff">
+
+  <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" type="text/javascript"></script>
+  <script src="/assets/js/jquery-3.5.1.min.js" type="text/javascript"></script>
+  <script
+    type="text/javascript">WebFont.load({ google: { families: ["Open Sans:300,300italic,400,400italic,600,600italic,700,700italic,800,800italic", "Roboto:300,regular,500"] } });</script>
+  <!-- Matomo -->
+<script>
+  var _paq = window._paq = window._paq || [];
+  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
+  _paq.push(['trackPageView']);
+  _paq.push(['enableLinkTracking']);
+  (function() {
+    var u="https://cognitect.matomo.cloud/";
+    _paq.push(['setTrackerUrl', u+'matomo.php']);
+    _paq.push(['setSiteId', '1']);
+    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+    g.async=true; g.src='//cdn.matomo.cloud/cognitect.matomo.cloud/matomo.js'; s.parentNode.insertBefore(g,s);
+  })();
+</script>
+<!-- End Matomo Code -->
+
+<script src="/assets/audiojs/audio.min.js"></script>
+
+<body>
+  <header>
+  <div class="header-inner">
+    <div id="logoWrapper" class="wrapper" data-content-field="site-title">
+      <div id="logoImage">
+        <a href="/">
+          <img src="/assets/images/cognitect-nubank-logo.svg" alt="Cognitect Blog">
+        </a>
+      </div>
+    </div>
+    <nav role="navigation" class="nav-clear">
+      <a href="/technologies.html">Technologies</a>
+      <a href="/blog/">Blog</a>
+      <a href="/cognicast">Cognicast</a>
+      <a href="/contact.html">Contact</a>
+      <a href="/archive.html">Archive</a>
+    </nav>
+  </div>
+</header>
+
+  <div class="wrapper">
+    <section>
+      <div id="articles-list">
+  <div id="categories">
+  <a href="/blog/index.html">All Topics</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/how-we-work.html">How We Work</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/events.html">Events</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/customer-stories.html">Customer Stories</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/technology.html">Technology</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/testing.html">Testing</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/the-new-normal.html">The New Normal</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/open-source.html">Open Source</a>
+  <span class="cat-separator"> - </span>
+  
+  <span class="cat-separator"> - </span>
+  <a href="/feed.xml">RSS Feed</a>
+  </div>
+</div>
+
+      <div id="post-page">
+        <div id="post-wrapper">
+          <div id="post-title">
+            Alan Dipert - Cognicast Episode 52
+          </div>
+          <div class="post-author">
+            <a href="/authors/CraigAndera.html"><img
+                src="/assets/Authors/CraigAndera.jpg"></a>
+            <span class="post-author-name">
+              posted by
+              <a href="/authors/CraigAndera.html">Craig Andera</a>
+              on March 18, 2014
+            </span>
+            <div class="tags">
+              tagged:
+              
+              <a class="tag" href="/blog/tags?tag=podcast cognicast">podcast cognicast</a>
+              
+            </div>
+          </div>
+          
+            <img class="cognicast-thumbnail" src="/assets/content/v1/5372821be4b0aefc6719057e/1405694508397-HOH07K4E5EZHYS2KGSDF/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/image-asset.jpeg">
+          
+          <H1>AUDIO</H1>
+          <div id="post-content">
+            <a href=""></a>
+            <div id="cognicast-audio">
+              <audio src="http://s3.amazonaws.com/cognicast/shows/cognicast-052-alan-dipert.mp3" preload="auto"></audio>
+              <span class="mp3-download">
+                <a href="http://s3.amazonaws.com/cognicast/shows/cognicast-052-alan-dipert.mp3">Download</a>
+              </span>
+            </div>
+            <p>We talk to <a href="https://twitter.com/alandipert">Alan Dipert</a> about <a href="http://hoplon.io/">Hoplon</a>, a set of Clojure libraries for writing interactive browser applications.</p>
+
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+          </div>
+          
+<div class="related">
+    
+  <span class="classifier">
+    <span class="content-cell related-title">
+    
+      <p>related</p>
+    
+    </span>
+    <span class="content-cell"><p class="recent-title">recent</p></span>
+  </span>
+  <div class="links left">
+    
+    
+     
+    <a href="/cognicast/162">
+      Craig Andera - Cognicast Episode 162<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/108">
+      Sam Tobin-Hochstadt - Cognicast Episode 108<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/132">
+      Jeb Beich - Cognicast Episode 132<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/069-scott-hanselman">
+      Scott Hanselman - Cognicast Episode 070<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/081">
+      Russ Olsen - Cognicast Episode 081<span class="dash">—</span>
+    </a>
+    
+    
+  </div>
+  <div class="links right">
+    
+     
+    <a href="/cognicast/172">
+      <span class="dash">—</span>Janet A Carr - Cognicast Episode 172
+    </a>
+     
+    <a href="/cognicast/171">
+      <span class="dash">—</span>Howard Lewis Ship - Cognicast Episode 171
+    </a>
+     
+    <a href="/cognicast/170">
+      <span class="dash">—</span>Michiel Borkent - Cognicast Episode 170
+    </a>
+     
+    <a href="/cognicast/169">
+      <span class="dash">—</span>Ed, Justin and Lindsey - Cognicast Episode 169
+    </a>
+     
+    <a href="/cognicast/168">
+      <span class="dash">—</span>Wilker Lucio - Cognicast Episode 168
+    </a>
+    
+  </div>
+</div>
+</div>
+
+          <div id="post-sidebar">
+
+            <div id="post-sidebar-container">
+              <!-- <div class="post-search right-block"></div> -->
+              <div class="post-email right-block">
+                <a href="/contact.html">Get In Touch</a>
+              </div>
+              <div class="post-authors right-block">
+                <ul>
+                  
+                  <li>
+                    <h2><a href="/authors/AlessandraSierra.html">Alessandra Sierra</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AlexMiller.html">Alex Miller</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/CarinMeier.html">Carin Meier</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DavidChelimsky.html">David Chelimsky</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DavidNolen.html">David Nolen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/GhadiShayban.html">Ghadi Shayban</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JebBeich.html">Jeb Beich</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JustinGehtland.html">Justin Gehtland</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/LynnGrogan.html">Lynn Grogan</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MarcPhillips.html">Marc Phillips</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MichaelNygard.html">Michael Nygard</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/NaokoHigashide.html">Naoko Higashide</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/PauldeGrandis.html">Paul de Grandis</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RichHickey.html">Rich Hickey</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RussOlsen.html">Russ Olsen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/StuartHalloway.html">Stuart Halloway</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/TimBaldridge.html">Tim Baldridge</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AaronBedra.html">Aaron Bedra</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ChrisRedinger.html">Chris Redinger</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/CraigAndera.html">Craig Andera</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DonMullen.html">Don Mullen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/GlennVanderburg.html">Glenn Vanderburg</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JaredPace.html">Jared Pace</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JasonRudolph.html">Jason Rudolph</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JonDistad.html">Jon Distad</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/LarryKarnowski.html">Larry Karnowski</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MichaelParenteau.html">Michael Parenteau</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MunessAlrubaie.html">Muness Alrubaie</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RobSanheim.html">Rob Sanheim</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/SamUmbach.html">Sam Umbach</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/KimFoster.html">Kim Foster</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JaretBinford.html">Jaret Binford</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JoeSmith.html">Joe Smith</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ClintonDreisbach.html">Clinton Dreisbach</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/TimEwald.html">Tim Ewald</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RobertRandolph.html">Robert Randolph</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AlexRedington.html">Alex Redington</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JoeLane.html">Joe Lane</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ChristianRomney.html">Christian Romney</a></h2>
+                  </li>
+                  
+                </ul>
+              </div>
+            </div>
+          </div>
+        </div>
+    </section>
+  </div>
+  <div class="footer left">
+  <div class="w-container">
+    <ul class="menu-footer-menu">
+      <li>
+        <a class="footer-head" aria-current="page">Nu International</a>
+        <ul class="sub-menu">
+          <li><a href="https://international.nubank.com.br/about" target="_blank">About Nu <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://international.nubank.com.br/careers" target="_blank">Careers <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://international.nubank.com.br/newsroom" target="_blank">Newsroom <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://www.investidores.nu/en/" target="_blank">Investor Relations <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Nu Impact</a>
+        <ul class="sub-menu">
+          <li><a href="https://international.nubank.com.br/impact/environmental" target="_blank">Enviromental <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+          <li><a href="https://international.nubank.com.br/impact/social" target="_blank">Social <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+          <li><a href="https://international.nubank.com.br/impact/governance/" target="_blank">Governance <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Global
+          Presence</a>
+        <ul class="sub-menu">
+          <li><a href="https://nubank.com.br" target="_blank">Brazil <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.mx" target="_blank">Mexico <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.co" target="_blank">Colombia <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.ar" target="_blank">Argentina <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Blogs</a>
+        <ul class="sub-menu">
+          <li><a href="https://building.nubank.com.br/" target="_blank">Building Nubank <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nubank.com.br/" target="_blank">Brazil <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nu.com.mx/" target="_blank">Mexico <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nu.com.co/" target="_blank">Colombia <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+    </ul>
+  </div>
+  <div class="w-container">
+    <div class="footer-text">Copyright 2025, Cognitect, a Nu Holdings, Ltd. company
+      | <a class="footer-link-s" href="/privacy-policy.html">privacy-policy</a>
+      | <a class="footer-link-icon" href="https://github.com/cognitect" target="_blank"><i class="fa fa-github"
+          aria-hidden="true"></i> Github</a></div>
+  </div>
+</div>
+<script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.4.1.min.220afd743d.js?site=58dee1dd9c1826ba43796eb4"
+  type="text/javascript" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
+  crossorigin="anonymous"></script>
+<script src="/assets/js/webflow.js" type="text/javascript"></script>
+<!-- [if lte IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/placeholders/3.0.2/placeholders.min.js"></script><![endif] -->
+  <!-- <script src="/assets/js/scale.fix.js"></script> -->
+  
+  <script>
+    (function () {
+      // This is the ugliest hack.
+      // Rouge highlighter puts a span element for the final white space (\n)
+      // This script splits on \n, so rouge coloured elements will end up with an extra line.
+      // So we process one fewer line if the pre element has more than one child.
+      var subtractor = 0;
+      var pre = document.getElementsByTagName('pre'),
+        pl = pre.length;
+      for (var i = 0; i < pl; i++) {
+        // detect if rouge
+        if (pre[i].childNodes[0].childNodes.length > 1)
+          subtractor = 1;
+
+        pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
+        var num = pre[i].innerHTML.split(/\n/).length;
+        for (var j = 0; j < num - subtractor; j++) { // num - subtractor = process one less if rouge
+          var line_num = pre[i].getElementsByTagName('span')[0];
+          line_num.innerHTML += '<span>' + (j + 1) + '</span>';
+        }
+      }
+    })(); 
+  </script>
+  <script>
+    audiojs.events.ready(function () {
+      var as = audiojs.createAll();
+    });
+  </script>
+</body>
+
+</html>
diff --git a/archive/techworks/items/cognicast/111-cover.jpg b/archive/techworks/items/cognicast/111-cover.jpg
new file mode 100644
index 0000000..64c4c21
Binary files /dev/null and b/archive/techworks/items/cognicast/111-cover.jpg differ
diff --git a/archive/techworks/items/cognicast/111.headers b/archive/techworks/items/cognicast/111.headers
new file mode 100644
index 0000000..2400740
--- /dev/null
+++ b/archive/techworks/items/cognicast/111.headers
@@ -0,0 +1,14 @@
+HTTP/2 200 
+content-type: text/html
+content-length: 124446
+date: Sun, 09 Aug 2026 19:54:36 GMT
+last-modified: Fri, 19 Sep 2025 18:37:58 GMT
+etag: "a81f0e8615bf77766597524b15d4f1b9"
+x-amz-server-side-encryption: AES256
+accept-ranges: bytes
+server: AmazonS3
+x-cache: Miss from cloudfront
+via: 1.1 3d4704605b9b7f44c7958c0627a493d6.cloudfront.net (CloudFront)
+x-amz-cf-pop: LAX53-P1
+x-amz-cf-id: X5pKgBnK5WsuTTM9b4iCEXy6lH20fRzh1iMRCOSsqmHJKoQW3mErpg==
+
diff --git a/archive/techworks/items/cognicast/111.html b/archive/techworks/items/cognicast/111.html
new file mode 100644
index 0000000..c1c9660
--- /dev/null
+++ b/archive/techworks/items/cognicast/111.html
@@ -0,0 +1,1507 @@
+<!DOCTYPE html>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+
+
+  <!-- Manually setup SEO for better results and smoother local dev experience  -->
+  <!-- Much better than the Jekyll SEO plugin -->
+
+  <title>
+    
+    Alan Dipert and Micha Niskin - Cognicast Episode 111
+    
+  </title>
+
+  <link rel="canonical" href="https://www.cognitect.com/cognicast/111">
+
+  <meta content="width=device-width, initial-scale=1" name="viewport">
+  <meta itemprop="description" name="description"
+    content="In this episode, we talk with Alan Dipert and Micha Niskin about solving problems and Boot. " />
+  <meta property="og:locale" content="en_US">
+  <meta charset="utf-8">
+  <meta property="og:type" content="article">
+  <meta property="og:title" content="Alan Dipert and Micha Niskin - Cognicast Episode 111">
+  <meta property="og:url" content="https://www.cognitect.com/cognicast/111">
+  <!-- Re-add if page thumbs become a thing <meta property="og:image" content="https://www.cognitect.com/thumbs/" /> -->
+  <meta property="og:site_name" content="Cognitect.com">
+  <meta property="article:publisher" content="https://www.cognitect.com" />
+  
+  <meta property="article:author" content="Craig Andera" />
+  
+  <meta property="article:published_time" content="2016-10-18 10:00:00 -0400" />
+  <meta property="og:description"
+    content="In this episode, we talk with Alan Dipert and Micha Niskin about solving problems and Boot. ">
+  <meta name="twitter:title" content="Alan Dipert and Micha Niskin - Cognicast Episode 111">
+  <meta name="twitter:description" content="In this episode, we talk with Alan Dipert and Micha Niskin about solving problems and Boot.">
+  
+
+  <meta name="twitter:site" content="@cognitect" />
+  <meta name="twitter:card" content="summary">
+  
+  <meta name="twitter:image" content="/assets/content/v1/5372821be4b0aefc6719057e/1476796491666-YOWI8KZV28Q9PVEZJP7S/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/110-dipert-niskin.jpg" />
+  
+
+  
+  
+
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+  <link rel="stylesheet" href="/assets/css/style.css?v=1.14">
+  <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
+  <link href="/assets/css/normalize.css" rel="stylesheet" type="text/css">
+  <link href="/assets/css/webflow.css" rel="stylesheet" type="text/css">
+  <link href="/assets/css/stripped-down.webflow.css" rel="stylesheet" type="text/css">
+  <!--[if lt IE 9]>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
+    <![endif]-->
+
+  <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
+  <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
+  <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
+  <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
+  <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
+  <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
+  <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
+  <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
+  <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
+  <link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png">
+  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
+  <link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
+  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
+  <link rel="manifest" href="/manifest.json">
+  <meta name="msapplication-TileColor" content="#ffffff">
+  <meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
+  <meta name="theme-color" content="#ffffff">
+  <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+  <link rel="shortcut icon" href="/favicon.ico?v=rMq4O6n057">
+  <style type="text/css">
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/l?subset_id=2&fvd=n1&v=3) format("woff2"), url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/d?subset_id=2&fvd=n1&v=3) format("woff"), url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/a?subset_id=2&fvd=n1&v=3) format("opentype");
+      font-weight: 100;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/l?subset_id=2&fvd=i1&v=3) format("woff2"), url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/d?subset_id=2&fvd=i1&v=3) format("woff"), url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/a?subset_id=2&fvd=i1&v=3) format("opentype");
+      font-weight: 100;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/l?subset_id=2&fvd=n3&v=3) format("woff2"), url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/d?subset_id=2&fvd=n3&v=3) format("woff"), url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/a?subset_id=2&fvd=n3&v=3) format("opentype");
+      font-weight: 300;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/l?subset_id=2&fvd=i3&v=3) format("woff2"), url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/d?subset_id=2&fvd=i3&v=3) format("woff"), url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/a?subset_id=2&fvd=i3&v=3) format("opentype");
+      font-weight: 300;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/l?subset_id=2&fvd=n4&v=3) format("woff2"), url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/d?subset_id=2&fvd=n4&v=3) format("woff"), url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/a?subset_id=2&fvd=n4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/l?subset_id=2&fvd=i4&v=3) format("woff2"), url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/d?subset_id=2&fvd=i4&v=3) format("woff"), url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/a?subset_id=2&fvd=i4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/l?subset_id=2&fvd=n5&v=3) format("woff2"), url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/d?subset_id=2&fvd=n5&v=3) format("woff"), url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/a?subset_id=2&fvd=n5&v=3) format("opentype");
+      font-weight: 500;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/l?subset_id=2&fvd=i5&v=3) format("woff2"), url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/d?subset_id=2&fvd=i5&v=3) format("woff"), url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/a?subset_id=2&fvd=i5&v=3) format("opentype");
+      font-weight: 500;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/l?subset_id=2&fvd=n6&v=3) format("woff2"), url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/d?subset_id=2&fvd=n6&v=3) format("woff"), url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/a?subset_id=2&fvd=n6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/l?subset_id=2&fvd=i6&v=3) format("woff2"), url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/d?subset_id=2&fvd=i6&v=3) format("woff"), url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/a?subset_id=2&fvd=i6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/l?subset_id=2&fvd=n7&v=3) format("woff2"), url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/d?subset_id=2&fvd=n7&v=3) format("woff"), url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/a?subset_id=2&fvd=n7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/l?subset_id=2&fvd=i7&v=3) format("woff2"), url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/d?subset_id=2&fvd=i7&v=3) format("woff"), url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/a?subset_id=2&fvd=i7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/l?subset_id=2&fvd=n8&v=3) format("woff2"), url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/d?subset_id=2&fvd=n8&v=3) format("woff"), url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/a?subset_id=2&fvd=n8&v=3) format("opentype");
+      font-weight: 800;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/l?subset_id=2&fvd=i8&v=3) format("woff2"), url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/d?subset_id=2&fvd=i8&v=3) format("woff"), url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/a?subset_id=2&fvd=i8&v=3) format("opentype");
+      font-weight: 800;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/l?subset_id=2&fvd=n9&v=3) format("woff2"), url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/d?subset_id=2&fvd=n9&v=3) format("woff"), url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/a?subset_id=2&fvd=n9&v=3) format("opentype");
+      font-weight: 900;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/l?subset_id=2&fvd=i9&v=3) format("woff2"), url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/d?subset_id=2&fvd=i9&v=3) format("woff"), url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/a?subset_id=2&fvd=i9&v=3) format("opentype");
+      font-weight: 900;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/l?subset_id=2&fvd=n4&v=3) format("woff2"), url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/d?subset_id=2&fvd=n4&v=3) format("woff"), url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/a?subset_id=2&fvd=n4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/l?subset_id=2&fvd=i4&v=3) format("woff2"), url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/d?subset_id=2&fvd=i4&v=3) format("woff"), url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/a?subset_id=2&fvd=i4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/l?subset_id=2&fvd=n6&v=3) format("woff2"), url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/d?subset_id=2&fvd=n6&v=3) format("woff"), url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/a?subset_id=2&fvd=n6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/l?subset_id=2&fvd=i6&v=3) format("woff2"), url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/d?subset_id=2&fvd=i6&v=3) format("woff"), url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/a?subset_id=2&fvd=i6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/l?subset_id=2&fvd=n7&v=3) format("woff2"), url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/d?subset_id=2&fvd=n7&v=3) format("woff"), url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/a?subset_id=2&fvd=n7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/l?subset_id=2&fvd=i7&v=3) format("woff2"), url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/d?subset_id=2&fvd=i7&v=3) format("woff"), url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/a?subset_id=2&fvd=i7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: italic;
+    }
+  </style>
+  <meta name="msapplication-TileColor" content="#ffffff">
+  <meta name="theme-color" content="#ffffff">
+
+  <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" type="text/javascript"></script>
+  <script src="/assets/js/jquery-3.5.1.min.js" type="text/javascript"></script>
+  <script
+    type="text/javascript">WebFont.load({ google: { families: ["Open Sans:300,300italic,400,400italic,600,600italic,700,700italic,800,800italic", "Roboto:300,regular,500"] } });</script>
+  <!-- Matomo -->
+<script>
+  var _paq = window._paq = window._paq || [];
+  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
+  _paq.push(['trackPageView']);
+  _paq.push(['enableLinkTracking']);
+  (function() {
+    var u="https://cognitect.matomo.cloud/";
+    _paq.push(['setTrackerUrl', u+'matomo.php']);
+    _paq.push(['setSiteId', '1']);
+    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+    g.async=true; g.src='//cdn.matomo.cloud/cognitect.matomo.cloud/matomo.js'; s.parentNode.insertBefore(g,s);
+  })();
+</script>
+<!-- End Matomo Code -->
+
+<script src="/assets/audiojs/audio.min.js"></script>
+
+<body>
+  <header>
+  <div class="header-inner">
+    <div id="logoWrapper" class="wrapper" data-content-field="site-title">
+      <div id="logoImage">
+        <a href="/">
+          <img src="/assets/images/cognitect-nubank-logo.svg" alt="Cognitect Blog">
+        </a>
+      </div>
+    </div>
+    <nav role="navigation" class="nav-clear">
+      <a href="/technologies.html">Technologies</a>
+      <a href="/blog/">Blog</a>
+      <a href="/cognicast">Cognicast</a>
+      <a href="/contact.html">Contact</a>
+      <a href="/archive.html">Archive</a>
+    </nav>
+  </div>
+</header>
+
+  <div class="wrapper">
+    <section>
+      <div id="articles-list">
+  <div id="categories">
+  <a href="/blog/index.html">All Topics</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/how-we-work.html">How We Work</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/events.html">Events</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/customer-stories.html">Customer Stories</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/technology.html">Technology</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/testing.html">Testing</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/the-new-normal.html">The New Normal</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/open-source.html">Open Source</a>
+  <span class="cat-separator"> - </span>
+  
+  <span class="cat-separator"> - </span>
+  <a href="/feed.xml">RSS Feed</a>
+  </div>
+</div>
+
+      <div id="post-page">
+        <div id="post-wrapper">
+          <div id="post-title">
+            Alan Dipert and Micha Niskin - Cognicast Episode 111
+          </div>
+          <div class="post-author">
+            <a href="/authors/CraigAndera.html"><img
+                src="/assets/Authors/CraigAndera.jpg"></a>
+            <span class="post-author-name">
+              posted by
+              <a href="/authors/CraigAndera.html">Craig Andera</a>
+              on October 18, 2016
+            </span>
+            <div class="tags">
+              tagged:
+              
+              <a class="tag" href="/blog/tags?tag=podcast cognicast">podcast cognicast</a>
+              
+            </div>
+          </div>
+          
+            <img class="cognicast-thumbnail" src="/assets/content/v1/5372821be4b0aefc6719057e/1476796491666-YOWI8KZV28Q9PVEZJP7S/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/110-dipert-niskin.jpg">
+          
+          <H1>AUDIO</H1>
+          <div id="post-content">
+            <a href=""></a>
+            <div id="cognicast-audio">
+              <audio src="https://s3.amazonaws.com/cognicast/shows/cognicast-111-das-boot.mp3" preload="auto"></audio>
+              <span class="mp3-download">
+                <a href="https://s3.amazonaws.com/cognicast/shows/cognicast-111-das-boot.mp3">Download</a>
+              </span>
+            </div>
+            <p>In this episode, we talk with Alan Dipert and Micha Niskin about solving problems and Boot.</p>
+
+<h1 id="our-guests-alan-dipert-and-micha-niskin">Our Guests, Alan Dipert and Micha Niskin</h1>
+
+<h2 id="alan">Alan</h2>
+
+<ul>
+  <li><a href="http://tailrecursion.com/~alan/index.cgi/index">On the Web</a></li>
+  <li><a href="https://twitter.com/alandipert?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor">On Twitter</a></li>
+  <li><a href="https://github.com/alandipert">On Github</a></li>
+</ul>
+
+<h2 id="micha">Micha</h2>
+
+<ul>
+  <li><a href="http://micha.github.io/">On the Web</a></li>
+  <li><a href="https://twitter.com/michaniskin">On Twitter</a></li>
+  <li><a href="https://github.com/micha">On Github</a></li>
+</ul>
+
+<h1 id="topics">Topics</h1>
+
+<p><a href="http://www.abelardomorell.net/project/camera-obscura/">Camera obscura</a><br />
+<a href="https://hoplon.io/">Hoplon</a><br />
+<a href="https://github.com/boot-clj/boot">Boot</a><br />
+<a href="https://github.com/hoplon/javelin">Javelin</a><br />
+<a href="https://defn.audio/2016/07/13/episode-5/">Defn podcast - Micha</a><br />
+<a href="https://github.com/rkneufeld/lein-try">Lein.try</a> <br />
+<a href="https://github.com/adzerk-oss/bootlaces">Bootlaces library</a><br />
+<a href="https://github.com/boot-clj/boot/wiki/Pods">Pods</a><br />
+<a href="https://github.com/boot-clj/boot/wiki/Filesets">Filesets</a><br />
+<a href="https://github.com/boot-clj/boot/wiki/Tasks">Tasks</a><br />
+<a href="http://docs.oracle.com/javase/7/docs/technotes/tools/windows/classpath.html">JVM Class path</a><br />
+<a href="http://www.javaworld.com/article/2077260/learn-java/learn-java-the-basics-of-java-class-loaders.html">JVM Class loaders</a><br />
+<a href="https://clojurians-log.clojureverse.org/boot/index.html">Clojurian Slack Boot channel</a><br />
+<a href="http://www.flyingmachinestudios.com/">Daniel Higginbotham</a><br />
+<a href="http://mxgo.io/">mxgo.io</a></p>
+
+<h1 id="subscribing-to-the-cognicast">SUBSCRIBING TO THE COGNICAST</h1>
+
+<p>The show is <a href="https://itunes.apple.com/us/podcast/thinkrelevance-the-podcast/id498067022">available on iTunes!</a> You can also subscribe to the podcast using our <a href="http://feeds.feedburner.com/cognicast">podcast feed.</a></p>
+
+<p>You can send feedback about the show to <a href="mailto:podcast@cognitect.com">podcast@cognitect.com</a>, or leave a comment here on the blog. Thanks for listening!</p>
+
+<h1 id="credits">CREDITS</h1>
+
+<p>EPISODE COVER ART</p>
+
+<ul>
+  <li><a href="http://michaelparenteau.com/">Michael Parenteau</a></li>
+</ul>
+
+<p>AUDIO PRODUCTION</p>
+
+<ul>
+  <li><a href="/authors/RussOlsen.html">Russ Olsen</a></li>
+  <li><a href="/authors/DaemianMack.html">Daemian Mack</a></li>
+</ul>
+
+<p>PRODUCER</p>
+
+<ul>
+  <li><a href="/authors/KimFoster.html">Kim Foster</a></li>
+</ul>
+
+<p>Our theme music for this episode is <a href="https://soundcloud.com/owslaofficial/kill-the-noise-feed-me-thumbs-up">Thumbs Up (for Rock N' Roll)</a> by <a href="https://soundcloud.com/killthenoise">killthenoise</a> with <a href="https://soundcloud.com/feedme">Feed Me</a> which was used under a Creative Commons License.</p>
+
+<p>In this episode, we talk with Alan Dipert and Micha Niskin about solving problems and Boot.</p>
+
+
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+                <h1 id="transcript">TRANSCRIPT</h1>
+
+<p><strong>CRAIG</strong>:     Hello, and welcome to Episode 111 of The Cognicast, a podcast by Cognitect, Inc. about software and the people who create it.  I'm your host, Craig Andera.</p>
+
+<p>Okay.  Well, in our notes today, things we want to make you aware of, includes a number of conferences.  The first one I'll mention is the FinDEVr's west coast conference.  That's happening Tuesday, October 18th through Wednesday, October 19th, 2016.  Our very own Timothy Baldridge will be presenting.  This is a technology conference about the technology side of FinTech.  If you happen to be in the Santa Clara area where that is being held and you can get there, then have a look.  Look for the FinDEVr Conference.  You'll find that.</p>
+
+<p>Of course I can't not mention EuroClojure.  That's coming up soon now, Tuesday, October 25th and 26th.  Tickets are still available at this point, but quite a few have already been sold.  We're getting into the later part of ticket sales, so if you're planning to go to EuroClojure in Bratislava, Slovakia, you should definitely go and pick up tickets.  You'll find those at the EuroClojure website.</p>
+
+<p>Michael Nygard, who has been on the show a bunch of times, one of my favorite guests, will be presenting at the DevOps Enterprise Summit in San Francisco, Monday, November 7th.  That's the conference is Monday, November 7th through Thursday, November 10th.  That again is in San Francisco, so you can look for the DevOps Enterprise Summit if you want to go to San Francisco and hear Mike Nygard talk.  He's always great to listen to as, if you've listened to the show, you're well aware.</p>
+
+<p>The O'Reilly Software Architecture Conference is also in San Francisco around the same time.  That's actually Sunday, November 13th and Monday, November 14th.  We will be holding a training course, a two-day training course also given by Mike Nygard.  The title is Architecture Without an End State.  This is not a Clojure specific course.  I don't really have the space to describe it here.  Again, look for the O'Reilly Software Architecture Conference and you'll be able to find details about it on their website.</p>
+
+<p>Finally, I'll mention the Clojure/conj.  That's coming up.  That's going to be Thursday, December 1st through Saturday, December 3rd.  I'll be there.  I'll be teaching the Intro to Clojure course immediately beforehand, the two days beforehand.  You can find all of the information about that at the Clojure/conj website at Clojure-conj.org.  Always fun.  Just a great time.  One of my favorite things during the year is to go to that.  Tickets are also still available for that, but there's no guarantee that will remain true forever.  We're about two months away.  It would not be a terrible idea to go and get your tickets for that.  Head on down to Austin and join us there.</p>
+
+<p>I think that's all I have for announcements.  We'll go ahead and go on.  Upcoming now is Episode 111 of The Cognicast.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Well, I think I'm set.  How are you guys?</p>
+
+<p><strong>ALAN</strong>:     Yeah, we're ready to go.</p>
+
+<p><strong>MICHA</strong>:     Ready to go.</p>
+
+<p><strong>CRAIG</strong>:     Excellent.  Excellent.  Excellent.  All right, then.  Here we go.</p>
+
+<p>All right.  Welcome, everybody.  Today is Friday, July 29th, 2016, and this is The Cognicast.  I am very pleased today to welcome back to the show two friends of mine, Alan Dipert and Micha Niskin.  Welcome to the show, guys.</p>
+
+<p><strong>ALAN</strong>:     Thank you.</p>
+
+<p><strong>MICHA</strong>:     Thanks.  Yeah, it's great to be here.</p>
+
+<p><strong>CRAIG</strong>:     They are both developers at Adzerk.  Alan is a former coworker of mine.  I will point out he was the first ever guest on The Cognicast, coming up on six years ago now, although we never actually aired that episode.  Alan is one of the mysterious lost episode guests.  Alan, I think you may have been the guest on every episode that we never aired for one reason or another.  Anyway, it's been quite a while since we've had you on, but really, really glad that you're back to talk to us again and super excited to talk to Micha as well.  You guys have done some really cool stuff that we will get into.</p>
+
+<p>But before we do that, we are going to throw to you the question that we always throw to our guests, which is, at the beginning we ask people to relate some experience of art, whatever that means to them.  Even though you told me approximately 30 seconds ago which one of you was going to do this question versus the one we ask at the end, I've already forgotten.  Which of you said that you would like to answer the art question?</p>
+
+<p><strong>MICHA</strong>:     Hey, this is Micha.  I will.  I'll do it.</p>
+
+<p><strong>CRAIG</strong>:     Excellent.</p>
+
+<p><strong>MICHA</strong>:     Two things, actually.  I saw the other day a picture of a newborn baby's skull without any flesh on it.  Seeing how the teeth are, you know, kind of cued up inside the jaw, man, I cannot get it out of my head.  I don't know if this is exactly art, but, man, it's an image that I can't stop thinking about.</p>
+
+<p>But, like, for actual art, there was a guy.  He would take, like, an aluminum, a big aluminum plate, like 20, 30 feet square and put an emulsion on it and then made a camera obscura where he would take a landscape shot and develop it on this plate.  You could go up to it, apparently, with like a magnifying glass and see more and more detail because it's like infinite depth of field.  That was super fascinating to me, the idea that you could have, like, this enormous image with just endless detail, as much as you could ever want.</p>
+
+<p><strong>CRAIG</strong>:     Now I feel like I want to do that, but for a baby's skull.  Both of those are super cool.  The baby's skull one obviously is a little – I don't know.  I guess I find it a little – I think if I saw it, I would have a hard time forgetting it too.  But to me, kind of art is something that someone does with the intention of making you feel something, and I could well imagine that falling into that category.  The camera obscura thing is also very neat.  We'll make sure that we drop a link to that in the show notes so people could check that out too.</p>
+
+<p><strong>MICHA</strong>:     I'll have to find it.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  No worries.  We can look for it too.  That's very, very cool.</p>
+
+<p>Well, so you guys have been doing cool things together for quite a while now.  Kind of the reason that I wanted to have you on is that, Alan, you actually were on the show over two years ago now.  At the time, we talked about boot and hoplon and javelin.  I feel like those were really good ideas then, and they are still really good ideas now.  But one of the things is that I've actually been starting to see more of them out in the Clojure universe.  People around here have been talking a lot about boot lately.</p>
+
+<p>I have actually personally switched over to using boot and hoplon and, of course, by extension, javelin.  We'll explain what all those things are, to our listeners who aren't familiar, in a minute.  I've been using all those for my personal projects lately, and I've really been digging it.  They're different from some of the other things that are out there right now, and I just thought what a great time to follow up with these guys to go back and revisit those topics to get more in-depth into them, especially now that I have a little more context and maybe I can actually ask slightly more intelligent questions.  Of course, like we always say, and this is always true, we'd love to hear about whatever is interesting to you, but are you guys up for a chat about some of those things on the way to whatever else we talk about?</p>
+
+<p><strong>ALAN</strong>:     Totally.</p>
+
+<p><strong>MICHA</strong>:     Yup.</p>
+
+<p><strong>CRAIG</strong>:     Excellent.  Maybe you could just start with talking about this triad.  I know that they are things that you can independently: boot, hoplon, and javelin.  But maybe you could just give us the tour for anybody that hasn't encountered them.</p>
+
+<p><strong>ALAN</strong>:     Well, I think I might take a tack with this that Micha took with a podcast he was recently on, the Defn podcast, which was a fun listen for me.  The way he began telling about the trilogy is basically how Micha and I met.  Micha and I met in a context that had nothing to do with computers.  In fact, we were maybe even starved for the keyboard.  In the Army we did work that had nothing to do with computers, but he was the only programmer I ever met, so we would often have conversations about computers and programming.  Micha was one of the few people I knew who had actual C programming experience, and I knew a lot of things about the Web that Micha didn't know, so we had a lot of interesting conversations.</p>
+
+<p>It's funny.  I feel like a lot of the most interesting conversations about computers and programming happen at times and in places when the keyboard and the computer and Wikipedia are far away because that's when you're really forced to imagine what could be.</p>
+
+<p><strong>MICHA</strong>:     Definitely.</p>
+
+<p><strong>ALAN</strong>:     We had a lot of those kind of conversations.  Then when we both left the Army later, we started to work together at places.  This is another kind of cool phenomenon in the professional computing world that I know a few groups like us who sort of do this, but basically you work at a company and then you can influence hiring.  You know who you work with well.  You look in your address book, and you call those people up.  You get them into a team.</p>
+
+<p>I think some company out west even started hiring teams.  Just flat out they would hire groups of two or three people.  I found that my professional trajectory has kind of orbited groups of people and individuals and one of those individuals is Micha.  The same is true for him.  We were working at places, and we would hook each other up with contract work or jobs at those places.</p>
+
+<p>As we worked together more, we started to develop – I wouldn't call it a philosophy since it's not formalized at all, but basically when you work with someone or a small group of people, you develop a way of working.  You develop a perspective on how you gather the information and materials together that you need to do work, the toolset and the outlook.  I think, after that, after you've done some things together in a small team or with another person, then you start to develop actual tools that you use to do these jobs that both people know how to use.</p>
+
+<p>Boot and hoplon and javelin are things that emerged from that collaboration.  They are more or less tools that followed conversations that Micha and I had.  We would independently go research things and build our own prototype things.  Show them to each other and argue about it, and then we ended up arriving that these set of tools, I guess, a few years ago is when we arrived at them.  Not much has changed about them since I last told you about them two years ago.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean we were basically, like, in it together, like doing – you know, working, trying to make money and there were problems that we needed to solve to be able to – you know, you don't want to solve the same problems all the time.  So, you know, little bit little, we were working on these problems.  Because there were two of us, and because we were always working on the same kind of things, we could be a little bit more ambitious.  You know what I mean?</p>
+
+<p>For us, we've solved some of these problems forever.  We're just going to use the things now and we do other things.  You know?</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.  Yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, I guess if we had a dynamic, it would be maybe the idealist and the skeptic.  I'm pretty idealistic about computers, and you know what a gift to humanity they are, and Micha is right there to cut me down.  He freely mentions how anything computers do instantly make worse and there's all kinds of holes in this idea.  But if you go back and forth like that with somebody, particularly if it's a friendly rapport, I feel like we've managed to make some decent decisions, or at least come up with a set of tools that we both like to use.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Go ahead.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  This is a roundabout way of getting to describing what boot, hoplon, and javelin are, but boot is a build tool, basically.  It's more a library of Clojure functions that help you craft your own build tool to match whatever your build scenario is for any definition of build that you have, which makes it difficult to explain, but we'll get into that, I'm sure.</p>
+
+<p>We came up with the idea  for boot after working on a Web framework called hoplon because the Web of today requires sophisticated tooling to get anything done just because there are so many technologies, file formats, and….</p>
+
+<p><strong>MICHA</strong>:     Yeah.  Not only that.  At the time, so this was in, like, 2012, ClojureScript was pretty rough then.  It was still awesome, but we needed different things.  Having our own – you could do a lot of things in the build process if you have a flexible enough environment to build in, and that's where we found.  We didn't have that, so we made it.</p>
+
+<p>In hoplon, originally, there were a lot of things that were actually going into the ClojureScript world and changing things around.  So implementing stuff that we wanted, but it doesn't make sense to go and try and get it into the ClojureScript compiler.  We just want to get work done.  If it works out, it could be, you know, upstream can take it.  But right now we want to get our work done.  You know?</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so boot basically filled in the holes that were missing for us in our workflow because we were very convinced that ClojureScript is the way to build stuff, especially when we need to build a single page app.  But the tools were not just immature.  They're more or less nonexistent.  The line cljs built predated what we were doing, but it was not used very widely, and ClojureScript, in general, wasn't.</p>
+
+<p>Then javelin is a ClojureScript library that was part of the hoplon framework.  They're all loosely related to each other through this goal of ours back in 2011, 2012, to come up with a solution for building Web apps.  But now they're usable separately from each other.  You can use boot without using hoplon.  You can use javelin without using either.  They're definitely separate pieces.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, and so of the three, I think boot is the one that people are most likely to encounter simply because the other two are ClojureScript specific.  Boot, of course, is usable even if you never touch ClojureScript.  I think it exists in the same space as Leiningen.  That's the tool that most people are using that if they go use boot, then they're no longer using Leiningen, which is what I've done.  It's kind of an either/or.  Although, I believe there is some.  Maybe you guys can talk later about what it would mean if anything is sensible to use both.</p>
+
+<p>But I've been using boot for this process of building.  The thing that I've been struck by, really–and this is something, Alan, that you explained to me last time, but that once you get a chance to use a tool that sometimes is what it really takes to kind of start to viscerally understand things–is that it really is quite a different approach in that it feels more like programming Clojure, about writing functions and passing data through functions than something else where you have like a DSL and you're building an interpreter over that DSL.  Right?  Does that make any sense?</p>
+
+<p><strong>ALAN</strong>:     Yeah, totally.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  The way I see it is the boot, I mean the reason why it's called boot is because all it really does, like the objective of boot is to bootstrap you to a place where you can program in Clojure.  It's like the minimum that you need to get Clojure, to make a Clojure program that will do something useful.  But then, additionally, it provides some functions that you can use, like namespaces, libraries, and whatnot that you can use to do things that you commonly want to do when you build stuff.  But primarily it just gets you to a place where you can start writing a program.  Then you can do anything.</p>
+
+<p><strong>CRAIG</strong>:     Right.  Of course, you guys do provide some.  Actually, that's a good question.  What does it look like to start a project in boot?  If I'm using Leiningen, I say "lein new" whatever and then I have a project CLJ.  Then I say "lein REPL," and now I've got a REPL, and I'm off and running.  I add dependencies in my project CLJ.  For people that haven't used boot yet, what is the process like for boot?  Then we can get into how you advance your project, like how you go beyond the default.  What is the sort of default introductory user experience?</p>
+
+<p><strong>MICHA</strong>:     What do you do?</p>
+
+<p><strong>ALAN</strong>:     Well, I think for the default – so, you know, project, I think is a pretty overloaded term because it can mean one of experiment, application, or library - in general.  An experiment is something where you don't even care to have a file.  You just want to see how some library works or try out some function idea you came up with on the train or whatever.  There are libraries where you already have some code or some idea for what you want to create.  It's going to be supporting some other application, which is a separate project.</p>
+
+<p>Then you may have an application, which is going to be code that's purpose built to solve a problem in the real world outside of the domain of programming, probably for your client or your boss.  All of those three things in boot have the same starting point, usually, which is the boot command.  You can start development on any of those three kinds of things just by typing "boot REPL," and that gets you to a Clojure REPL.</p>
+
+<p>The biggest distinction in the beginning part of a project between boot REPL and lein REPL or Clojure's native REPL is that boot has the ability for you to bring in dependencies from the REPL.  So you don't need to specify your dependencies in a file before starting the REPL.  At the REPL, you can bring them in.  This is analogous to, I think, a lein plugin that Ryan Neufeld wrote a couple years ago called lein-try, and the idea is you want a REPL with a dependency on it just to experiment.  That's where a lot of projects begin.  That's probably how most or at least how I start almost anything with boot.</p>
+
+<p>Then for an application or a library, you're going to probably have some idea ahead of time of what dependencies you need already.  You're not going to be dynamically discovering things trying libraries out.  You probably have an idea of what you want to work with, so you'll create a build.boot file.  That's analogous to pom.xml or project.clj.  The main difference is that a build.boot file is a Clojure program.  It's not a language other than Clojure.  It's interpreted by the Clojure evaluator.</p>
+
+<p><strong>MICHA</strong>:     Yeah, because the boot tasks are just functions – well, everybody always says everything is just functions, but anyway you can compose them like functions and call them like functions and stuff.  We have a library, this bootlaces library, but that's kind of what I do.  I pre-stage my own little workflow as prepackaged tasks.  I can pull that Maven and have it loaded.  Then I have the normal ways that I build jars and all that stuff, you know, configured the way I like it already set up.</p>
+
+<p><strong>ALAN</strong>:     Which is kind of analogous to the way that compile and run time are interleaved in Lisps traditionally in the sense that a defmacro and a defn can inhabit the same runtime.  You can defn something and then make a defmacro where you call that thing that you defn.  Then you make another defmacro, so the phases of macro, expand, compile, and run are interleaved over the lifetime of your execution.  This is the sequential evaluation model of Lisp interpreters.</p>
+
+<p>Boot kind of supports that, so you can create a boot task, run it, edit it, reload your build.boot file, try it again in a build tool that has a static build description language like Make or Maven.  You're going to need to edit that file, shut down your JVM, restart your JVM after you've edited the file.  I would say it's just Lisp-ier, in general.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  That's exactly one of the things that I've really been enjoying about it.  I think the one that hits me right away is the one you mentioned, which is the ability to pull in new dependencies dynamically and to really – I mean, you know we talk about you could sit down at a REPL and build your whole program, right?  You could just say, defn, defn, defn.  Oh, I'm going to redo that one.  I've got state.  Boom.  I have a running program.  I never saved a file, really.  I just typed it all in.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I think it's kind of the same way that you could do with boot.  Now the same way that you don't typically create production systems by opening up a REPL on the prod box and typing until the system is working, you would probably not create nontrivial systems with boot by simply building it up.  But you can, and then you can go from that to kind of capturing what you've come up with interactively and working with that.  I really, really like that approach.  It resonates with me very well.</p>
+
+<p>I think there's another thing I would like you guys to comment on is how much of this was planned, how much of it you think is an outcome of the philosophy that was happy accident.  It seems to me one of the places where boot really shines is actually hard to explain to beginners because it has to do with the wins that you get as you get into projects that are less trivial, that are more kind of industrial strength.</p>
+
+<p>Micha, you said, "The way that I like to work."  Well, you have these projects and, over time, you're like, oh, we have to have some special asset built, asset pipeline build because people from the documentation team are sending us Word docs, and we need to transform those somehow.  We want to integrate that all in.  You wind up with these extra bits that you need to do.  If you have the DSL approach, then you have to write an interpreter and find a way to express it or do some other type of integration.  Maybe it's a bash script.</p>
+
+<p>With boot, it's really – let's have an execution model so that, since my model is execution and it's in Clojure, I start right there.  I say, well, I have a process, it has steps, and it does things, not a language where I say things and then I have to write something that knows how to speak that language.  I don't know if that makes any sense.</p>
+
+<p><strong>ALAN</strong>:     It makes a lot of sense, and it actually gives me a thought of how to set up Micha to explain it.  I'll try this.  I'll try to–</p>
+
+<p><strong>MICHA</strong>:     Okay.  Hit me.</p>
+
+<p><strong>ALAN</strong>:     –pass it to Micha and then he can spike it.</p>
+
+<p><strong>CRAIG</strong>:     Bump.  All right, I did the bump.  You're doing the set.  Got it.  All right.</p>
+
+<p><strong>ALAN</strong>:     Okay.  Yeah, I'll set it up.  I heard Rich Hickey say, maybe in a talk when I was in the beginning of my Clojure learning five, six years ago, seven years ago, about why Java "won" and C++ "lost."  Now, of course, C++ hasn't lost.  A lot of people use C++, and there's definitely a space within application and library development where C++ is very much alive.</p>
+
+<p>I think 15 years ago or 20 years ago people saw Java and C++ as competitors in the development of large-scale applications where large-scale is some function of application size and team size.  He made the point that Java developed over time this library ecosystem where C++ more or less stagnated as far as libraries go.  His reasoning for that disparity was Java gave library authors the elements they needed to capture workflows in a way that could work universally.  One of those key things is probably garbage collection.</p>
+
+<p>You can't combine libraries that have different strategies for allocating and de-allocating memory because each of those strategies forms a lifecycle and it's very hard to interleave resource dependent lifecycles.  It's just a super hard problem coordinating IO like that, and that's basically the problem that garbage collection solves.  Obviously there are tradeoffs involved, but if you want to share workflows and combine them meaningfully, you definitely need garbage collection.</p>
+
+<p>What  garbage collection lets you do is have what you might call first class data structures in the sense that the system supports the tracking and management of anonymous structures, so functions can take managed structures that are managed invisibly by the garbage collections underlying part of the language run time, and they can also return these structures.  They don't need to manage them while they're using them.  That lets us bundle up solutions to problems in ways that are very easy to consume.</p>
+
+<p>I think one of the things we came to appreciate after working on boot, and I should say it's not like all the pieces of boot we just figured out in one of our conversations in the Army and then sat down and typed it out.  It's definitely been years of fumbling, hitting guardrails, slapping each other around, and eventually arriving at something that works.  But one of those things was identifying what are the parts, what are the aspects of build processes that are preventing us from doing this like programming?  What is preventing us from capturing workflows and sharing them in libraries like the way we do in the JVM or in Clojure?  I think the two things in boot that represent those first class structures are pods and file sets.</p>
+
+<p><strong>MICHA</strong>:     Yup.</p>
+
+<p><strong>ALAN</strong>:     Then, Micha, it's over to you now to spike it.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  A weird thing, well, a different thing about boot is that there's no dependency graph or anything like that.  Boot isn't going to do anything.  Boot doesn't try and figure out what you're trying to do, and it won't do anything unless you explicitly tell it to do it.  You need to call a function or compose some things together and then call that.  That's kind of different than any of the other things that I've really used in the past.</p>
+
+<p>But one of the things that means is that it gives you – I think it gives you a lot more flexibility and reach because, to the programmer when you're setting up a workflow, a pipeline, it's obvious to you what you need to do first and what you need to do next and so on.  But it might be very, very difficult for the computer to figure out what the dependencies really are.</p>
+
+<p>You might make a mistake and, when you do your build, you see immediately what went wrong, and you reorder things.  To a human it's pretty obvious what you want to do.  You just have to have a very direct way to tell it, to tell the computer to do it.  Lisp obviously gives you the best way to describe to a computer what you want it to do.  That's one part.</p>
+
+<p>Another part is that a lot of the more odd things in boot arise from the need to keep this JVM alive for as long as possible because it's expensive to keep restarting JVMs and stuff.  That means that we have to think really hard about how to manage the mutable JVM sub-strait and build things on top of it that you could still program with some of the affordances of immutability.  That's where pods and the file set kind of come in where you can isolate things that mutate.  In other words, you can make a pod that isolates classpath mutation, and you could have that pod creating files in an anonymous, temporary directory that only boot really knows where it's located.  Then you could take those files and add them to a file set, which is an immutable representation of the class path of the main pod that you're in.</p>
+
+<p>Yeah, I think a lot of it kind of immerged from the fact that there is a need to get incremental compilation and long-lived.  You know, like that's a lot of the reason why the REPL, why there was so much emphasis on everything being workable from the REPL because you have a long-lived REPL session and you want to leverage that.  You don't want to have to keep restarting it.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Right.  You mentioned a couple things in there.  A lot of super interesting stuff, but you mentioned, concretely, pods and file sets.  I have to say, as a relatively new user of boot, these are not actually things that I am smacked in the face with.  I know they're there, but I write a build boot file and I kind of say boot REPL and maybe a couple other things.  It's fairly easy for me to add my own steps into the build and whatnot.  I haven't really had to confront what a pod is, what a file set is, so educate me.  What are these things and how would I use them?  What am I missing out on by not taking advantage of them?</p>
+
+<p><strong>MICHA</strong>:     Man, you know, that's actually – that's a thing that I really – I like it when people say that because I think it's really great to have software that separates architecture from building an actual application.  Meaning this is what we try and achieve with hoplon as well where you make a bunch of libraries where the actual functionality is, but you should be able to assemble an application out of those components just by composition without knowing too much about the internals.  If it's really done well, then there are so many ways that you could compose them that you could stay out of that world unless you need to do something novel.</p>
+
+<p>I'm glad you said that.  It makes me feel good.</p>
+
+<p><strong>CRAIG</strong>:     Good.  Yeah.  I have quite enjoyed it.  We'll talk more about my experience because I've been primarily using it with hoplon, and maybe when we talk about hoplon.  But explain to me what–?  Given that I don't have or have not yet had to know, I still am enjoying boot enough that I'm like, well, at  some point I'm probably going to want this stuff.  Arm me.  Arm me with the knowledge of what pods and file sets are so that when I have a problem, I will go ah-ha, that is a file set shaped problem.</p>
+
+<p><strong>MICHA</strong>:     Sure.  Maybe I'll do file sets and then Alan can do pods.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I guess it's worth saying that kind of the three pillars of boot are probably tasks, file sets, and pods.  Tasks came first, and those are the things that are just functions.  Pods and file sets came after when we really wanted for tools to do functional programming in the build setting.  It turned out the tools….</p>
+
+<p><strong>MICHA</strong>:     …build large projects too.</p>
+
+<p><strong>ALAN</strong>:     Yeah.   Yeah, and it turned out the tools we needed to work with these things were not functions.  We had functions up the wazoo.  We were composing them and calling them.  But the problem is, to do functional programming, you need not just functional – not just functions.  You need really immutable collection types and immutable aggregates that you can build on incrementally, immutably, and efficiently.  I think pods and file sets are really the values that you work with, with tasks, which are functions.</p>
+
+<p><strong>MICHA</strong>:     Yeah, so maybe we do file sets first because pods are more useful when you're using them kind of with file sets.</p>
+
+<p><strong>ALAN</strong>:     Yeah, or we could do a problem approach, like you're building a thing and you want to do some kind of processing, and how do you do it.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean for file sets, though, at the high level what you want to do in a build is you have a bunch of artifacts, which is things that are on the classpath in the JVM and things that might end up in some kind of packaged artifact like a JAR file or just a directory that has a bunch of files.  Whatever you want at the end, like when boot stops running, you're going to want to have something, usually.  It might be something that you ship to S3, so maybe it never exists on your disk, but there's this concept of having an artifact that you're creating.  In order to create that, you take some source files that are usually in Git or something.  These are the files that are owned by you that you're working on.  Then you run this build process on it, which performs a number of transformations and does a number of steps sequentially and, at the end, produces these artifacts.</p>
+
+<p>Working in the JVM and in Clojure, you're going to need to manage the classpath, which means you could pull in JAR files and things like that, which are treated more or less immutably by the JVM, meaning once a class loader has loaded a JAR in there, you can't really unload it.  But there's also immutable classpath, which is you could add a directory to a class loader.  You could add, remove, or change files from there, and it doesn't cache them.  It doesn't cache the byte code that was generated from them.</p>
+
+<p>Part of what boot does is manage the classpath for you.  The reason why you'd want to do this is because one task might create some files that need to be on the classpath for the next task because traditionally all the actual Java machinery that you're going to use, like the Java compiler, the ClojureScript, the Google Closure Compiler, all these big, giant projects that predate Clojure, boot, and everything expect to find things on the classpath and they put things back somewhere in a directory, usually.</p>
+
+<p>We needed to work within that world.  We don't want to throw away everything from the JVM.  That means that when a task is doing its work, its input is generally going to be on the classpath and its output is going to go into some directories or something.  Then we're going to want to take the output, maybe, and merge it into the classpath.  That's where the file sets come in.</p>
+
+<p>The file set is an immutable snapshot of all the files related to this build.  Some of them are on the classpath.  Some of them are not.  They're organized in different ways.  But it's like an immutable snapshot of the file system and its physical manifestation, sort of, is a record type, so a Clojure record, which is an immutable data structure.  Given a file set object, this immutable record, you can call methods on it to sync it with the file system, say, which means make the real file system and the real classpath and so on like my file set object.  You can also do Git-like operations, so you can say, add all the files in this directory here to the file set.</p>
+
+<p><strong>ALAN</strong>:     Underneath it is the implementation of it is more or less Git, content address stuff.</p>
+
+<p><strong>MICHA</strong>:     Yep.  Yeah, so you can add files and then commit them.  When you commit them, they get synced to the file system.  Then you can pass.  You can hold onto a file set, so if somebody passes you a file set, you do some work, maybe create a new file set, give that to someone else, but you can still hold onto the one that you had, which is the benefit of immutable data, right?  If you want to roll back time and reset the file system to where it was when you first started, you can just commit the file set object that you've saved.  The file system will be just like it was in that state.</p>
+
+<p>The idea is that a task gets a file set given to it.  It's an immutable representation of the state of the file system.  Then it does some work, which is for side effects, creating files and things like that.</p>
+
+<p><strong>ALAN</strong>:     Compiling stuff.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Less Java, AOT, Clojure, whatever.</p>
+
+<p><strong>MICHA</strong>:     Making ERB files into HTML files, whatever it is.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Then it takes the output of that and adds it back into the files to a new file set and then passes that to the next task.  This is good for, like, the incremental build cycle because the pipeline is a bunch of nested middleware, kind of like a transducer, and it can keep calling itself.  Each step can call the next step one time, zero times, or many times–however they want–and pass it, you know, a saved file set.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.  Right.  That's the pipeline aspect.  Right?</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Yup.</p>
+
+<p><strong>MICHA</strong>:     So the file set was necessary for the pipeline to work properly because you need to be able to rewind to any step in the pipeline to rerun it - if that makes sense.</p>
+
+<p><strong>CRAIG</strong>:     Actually, I don't quite follow that bit.  What is the–?  Maybe you can help me with an example of where I would need to rerun some step of this process.</p>
+
+<p><strong>MICHA</strong>:     Sure.  I made a task recently.  I wanted, in ClojureScript, to be able to do refer all and use accept.  You know what I mean?</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     In other words refer all the names.  I don't want to distinguish between macros and so I thought it could be done.  I was like the first thing I'll do is I'll make a boot task to transform a file into a different ClojureScript file, right?  I have foo.cljs in my source directory of my repo, and I put NS+ instead of NS.  I make a boot task that looks for every CLJS file in my project and, if it sees that the first form is NS+, it's going to perform this transformation, which finds out which things are macros, which aren't, and adds them and transforms it into a regular ClojureScript NS macro.</p>
+
+<p>What I want to do, though, is I want to replace the file that was there.  If I made foo.cljs in my project, I want it to just replace that with the modified one so that it can go through the compilation, the rest of the pipeline, which includes maybe the ClojureScript compiler and stuff like that.  They won't even know that this transformation took place.</p>
+
+<p>In order to do that, you really need to have some kind of immutable representation of the file system because you're actually replacing a file with a different one.  If I'm running an incremental build where every time I change a file it rebuilds things that have changed, so whenever I type in foo.cljs and I save it, it's going to run this thing, this pipeline again.  And so it needs to be able to start off, to undo the changes that were done by subsequent tasks.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.  Yep, that makes sense.</p>
+
+<p><strong>MICHA</strong>:     You know what I mean?</p>
+
+<p><strong>CRAIG</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     I mean because you're doing destructive actions, mutating all over town however you want, and so you need to be able to roll back those commits.  Reset minus, minus hard, is basically what it is.</p>
+
+<p><strong>CRAIG</strong>:     Yep.  That makes a lot of sense.  That example is a good one, I think, because you mentioned the NS macro.  That's actually a tough one to do any other way, right?</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, the NS macro is maybe the one thing in Clojure that the user has no control over the operation of.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     It's funny.  Over the years since we started on hoplon, we've added all kinds of cool features to Clojure like multiline strings.  What else?  All kinds of automatic refer stuff because basically we'd be working on these big applications and it's like, man, who wants to copy a 20-line NS thing into every single file that they're working on?  This is where the build tool needs to help us because the language can't.  You know just the way Clojure works, we can't draw that up.</p>
+
+<p>Historically, we've been pretty skeptical of features going into Clojure that solve these problems because our view is kind of if the build tool can solve it then the language should not because every time something goes into language, everyone has to use it.  But we're kind of–</p>
+
+<p><strong>MICHA</strong>:     And the administrative overhead of, like, you know, just discussing with hundreds of people when you could just have your own – you know what I mean?  Like ES6 versus making a macro that gives you let in five minutes.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     We wanted to be able to just make whatever crazy thing that maybe is unwise, but we could do it inside of our build task.  Nobody needs to care.</p>
+
+<p><strong>ALAN</strong>:     Yeah, we needed no approval.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Interesting.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so we have kind of this suite of experiments, really, extending the language syntactically, semantically, in various weird ways.  Boot is a great way to do that, and I would encourage people to explore that aspect of using Clojure because I think if you've used it for more than a few months, you probably have gripes and you might be able to craft it into something that you like more.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  I think the analogy is if you're working in a language like Java, there are a lot of things you can't do and you wind up repeating yourself a lot.  Then people say, well, why do you like Clojure?  It's like, well, because of that.  Right?  Because I don't have to do almost any of that any more.  I can mutate the language to fit my needs.  I think what you're saying is that although boot is not limited to that, it gives you even more power to do that when the language can't or doesn't.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  It gives you a limited form of syntactic extension of Clojure, which is traditionally poo-poo’ed.  But we know when you own the files that the syntax is in, you can do whatever you want to them before you hand it to the Clojure compiler.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     We found doing that was pretty useful.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, you use it to good effect in hoplon, which I hope we will – I might have to have you guys on again at this point because this is super interesting and I want to move on yet.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     You certainly use it to good effect in hoplon where you have crazy stuff like you write what looks like HTML, what any designer could pick up and look and say that looks very, very familiar.  Yet at some point it turns into something else.  It's very cool.</p>
+
+<p><strong>ALAN</strong>:     Yeah, we're kind of calling off that experiment, though.</p>
+
+<p><strong>CRAIG</strong>:     Interesting.  Okay.  All right, well, we'll have to talk about that.  I actually haven't gone down that road, but anyway.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Let's not lose track.  File sets I understand.  Great explanation.  I get why you'd want to have that.  I think it's pretty straightforward.</p>
+
+<p>The other thing we wanted to talk about, though, was pods.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I can maybe try and do that one.</p>
+
+<p><strong>MICHA</strong>:     Yes, please.</p>
+
+<p><strong>ALAN</strong>:     The JVM is a very compelling platform for many, many reasons, but maybe one of the most underappreciated and misunderstood and maybe even hated feature is this concept of the classpath and the business with class loaders.  This is like mid level to advanced sort of Java person adventure at some point if someone interacts with class loaders and dynamically adding Java classes or resources to the classpath depending on various situations.  It's something people will run up against at some point in their usage of the JVM platform regardless of what language they're on.</p>
+
+<p>They're one of those things that are very unwieldy, but it's also very powerful.  Once you understand how class loaders work, you can do some pretty powerful things.  Java application servers are examples of things that people have built that are based on the utility of the class loader, the idea that you can have a JVM, for instance, serving multiple different Web applications, and each of those Web applications is its own set of dependencies.  Maybe a different version of the same dependency.  The way you can do that is with class loaders.</p>
+
+<p>The class loader thing is not – I'm not aware of any other language run times.  I don't know much about the CLR.  I'm not sure if it has a class loader type thing.  But the really weird, compelling thing about class loaders in the JVM that distinguishes them is that they are values, more or less.  They're first class in the sense that you can create a variable that contains a class loader where a class loader is effectively a global scope for some execution context.</p>
+
+<p>Code that runs inside that class loader can see things that code running outside of it can't necessarily see.  It's almost like you're running JVMs within JVMs for a lot of values in JVM.  So it's a scoping mechanism.  It's basically a first class global scope.</p>
+
+<p>But because it's so difficult and tricky to work with traditionally, few people, even if they need them, sort of shy away from working directly with class loaders.  There are some gotchas, some historical things about class loaders that make them kind of daunting.  But any JVM language makes good use of class loaders, and anybody who is doing any kind of application server type stuff where they have some kind of container for other kinds of app is going to do class loader stuff.</p>
+
+<p>Pods in boot are basically the working person's practical class loader.  It is a set of functions that give you the ability to create a class loader, more or less, and to run code inside of it, and to get and to ship data to and from this isolated environment.  It's like a very lightweight container.</p>
+
+<p><strong>MICHA</strong>:     Clojure runtime specifically.</p>
+
+<p><strong>ALAN</strong>:     What's that?</p>
+
+<p><strong>MICHA</strong>:     Specifically Clojure.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, so each pod is an instance of the Clojure runtime running inside the same JVM that the creator of the pod is running in.  But it's a totally different Clojure runtime.  For instance, if you do def X1 in the parent Clojure runtime, but then in the pod you do def X2, and then you evaluate code in both places, in the runtime where you created the pod X is going to be 1.  Inside the pod, X is going to be 2.</p>
+
+<p>They're different Clojure runtimes, but they're also different JVMs to the extent that you can use boot's dependency resolution set to load dependencies into pods that sibling pods or parent pods will not see.  And so the utility of this is, I guess, one of the reasons I use pods a lot is we do a lot of stuff on AWS.  When I can, I use Clojure libraries that add niceties to working with AWS Java APIs.  The problem, though, is that a lot of these different Clojure libraries depend on different versions of the AWS SKD, which is a massive dependency, and you can run into weird problems if you load it multiple times, different versions of it.</p>
+
+<p>One mitigation is you can add.  You can create a pod, so you create a Clojure instance.  Then you add dependencies to it.  For instance, the AWS SDK and then maybe Bandalore, which is a library for working with SQS that depends on the SDK.</p>
+
+<p>Now inside that pod you can run Clojure code that uses Bandalore, uses that version of the AWS SDK, but is not impacted by whatever version of either of those libraries you load into the parent pod or the parent environment in which you've created the pod.  It's a way for you basically to program as if you're spawning new JVMs with totally different sets of dependencies and then communicate with these runtimes.  That really reduces the likelihood of you running into strange dependency problems.  They're, I guess, a mitigation tool, a tool for mitigating classpath issues.</p>
+
+<p><strong>CRAIG</strong>:     Would you use this at development time for an exploratory program, or is this something that you would deploy?  What's the use case here?</p>
+
+<p><strong>ALAN</strong>:     I guess there are two.  The first use case that it was developed for primarily was, say you're writing a task.  Say you're writing – say Micha ships a library that has this NS+ library in it.  He depends on some other library.  What would be one that you would depend on?  Tools namespace or–</p>
+
+<p><strong>MICHA</strong>:     Sure.</p>
+
+<p><strong>ALAN</strong>:     –ClojureScript Analyzer.</p>
+
+<p><strong>MICHA</strong>:     Anything from Apache with a million dependencies.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  StringUtils from IO Commons or whatever he uses in there.  Let's say he distributed this not as a boot task, but as a library, just a Clojure function and a Clojure project with dependencies in Maven and a single function that maybe let's say it takes a file and it rewrites it into one of Micha's NS augmented files and ClojureScript files.</p>
+
+<p>I would look at this.  I would be like, well, I want to use Micha's thing.  I have a build going on over here in boot, but I see he depends on, like, all kinds of stuff from IO Commons and whatever that conflicts with things that are already in my application.  The question is, how can I integrate Micha's cool function for transforming files into my build without messing up my build time dependencies and potentially my runtime dependencies depending on what I'm doing?  The answer there is I write a boot task and, inside the boot task, I maintain a pod that contains an instance of Micha's library that's totally isolated from everything else in my application, and I can feed it files to transform, and I can get files back from it that have been transformed.  But that is totally isolated from a dependency perspective from the rest of my JVM or my runtime.</p>
+
+<p>In the build context, pods are a way to use libraries from the Internet from Maven that do useful things, integrate them into your build process without imposing on yourself any kind of classpath pollution or overwriting or general classpath problems.  Basically, you bring them in scot-free.  That's kind of the reason we came up with them.</p>
+
+<p>The second reason you might use them, which is rarer, is if boot is the entry point to your application in production.  In most cases people are –say you're building a Web app with boot.  What you'll do is you'll work with the Web app locally with the boot REPL or you start a local ring jetty or you'll use the Web serve task to work on it locally.</p>
+
+<p>But at the end of the day, you want to ship a WAR file.  That's going to go up to Heroku, Beanstalk, or your own Tomcat, whatever.  In the local development case, the entry point to your application is you typing boot development and whatever your task name is.  In production, the entry point to your application is the servlet entry point that was produced by the WAR task.</p>
+
+<p>In the local case where boot is the entry point, all of the boot runtime stuff is available for you to use like pods and file sets.  But in the production setting where Tomcat selects and uses the entry point to your function, the boot runtime stuff is not available there because, in order to make pods work, we need to run Java code before we run any Clojure stuff.  Basically, we set up the pods before starting any Clojure instances.  It's kind of a hand-wavy technical description of the issue.</p>
+
+<p><strong>MICHA</strong>:     Yeah, like all Clojure code needs to run in a pod and, if it's not running in a pod, then it kind of ruins it for the rest of us.  Yeah, the boot executable starts with the Java program that constructs the first pod where your code is going to run.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     But if there is no phase distinction between build and run, like they're just kind of interleaved and production boot is your entry point, which it might be if you're running–I don't know–we've done this in Docker.  You can run boot in Docker and then boot is your entry.  Then all the boot runtime stuff is available, and then you can use pods at runtime.</p>
+
+<p>I've done this in the past with this Bandalore library.  I was using dependencies at runtime to interact with SQS, and I didn't want to suffer their transitive dependencies.  In retrospect, maybe ill-advised.  I don't know.  Maybe it's good to–</p>
+
+<p><strong>MICHA</strong>:     I think it works out well with Docker because, with Docker, you can bake the Maven cache into the….</p>
+
+<p><strong>ALAN</strong>:     Right, yeah.  That's right.  The problem with doing it at runtime is the Maven resolution then also happens at runtime, which means that you're potentially pushing something into production that can't yet run.</p>
+
+<p><strong>CRAIG</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     It still needs to talk to Maven central or whatever to download the stuff.  Yeah, if you're working in Docker, you can build your image separately from deploying it and, as part of the build step, you can cache the dependencies you're going to need at runtime.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and being able to use pods, like if you run into some problem, you could spend a long time messing around with dependencies and trying to figure out a way out of it–</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     –by negotiating amongst all the libraries.  It's like the U.N.  You could just throw a pod at it and the fire is out, at least.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, that's interesting.  I've definitely dealt with that problem of kind of different fiefdoms, right?  It's worse than the U.N. because at least there you have national borders.  This is like, well, I'm going to take the U.S. and overlap it with Canada.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     There are two St. Louises or two towns that want to occupy the same piece of ground.  How are we going to do that?</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Yeah, St. Louis 1.0 and 2.0, and they're incompatible.  Yeah.  No, that makes a lot of sense to me.  Okay.  Very cool.  This is such good stuff.</p>
+
+<p>I am quite happy with what you said, Micha, which is being able to use boot without having to have had a really deep understanding of this stuff.  But I'm certainly glad we had this discussion about it.  It's funny.  We've been talking for close to an hour now, and very usefully, I think, and yet when I step back, and maybe this is me being naïve, but I don't think so.  It really is a fairly smallish thing, right?</p>
+
+<p>You mentioned tasks, file sets, and pods.  I've only really had to kind of vaguely understand one of those things to be useful with it.  That's pretty cool.  I always like it when that happens with software that I write, although I can't claim to have done anything as elegant as what you guys have pulled off.</p>
+
+<p><strong>ALAN</strong>:     Thank you.</p>
+
+<p><strong>MICHA</strong>:     Thanks.  Yeah, that's–</p>
+
+<p><strong>ALAN</strong>:     That's very high praise indeed.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Well, man, I really do want to talk about hoplon.  I think we're going to wind up abbreviating the discussion, but it's just something I've been working on lately, working with lately, rather.  Maybe we can at least–</p>
+
+<p>Well, I guess maybe I should stop there and say, is there anything else that we should say about boot?  Is there another important part of the boot story that we haven't discussed?</p>
+
+<p><strong>ALAN</strong>:     I would say a couple things about boot.  First of all, the barrier to trying it is super low.  It's as low as it ever has been.  We have a number of – for a long time a lot of people didn't like boot or at least were discouraged from using boot because it was a real pain to use in Windows.  We still don't support Windows 7 and below and never will because of limitations of the file system API.  But actually Sean Corfield, who is a heavy boot user and contributor and sort of friend to the cause, has been happily using boot on Windows 10.  As far as we know, it works very well on Windows 10.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     And on Mac and Linux, those are the platforms we use boot on every day, so it's in really good shape there.  It's really easy to install.  The second thing I would say is that we have probably one of the most friendly and knowledgeable communities out there in the Clojure world, maybe even in the open source at large, and particularly on the Clojurian Slack thing in the boot channel.  I guess we can make a liner note for this.</p>
+
+<p>We have a boot channel in there of people who have written tasks.  There are people who are using boot for Web development.  There are people who are using boot to work with.  One guy did it – they used it in stuff like protobuf.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     All kinds of interesting things going on and people are very friendly.  Like I said, the barrier to entry is very low and it's very easy to get help if you're stuck.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and Martin and Juho work on the ClojureScript front.</p>
+
+<p><strong>ALAN</strong>:     Yeah, there is a tremendous momentum in the ClojureScript world, and a lot of it is boot centric.  Basically people extending boot and, well, not even boot.  Basically creating and sharing and integrating libraries to sweeten the ClojureScript development experience in a boot based app.  There are a lot of directions, somebody interested in learning about boot, could go with it, but I think you'd be hard pressed to come up with some kind of application that you're going to do on the JVM that boot wouldn't help you do it somehow.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, I've certainly had no trouble doing the things that I've wanted to do, and I've done so far one, I would say, definitively non-trivial application.  Nothing at a client yet, nothing kind of that kind of environment, but I've shipped a single page Web app that's a real piece of software.  It's not one weekend hacking or anything like that.</p>
+
+<p><strong>ALAN</strong>:     Awesome.</p>
+
+<p><strong>CRAIG</strong>:     I had no trouble whatsoever with boot.  Boot never – I shouldn't say that.  I think I have a very small amount of times where I had to go read the wiki to overcome some minor thing, but I don't remember any time where I was like, oh, my God.  I just spent an entire day just getting files to compile or something that should be trivial, so it was a good experience.</p>
+
+<p><strong>ALAN</strong>:     Cool.</p>
+
+<p><strong>MICHA</strong>:     That's really awesome.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.  I really want to talk about hoplon, so let's do that.  We are going to wind up cutting it short.  There's no question because I think hoplon is another very interesting piece of kit and given that we just spent an hour talking about boot, which is also interesting.  But given the relative surface areas, I suspect that we would wind up with a three-hour show, which we attempt not to inflict on our listeners.</p>
+
+<p>I think maybe if we could at least get you guys to mention what hoplon and, of course, javelin are, I do have a couple quick things I'd like to touch on and then we'd have to figure out a time it makes sense for you to come back and for us to really devote the time to it that it would deserve.</p>
+
+<p><strong>ALAN</strong>:     Sure.  Well, I guess, I would say we can cover.  We can get into it here, but there's also a hoplon channel in Clojurian Slack that has an active user base.  We're there, so anyone who is listening to this and is wanting for more on hoplon or any of the things we're about to discuss, they can always find us there.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  You know what?  I have to say that all these things, for me anyway, is like the main – it's really – I don't know.  For me, Clojure is very unique in my experience.  Hoplon, boot, and all these things, they're very – it's kind of like – it's very rewarding to me because they are things that, as far as my use of them professionally to make money and to get actual work done, they're pretty much done.  They do everything we need them to do, and we're moving on.  We're thinking about other problems now, and we don't need to keep solving these problems.  I've never experienced that before using Clojure.</p>
+
+<p>Using other languages, I'd always end up – I could never form the abstractions that were durable and composable enough to be used in the next project.  I would always end up having to rewrite something or solve the same problem over and over again.  I'd never experienced actually solving a problem before or even thinking that it was something that was worth spending your time on trying to do, like trying to solve a problem of making websites once and for all.  That's all due to Clojure, I think.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  I have had the same experience with a couple and I mean two different things that I've written.  I've got this little Stochastic Markov chain thing, and it's like it's done, right?  If anybody asks me, should I use that, I'd be like, yeah.  Go for it.  It's good.</p>
+
+<p>If they say, is there anything that you could change?  I'm like, well, sure.  I've got a laundry list, but do I need to bother?  Eh.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     It's great.  It's a great feeling.</p>
+
+<p><strong>ALAN</strong>:     Then people have so much power to pave over whatever omissions you made too, thanks to Clojure's dynamism and stuff.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Cool.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.  We are actually going to save hoplon and javelin for another time because I really don't want to shortchange them.  I think you could probably explain them in five minutes, but people can go over to the Web page for that.  I think there's useful, extended conversation we could have.  Let's save that up.  Let's have you back on and have that discussion some other time rather than attempting to shortchange these technologies now.  What do you think?</p>
+
+<p><strong>ALAN</strong>:     Sounds like a good idea.</p>
+
+<p><strong>MICHA</strong>:     Sounds good.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Cool.  Awesome.  That's great.  I just got you to agree to come on again, which is fantastic.</p>
+
+<p>Cool, so I guess I will say, though, even though we're not going to spend an hour on hoplon, I always reserve time at the end of the show, as much as makes sense, as much as we need, to talk about anything else.  We often have a main topic in mind.  Today we certainly did.  But is there anything else?</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Here we are, right?  It's a good opportunity.  What else is going on that we should talk about today?</p>
+
+<p><strong>ALAN</strong>:     There was something that I wanted to mention.  It's funny you brought up earlier in our conversation the production on the Pluralsight course.  There is a project that I have started with Daniel Higginbotham.</p>
+
+<p>Daniel Higginbotham, author of Clojure for the Brave and True, man about town in really every single way, he's made his brave Clojure thing.  He's got a Clojure jobsite now.  The dude is–</p>
+
+<p><strong>MICHA</strong>:     Also works at Adzerk.</p>
+
+<p><strong>ALAN</strong>:     Works at Adzerk, a great person, working on all kinds of fun stuff, very enthusiastic.  He and I collaborated, I guess, two years ago on his Clojure for the Brave and True book.  By saying we collaborated on it, really I'm taking way more credit than I deserve because he had it basically written before he went to a publisher.</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>I had the opportunity to be the technical editor and even write the foreword, and I kind of developed a cool working relationship with Daniel.  He and I both have a lingering interest in the concept of education, or at least we're just so excited about Clojure that we feel like it's something we should do.  I don't know.  I feel like a lot of Clojure people have this inclination.  It's like I know this awesome thing.  How do I tell other people about it without getting slapped?  
+</code></pre></div></div>
+
+<p>He and I started on this project called MX Go, mxgo.io.  The concept is basically online learning, short courses modeled more after talk length things than course length things.  I guess the TLDR would be what if Strange Loop had a baby with Pluralsight.</p>
+
+<p>[Laughter]</p>
+
+<p><strong>ALAN</strong>:     The site isn't up as of this recording, but that's something we're going to be developing.  I think, by the time that this goes out, we'll have that up, so mxgo.io.  If it's something you're interested in, either producing content for or subscribing to, then I would encourage you to check that out.  That's kind of been ramping up in my world.  Then hopefully I can convince Micha to come on and do the boot course.  Maybe you can do the hoplon course.  Then instead of recording another Cognicast, we can just tell people to subscribe to MX Go.</p>
+
+<p><strong>CRAIG</strong>:     There you go.  Is this all going to be–?  I mean obviously you and Daniel are both huge fans of Clojure.  Is it going to be specific to Clojure and related technologies?</p>
+
+<p><strong>ALAN</strong>:     That's a really good question and a cool thing about it is that it's not specific to Clojure.  Like I said, one of the main inspirations for it is the Strange Loop sort of….  The world filled with inquisitive minds, and there's a lot out there in computing going on outside of Clojure and outside of functional programming.  A lot of times people are – you don't know what you want to learn, right?  How do you find things that you would like to learn?  Well, you kind of need to be exposed to things that you weren't looking for.</p>
+
+<p>No, the content will not be limited to Clojure.  We've got some ideas lined up for different kinds of languages and CS topics.  We hope to mine the papers we love presenters.  We're really attracted to the idea of getting people to produce content who have already given a talk and encouraging them and helping them to convert their talk into a set of 20-minute explications with exercises on that topic.  Yeah, hopefully we have a pretty diverse set of topics.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  You just said "with exercises," which I think is a key point because people might say, well, YouTube.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I can go watch ten million conference talks, no problem.</p>
+
+<p><strong>ALAN</strong>:     Yeah, the big difference, I think, will be exercises, but also very few things actually go through the edit repeat cycle, which I experience in real time with you when you and I were making the Pluralsight Clojure course.</p>
+
+<p><strong>CRAIG</strong>:     Yes, you did.</p>
+
+<p><strong>ALAN</strong>:     I can lay down a track and in my mind it was amazing.  But if you look at like, you know, you forgot to talk about this.  You said this word three times.  There's a typo on line 25.  Not to disparage people who make content on YouTube because I think that's a great way to find new material too and just see awesome stuff, but it's free for a reason.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Addition definitely makes a difference.  You mentioned that you and I spent a week together producing a video.  I think that video was a total of maybe 3 or 4 hours, and it was two people for 40.  I mean it wasn't 40 hours.  You and I worked like at least one 10-hour day, right?  It was a boatload of work to produce, and there was no video.</p>
+
+<p><strong>ALAN</strong>:     That's true.</p>
+
+<p><strong>CRAIG</strong>:     It was slides and voice, so it's just a lot of work to do video.  There's no question about it.</p>
+
+<p><strong>ALAN</strong>:     That's why we're hoping we can cut down the size of the deliverable and then hopefully authors can leverage the fact that they've probably already given a talk or at least have notes on the topic, so then that cuts down on prep time too.  We don't want the production side to be too daunting.</p>
+
+<p><strong>CRAIG</strong>:     Right, and I think there are a lot of things you can do there for sure.  The comment was more aimed at the fact that when you see something polished there's a difference.</p>
+
+<p><strong>ALAN</strong>:     Totally.</p>
+
+<p><strong>CRAIG</strong>:     It's one thing to aim a camera that keeps tipping over at somebody standing at the front of a room full of people and hopefully you can hear them in whatever, versus oh, yeah, I can make out what all this, and there's bookmarks or whatever it is.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, totally.  Absolutely.  Cool.  Awesome.  Yeah, that's great.  I'm actually super excited to check that out.  I'm looking forward to seeing what you guys have to offer.  I mean one of the reasons I go to Strange Loop is exactly what you're talking about.  Just a world full of cool stuff and, quite frankly, I'm not aware of a lot of it.  Just being around people who are essentially a list of what's exciting is awesome.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I think it's super cool that, in our profession, you can meet – like at one Strange Loop I had the chance to meet Chuck Moore, which was like one of the formative experiences in my computing adventure.  Meeting Chuck Moore, holy cow, this is one of the names in computers and will be forever.  The fact that our profession is small enough and that the celebrities are usually friendly enough that you can meet really cool people and hear about really cool ideas.</p>
+
+<p><strong>MICHA</strong>:     I wonder if Larry Wahl was there.</p>
+
+<p><strong>ALAN</strong>:     I don't think he was, but he gave that talk that you linked me to at some other conference recently that I ended up watching.  It was really awesome too.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  All right.  Awesome.  Anything else that we should make sure to get to?  Micha, you have anything you wanted to share?</p>
+
+<p><strong>MICHA</strong>:     Well, I mean I have like a little reflection on boot, or are we past that time?</p>
+
+<p><strong>CRAIG</strong>:     No, it's all good.</p>
+
+<p><strong>MICHA</strong>:     Okay.  Yeah, so one thing that I think is good about it is maybe that it exposes the Java primitive, the JVM primitives to you in kind of a direct way, like when you make a pom.xml separately from the rest of the packaging.  What I think is good about this is, like, I'm not a big fan of Java, the language, but looking at java.util.concurrent, for me that was like a computer science education.  The way Maven is engineered, it's great that I knew that when I started working on node.JS stuff because then I was like in NPM land and I could see exactly why things were not going well.</p>
+
+<p>I think for beginners, they might be exposed to a lot of the JVM things, but I think that that's actually good because the JVM, the parts that we have to deal with, at least in Clojure, are super well engineered.  If you need to get stuff done reliably and people are depending on you, you can't go wrong with all those things.  I think boot exposes it to you, which lets you learn about them in kind of a friendly way.</p>
+
+<p><strong>ALAN</strong>:     We definitely – the JVM, the Java language are very conservative and well thought out approaches to managing change and improvement in their APIs.  Clojure, of course, does a spectacular job of basically never removing things.  Things will be added to the Clojure language, but things are never removed.  It's an extremely stable runtime environment.</p>
+
+<p>Then we kind of try to do the same thing with boot.  We haven't had a breaking boot in two-ish years, a year and a half.  Basically, it's a huge goal of ours to not introduce breaking changes to boot because we have dozens of services that are boot based that we would like to upgrade periodically, and we do not want to suffer for it.  Yeah, the whole stack, I think is like Micha says, can be daunting.  But once you learn it, you'll know it for a long time and it'll give you the ability to look at other systems and work with other systems in a new and powerful light, for sure.</p>
+
+<p>I totally just hijacked your moment.</p>
+
+<p><strong>MICHA</strong>:     No, I'm in agreement, dude.</p>
+
+<p><strong>ALAN</strong>:     Oh, okay.  All right.  I felt like I kind of swooped in.</p>
+
+<p><strong>MICHA</strong>:     Well, that's what I was going to say.</p>
+
+<p><strong>ALAN</strong>:     Okay.  Cool.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  All right, well, that sounds like as good a place to wrap up as any.  Assuming you agree, then, Alan, I will throw it to you for our final question, the one we always ask at the end of the show.  We ask our guest or guests to give us a piece of advice.  This can be of any form that they prefer, whether it's advice that you've been given or that you like to give.  I often throw in the addendum, it could be good advice or bad advice.  I don't think I've had anybody take me up on the bad advice one yet, but what do you got for us, Alan?</p>
+
+<p><strong>ALAN</strong>:     Well, so I found this really challenging because I have a conflicted – I'm conflicted about the very nature of giving and taking advice.  I don't know.  I look at a lot of things, and I see someone got very lucky.  It seems like the luckier someone is, the more freely they give advice.  But what does their advice mean?</p>
+
+<p>It's like getting number suggestions for the lottery from the lottery winner.  Is that going to help you?  Is that meaningful to you?  Maybe.</p>
+
+<p>I wracked my brain for, like, okay, this is a computer podcast.  What are some – who are the lottery winners and what–?</p>
+
+<p><strong>MICHA</strong>:     Give advice on being tall.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     Tell people how to be tall.</p>
+
+<p><strong>ALAN</strong>:     Yeah, how to be tall.</p>
+
+<p><strong>MICHA</strong>:     You obviously know the secret.</p>
+
+<p><strong>CRAIG</strong>:     I have a bit of advice about being tall.</p>
+
+<p><strong>ALAN</strong>:     Sure.</p>
+
+<p><strong>CRAIG</strong>:     Can I inject it?  So I am myself nothing like your height, Alan, but I always wanted to be taller just so I could use this line where someone walks up to you, and I'm sure you've had someone ask you, "Oh, do you play basketball?"  I always wanted to be tall enough to get that question so I could respond, "No, do you play mini golf?"</p>
+
+<p>[Laughter]</p>
+
+<p><strong>CRAIG</strong>:     I hope you'll use that sometime.  Anyway, back to your advice.</p>
+
+<p><strong>ALAN</strong>:     Oh, man.  I need to get a Google glass or something so I can record that moment and send it to you because I do get asked that question a couple times a year.</p>
+
+<p>Anyway, I wracked my brain for what is some advice that I've really taken to heart or has really paid off for me.  Then I thought, well, you know, in Matthew 25 Jesus' Parable of the Talents, is that the direction we want to go with this, you know, go religious with it?  I thought, well, probably no.  It needs to be like a computer thing.</p>
+
+<p>I thought, well, you know, it's really dumb, but one of the best pieces of advice ever was given to me by my drill sergeant in basic training, which was, if you're going to do something important tomorrow, get everything ready the night before.  That's something that never really came naturally to me, preparing for things that are important, but it's a very simple thing, especially if it's going to be early in the morning.  It's very simple.  You just lay out the clothes you're going to change into.  Or if you have a test, you study for it.  A very simple piece of advice, but I feel like I personally was never good at preparing for things, so I just had great faith that it's going to work out for me every time.  That was a piece of advice that I reflect on sometimes and I think is very simple and good.  Be prepared for things that are happening tomorrow.</p>
+
+<p><strong>CRAIG</strong>:     Well, we're all Clojurists.  We like simple, and that does not – as we are well aware, something being simple does not prevent it from being correct, profound, or any one of a number of other desirable qualities, so I definitely appreciate the advice.  As a father of two smallish children, you know, things like that need to be said to you at some point in your life.  It's not obvious automatically, so I'll have to maybe bring that….</p>
+
+<p><strong>ALAN</strong>:     Yeah, well, I guess as a new father, I can say it's definitely paid off too with bottle prep and clothing prep.  There's a lot of costume changes when they're two months old.</p>
+
+<p><strong>MICHA</strong>:     You waited until the night before to prepare for your kid?</p>
+
+<p><strong>ALAN</strong>:     Yes.</p>
+
+<p><strong>MICHA</strong>:     Laid out some clothes – ready.  Done.</p>
+
+<p><strong>ALAN</strong>:     Well, you know.  What is it?  Amazon.  There was Amazon Prime, but now there's Amazon – what is the hourly one?</p>
+
+<p><strong>MICHA</strong>:     Oh, yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Just in time.  I need a crib.  I need a box of diapers stat.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  You just install Amazon Echo or whatever it's called, the thing that listens, and it hears you swearing and the next thing there's a knock on your door with a bunch of diapers or whatever you need.</p>
+
+<p><strong>MICHA</strong>:     Oh, the button.  Right, right.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Cool.  Well, all right.  We've degenerated into puns and computer jokes, but I do appreciate.  The advice is very good, and I thank you for sharing it with us.</p>
+
+<p><strong>ALAN</strong>:     Sure.</p>
+
+<p><strong>CRAIG</strong>:     I love the fact that it came from a drill sergeant.  That just makes it so much better in my opinion.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  His version of it was a little more obscene, so I toned it down.</p>
+
+<p><strong>CRAIG</strong>:     Appreciate that.  I appreciate that.  I'm converting it back in my head right now, but I won't share it.  Anyway, like I said, clearly people know that I've worked with you a lot, Alan.  You've worked with Micha a lot.  Micha and I have hung out a bit, so rather than make people listen to our idle banter for the next 45 minutes, I'm going to wrap it up there.  But I will stop to thank you both very much for coming on.  I really, genuinely enjoyed the conversation, learned a lot.  Thanks for the tools, too, by the way.  I really have been digging using this stuff.  Change is always fun, but I've also found it productive, useful, and enabling, so thanks on both counts, guys.</p>
+
+<p><strong>ALAN</strong>:     Thank you.</p>
+
+<p><strong>MICHA</strong>:     Thank you.</p>
+
+<p><strong>ALAN</strong>:     Yeah, really fun to be here.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  All right.  We'll wrap it up there, then.  This has been The Cognicast.</p>
+
+<p><strong>MICHA</strong>:     Bye.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Thanks.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     You have been listening to The Cognicast.  The Cognicast is a production of Cognitect, Inc.  Cognitect are the makers of Datomic, and we provide consulting services around it, Clojure, and a host of other technologies to businesses ranging from the smallest startups to the Fortune 50.  You can find us on the Web at cognitect.com and on Twitter, @Cognitect.  You can subscribe to The Cognicast, listen to past episodes, and view cover art, show notes, and episode transcripts at our home on the Web, cognitect.com/podcast.  You can contact the show by tweeting @Cognicast or by emailing us at podcast@cognitect.com.</p>
+
+<p>Our guests today were Alan Dipert on Twitter @AlanDipert and Micha Niskin on Twitter @MichaNiskin.  Episode cover art is by Michael Parenteau, audio production by Russ Olsen and Daemian Mack.  The Cognicast is produced by Kim Foster.  Our theme music is Thumbs Up (for Rock N' Roll) by Kill the Noise with Feed Me.  I'm your host, Craig Andera.  Thanks for listening.</p>
+
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+          </div>
+          
+<div class="related">
+    
+  <span class="classifier">
+    <span class="content-cell related-title">
+    
+      <p>related</p>
+    
+    </span>
+    <span class="content-cell"><p class="recent-title">recent</p></span>
+  </span>
+  <div class="links left">
+    
+    
+     
+    <a href="/cognicast/008-michael-fogus">
+      Michael Fogus - Podcast Episode 008<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/068-keith-sparkjoy">
+      Keith Sparkjoy - Cognicast Episode 068<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/027-tim-ewald">
+      Tim Ewald - Podcast Episode 027<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/074">
+      Aaron Brooks - Cognicast Episode 074<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/029-lake-denman">
+      Lake Denman - Podcast Episode 029<span class="dash">—</span>
+    </a>
+    
+    
+  </div>
+  <div class="links right">
+    
+     
+    <a href="/cognicast/172">
+      <span class="dash">—</span>Janet A Carr - Cognicast Episode 172
+    </a>
+     
+    <a href="/cognicast/171">
+      <span class="dash">—</span>Howard Lewis Ship - Cognicast Episode 171
+    </a>
+     
+    <a href="/cognicast/170">
+      <span class="dash">—</span>Michiel Borkent - Cognicast Episode 170
+    </a>
+     
+    <a href="/cognicast/169">
+      <span class="dash">—</span>Ed, Justin and Lindsey - Cognicast Episode 169
+    </a>
+     
+    <a href="/cognicast/168">
+      <span class="dash">—</span>Wilker Lucio - Cognicast Episode 168
+    </a>
+    
+  </div>
+</div>
+</div>
+
+          <div id="post-sidebar">
+
+            <div id="post-sidebar-container">
+              <!-- <div class="post-search right-block"></div> -->
+              <div class="post-email right-block">
+                <a href="/contact.html">Get In Touch</a>
+              </div>
+              <div class="post-authors right-block">
+                <ul>
+                  
+                  <li>
+                    <h2><a href="/authors/AlessandraSierra.html">Alessandra Sierra</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AlexMiller.html">Alex Miller</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/CarinMeier.html">Carin Meier</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DavidChelimsky.html">David Chelimsky</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DavidNolen.html">David Nolen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/GhadiShayban.html">Ghadi Shayban</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JebBeich.html">Jeb Beich</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JustinGehtland.html">Justin Gehtland</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/LynnGrogan.html">Lynn Grogan</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MarcPhillips.html">Marc Phillips</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MichaelNygard.html">Michael Nygard</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/NaokoHigashide.html">Naoko Higashide</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/PauldeGrandis.html">Paul de Grandis</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RichHickey.html">Rich Hickey</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RussOlsen.html">Russ Olsen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/StuartHalloway.html">Stuart Halloway</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/TimBaldridge.html">Tim Baldridge</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AaronBedra.html">Aaron Bedra</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ChrisRedinger.html">Chris Redinger</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/CraigAndera.html">Craig Andera</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DonMullen.html">Don Mullen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/GlennVanderburg.html">Glenn Vanderburg</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JaredPace.html">Jared Pace</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JasonRudolph.html">Jason Rudolph</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JonDistad.html">Jon Distad</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/LarryKarnowski.html">Larry Karnowski</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MichaelParenteau.html">Michael Parenteau</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MunessAlrubaie.html">Muness Alrubaie</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RobSanheim.html">Rob Sanheim</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/SamUmbach.html">Sam Umbach</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/KimFoster.html">Kim Foster</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JaretBinford.html">Jaret Binford</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JoeSmith.html">Joe Smith</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ClintonDreisbach.html">Clinton Dreisbach</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/TimEwald.html">Tim Ewald</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RobertRandolph.html">Robert Randolph</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AlexRedington.html">Alex Redington</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JoeLane.html">Joe Lane</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ChristianRomney.html">Christian Romney</a></h2>
+                  </li>
+                  
+                </ul>
+              </div>
+            </div>
+          </div>
+        </div>
+    </section>
+  </div>
+  <div class="footer left">
+  <div class="w-container">
+    <ul class="menu-footer-menu">
+      <li>
+        <a class="footer-head" aria-current="page">Nu International</a>
+        <ul class="sub-menu">
+          <li><a href="https://international.nubank.com.br/about" target="_blank">About Nu <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://international.nubank.com.br/careers" target="_blank">Careers <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://international.nubank.com.br/newsroom" target="_blank">Newsroom <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://www.investidores.nu/en/" target="_blank">Investor Relations <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Nu Impact</a>
+        <ul class="sub-menu">
+          <li><a href="https://international.nubank.com.br/impact/environmental" target="_blank">Enviromental <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+          <li><a href="https://international.nubank.com.br/impact/social" target="_blank">Social <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+          <li><a href="https://international.nubank.com.br/impact/governance/" target="_blank">Governance <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Global
+          Presence</a>
+        <ul class="sub-menu">
+          <li><a href="https://nubank.com.br" target="_blank">Brazil <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.mx" target="_blank">Mexico <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.co" target="_blank">Colombia <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.ar" target="_blank">Argentina <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Blogs</a>
+        <ul class="sub-menu">
+          <li><a href="https://building.nubank.com.br/" target="_blank">Building Nubank <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nubank.com.br/" target="_blank">Brazil <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nu.com.mx/" target="_blank">Mexico <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nu.com.co/" target="_blank">Colombia <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+    </ul>
+  </div>
+  <div class="w-container">
+    <div class="footer-text">Copyright 2025, Cognitect, a Nu Holdings, Ltd. company
+      | <a class="footer-link-s" href="/privacy-policy.html">privacy-policy</a>
+      | <a class="footer-link-icon" href="https://github.com/cognitect" target="_blank"><i class="fa fa-github"
+          aria-hidden="true"></i> Github</a></div>
+  </div>
+</div>
+<script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.4.1.min.220afd743d.js?site=58dee1dd9c1826ba43796eb4"
+  type="text/javascript" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
+  crossorigin="anonymous"></script>
+<script src="/assets/js/webflow.js" type="text/javascript"></script>
+<!-- [if lte IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/placeholders/3.0.2/placeholders.min.js"></script><![endif] -->
+  <!-- <script src="/assets/js/scale.fix.js"></script> -->
+  
+  <script>
+    (function () {
+      // This is the ugliest hack.
+      // Rouge highlighter puts a span element for the final white space (\n)
+      // This script splits on \n, so rouge coloured elements will end up with an extra line.
+      // So we process one fewer line if the pre element has more than one child.
+      var subtractor = 0;
+      var pre = document.getElementsByTagName('pre'),
+        pl = pre.length;
+      for (var i = 0; i < pl; i++) {
+        // detect if rouge
+        if (pre[i].childNodes[0].childNodes.length > 1)
+          subtractor = 1;
+
+        pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
+        var num = pre[i].innerHTML.split(/\n/).length;
+        for (var j = 0; j < num - subtractor; j++) { // num - subtractor = process one less if rouge
+          var line_num = pre[i].getElementsByTagName('span')[0];
+          line_num.innerHTML += '<span>' + (j + 1) + '</span>';
+        }
+      }
+    })(); 
+  </script>
+  <script>
+    audiojs.events.ready(function () {
+      var as = audiojs.createAll();
+    });
+  </script>
+</body>
+
+</html>
diff --git a/archive/techworks/items/cognicast/112-cover.jpg b/archive/techworks/items/cognicast/112-cover.jpg
new file mode 100644
index 0000000..a7918a0
Binary files /dev/null and b/archive/techworks/items/cognicast/112-cover.jpg differ
diff --git a/archive/techworks/items/cognicast/112.headers b/archive/techworks/items/cognicast/112.headers
new file mode 100644
index 0000000..e4a551b
--- /dev/null
+++ b/archive/techworks/items/cognicast/112.headers
@@ -0,0 +1,14 @@
+HTTP/2 200 
+content-type: text/html
+content-length: 139869
+date: Sun, 09 Aug 2026 19:54:36 GMT
+last-modified: Fri, 19 Sep 2025 18:37:58 GMT
+etag: "ab9a0247b244c4c3350e22197aa99741"
+x-amz-server-side-encryption: AES256
+accept-ranges: bytes
+server: AmazonS3
+x-cache: Miss from cloudfront
+via: 1.1 8c0cf74a8ac4637a28b8ef40ac35c710.cloudfront.net (CloudFront)
+x-amz-cf-pop: LAX53-P1
+x-amz-cf-id: qaJNnN-67Sn-agdLsjpSOyKtTHk0_CejfglaTSWRgjJRLplqF-ATag==
+
diff --git a/archive/techworks/items/cognicast/112.html b/archive/techworks/items/cognicast/112.html
new file mode 100644
index 0000000..8ef447a
--- /dev/null
+++ b/archive/techworks/items/cognicast/112.html
@@ -0,0 +1,1748 @@
+<!DOCTYPE html>
+<html lang="en-US">
+<head>
+  <meta charset="UTF-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+
+
+  <!-- Manually setup SEO for better results and smoother local dev experience  -->
+  <!-- Much better than the Jekyll SEO plugin -->
+
+  <title>
+    
+    Alan Dipert and Micha Niskin Part II - Cognicast Episode 112
+    
+  </title>
+
+  <link rel="canonical" href="https://www.cognitect.com/cognicast/112">
+
+  <meta content="width=device-width, initial-scale=1" name="viewport">
+  <meta itemprop="description" name="description"
+    content="In this episode, we talk to Alan and Micha about Javelin and Hoplon. " />
+  <meta property="og:locale" content="en_US">
+  <meta charset="utf-8">
+  <meta property="og:type" content="article">
+  <meta property="og:title" content="Alan Dipert and Micha Niskin Part II - Cognicast Episode 112">
+  <meta property="og:url" content="https://www.cognitect.com/cognicast/112">
+  <!-- Re-add if page thumbs become a thing <meta property="og:image" content="https://www.cognitect.com/thumbs/" /> -->
+  <meta property="og:site_name" content="Cognitect.com">
+  <meta property="article:publisher" content="https://www.cognitect.com" />
+  
+  <meta property="article:author" content="Craig Andera" />
+  
+  <meta property="article:published_time" content="2016-11-03 12:01:23 -0400" />
+  <meta property="og:description"
+    content="In this episode, we talk to Alan and Micha about Javelin and Hoplon. ">
+  <meta name="twitter:title" content="Alan Dipert and Micha Niskin Part II - Cognicast Episode 112">
+  <meta name="twitter:description" content="In this episode, we talk to Alan and Micha about Javelin and Hoplon.">
+  
+
+  <meta name="twitter:site" content="@cognitect" />
+  <meta name="twitter:card" content="summary">
+  
+  <meta name="twitter:image" content="/assets/content/v1/5372821be4b0aefc6719057e/1478187443066-I9CNDJJGDI0TWDPS5JJO/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/112-dipert-niskin.jpg" />
+  
+
+  
+  
+
+  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+  <link rel="stylesheet" href="/assets/css/style.css?v=1.14">
+  <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans" />
+  <link href="/assets/css/normalize.css" rel="stylesheet" type="text/css">
+  <link href="/assets/css/webflow.css" rel="stylesheet" type="text/css">
+  <link href="/assets/css/stripped-down.webflow.css" rel="stylesheet" type="text/css">
+  <!--[if lt IE 9]>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script>
+    <![endif]-->
+
+  <link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
+  <link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
+  <link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
+  <link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
+  <link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
+  <link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
+  <link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
+  <link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
+  <link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
+  <link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png">
+  <link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
+  <link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
+  <link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
+  <link rel="manifest" href="/manifest.json">
+  <meta name="msapplication-TileColor" content="#ffffff">
+  <meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
+  <meta name="theme-color" content="#ffffff">
+  <link rel="mask-icon" href="/safari-pinned-tab.svg" color="#5bbad5">
+  <link rel="shortcut icon" href="/favicon.ico?v=rMq4O6n057">
+  <style type="text/css">
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/l?subset_id=2&fvd=n1&v=3) format("woff2"), url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/d?subset_id=2&fvd=n1&v=3) format("woff"), url(https://use.typekit.net/af/c47696/00000000000000003b9b305e/27/a?subset_id=2&fvd=n1&v=3) format("opentype");
+      font-weight: 100;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/l?subset_id=2&fvd=i1&v=3) format("woff2"), url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/d?subset_id=2&fvd=i1&v=3) format("woff"), url(https://use.typekit.net/af/c31dbb/00000000000000003b9b305f/27/a?subset_id=2&fvd=i1&v=3) format("opentype");
+      font-weight: 100;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/l?subset_id=2&fvd=n3&v=3) format("woff2"), url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/d?subset_id=2&fvd=n3&v=3) format("woff"), url(https://use.typekit.net/af/cebe0e/00000000000000003b9b3060/27/a?subset_id=2&fvd=n3&v=3) format("opentype");
+      font-weight: 300;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/l?subset_id=2&fvd=i3&v=3) format("woff2"), url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/d?subset_id=2&fvd=i3&v=3) format("woff"), url(https://use.typekit.net/af/40ff7f/00000000000000003b9b3061/27/a?subset_id=2&fvd=i3&v=3) format("opentype");
+      font-weight: 300;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/l?subset_id=2&fvd=n4&v=3) format("woff2"), url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/d?subset_id=2&fvd=n4&v=3) format("woff"), url(https://use.typekit.net/af/705e94/00000000000000003b9b3062/27/a?subset_id=2&fvd=n4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/l?subset_id=2&fvd=i4&v=3) format("woff2"), url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/d?subset_id=2&fvd=i4&v=3) format("woff"), url(https://use.typekit.net/af/5c70f2/00000000000000003b9b3063/27/a?subset_id=2&fvd=i4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/l?subset_id=2&fvd=n5&v=3) format("woff2"), url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/d?subset_id=2&fvd=n5&v=3) format("woff"), url(https://use.typekit.net/af/6e816b/00000000000000003b9b3064/27/a?subset_id=2&fvd=n5&v=3) format("opentype");
+      font-weight: 500;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/l?subset_id=2&fvd=i5&v=3) format("woff2"), url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/d?subset_id=2&fvd=i5&v=3) format("woff"), url(https://use.typekit.net/af/5b5251/00000000000000003b9b3065/27/a?subset_id=2&fvd=i5&v=3) format("opentype");
+      font-weight: 500;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/l?subset_id=2&fvd=n6&v=3) format("woff2"), url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/d?subset_id=2&fvd=n6&v=3) format("woff"), url(https://use.typekit.net/af/576d53/00000000000000003b9b3066/27/a?subset_id=2&fvd=n6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/l?subset_id=2&fvd=i6&v=3) format("woff2"), url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/d?subset_id=2&fvd=i6&v=3) format("woff"), url(https://use.typekit.net/af/f7d492/00000000000000003b9b3067/27/a?subset_id=2&fvd=i6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/l?subset_id=2&fvd=n7&v=3) format("woff2"), url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/d?subset_id=2&fvd=n7&v=3) format("woff"), url(https://use.typekit.net/af/949f99/00000000000000003b9b3068/27/a?subset_id=2&fvd=n7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/l?subset_id=2&fvd=i7&v=3) format("woff2"), url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/d?subset_id=2&fvd=i7&v=3) format("woff"), url(https://use.typekit.net/af/4c4052/00000000000000003b9b3069/27/a?subset_id=2&fvd=i7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/l?subset_id=2&fvd=n8&v=3) format("woff2"), url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/d?subset_id=2&fvd=n8&v=3) format("woff"), url(https://use.typekit.net/af/d82519/00000000000000003b9b306a/27/a?subset_id=2&fvd=n8&v=3) format("opentype");
+      font-weight: 800;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/l?subset_id=2&fvd=i8&v=3) format("woff2"), url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/d?subset_id=2&fvd=i8&v=3) format("woff"), url(https://use.typekit.net/af/3e6df8/00000000000000003b9b306b/27/a?subset_id=2&fvd=i8&v=3) format("opentype");
+      font-weight: 800;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/l?subset_id=2&fvd=n9&v=3) format("woff2"), url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/d?subset_id=2&fvd=n9&v=3) format("woff"), url(https://use.typekit.net/af/b683e3/00000000000000003b9b306c/27/a?subset_id=2&fvd=n9&v=3) format("opentype");
+      font-weight: 900;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: proxima-nova;
+      src: url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/l?subset_id=2&fvd=i9&v=3) format("woff2"), url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/d?subset_id=2&fvd=i9&v=3) format("woff"), url(https://use.typekit.net/af/d32834/00000000000000003b9b306d/27/a?subset_id=2&fvd=i9&v=3) format("opentype");
+      font-weight: 900;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/l?subset_id=2&fvd=n4&v=3) format("woff2"), url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/d?subset_id=2&fvd=n4&v=3) format("woff"), url(https://use.typekit.net/af/2011b6/00000000000000003b9b00c1/27/a?subset_id=2&fvd=n4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/l?subset_id=2&fvd=i4&v=3) format("woff2"), url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/d?subset_id=2&fvd=i4&v=3) format("woff"), url(https://use.typekit.net/af/5cace6/00000000000000003b9b00c2/27/a?subset_id=2&fvd=i4&v=3) format("opentype");
+      font-weight: 400;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/l?subset_id=2&fvd=n6&v=3) format("woff2"), url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/d?subset_id=2&fvd=n6&v=3) format("woff"), url(https://use.typekit.net/af/fb3638/00000000000000003b9b00c3/27/a?subset_id=2&fvd=n6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/l?subset_id=2&fvd=i6&v=3) format("woff2"), url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/d?subset_id=2&fvd=i6&v=3) format("woff"), url(https://use.typekit.net/af/d68363/00000000000000003b9b00c4/27/a?subset_id=2&fvd=i6&v=3) format("opentype");
+      font-weight: 600;
+      font-style: italic;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/l?subset_id=2&fvd=n7&v=3) format("woff2"), url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/d?subset_id=2&fvd=n7&v=3) format("woff"), url(https://use.typekit.net/af/af619f/00000000000000003b9b00c5/27/a?subset_id=2&fvd=n7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: normal;
+    }
+
+    @font-face {
+      font-family: adobe-garamond-pro;
+      src: url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/l?subset_id=2&fvd=i7&v=3) format("woff2"), url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/d?subset_id=2&fvd=i7&v=3) format("woff"), url(https://use.typekit.net/af/6c275f/00000000000000003b9b00c6/27/a?subset_id=2&fvd=i7&v=3) format("opentype");
+      font-weight: 700;
+      font-style: italic;
+    }
+  </style>
+  <meta name="msapplication-TileColor" content="#ffffff">
+  <meta name="theme-color" content="#ffffff">
+
+  <script src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js" type="text/javascript"></script>
+  <script src="/assets/js/jquery-3.5.1.min.js" type="text/javascript"></script>
+  <script
+    type="text/javascript">WebFont.load({ google: { families: ["Open Sans:300,300italic,400,400italic,600,600italic,700,700italic,800,800italic", "Roboto:300,regular,500"] } });</script>
+  <!-- Matomo -->
+<script>
+  var _paq = window._paq = window._paq || [];
+  /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
+  _paq.push(['trackPageView']);
+  _paq.push(['enableLinkTracking']);
+  (function() {
+    var u="https://cognitect.matomo.cloud/";
+    _paq.push(['setTrackerUrl', u+'matomo.php']);
+    _paq.push(['setSiteId', '1']);
+    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+    g.async=true; g.src='//cdn.matomo.cloud/cognitect.matomo.cloud/matomo.js'; s.parentNode.insertBefore(g,s);
+  })();
+</script>
+<!-- End Matomo Code -->
+
+<script src="/assets/audiojs/audio.min.js"></script>
+
+<body>
+  <header>
+  <div class="header-inner">
+    <div id="logoWrapper" class="wrapper" data-content-field="site-title">
+      <div id="logoImage">
+        <a href="/">
+          <img src="/assets/images/cognitect-nubank-logo.svg" alt="Cognitect Blog">
+        </a>
+      </div>
+    </div>
+    <nav role="navigation" class="nav-clear">
+      <a href="/technologies.html">Technologies</a>
+      <a href="/blog/">Blog</a>
+      <a href="/cognicast">Cognicast</a>
+      <a href="/contact.html">Contact</a>
+      <a href="/archive.html">Archive</a>
+    </nav>
+  </div>
+</header>
+
+  <div class="wrapper">
+    <section>
+      <div id="articles-list">
+  <div id="categories">
+  <a href="/blog/index.html">All Topics</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/how-we-work.html">How We Work</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/events.html">Events</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/customer-stories.html">Customer Stories</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/technology.html">Technology</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/testing.html">Testing</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/the-new-normal.html">The New Normal</a>
+  <span class="cat-separator"> - </span>
+  
+  <a href="/blog/open-source.html">Open Source</a>
+  <span class="cat-separator"> - </span>
+  
+  <span class="cat-separator"> - </span>
+  <a href="/feed.xml">RSS Feed</a>
+  </div>
+</div>
+
+      <div id="post-page">
+        <div id="post-wrapper">
+          <div id="post-title">
+            Alan Dipert and Micha Niskin Part II - Cognicast Episode 112
+          </div>
+          <div class="post-author">
+            <a href="/authors/CraigAndera.html"><img
+                src="/assets/Authors/CraigAndera.jpg"></a>
+            <span class="post-author-name">
+              posted by
+              <a href="/authors/CraigAndera.html">Craig Andera</a>
+              on November 3, 2016
+            </span>
+            <div class="tags">
+              tagged:
+              
+              <a class="tag" href="/blog/tags?tag=podcast cognicast">podcast cognicast</a>
+              
+            </div>
+          </div>
+          
+            <img class="cognicast-thumbnail" src="/assets/content/v1/5372821be4b0aefc6719057e/1478187443066-I9CNDJJGDI0TWDPS5JJO/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/112-dipert-niskin.jpg">
+          
+          <H1>AUDIO</H1>
+          <div id="post-content">
+            <a href=""></a>
+            <div id="cognicast-audio">
+              <audio src="https://s3.amazonaws.com/cognicast/shows/cognicast-112-alan-and-micha-part-deux.mp3" preload="auto"></audio>
+              <span class="mp3-download">
+                <a href="https://s3.amazonaws.com/cognicast/shows/cognicast-112-alan-and-micha-part-deux.mp3">Download</a>
+              </span>
+            </div>
+            <p>In this episode, we talk to Alan and Micha about Javelin and Hoplon.</p>
+
+<h1 id="our-guests-alan-dipert-and-micha-niskin">OUR GUESTS, ALAN DIPERT AND MICHA NISKIN</h1>
+
+<h2 id="alan">ALAN</h2>
+
+<ul>
+  <li><a href="http://tailrecursion.com/~alan/index.cgi/index">On the Web</a></li>
+  <li><a href="https://twitter.com/alandipert?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor">On Twitter</a></li>
+  <li><a href="https://github.com/alandipert">On Github</a></li>
+</ul>
+
+<h2 id="micha">MICHA</h2>
+
+<ul>
+  <li><a href="http://micha.github.io/">On the Web</a></li>
+  <li><a href="https://twitter.com/michaniskin">On Twitter</a></li>
+  <li><a href="https://github.com/micha">On Github</a></li>
+</ul>
+
+<h1 id="topics">Topics</h1>
+
+<ul>
+  <li><a href="https://www.youtube.com/watch?v=4Sso4HtvJsw">Russ Olsen’s “To the Moon”</a></li>
+  <li><a href="https://www.youtube.com/watch?v=NAeMM7b4ojI">Lindstrom space Apollo 8</a></li>
+  <li><a href="https://twitter.com/freshdietray">Ray Willig</a></li>
+  <li><a href="http://www.thefreshdiet.com/">The Fresh Diet</a></li>
+  <li><a href="https://jekyllrb.com/">Jekyll</a></li>
+  <li><a href="http://knockoutjs.com/">Knockout</a></li>
+  <li><a href="https://github.com/hoplon/javelin">Javelin</a></li>
+  <li><a href="https://en.wikipedia.org/wiki/Atomicity_(database_systems)">Atomicity</a></li>
+  <li><a href="https://github.com/google/guava/wiki/EventBusExplained">EventBus</a></li>
+  <li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Web of promises</a></li>
+  <li><a href="https://github.com/hoplon/ui">Hoplon UI</a></li>
+  <li><a href="https://github.com/hoplon/ui">Elem (Hoplon UI)</a></li>
+  <li><a href="https://twitter.com/colinfleming">Colin Fleming - Cursive</a></li>
+</ul>
+
+<h1 id="subscribing-to-the-cognicast">SUBSCRIBING TO THE COGNICAST</h1>
+
+<p>The show is <a href="https://itunes.apple.com/us/podcast/thinkrelevance-the-podcast/id498067022">available on iTunes!</a> You can also subscribe to the podcast using our <a href="http://feeds.feedburner.com/cognicast">podcast feed.</a></p>
+
+<p>You can send feedback about the show to <a href="mailto:podcast@cognitect.com">podcast@cognitect.com</a>, or leave a comment here on the blog. Thanks for listening!</p>
+
+<h1 id="credits">CREDITS</h1>
+
+<p>EPISODE COVER ART</p>
+
+<ul>
+  <li><a href="http://michaelparenteau.com/">Michael Parenteau</a></li>
+</ul>
+
+<p>AUDIO PRODUCTION</p>
+
+<ul>
+  <li><a href="/authors/RussOlsen.html">Russ Olsen</a></li>
+  <li><a href="/authors/DaemianMack.html">Daemian Mack</a></li>
+</ul>
+
+<p>PRODUCER</p>
+
+<ul>
+  <li><a href="/authors/KimFoster.html">Kim Foster</a></li>
+</ul>
+
+<p>Our theme music for this episode is <a href="https://soundcloud.com/owslaofficial/kill-the-noise-feed-me-thumbs-up">Thumbs Up (for Rock N' Roll)</a> by <a href="https://soundcloud.com/killthenoise">killthenoise</a> with <a href="https://soundcloud.com/feedme">Feed Me</a> which was used under a Creative Commons License.</p>
+
+<p>In this episode, we talk to Alan and Micha about Javelin and Hoplon.</p>
+
+
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+                <h1 id="transcript">TRANSCRIPT</h1>
+
+<p><strong>CRAIG</strong>:     Hello, and welcome to Episode 112 of The Cognicast, a podcast by Cognitect, Inc. about software and the people who create it.  I'm your host, Craig Andera.</p>
+
+<p>Well, we have a bunch of Cognitects that will be out and about in the world.  I want to mention a few of the places they'll be this month.  This is all in 2016, November of 2016 specifically.</p>
+
+<p><strong>First up, there's a meet-up</strong>:  Clojure PDX in Portland, Oregon.  Stu Halloway will be there.  Rather, he'll be giving a remote presentation on agility and robustness in clojure.spec.  That's November 3rd.  The venue for that is Portland.  Although, like I said, it's a remote presentation.</p>
+
+<p>Mike Nygard will be doing a bunch of stuff in November.  He'll be all over the place, actually, doing a lot of cool talks.  The first stop for him is the DevOps Enterprise Summit, which is in San Francisco.  That's happening November 7th through the 10th at the Hilton San Francisco Union Square.  He will be presenting at that conference.</p>
+
+<p>He will be doing training at the O'Reilly Software Architecture Conference also in San Francisco.  That's happening November 13th and 14th.  The title there is Architecture without an End State.  It's a two-day course, again taught by Mike Nygard.  This, by the way, is not Clojure specific.  You can search on that for more info.</p>
+
+<p>We've got a lot of things to talk about today, so I'll leave you to discover those on the Internet.</p>
+
+<p>More Mike Nygard in Iceland at G/O Digital.  This is November 16th at the Hilton Reykjavik Nordica.  He will be speaking there at that conference.</p>
+
+<p>Carin Meier will be speaking at Ohio DevFest, which this is happening Saturday, November 19th at the Tangeman University Center.</p>
+
+<p>Of course, the Clojure/conj is coming up.  That is, I suppose, technically in December, although the training course is happening immediately before.  We have a Datomic course.  I'll be teaching the Clojure course.  Those are at the very end of November.  The conference itself is December 1st, 2nd, and 3rd.  This is happening in Austin, Texas.  Still tickets available.  You should go to Clojure-conj for information about the speaker lineup, which has been posted, and to buy tickets.  Sponsorship opportunities are still available, so lots of good stuff at Clojure-conj.org.</p>
+
+<p>Finally, I want to mention InClojure.  This is India's first ever Clojure conference - very exciting.  This is November 26th at the Hotel Novotel in Pune, India.  We've actually had a whole episode where we talked about our producer Kim Foster's visit to India and about the Clojure scene there.  Obviously that's coming along very nicely since they are now having a conference.  You can check that out at InClojure.org.  Definitely check that out.  That looks to be exciting.  We're certainly psyched that that's happening there.</p>
+
+<p>But that's a lot of stuff, so we will leave it with that and go on to Episode 112 of The Cognicast.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     Okay.  Are you ready?</p>
+
+<p><strong>ALAN</strong>:     Yep.  Ready.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, you were ready all along.  I was the one that clearly wasn't ready.  So here we go.</p>
+
+<p>Welcome, everybody.  Today is Tuesday, October 18th in the year 2016, and this is The Cognicast.  We are very, very pleased to welcome back, right back in fact, as it turns out.  We just shipped their episode, their previous episode today.  We're recording again right after the release of that.  I'm talking, of course, about Micha Niskin and Alan Dipert.  Welcome to the show, Micha and Alan.</p>
+
+<p><strong>ALAN</strong>:     Hey.  Thank you, Craig.</p>
+
+<p><strong>MICHA</strong>:     Good to be back.</p>
+
+<p><strong>CRAIG</strong>:     It's really great that you were able to record again.  I mean it's not that soon for us.  We recorded that episode way back a couple months ago, but it's perfect timing, in my opinion, to have you back on.  You know we just got done talking about – our audience will have just, in the last couple weeks, have heard you talking about boot.  They're well aware then that that conversation – we left off before we could talk about javelin and hoplon, which are two other extremely interesting technologies that I have been using in my free time projects quite extensively over the last few months.</p>
+
+<p>Of course, we will cover other things as they come up.  The two of you are both just endless fonts of interesting information, anecdotes, high jinks, so forth and so on.  So I'm sure we will have another great conversation.  I'm looking forward to it.</p>
+
+<p>But, of course, before we get into that, we always ask at the beginning of the show a question about art.  Specifically, we ask for our guests to share with us some experience of art, whatever they think that means.  Since we had Micha go last time, which resulted in, I think it's safe to say, the creepiest cover we've ever had on any of our episodes ever – it was also awesome, by the way–</p>
+
+<p><strong>MICHA</strong>:     Bam!</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  We had you go last time.  That resulted in that.  This time we're going to ask Alan to answer the art question.  Alan, would you like to share with us an experience of art?</p>
+
+<p><strong>ALAN</strong>:     Sure.  Maybe it's a kind of performance art.  I mean everything is art.  Nothing is art.  But I would call this art.</p>
+
+<p>As you know, I'm kind of fascinated with space travel and space exploration and, you know, the heyday of space travel, the Apollo program, stuff like that.  I've always been interested in that and, when I was a kid, I wanted to be an astronaut and a pilot, but I think, in my adult life, I was sort of reinitiated with Russ Olsen's incredible talk about sort of the developer engineer legacy and the relationship of that to the space race.  I'm sure you know what I'm talking about.</p>
+
+<p><strong>CRAIG</strong>:     Oh, yeah.  That talk is excellent.  People should go look up Russ Olsen's To the Moon to see exactly what you're talking about.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Amazing.  I was really fortunate to have seen it live, and it was just really moving to hear the story told from someone who was there, who was there as a child, you know, a particularly imaginative, engaged child talking about what it was like to be in the same world while that was going on.  As someone who existed in the future, I've always had this sense of nostalgia about it, so it's like ten times more awesome probably than it ever was.</p>
+
+<p>But obviously you know the space program is not really a work of art.  But I think, like any big endeavor, there are works of art performed routinely.  One of the neater things that I've seen related to the space program that was kind of an artistic interaction was – and this is kind of – the astronauts actually have some artistic flexibility, especially in the '60s because the astronauts would be on TV, and they would be on the radio.  NASA, amazingly, did not really script what they were going to say.  They gave the astronauts a fair amount of leeway into what they were going to say on these shows, which is pretty incredible, I think.  The first humans doing this basically are just given an open mic and asked, "How do you feel about this?" because everybody really wanted to know, like, what's it like to be further away from earth than any human ever has been.  And what would a person say to that?</p>
+
+<p>I think, by and large, the astronauts were performers and artists because they were probably the only people in the world who were capable of both doing that mission and also having, like, that casual tongue in cheek kind of test pilot sort of worldview.  So they could be like, you know, flying into the sun to their doom and crack some joke, you know.</p>
+
+<p><strong>CRAIG</strong>:     Is it warm in here?</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Is that just me?  Did someone turn it up, or are we going to die in ten seconds?  You know?</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     And I'd always admired that kind of humor and that kind of affect.  If you've read The Right Stuff by Wolfe, he talks about that a lot and the whole Chuck Yeager personality meme.  That's kind of the context.</p>
+
+<p>The piece of art in particular that I'm thinking of, there was a mission Apollo 8, which was in December of 1968.  We landed on the moon in, I think, May of 1969.</p>
+
+<p><strong>CRAIG</strong>:     July, I believe.</p>
+
+<p><strong>ALAN</strong>:     July?  That's right.  Apollo 8 was one of the precursor missions.  It was the first mission to orbit the moon.  They did not land on the moon, but they went all the way out there.  They orbited it, went around the dark side, and came back.</p>
+
+<p>As I understand it just from history books and stuff, 1968 was a tough year for everybody with Tet Offensive and RFK assassination and Martin Luther King was assassinated in that year too, so everyone was on edge - a very crappy year.  These astronauts on this Apollo 8 mission were kind of in a weird spot because they were supposed to say something nice, and it happened that they were headed to the moon on Christmas Eve of 1968, so everyone was tuned in anticipating what they were going to see and, I imagine, hoping to be distracted.</p>
+
+<p><strong>There was an interview, later I saw, where they explained why they made the selection.  But basically the astronauts chose to read from the Book of Genesis, like from the beginning.  And there's this very moving piece of video where they had the spacecraft camera aimed at earth with an odometer that was rising</strong>:  172,000 miles, 173,000 miles.  You can tell they're going at super fast speeds.  The guy is just reading from the beginning of the Book of Genesis.  In the beginning there was nothing and then God moved over the face of the waters and so on.</p>
+
+<p>It's kind of – I don't know.  It's music video like in that it seems almost too beautiful to have happened for real.  I don't know.  It was an artistic experience, and I definitely would count the astronauts who had that idea as artists because I would have no idea what to say.  They said, hey, you're going to the moon.  What do you tell the folks back at home?</p>
+
+<p>Yeah, I don't think art is necessarily an artifact that you make because art, I think it's more like when you look at something, you might consider it to be art because of what it does.  So a cool part of it is there is kind of an artifact because there is somebody who recently made a music video that mashes up a kind of spacey, upbeat tune with the NASA footage of the dude saying this.  The artist is Lindstrom.  He's like a Norwegian – Norwegian space disco is the genre.</p>
+
+<p>But there's this kind of weird, spacey, futuristic music playing and then the astronaut reading from Genesis, and it's pretty surreal.  If you search for, I think, Lindstrom space Apollo 8 on YouTube, you'll hit it.  It's a very crazy, interesting video.</p>
+
+<p><strong>CRAIG</strong>:     Very cool.  We will, of course, put a link to that in the show notes so people can find it easily that way too.  Well, it's interesting to me.  I mean, so I agree with your statement at the beginning there, Alan.  It's like, well, what is art?  Art is everything.  Art is nothing.</p>
+
+<p>But the definition I always kind of reach for just to have something to hang onto is something whose intent is or effect perhaps is to make you feel something, to make the observer or participant feel something.  The space program is clearly, clearly, like, a very strong intersection of emotion and technology for many people.  I mean it's the pinnacle of technology in many ways, and yet people also have this really strong kind of emotional attachment too.  I think your example is a great, you know, almost the pinnacle of that, right?  Like how could you – that's clearly something that is definitely about the feel of something, the emotional impact of a moment combined with technology.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Admittedly, technology that is less powerful than what we all have in our pockets right now, but more impressive nonetheless.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  Yeah, no, I think by that definition, you know, something meant to impart a feeling.</p>
+
+<p><strong>ALAN</strong>:     I don't necessarily think the intent is at all relevant.  I think it's the effect that makes it art, not the intent.</p>
+
+<p><strong>CRAIG</strong>:     I'll buy that.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean there's multiple definitions.  I mean some things, some things you can call art retroactively.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, sure.</p>
+
+<p><strong>ALAN</strong>:     I think that, yeah, for me anyway, I think that's the necessary and sufficient condition.  I don't think you can actually make art.  I think it can be art, you know, if a person experiences it in a certain way.  You know?</p>
+
+<p><strong>MICHA</strong>:     You're saying it's like eye of beholder kind of thing.</p>
+
+<p><strong>ALAN</strong>:     Yeah, just like, you know – yeah.  I mean I think we have math and science and whatnot to explain the world, but we have art to explain ourselves.  That has to be, I think, an internal thing that the person experiences that.  You can't really describe it in terms of logical systems.</p>
+
+<p><strong>CRAIG</strong>:     The distinction that comes to my mind when you say that is – so this is what I talk to my kids about is I think there's a confusion a lot of times.  I'm not saying that this is something that either of you is doing, but just as an interesting phenomenon between kind of an artifact and an event.  Like I said, well, let's say that we all sat down and played a game of Monopoly.  Then we put the game in the box, and we put the game on the shelf.</p>
+
+<p>I would say, "Well, where is the game?"<br />
+They would say, "Well, it's on the shelf."<br />
+And I said, "No, no.  I mean the game we just played."  Right?</p>
+
+<p>Like we all sat around and we can talk about that.  We played at this time.  We played at that time.  Where is that?  Of course, the answer doesn't make any sense, but I think that there are times.  That's kind of the point of that exercise that I ran through with them is to be able to differentiate between artifacts and events because sometimes we talk about things like where is this thing, but really it was an event.  It was a process, and it doesn't make sense for it to be in a place.  Like where does the light go when you turn it off?  That type of question.</p>
+
+<p>Anyway, sorry.  No, that's a really cool story, Alan, I mean a really cool – I'm glad you related that.  That's very good and it's good observations from the both of you on that.</p>
+
+<p>I love this part of the show, but we do, of course, have other things that we would like to talk about as well.</p>
+
+<p><strong>ALAN</strong>:     No, no, no.  Let's keep going with this.</p>
+
+<p><strong>CRAIG</strong>:     We could.  I know we definitely could.</p>
+
+<p><strong>ALAN</strong>:     No, no.  Let's please not.</p>
+
+<p><strong>CRAIG</strong>:     The only thing that stops me from doing that is that we were in the middle of what I thought was a really interesting conversation last time.</p>
+
+<p><strong>ALAN</strong>:     Yes.</p>
+
+<p><strong>CRAIG</strong>:     We didn't get a chance to finish it, and so as much as this is interesting, I'd love to loop back to that.</p>
+
+<p><strong>ALAN</strong>:     No, totally.  I'm just kidding.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     No, but right.  I get that.  Alan, you're a funny guy.  Funny guy, Alan - real funny guy.</p>
+
+<p><strong>ALAN</strong>:     I'll shut up now.</p>
+
+<p><strong>CRAIG</strong>:     No, no, don't shut up.  That's kind of the point is for you not to shut up.  If you shut up, the show gets really–</p>
+
+<p><strong>ALAN</strong>:     I'll shut up and then Micha can talk.</p>
+
+<p><strong>CRAIG</strong>:     Well, that'd be okay.  That'd be okay.  Anyway–</p>
+
+<p><strong>MICHA</strong>:     Alan, can you do anything right?</p>
+
+<p><strong>CRAIG</strong>:     The last time on the show we basically covered the first leg of the tripod of technologies that I kind of had you on to talk about, which the three are boot, hoplon, and javelin.  I don't know if that's the right order, but we talked about boot first, which makes sense to me.  It's kind of, in my opinion, the right place to start.  But we didn't get a chance, because there was so much interesting stuff to go through, to talk about javelin and hoplon.</p>
+
+<p>Now, if I was going to guess, I would imagine that it makes sense to sort of jump over to javelin first, but maybe you, as the creators of these technologies, have a different opinion.  I'll leave it to the two of you to decide how we should approach that.  What we would like to do, I think, is maybe explain what it is for anybody that hasn't had  a chance to encounter it or not.  But then I have a bunch of questions I want to ask you about it since I've been using it a bunch.</p>
+
+<p>So all of which is a long way to–</p>
+
+<p><strong>ALAN</strong>:     So, yeah.</p>
+
+<p><strong>CRAIG</strong>:     Go ahead.  Go ahead.  Go ahead.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     No, I have a thought about how to lead into this.</p>
+
+<p><strong>CRAIG</strong>:     Okay.</p>
+
+<p><strong>ALAN</strong>:     The last time, if I remember correctly, we talked a little bit about the origin story to, like, set up the background and the kind of things we were facing that resulted in the thing.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     I feel like I told most of that story, but I feel like in this case Micha kind of owns the origin story because he's the one who did the original work on this technology at the Fresh Diet.  I think he probably went through the most evolutions of it.  I'm talking about the white labeling problem and stuff.</p>
+
+<p><strong>MICHA</strong>:     Yeah, yeah, yeah.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.</p>
+
+<p><strong>MICHA</strong>:     Sure.</p>
+
+<p><strong>ALAN</strong>:     Maybe Micha could start there and then I could.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  I love origin stories.  Go for it.</p>
+
+<p><strong>ALAN</strong>:     All right, cool.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     Yeah, so originally I was working with Ray Willig at the Fresh Diet.  He also, like, we started using Clojure there, and we had really, really good – a good experience with Clojure.  This was in, like, maybe 2012, something like that.</p>
+
+<p>The specific problem that we had, the company delivered fresh, gourmet meals all around the country, so we had kitchens all over the place in all these different cities, and we did the entire stack from sourcing fresh ingredients.  We had our own deliveries.  We did routing, everything, and we had, like a very full featured interface that the customers could use to figure out which.  We would publish menus that had lots of choices, and they could choose different things that they wanted.  They could also adjust them saying they didn't like things or, if they did like things, they could have extra, like extra peppers, whatever.</p>
+
+<p>Also, there were a ton of more and more complex promotional, like marketing promotions.  They would involve things like you can order a plan for a month, so it's a month's worth of food.  But you don't have to consume it all.  You could only get, like, a day here and then, like, next week you get two days of food and so on.  So you could order 30 days worth of food and then, if you want to quit within the first week, we prorate it according to this formula, and then if you want to quit with the second week.</p>
+
+<p>Anyway, they kept making more and more complex marketing type models that we would have to implement.  Also, they were reaching the size where they had to start modularizing the business because they already were doing a lot of direct business with customers, but there was a lot of money also in being the backend to other people, so like celebrity chefs, for example, would want to make their own front end and use our services because we had the domain knowledge to actually make the food and deliver it, which is pretty complicated.  Anyway, so our system was this, like, 250,000 line PHP application that basically mediated every single aspect of operations of the company.</p>
+
+<p>They're like, "Hey, Micha.  Can we, like, just white label this stuff?"  There's no way.  You cannot.  It was all, like, HTML being admitted by PHP with, like, hundreds of CSS things coming in and out, so it was just not possible.</p>
+
+<p>We had to think about how to make a system that would be flexible enough to allow different customers to have different workflows.  An example of a specific case of this was we had a customer who wanted to use us with a nutrition focus rather than the focus that the Fresh Diet had.  That means that the user interface would be kind of centered around nutritional, like this nutrition database view of your meals, which was unlike what the Fresh Diet itself was doing.</p>
+
+<p>And so how do you start to reconcile the two?  It's not just changing CSS or making colors different or whatever.  It's an actual workflow change.  And so we wanted to think of a way to make basically a framework for making applications on top of our service.  It had to be done such that we could make a new white label site within a certain amount of time in order to get the deal, you know?</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     We looked around at all the different things that were available and tried experiments.  We did a lot of weird things too like using Jekyll to generate a static site, which then used Knockout to talk to the backend - weird stuff like that.  We ended up realizing that we needed to separate completely the workflow part, which is basically the state of the application and the application as a state machine from the user interface, the presentation, or what you see on the screen because a lot of the aspects of the workflow are business logic, business concerns.  Those are constant.  Those will be in any implementation, but they have to be in the client too.  In other words, a person needs to select whether they're vegetarian or not before they can look at their menu, for instance, or something like that.  These aspects of the workflow are universal, and they always need to be maintained by the system.  We ended up eventually using ClojureScript, and hoplon basically came out of that.</p>
+
+<p><strong>ALAN</strong>:     And I think the influence of the spreadsheet model, too, it seemed like.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Because, yeah, I think one of the things that – so when Micha did most of this thinking and initial implementation, I did not work at The Fresh Diet, but I was communicating with him on the side channel.  It seemed like one of the things that he arrived at was the idea that you needed to separate the workflow, in other words the business.  You have a business, and there's domain knowledge with the business.  There are certain operations that are valid or invalid given some configuration of domain data.  That's a separate thing from what the person can see and how they're allowed to influence that workflow.</p>
+
+<p>One of the things that Micha ran into that he very excitedly told me about, if I remember right, was that that's basically what a spreadsheet is.  If you consider a spreadsheet and charts based on a spreadsheet as a workflow and views into that, like mediated views into the underlying workflow.  What you end up with, and I think an example he said in a previous talk–I remember Micha talking about–is like if you're at a business and someone comes up with a spreadsheet.  Let's say someone in the accounting department comes up with a spreadsheet, and the spreadsheet has the financials for the past three quarters.</p>
+
+<p>But then someone in the marketing department wants to make charts for their presentation.  They don't understand the accounting bit, but they can look at the existing spreadsheet and hook up new, different kinds of charts.  I guess the modern term for this is mash-ups.  Like you mash up the data you got from the accounting department with data you get from the business analysis team or whatever, and you come up with a derivative diagram.  What you end up with is a directed acyclic graph of data and dependencies and visualizations.  The visualizations are the leaves.  Those are the things that the end user sees.  But underneath is a DAG of views into the state of the workflow.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Then the part that spreadsheets don't have as much, I mean they do have this if you are willing to tango with PB scripts, but an input thing other than manipulating the cells directly.  Adding buttons and behaviors to initiate workflows.  That's something that we take on with hoplon and javelin too.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I think there's an interesting division between.  There's probably an official word for this, but I think of it as resident programs and applications that perform work.  The backend of our application, for example, the thing that runs on the server, it's the request response type of model.  It's not a resident program that's containing a bunch of state that can be inspected individually.</p>
+
+<p>A user interface, though, or an editor or something like that I think of as like a resident system in that there's all this state that's in there and the user might be looking at a lot of it at once.  With a request response like a database, say, you get all these requests coming in and you want everything to be lazy rather than eager.  In other words, I'm not going to – like in a database you have views, and views are not really tables, usually.  Usually there's some kind of like compiled query because you don't want to do the work of updating every view when a new row comes into the database because that would be very expensive.  Whereas with, like, a user interface or a resident type of program, you actually do want to do that work because you don't know what the user is looking at.</p>
+
+<p><strong>ALAN</strong>:     Right.  I think maybe the difference between them is the entry points or the things that you choose to make visible or not.  Like when you have a service that multiple users are going to be using, like your multi-tenant or multi-client, it's important that you don't expose all of the data to any one peer or client as opposed to in the JVM or Emacs where you have no idea which pieces of data that the program has accumulated that they're going to want to look at or not.  You make no effort to protect or hide data from people, at least in sane systems.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean I think for the two types of applications that you have, you have two different types of sort of stateflow models.  For a user interface where a lot of state needs to be accessible, you have a situation where you have a database that's updating the views as soon as new information comes in.  Meaning it's pushing it out.</p>
+
+<p>For example, well, I guess we could look at the other side now.  The other side is sort of on the backend like a database, say.  You don't actually want to do that.  If you have a million users and each user can see their own stuff in the database, every time a new piece of information comes in you don't want to update every view for every user.  Even if a piece of data might affect a bunch of users, you wait until they make a query.  I think that's kind of the separation.</p>
+
+<p>If you have a situation where you want to eagerly push out changes everywhere, which is, I think, what you want to do in a UI, then you could use something like javelin.  Whereas if you're on the other end where you want to resolve those things lazily, that's something, a place where core.async would be good because you're feeding data down a pipe, so that's where you want queues and things like that.</p>
+
+<p>But on the other end, in the UI, you don't really want a queue.  The thing needs to fan out and constraints need to be satisfied.  You have a bunch of constraints, so I think that's basically how we ended up with javelin was the need to not use queues in the front end because what we really needed was the spreadsheet.</p>
+
+<p><strong>CRAIG</strong>:     Let's dig down that a little bit because there's a couple things in there that I'd like to unpack.  What is it about queues that's inherently bad?  We do asynchronous things in the front end all the time, even in a reactive metaphor like javelin.  Certainly when we're talking off the box, right, that's inherently asynchronous.</p>
+
+<p>But even when I've written UIs, and I'm far from an expert, so I'm more than willing to believe that I'm doing something wrong, I do in fact employ queues.  I mean Web workers, I use those in my UI to get certain properties.  Maybe that's not quite what you're talking about, though.</p>
+
+<p><strong>MICHA</strong>:     No.</p>
+
+<p><strong>CRAIG</strong>:     I'm curious, though.</p>
+
+<p><strong>MICHA</strong>:     I don't mean to say that queues are bad because, of course, a queue is like one of the fundamental building blocks that we use to build applications.  But I think there are times when you need to push out changes and there's times when you want to pull changes.  I guess that's not – I'll give an example.  With a spreadsheet, for example, when you change a cell, it pushes updates to all the other cells, which are satisfying constraints.  All the formulas are kind of like a constraint solver.  It pushes out, all the formulas update, the state sort of atomically changes from one state to the next, and all of your charts update themselves.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     What that eliminates is the type dependency.  You don't care necessarily – like all the cells know when they need to update.  In fact, at the end of the day, it's as if they had all updated atomically in one instant because no cell can see any other cell other than in the latest state that it was in.  For example, if I have cells A and B that are input sells, and then I have some cell C, which contains the sum of A and B, C will never see A in an older state than B, say.</p>
+
+<p><strong>CRAIG</strong>:     Right, right.</p>
+
+<p><strong>MICHA</strong>:     I guess if I update – yeah, so each cell only sees the things that it depends on, the cells it depends on, after they've already updated, if they're going to update.</p>
+
+<p><strong>CRAIG</strong>:     It's really about atomicity and, of course, if you have a queue, you can't guarantee that, right?  You've gone from–</p>
+
+<p><strong>MICHA</strong>:     Right.  If you have three queues, how long do you wait until all the results are in before you act on it, say?</p>
+
+<p><strong>CRAIG</strong>:     Right.  Right, right, right.</p>
+
+<p><strong>MICHA</strong>:     Right?</p>
+
+<p><strong>CRAIG</strong>:     Okay.  Okay.</p>
+
+<p><strong>ALAN</strong>:     Yeah, I have experienced this.  Well, before Micha started working on javelin and caught the spreadsheet bug, I was actually at Relevance where I was working on a system that was an online video conferencing system.  The metaphor we picked for modeling state transitions in the UI, which I think it was CoffeeScript in a browser at the time, was the EventBus, which is kind of the classical pattern for modeling events in a UI.  I think that's when I sort of hit on this problem of suddenly time becomes important again in consuming – like a queue consumer is kind of like an infinite loop in the sense that it's a process that has its own lifecycle because it's consuming from this queue.  Suddenly it becomes important, you know, how close the messages are to each other, like flash messages for example, like places in this UI would put a message on a queue if they wanted to show the error connecting dialog.</p>
+
+<p>Now obviously we don't want to spam the user to fill up their screen with these error connecting dialogs.  If one exists already, then we shouldn't show a new one.  What that means is now we have a little accumulator in there, a stateful accumulator that says, "If there's a thing showing when I receive a message, re-enqueue this message to show up in 30 seconds," or whatever, which was less than ideal.  I mean granted I may have been just doing it wrong at the time, but it was definitely evident to me that there was this temporal, like once I admitted queues or, in this case, a bus, which I think they have the same properties as far as UIs go in that there was no implicit ordering of events, you need to bring the ordering yourself.</p>
+
+<p>You needed to do that by accumulating things in places and then have time out policies and stuff like that.  Instead of being a nice graph of dependencies, the state associated with the way the UI looks becomes a graph of accumulators and policies and retry policies.  It was ungainly.</p>
+
+<p><strong>CRAIG</strong>:     Okay.</p>
+
+<p><strong>MICHA</strong>:     A lot of the real strengths of queues is when you need to farm out work to independent, separate processes that don't necessarily know about each other.  You have workers, like a Web worker or whatever.  Things like that are great when you have some process that can be done by any anonymous worker, and you just need to make sure it gets done.  That's what's really great about queues.  Then you can get back pressure, and you can manage all these other little threads or processes or whatever.</p>
+
+<p>But with user interfaces, that's not the case a lot of times.  A lot of times, like the place that's showing you this flash message or whatever is a particular place.  It's not like any element can just pick up this job of showing an error.  It's like it has to be in that particular place.</p>
+
+<p><strong>ALAN</strong>:     Right.  It's not necessarily.  This is, I think, inherent in the problem of the UI is that the UI is a singleton thing.  The human being can only perceive so much stuff, and that stuff constitutes one single place per the application.  The place in the UI where the flash message shows, for the purposes of the user's visual field, that is a singleton place.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     It is a single place in the person's field of view where a thing may or may not appear.  That's just not appropriate.  Queues aren't appropriate there because they're applicable when, like Micha said, you have work that needs to get done, but you don't care when it's done.  With UIs, it's more important when it's done.</p>
+
+<p><strong>CRAIG</strong>:     True.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and also the progression of state needs to be – I think you need to think a lot about – that's mostly what I think about when I make a UI is like how to state progress.  And so it can progress either from – well, so the user interface, at any given time when you load the page, it'll be quiescent.  It will have loaded everything that it needs to initialize and then it waits for the user to interact with it, usually, unless there's some kind of connection with the backend that might do things.  The UI is at rest.  The only thing that will transition it to a new state is something from the outside world, from the environment, so either the user interacts with it or the backend or some interaction with, you know, your database or whatever.</p>
+
+<p>I think, when you have a system like that also, and all the elements that are on the screen, all the widgets, they're stateful as far as the user is concerned.  Those states are satisfying some constraint, meaning they have some relationship to the state that's in the front end.  Now the state might change, so in other words the user might do something and some interaction might happen with the backend.  Maybe the two of those, together, interact with each other.  Meaning the user says they want to create – they want to buy a shoe, and maybe the backend says there's no shoes available or something like that.  But that's when it becomes really useful to have formulas that have the dependency graph because that can allow you to not do extra work.  I guess the guarantees of javelin, we're kind of getting into what the guarantees are.</p>
+
+<p><strong>CRAIG</strong>:     That's cool.  Yeah.</p>
+
+<p><strong>ALAN</strong>:     Well, and I guess javelin, too, it's a ClojureScript library that you use from ClojureScript, and it gives you this spreadsheet like computing environment for building and arranging these state machines/spreadsheet-like constructs that are aligned with this philosophy that we're unveiling.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     We should go over the–</p>
+
+<p><strong>CRAIG</strong>:     Please.</p>
+
+<p><strong>MICHA</strong>:     –what are the constraints or the features of a spreadsheet.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, yeah.  Please, go ahead.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so your average spreadsheet, it's important to make a distinction between the spreadsheet that you have in mind right now, which is this grid of cells, and what we say when we talk about spreadsheet, which is like the underlying computation model.  A typical spreadsheet like Excel, it has a field, X and Y dimensions, and that's your namespace, more or less.  That's how you enter values and see values.</p>
+
+<p>Then there's the computing model underneath that, which is the relationship between these cells and the constraints that mediate the relationship between the cells.</p>
+
+<p><strong>CRAIG</strong>:     Right, which isn't rectangular even a little bit.</p>
+
+<p><strong>ALAN</strong>:     Right.  Right.  Yeah, it's sort of incidental that it's a rectangle.  I mean it could be a hypercube.  Whatever.</p>
+
+<p><strong>CRAIG</strong>:     Arguably it is if you consider tabs where you can have formulas on one tab, so it's not strictly rectangular, right?  It goes beyond that.  I think you can even pull in data from other sources.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Anyway, we're kind of going outside the useful bit.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I'll throw it back to you.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  No, but you're absolutely right.  As a computing environment, the average desktop spreadsheet, it takes on variables and namespaces.  It takes on dependency or propagation of new values throughout the thing.  The part that we talk about when we say spreadsheet is the part that propagates the value.</p>
+
+<p>Now, in ClojureScript, when you're using this javelin library, there's nothing grid-like about it.  Your values, your input cells are going to be named either locals or top level definitions, just like any other ClojureScript program.  And what javelin does is it gives you a way to connect those places in a way similar to the way that you connect cells in a spreadsheet.  So you can have the same expectations about what data will appear where when these inputs change.</p>
+
+<p>You're welcome to make a grid of these if you want.  It's pretty straightforward to make a spreadsheet when you have javelin, and probably even easier now that there's ClojureScript, and ClojureScript is pretty easily available.  You can very easily make a spreadsheet in ClojureScript, a ClojureScript spreadsheet.  We haven't.  I don't think we've done that.  I'm not sure anyone has done that, but that's because we already have awesome spreadsheets.</p>
+
+<p><strong>MICHA</strong>:     But, yeah, some of the things that are interesting about a spreadsheet is that first you have two kinds of cells.  There are input cells and formula cells.  Input cells are the ones that you edit.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     A formula cell is like in Excel.  You type equal and then you type a formula.  That formula is like an in – I can't think of this word.  It's really killing me.  Invariate?</p>
+
+<p><strong>ALAN</strong>:     Invariant?</p>
+
+<p><strong>MICHA</strong>:     Invariant.  Yes.  Thank you.</p>
+
+<p><strong>ALAN</strong>:     Yes, or a constraint.</p>
+
+<p><strong>MICHA</strong>:     Right.  Right, so this is like an invariant.  A formula is an invariant.  You specify that if you have a formula, so let's say you have two cells: A1 and B1 in Excel.  You're just going to type numbers into that.  Then you have cell C1, which is =A1+B1.  That says that cell will never be its value.  The value associated with that cell will never not equal the sum of the value in A plus B.  Additionally, there is a guarantee that the formula will update only once.  In other words, if you make one – when you change input cells, formulas will not update more than once or unnecessarily.</p>
+
+<p>If the value – if the things – if the cells that they depend on have not changed their values, no updating will occur, so work does not need to be done.  And if work does need to be done, it'll be performed only once.  This is pretty important because you can imagine sort of a naïve way to make a spreadsheet would be to, you know, you have your cells.  And whenever anything changes–kind of like how macro expansion works in Clojure–you keep evaluating all the formulas until they stop changing.</p>
+
+<p>Originally I had a simple thing that worked like this.  We kind of devised – that's called glitches in, like, spreadsheet parlance kind of – so glitch elimination is important because you have situations like we called it the pregnancy test, which was, say you have a form.  And the form has your sex, which could be male or female.  Then, if you're female, you could be pregnant or not.  Every time you click in this – and so this is in, like, a user interface in a form.  Any time you modify this form, it should send the current state of the form to the backend, but such that it is always valid.  Meaning, if you're male, you're never pregnant and so on.</p>
+
+<p>If you don't have glitch elimination, it's pretty much impossible to do this without building glitch elimination into your system because, suppose you're female and pregnant and you change your sex to male.  It has to know to uncheck the female part.  Sorry, the pregnant part.  With javelin, we make that a formula cell and stuff.</p>
+
+<p><strong>ALAN</strong>:     Cells together in javelin can constitute a type, like a ClojureScript def type.  But even cells in a normal spreadsheet, they have a contract, which is, every cell has a value at all times.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     And that maps up really well with the way Clojure works and Clojure's philosophy of state and time because, in Clojure, there's a rigorous separation of looking at something versus changing it.  Like every reference type in Clojure, you have the ability to de-reference it.  You can see its value at a point in time.</p>
+
+<p><strong>MICHA</strong>:     And to add a watch.</p>
+
+<p><strong>ALAN</strong>:     Right.  So you can – these reference types, atoms are the most popular, but there are agents, refs, various–</p>
+
+<p><strong>CRAIG</strong>:     Agents, vars.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Yeah, var.  Yeah, all of these things.  You can see their value and hold onto that value for the rest of the program.  You don't need to worry about what happens to the underlying container, the box.  And javelin cells work like that too.  Both the input cell and formula cell types support de-reference.  And this de-reference, because we do the propagation eagerly and in dependency order, the de-reference is going to give you a consistent view.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.  Yeah, so in working with javelin, it was actually one of the things that got me using hoplon for the little side project I've been using it for is that, you know, I'm a backend guy.  I don't really do the front end stuff very much, although I've been doing more of it recently.  Kind of it's always a question of when you roll up to a new library or framework, what do you need to know?</p>
+
+<p>For me, to a first approximation, the thing I needed to know in order to understand javelin, which is an important part of doing a hoplon application, was atoms and watches, which are very familiar concepts to me as a backend programmer.  Now, of course there's more, right?  You guys were talking about the fact that you can have chains of dependencies, and there is an atomicity guarantee.  But to a first order, it seemed very comfortable.  It's like, oh, there's a thing and I can look at it, and there is an API for changing its value, which is actually swap and reset.  Hey, that looks a lot like an atom, so that part was all very familiar.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I think the stuff that you were saying about the model makes a lot of sense.  I do want to make sure that we talk as well about hoplon because javelin is very cool, and I found it a very comfortable, familiar, easy to acquire way to model my programming, not without some onboarding, but it didn't take very long.  But, you know, it wasn't bad.  I think most people would roll up to it, so I'm curious then to talk more about – well, I don't want to cut you off.  If there's more interesting to say, we should say it.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  No, I see the way you want to go, and it's a good direction.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so javelin has nothing to do with the browser or the DOM or HTML, which is part of the reason I think that we feel like it's done as a library.  It occupies a part of the hoplon framework and our workflow in which it's done.  We're not going to add anything to it, and we're not going to deprecate anything.  It's done as a library.  Which also, if that was all there was, it would be useless because, like, how do you make a webpage with it?</p>
+
+<p><strong>CRAIG</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Well, there is no inherent way in doing that, so there is a linkage, conceptual and software, between javelin and the browser.  That is traditionally we call that hlisp, and there are library components of it that are in the hoplon boot task, but it is a set of conventions for working with the native DOM elements that allows you to use native DOM elements to provide views into your javelin spreadsheets.</p>
+
+<p>I don't know.  Does that seem like a good–?</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean hoplon originally, like in 2012, doing stuff in ClojureScript was a lot more difficult than it is now.  And so a lot of this stuff that is hoplon was to make that easier too.  Then when we made boot, we incorporated them into the boot tasks.</p>
+
+<p>Hoplon itself is a library, a ClojureScript library that you can use in any application.  It doesn't need boot or anything like that.  But the boot task does things like creating the actual HTML file in which you're going to run your JavaScript.  You know, pre-rendering stuff, which means you can run your application in PhantomJS to generate the HTML.  Stuff like that.</p>
+
+<p>There's hoplon the library and then there's the stuff that boot does, which is optional, but me myself, I find it useful.  I don't want to be hand coding HTML files any more, so my applications are kind of more like just JavaScript that I want to launch into somebody's browser.  The only way I can do that is if an HTML file is generated somehow.</p>
+
+<p>Hoplon itself, it's sort of meant to be a foundation for something more useful, to write something more useful on top of it.  It doesn't actually do very much at all.  It just allows you to wire up javelin cells to DOM elements.  You can think of DOM elements as, well, first of all in hoplon, all of the DOM elements that appear on the user's screen in the browser are created via JavaScript.  Meaning they're JavaScript objects first, and then they go into the DOM.  They're not HTML.  They're not DOM elements that are created from HTML.</p>
+
+<p>When you think about it that way, the goal of it is to provide a platform that you could hook up your application state, which is expressed as these cells, these formula cells, input cells, and so on, to widgets that you make by composing these DOM elements.  And so, like, if you think about a JavaScript, the JavaScript representation of a DOM element, you have properties and methods on them.  You can call set attribute and so on.</p>
+
+<p>My kind of intuitive view, the way I think about is attributes are like methods on the DOM element.  Kind of like a world line of this, of the method, so if you take like the class attribute of an element and you hook it up to a javelin cell that might contain different values over time, meaning the class might change over time, you could sort of consider that to be a method that's called every time the value in the cell changes.</p>
+
+<p><strong>ALAN</strong>:     It would be as if, say, you had the class string in an atom.  Then separately you created a DOM object.  Then you made a watch, an add watch with a function that set the new value on the thing every time it changed.</p>
+
+<p><strong>MICHA</strong>:     That's precisely what hoplon is actually doing.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     It just makes it easy for you to express it as attributes when you type your source code.</p>
+
+<p><strong>CRAIG</strong>:     Right.  In Alan's example the nice convenience is that you don't have to link up the cell or the atom and the attribute via some piece of code that runs.  You just say the value of this attribute is the javelin cell, and then the wiring happens.</p>
+
+<p><strong>ALAN</strong>:     Right.  Conceptually, you can think of attributes as continuous, basically.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     As opposed to one shot things that you have to set manually.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I think of it like a world line of a method or something.  You have this object that has a method, and it's going to be called with different values over time.</p>
+
+<p><strong>ALAN</strong>:     Right.  But you don't care about that plumbing, really.</p>
+
+<p><strong>MICHA</strong>:     Right.  The thing that represents the values, which will be used over time is the cell.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Yep.  Yep.</p>
+
+<p><strong>MICHA</strong>:     That's what – so in hoplon you have the hoplon element, these DOM elements.  They have attributes, which are like methods on the object, and they have children.  Children have a special relationship in the browser so elements can contain other elements, obviously.  And so the children can also change over time.  That's really it.  There's not much more.  Hoplon, what we wanted to do with it is we wanted to make a foundation that we could build UI kits on top of.</p>
+
+<p><strong>ALAN</strong>:     This comes back to the original motivation with the white labeling with the Fresh Diet.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     This was kind of – we've arrived at the problem we, well, set out to solve originally, which was how do we describe an application in terms of both its workflows and its UI in separate pieces such that we can modify one or the other without necessarily modifying the other.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and to be able to – so the goal, the end goal would be that you identify some widget that's going to be useful to you.  Say – let me think of – just take an input, like a text input.</p>
+
+<p><strong>ALAN</strong>:     Auto-completing.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     I actually have an example from a side project that I think might be what you're talking about, and you can tell me whether you think it's–</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     If you like, I can share and you can tell me whether you think this is what you're talking about.</p>
+
+<p><strong>MICHA</strong>:     Absolutely.</p>
+
+<p><strong>CRAIG</strong>:     I used hoplon to write a weather generator for my – my own hobby is flight sims.  I'm making weather for this game that I fly in.  It's random.  It has neat features.  You can control things about it.  It doesn't matter.</p>
+
+<p>I fly with other people online, and I would like the weather to be a surprise.  Right?  I don't want them to know that when we come back to the air base that they're going to have to land in the middle of a thunderstorm necessarily, right?  But at the same time, you know, we're interested in this experience where you can see what the weather is because, hey, they could stick their head out the window when they take off, right, and they kind of know.  And so I'd like to provide them with a weather forecast.</p>
+
+<p>I have the same data, like I had this model that I can manipulate.  I have a set of controls for doing that so I can step forward in time and say, okay, yep.  The storm is going to arrive at 3 o'clock.  That's about when we'll be landing.  But then I want to also give them that same exact data, like the whole model is parametric, and so everything is completely deterministic.  But I don't want them to be able to go past takeoff time because, if it were the real world, they would know what the weather was, but they wouldn't know what it's going to be.</p>
+
+<p><strong>MICHA</strong>:     Mm-hmm.</p>
+
+<p><strong>CRAIG</strong>:     And so it's the same data, the same computation, but it's a different view.  It has limitations.  It's not the same.  If you were looking at it without knowing anything about the internals, it's not the same application even though the underlying data is.  And not only data, but computation is identical.  Is that kind of what you guys are talking about?</p>
+
+<p><strong>MICHA</strong>:     Yeah, I think that's – well, what's interesting about that is that there's a separation of the presentation from the sort of state machine that describes the different things that get presented in the context of your widget, right?</p>
+
+<p><strong>CRAIG</strong>:     I didn't quite follow that.  Explain further, please.</p>
+
+<p><strong>MICHA</strong>:     Well, so you have a widget there that is going to display the weather for the user, but they won't be able to see the weather for the future, right?</p>
+
+<p><strong>CRAIG</strong>:     I've got two sets of users.  One is me, the weather designer.  I've got tons of controls where I can say it's 30% likely to rain.  It's like the winds are this, blah, blah, blah, blah.  Then I'm like, great.  I know the weather for all time, including the future.</p>
+
+<p>Then I want to be able to say, take that same data, some other user, and get a different view on the same information, but that's limited in terms of how they can interact with it.  They can't change things.  Maybe they can change a few things like where they are in time, but even there maybe not past a certain point that I specify.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I was just really wondering if that's kind of what you were getting at around saying, well, there's still a workflow.  There's still, when time goes from 2 o'clock to 3 o'clock, the following things change in the underlying. Like the data is the same, but the way I interact with that, what I can see, what I can interact with is different.</p>
+
+<p><strong>MICHA</strong>:     Yeah, that's actually a good example because I could imagine the situation when maybe you are going from your view to, like, the pilot view also or something like that.  And so you could be turning things on and off inside of your widget, like certain controls are only visible if you are in God mode versus pilot mode or something like that.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     And so you might design a widget that has those that exposes them as attributes.  You could have an external state machine that tells it which state it's in.  The presentation part, the widget, the thing that's in the DOM would be controlled maybe – you know, the different configurations of it are via attributes, just like in the normal DOM elements, you know.  You change the configuration of the built in DOM elements by adjusting the values of these attributes.</p>
+
+<p>The idea in hoplon was to expose the same exact interface.  You can make your own widget that exposes the same ways, means of controls, like these attributes and children, you know, that you could do the same thing on yours.  The components that you make are not different than the ones that come in the browser like, you know, text area or whatever.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I think your example is great from another perspective too, which is you have this underlying process, which in your case is parametric and very well defined.  But the magic to it, the purpose for its being is that not all of the users can see into all of it.  Not everybody has full fidelity.  Different kinds of users have different levels of access, kind of.</p>
+
+<p>I can imagine in your case, you have the God mode view and then you have the pilot view.  Let's say you have a widget for each of these, or maybe a set of javelin cell values that determine what certain widgets show or don't.  Like I'm imagining your God mode thing you have a slider from the past into the future by some number.  The pilot has a slider from the past to the present.  That's managed.  Whether or not the user can see the weather in the future depends on whether the God mode cell is true or false.</p>
+
+<p>But maybe the God mode cell is not really that.  Maybe it's named like the user level cell, and it can be one of God, you know keywords here, keyword "God," keyword "pilot," or maybe keyword "ECWACS," you know.  What are those planes with the big saucer?</p>
+
+<p><strong>MICHA</strong>:     Mm-hmm.</p>
+
+<p><strong>CRAIG</strong>:     The AWACS.</p>
+
+<p><strong>ALAN</strong>:     The AWACS.  The AWACS weather guy has more fidelity than the pilot, but not as much as God.  Maybe his maps are higher quality.</p>
+
+<p><strong>MICHA</strong>:     He's a lesser god.</p>
+
+<p><strong>ALAN</strong>:     Yes, a demigod.  But we find the exact same thing in our business applications that we build with this stuff, which is, there are all these different concerns, and they're usually oriented around the way the person is supposed to interact with the system, whether it's constraints based on the kind of user they are or constraints based on what the way that's most efficient for them to work with the system is.  Yeah, the separation of the widget behavior from the underlying model behavior is, I think, the way of building these things that gives you the most flexibility to do that.  Especially, I mean, the key thing is being able to add, remove, and modify these perspectives over time.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  The really key thing is that, well, I think, and we've pretty much achieved this with the application that we have at work is that there should be sort of two completely separate phases of development.  Not even phases because they happen at the same time, but you have widgets that you're working on, so you develop these widgets.  Then your application is actually just an assembly of widgets, which is different than – I mean it becomes an application.  But by assembly I mean you only use composition, essentially, to construct it.</p>
+
+<p><strong>ALAN</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     So you make all these components, and the way you compose them – the way you build an application from all of these separate components is exclusively composition.  I mean obviously there's going to be, like, a few little conditionals here and there, but if you were to look at the source for, you know, the Adzerk UI, all of the views are simple composition of these components.  The big advantage there is, like, if you consider for example – like we did a lot of work around forms and how to handle forms.  By that I mean things that talk to the backend and also interact with the user.  We develop a really – I think it's a really good system where we have a state machine that describes talking to the backend.  And so we have this RPC framework that we use.</p>
+
+<p><strong>ALAN</strong>:     Castra.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     The library, ClojureScript, Clojure.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and so the state machine on the front end is an object.  It's a def record, and there are methods on this object that you can call, which might cause it to change state.  It might not.  But you can call them to command a change, and it exposes its state as javelin cells.</p>
+
+<p>If you think about, like, you have, say, a login form is pretty simple.  You have username and password.  There will be – you construct a form machine for that form and maybe tell it the schema so it knows you have these two fields.  But then it'll expose to you an error cell for the username and an error cell for the password.  And it'll expose the data cell for the user name and the data cell for the password because there might be some default there or you might have already edited, whatever.</p>
+
+<p>The machine has this.  And you can wire those cells up to DOM elements on one end, and whenever you change them – so the way we like to do it – there are many different ways to make the state machine, but the one that we settled on is you can edit a form as much as you want as a user.  When you first click submit, that's when validation happens.  Then thereafter, as you type, the validation is done as you type.  The validation is actually all done on the backend to simplify, to simplify our whole model.  So every time you type, it's validating on the backend.  And the error cells are being populated.</p>
+
+<p>The error cells, or there's also like a general state for the state machine that is exposed to the cell.  But the benefit here is imagine I'm actually making the widget now for this form.  I can have a widget, a sub-widget that displays an error, right?  I could have a widget that accepts input from the user.  These things are completely decoupled from the state machine because they're going through this common interface now of attributes.  So for example I might have–</p>
+
+<p><strong>ALAN</strong>:     And cells.</p>
+
+<p><strong>MICHA</strong>:     Right, and cells.  So I might have, like – so we in fact do have this.  We have our own text input, which does certain things and displays itself in certain ways.  Whatever.  So you do text input and then colon value, which is the way you set attributes, and you give it the data cell from the form machine.  Now whenever you type in there, the form machine is getting that updated data because it also, you know, knows about this cell.  Likewise, the error gets passed as an attribute to the little widget that we make that displays the errors.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     And you know, I think, if people listening to this are coming from a JavaScript background, they'll recognize some of the affordances of this setup and the idea of a promise, which is a kind of trending JavaScript idea.  But a promise, if you're not familiar, it's basically a value that you can get or an object that you can get that will contain a value.  Clojure has them too, incidentally.  And a value can be delivered to the promise once.  When the value is delivered, there's an API for a function being called.  It's kind of like a one shot atom.  Where a promise is a one shot atom, a cell is like a continuous promise, again because it doesn't just fire once when the value changes.  Whatever thing is looking at it, you can use stuff in javelin to make happen whenever the value changes, forever.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     So–</p>
+
+<p><strong>MICHA</strong>:     Well, the difference there, though, is that javelin does maintain the dependency graph.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     So like if you have a web of promises–</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     –that's where you get into trouble.</p>
+
+<p><strong>ALAN</strong>:     Right, right.  Yeah, unless you're very diligent.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, and so like I said, I've built applications, and this makes sense to me.  In fact, it was kind of the first UI framework that I tried that I did really connect with.  And I mean, to be fair, I didn't give all of the others as much of a run as I've now given hoplon.  But still–</p>
+
+<p><strong>ALAN</strong>:     Oh, I know that you were a huge spreadsheet fan originally, too, right?</p>
+
+<p><strong>CRAIG</strong>:     I do love spreadsheets, actually.</p>
+
+<p><strong>ALAN</strong>:     I imagine we suckered you in a little with that.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  No, there's definitely – I am a huge fan of spreadsheets.  However, there's an xkcd where there's like an amusing graph of complexity and, at the left end, is a two line bash script, and at the right end is some spreadsheet that's been being maintained for 20 years to maintain the scheduling on some church in Georgia, right?  That's the joke in the slide in the comic.  I'll have to post the link to that.</p>
+
+<p>The point, though, is that there exists some extremely sophisticated spreadsheets in the universe.  I think something that some of our audience will have been exposed to is this common task, which is, well, I've made a spreadsheet.  Now the spreadsheet is inadequate, and so now I have to turn it into a "real program."</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I guess what I'm trying to ask is I could kind of imagine that the cell model where you have this potentially very wide graph of interconnected bits of computation to have a sort of complexity ceiling.  Now I've only used hoplon to solve smallish problems.  I mean I think the thing that I did actually is nontrivial.  The things that I've done are nontrivial.</p>
+
+<p>But, you know, they're small compared to anything that I would have done if I were working on it day in and day out like you have been doing with your work at Adzerk.  Have you experienced limitations of the cell model?  If I squint, I could convince myself that you would fall off a complexity cliff eventually there.  Has that been your experience?</p>
+
+<p><strong>ALAN</strong>:     I guess I would say there are two kinds of ceilings.  One is easily navigable and the other is, I guess, sort of open – open, and we could talk about this thing called UI.  But cells definitely have straightforward, technical limitations just because of the way the browser works.  The foremost of these is that they're not automatically garbage collected by the JavaScript runtime because of the way we maintain the dependency graph and because JavaScript doesn't have a weak reference and probably never will for security reasons.  It's possible using cells naïvely, and people do this regularly, to have memory leaks.  And so there's a certain diligence that comes with working with cells, and I think it's easy to learn.  It's, in practice, not a huge problem.  But it's a definite hard technical limitation.  You can easily drive yourself crazy trying to if you sort of have the wrong mindset.  You can sort of correct the way that you're thinking about using cells and easily get yourself out of this.</p>
+
+<p>The other limitation, which is kind of the open problem, is cells presume so little about – cells and hoplon presume so little about how you're going to build your application.  Micha talked about this a little earlier when he said that, you know, our goal is to get you to the place where you can start to solve the problem.  We don't presume to solve the problem completely for you at all.  I think how you approach that is going to be application dependent, and whether or not you reached the complexity ceiling is kind of on you.</p>
+
+<p>I don't know.  Maybe this is a good time to talk about the UI library.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean–</p>
+
+<p><strong>CRAIG</strong>:     I would love to hear about that, actually.</p>
+
+<p><strong>ALAN</strong>:     Okay, or maybe Micha.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean I don't actually see – like, we have really big hoplon applications now.  Big meaning like many, many different screens and a lot of complex workflows and back-ends.  You know, so the one that we're building at Adzerk is a pretty complex application and complex workflows.  We really haven't – like, I don't really see that we're even approaching any kind of – I don't see a complexity growing at all.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     The reason is because, just like in a spreadsheet – like, the reason why spreadsheets get unmanageable, I think, is mostly because, like, the names.  In other words being in the grid with A1 and B7 and so on, like that's okay if it's small.  But, you know, if you're making a bigger – if you're making an application with spreadsheets, you kind of want to have names for things.</p>
+
+<p><strong>ALAN</strong>:     Right, and you can't have anonymous cells in a spreadsheet, of course.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     You can't make self-contained machinery.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Everything is global.</p>
+
+<p><strong>MICHA</strong>:     Yeah, so this isn't something you run into with javelin.  Also, like with javelin, the formulas that you do have end up being pretty small.  If you see a formula starting to get large, you just break it up into smaller ones, just like you would do in a normal spreadsheet.  And I think that has – I mean, for me anyway, it just happens naturally that most of the formulas I have are very small, and they all just kind of mesh together.  And because of the glitch elimination, it's not like – like, we don't even really have any debugging tools for javelin.  You know?  There's no – like Alan, I know, made the graph view of it.  We keep losing it and so on.  I just never really found it necessary.</p>
+
+<p><strong>ALAN</strong>:     Well, see, I think that can still be a thing.  I think that could be a thing.  Some of the best criticism we've gotten about hoplon is from Daniel Higginbotham, a great friend of mine, awesome guy who worked at Adzerk part time on this hoplon system.  He did point out that, you know, figuring out what's going on is less than easy if you're the people who made it.  I think we can improve there, but we've gotten pretty far without having that.</p>
+
+<p>What I imagine, in my copious free time, doing at some point is making a layer or an extension for Chrome that gives you a visual graph representation of the cells.  Then you can click on the cells and see the source code for the cell or its value.  I think that would be awesome.  It's attainable now because we can put metadata on vars in ClojureScript.  I think that's just a matter of time.</p>
+
+<p>To Micha's point, it's a conceptually simple model.  And Micha mentioned that you can split up a big cell into smaller cells, and you can do that because of our glitch elimination, because of the consistency properties of the model.  You can basically, by rote, break a cell into a set of smaller cells, and you don't have to reason again about the states of these cells.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  When I need to debug something, I just make a cell that has a print def in it that prints out the value of a cell, and I very quickly – I can pretty much bisect any weird javelin issue, I mean, and because the types of issues that you might have are actually computing problems rather than timing issues.  You know what I mean?</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     They're not likely to be race conditions like you would have if you were using a bunch of promises.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     Like a web of promises.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     Right, so these are all, like, you're just getting the wrong value in some cell.  So tracking down how that value arrived there is way simpler than saying, like, is it getting the wrong value because things happened in the wrong order?</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     That's the kind of thing that's, like, time consuming.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, absolutely.</p>
+
+<p><strong>MICHA</strong>:     For the next step, there's this thing called hoplon UI.  Jessie has been working on it.   He's been doing a ton of work on it.  His goal there is to make the next level foundation, which provides basically a sane and well factored platform for building user interfaces as opposed to, like, documents.</p>
+
+<p><strong>ALAN</strong>:     Basically a new browser.  He's building – it's basically a browser API on top of javelin and the conventions in hoplon that we've established.  Like where today if you take the stock hoplon stuff and you make an application, you're interacting more or less with stock CSS stuff, stock JavaScript script things, DOM things, which is great because that means there are really no surprises.  You can stack overflow, search for things.</p>
+
+<p><strong>CRAIG</strong>:     Yes.  I've done so much of that.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, so it's all the native stuff, so it's Googleable.  But you're not really escaping the inherent complexity of the browser environment by doing that.  You're choosing to live in it, for better or worse.</p>
+
+<p>The idea with UI, as I understand it, is Jessie has been using hoplon for years, almost as long as we have, and built a series of applications, and identified in his own work patterns and practices.  He has put a lot of effort into codifying those into this library UI, which is a higher level starting point that doesn't make you give up too much about being in the browser, if anything.  So the fidelity is still there, but the complexity is reduced, which is – I mean that's a big value proposition.  But I think it's really impressive work.  Micha probably knows more about how it works and stuff than I do.</p>
+
+<p><strong>CRAIG</strong>:     Okay.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean, like an interesting thing that you can do with hoplon is, instead of using CSS in CSS style sheets or, you know, style tags, whatever, you can manipulate attributes from cells to set the properties directly.</p>
+
+<p><strong>CRAIG</strong>:     Yes.  That's actually super interesting that you can do stuff with that that you really can't do easily any other way.</p>
+
+<p><strong>MICHA</strong>:     Right, so like even SCSS or LESS or Sass, those things are computing CSS statically and emitting a CSS file.  But with hoplon, you can have a javelin cell that represents the styles for your element that updates via ClojureScript at runtime.  Meaning, constantly it's a first class.  It gives you first class access.  What Jessie has done is, on top of that, he's using that to rebuild.  So he's had experience doing Flex and all kinds of action script stuff.</p>
+
+<p><strong>ALAN</strong>:     AIR?  Is that one of the things?</p>
+
+<p><strong>MICHA</strong>:     Yeah.  He's done like a ton of basically all the different ways you can make user interfaces.  From that he's sort of collected a core set of functionality.  One of the main things is that, in the DOM, you have documents and user interfaces.  The two are not really very well separated.  There's a lot of concerns for, like, making a newspaper that are conflicting with concerns for making–</p>
+
+<p><strong>ALAN</strong>:     Gmail.</p>
+
+<p><strong>MICHA</strong>:     Gmail.  Exactly.  And so that's really kind of what he's attacking.  He's attacking the user interface side.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>ALAN</strong>:     Another example of a simplification he made, which is one of those, like, makes total sense in retrospect things, and it's just we're constantly fighting with since we started working with JavaScript seriously is the fact that there are so many different kinds of elements in HTML.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Like &lt;div&gt;, &lt;p&gt;.  Now there's &lt;section&gt;, &lt;header&gt;.  These are the concerns of the newspaper imposing themselves on the concerns of the people who make things like Gmail in 2016.  It's insane.  And they all have different default styling attributes and behaviors and different flow properties, have different implications on the positioning model, and so what sold me on the UI concept was he just has a single kind of thing, the LM, ELEM function.  It's a general purpose object that can represent a piece of the user interface.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>ALAN</strong>:     You can put them inside each other.  They all have the same number and kind of attributes.  They all have the same positioning and style, default style properties.  Yeah, that's just an example of the….</p>
+
+<p><strong>MICHA</strong>:     Yeah, and some of the stuff that – so it's also a low level library in that it doesn't necessarily give you the components that you will actually use to build an application.  It provides the underlying primitive that you need to build a user interface.  And so the kinds of things that it does is make an element that fills the screen and put inside of it children who fill its parent, who fill their parent, but in a certain way.  Meaning like the middle one should be 10%, the one on the left should be 20% of the width, and the one on the right should just fill the rest of it.  Or you might have the one on the right actually contains two others that themselves are each 50% of the remainder.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     Things like that, so it's essentially – you know, it's kind of ParEdit, but there's one type.  So there's the LM, but there are also special form.  The different form elements, like an input box, things like that, those need to be special cases just because of all the concerns of–</p>
+
+<p><strong>CRAIG</strong>:     Sure.</p>
+
+<p><strong>MICHA</strong>:     –user interaction like when the persons have completes and all that stuff.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     So you want those to be – a lot of times the browser, like, you need to choose a particular element.  You can't make your own.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     But–</p>
+
+<p><strong>ALAN</strong>:     But he investigated doing that.  I mean I remember him talking about his early work where he thought, you know, what if we do the browser visually from first principles?  Why can't I just use SVGs for everything?</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     You know, whatever.</p>
+
+<p><strong>CRAIG</strong>:     It's interesting you say that.  I was thinking about this, and I would say the things that I've been gravitating towards as I've been building my applications are div, SVG, and flexbox, which actually sounds like a poor man's version of what you're talking about.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Yep.  That's exactly what Jessie did as well.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so just do that for five years–</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     –and you'll have UI.</p>
+
+<p><strong>CRAIG</strong>:     Let me get started.  I gotta go.</p>
+
+<p><strong>MICHA</strong>:     Yeah, yeah.  He did a full–</p>
+
+<p><strong>ALAN</strong>:     You're on the bat, yeah.</p>
+
+<p><strong>MICHA</strong>:     He has a lot of interesting stuff to say about flexbox.  I remember when he was like – yeah, he made everything out of divs for a while.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     I mean designers frequently do the same thing.  I mean for a long time a hallmark of any serious, large, single page app was the reset.css.  It's like, okay, let's turn off everything in the browser so we have a place to start with that's predictable.</p>
+
+<p><strong>MICHA</strong>:     Yep.  So what's interesting about UI is that this LM, this generic component is actually three – it's constructed from three divs.  There's like an outer one, a middle one, and an inner one.  Each one of them has its own role to play because of the way padding and margin and width and so on work in the browser.  He realized that you need three of them in order to get a consistent – in order to be able to consistently–</p>
+
+<p><strong>ALAN</strong>:     And to satisfy every aspect of the–</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     –positioning and styling model that he wanted to support, which is his view of how you should do it.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     Right, and so you would think that you'd end up with like a ton of three times as many components in your application.  But in fact, I think we're finding that there are way fewer elements compared to, say, a bootstrap.  You know, like bootstrap, the Twitter bootstrap is one way that you can – you know these CSS frameworks–</p>
+
+<p><strong>CRAIG</strong>:     Sure.</p>
+
+<p><strong>MICHA</strong>:     –that are sort of trying to accomplish the same thing, give you a kit, a UI kit that you can use to construct your application from.  But they actually end up with, like, a lot more elements because kind of the only way they can fix things is by adding more structure because I think, fundamentally, like the LM that Jessie has developed is a really good, fundamental unit that's worked out at a low level.</p>
+
+<p><strong>ALAN</strong>:     It's the ultimate div.</p>
+
+<p><strong>MICHA</strong>:     Right, so, like, in order to fix some weird padding issue in a bootstrap thing, you'd have to add more wrappers, you know, like maybe a clear div, whatever.</p>
+
+<p><strong>CRAIG</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     You're like adding more and more stuff.  Then that compounds itself when you compose those with other and so on.  It's really very interesting.  I think that we're finally reaching an age, like in web, you know, the way people use the web that a lot of business stakeholders are not going to – they don't care about, like, inventing some new user interface concept.  We've already figured out how to interact with the user to get information and give information to them.  What's really important, I think, to people now is the workflow.  In other words, if somebody comes onto my application, they're like a business user and they want to actually get something done and their time is precious, they don't care if it's all just gray.  You know?  Nobody cares what it looks like any more.  Nobody is going to be impressed with, like, some fancy drop shadow or something.  They want to know that you can get in, do their work reliably, and get out.</p>
+
+<p><strong>ALAN</strong>:     Well, that's the big difference between these.  This is kind of the dual, the two faces of the web.  And they're always at odds because I don't think people recognize them as totally different concerns.  The newspaper, like are you going to make a killer above the fold, catch people's eye brochure site, or are you going to make an application that people are going to live in for eight hours a day?  Within the first 30 minutes of serious use, they're not going to even notice what the colors of the things are.  And the primary concern is usability, not necessarily flashiness.</p>
+
+<p>Sorry to cut in.  I just–</p>
+
+<p><strong>MICHA</strong>:     Yeah, totally.</p>
+
+<p><strong>ALAN</strong>:     But, yeah, that's kind of – like in the world that we seem to live in, building large sites with JavaScript, we're definitely on the user experience side, not the new media or design side.  Granted there is still some give and take there, but for the most part people seem to be interested in what Micha said: the workflow, like, is this an efficient place for someone to live and work in all day long, like one does in Gmail?</p>
+
+<p><strong>MICHA</strong>:     Yeah, so I can totally imagine something built on hoplon UI, which implements all of the – like I'm pretty sure that we can now enumerate all of the types of widgets we're going to need to make business applications.  And we can make, you know, instances of them, and we can also make, you know, sort of a zoo of state machines that can be composed to form the really responsive workflows that you need, the really efficient workflows.  In other words, the workflows that help the user accomplish their task more directly.</p>
+
+<p><strong>CRAIG</strong>:     Well, you guys just blew my mind.  I definitely have to check out hoplon UI.  And, you know–</p>
+
+<p><strong>ALAN</strong>:     Oh, but an important caveat.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, please.</p>
+
+<p><strong>ALAN</strong>:     Jessie says we shouldn't use it yet.</p>
+
+<p><strong>CRAIG</strong>:     Okay.  Cool.</p>
+
+<p><strong>ALAN</strong>:     But go ahead and use it.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  Yeah, everybody has been using it.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     And he has, like, 10,000 warnings.</p>
+
+<p><strong>ALAN</strong>:     Yeah, the Read Me is just warning after warning, you know, this is unstable.  Don't use it.  But of course there are businesses using it now, so.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, well, I could kind of imagine that I've got completely broken, 10% versions of what he's already doing, and so his 90% semi-broken version might be a vast improvement for what I'm trying to do.</p>
+
+<p><strong>ALAN</strong>:     Well, in my case I used it as a reference or a Rosetta Stone to figure out how to do a CSS thing.  He's got the distilled knowledge in there, so there was some CSS3 feature I needed to use on some side project recently, and I was able to figure out how to do it from his code, so it's useful there too.</p>
+
+<p><strong>CRAIG</strong>:     Well, guys, I don't want to cut off the conversation because I think – in fact, I know we could keep going, and I for one would be sitting here fascinated, but I think there may be people in our audience that need to use the restroom.</p>
+
+<p><strong>ALAN</strong>:     Okay.  Well, they can wait for just one more little point I want to make.</p>
+
+<p><strong>CRAIG</strong>:     Absolutely.  Absolutely.</p>
+
+<p><strong>ALAN</strong>:     Which is, another hoplon community guy, Thomas Herman, he gave a screencast, which I'm really – I feel bad that we didn't record because it was incredible.  But he demonstrated the power of working entirely in code instead of trying to straddle document and code in terms of making an application.  He's a heavy Cursive user.  Colin Fleming, another Clojure community superstar, has this tool: Cursive.  It's a great Clojure and ClojureScript environment for IntelliJ.</p>
+
+<p>I don't use it personally, but I have a lot of friends that do and they love it.  And it turns out that when everything in your application is ClojureScript code, then you can start to use your ClojureScript IDE as a design tool.</p>
+
+<p><strong>CRAIG</strong>:     Mmm.</p>
+
+<p><strong>ALAN</strong>:     Thomas Herman is building a site using UI and, in his demo, screencast, he like hovered over the attributes in one of these LM things, and the Cursive tool tip popped up with all the color values that it could take at that place in the code because this was, you know, code inference that incidentally was style inference because all the style is happening in code.  And, you know, he was defining sets of colors and defining maps of class names to colors that Cursive was smart enough to track down and show in the editor, which seemed like a quick little peek into the future of the design tools.</p>
+
+<p><strong>CRAIG</strong>:     Oh, yeah.  I mean I know this is only a corner of what you're talking about, but I totally want now to go back and put into my little apps that CSS code because the means of abstraction there are garbage.  And I'm not using Less or  Sass, right, but it's just terrible, right?  You have to say the same thing six times, and it's static, and blah, blah, blah.  And so I think even just that little piece of what you're talking about, to me, looking at it as a front end newb, I'm like, man, that seems like an obvious win.  Why don't we have that normally?</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, and you know, I guess I wouldn't go so far as to say that Less and Sass are bad.</p>
+
+<p><strong>CRAIG</strong>:     No.  Sorry.  That's not what I was saying.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  No, no.</p>
+
+<p><strong>CRAIG</strong>:     I was saying I'm not using them, but CSS itself lacks abstraction.</p>
+
+<p><strong>ALAN</strong>:     Right.  They're great for brochure sites.  They're great for designers who are making media.  But for programmers, not so good.</p>
+
+<p><strong>CRAIG</strong>:     I see what you're saying now.  Okay.  Yeah, I gotcha.  Yeah.</p>
+
+<p><strong>ALAN</strong>:     But, yeah.  Okay.  I'm done with my thing.</p>
+
+<p><strong>CRAIG</strong>:     Cool.</p>
+
+<p><strong>ALAN</strong>:     You may go to the bathroom.</p>
+
+<p><strong>CRAIG</strong>:     Yes.  It is a podcast.  There's a pause button.</p>
+
+<p><strong>ALAN</strong>:     That's true.</p>
+
+<p><strong>CRAIG</strong>:     Anyway, yeah.</p>
+
+<p><strong>ALAN</strong>:     It didn't occur to me.</p>
+
+<p><strong>CRAIG</strong>:     No, but I do think it probably would make sense to wind down.</p>
+
+<p><strong>MICHA</strong>:     You can just hit mute.</p>
+
+<p><strong>CRAIG</strong>:     There you go.</p>
+
+<p><strong>MICHA</strong>:     You'll be fine.</p>
+
+<p><strong>CRAIG</strong>:     Mute my part.  Mute my part.  I'm not saying anything interesting.  But I do want to kind of bring it to a close here, and I want to make sure that we have – I mean, Alan, obviously you said you wanted one more thing, and that thing was very worth hearing.  I'd like to make sure we give Micha the same opportunity.  Micha, is there anything else that you think we should touch on before we wind down to the final question?</p>
+
+<p><strong>MICHA</strong>:     No, I think we're good.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Yeah, this was awesome, guys.  Yeah, I really enjoyed our last conversation.  And, as I was coming to this one today, I'm like, okay, cool.  We talked about boot.  We'll talk about javelin and hoplon.  That'll be good.  That'll be good.  Clearly there is a lot to talk about here, a lot of really interesting, really important stuff to say, so much so that I will feel comfortable in saying that we will have you back on again.</p>
+
+<p>I don't think we'll do a third part to the show, but at some point in the future, the not too distant future, we'll have you back on.  It'd certainly be great to hear more about what's happening in the hoplon, boot, javelin, Adzerk, Alan, Micha universe.  Always good stuff happening there.</p>
+
+<p>But I do of course have one more question for Micha, which is, we'd like to close the show with a piece of advice.  I'll go ahead and say that use hoplon is now obvious.  Maybe that was your piece of advice, or at least try it, I suppose, would be the better way to put that.  But I'm imagining you have something else in mind.  What advice would you like to share with our audience today, Micha?</p>
+
+<p><strong>MICHA</strong>:     Can it be like a little pro tip kind of thing?</p>
+
+<p><strong>CRAIG</strong>:     Literally anything you like.</p>
+
+<p><strong>MICHA</strong>:     Oh, well, I really enjoy – I have a paintbrush in my bag, and I use it to clean off my monitor and my keyboard constantly.  Not obsessively, but just whenever there is stuff on my keyboard, and I really enjoy it.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.  So it'll get, like, between the keys, all the crumbs and everything that wind up in there or whatever?</p>
+
+<p><strong>MICHA</strong>:     Totally!</p>
+
+<p><strong>CRAIG</strong>:     Huh.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Well, at one point you compared yourself to an umpire.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Kind of a similar habit.</p>
+
+<p><strong>MICHA</strong>:     Yeah, sweeping off the plate, getting ready to go.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     And I only mention it because now there's like three paint brushes around the office or something.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     Generally, people enjoy it, so maybe, you know–</p>
+
+<p><strong>ALAN</strong>:     Yeah, everyone seems to crack their knuckles.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Pull out their paintbrush.  Dust off their screen and keyboard.  And then–</p>
+
+<p><strong>CRAIG</strong>:     Well, I have to say I will take that one to heart because I have been known to be on the phone with somebody and to kind of flip my keyboard over and bang it on the desk.  As a result, like, drop it on the floor and hang up a call.  And so I think the paintbrush is a much, much better way to handle that.  I like that a lot.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Elegant.</p>
+
+<p><strong>CRAIG</strong>:     All right.  Well, look, guys.  Thanks a ton for coming back on.  I'm actually really psyched that we were able to do this so soon, at least in podcast time, after the last show.  I think they complement each other really, really well, and I've been really into your tech.  I said last show, but I'll say it again.  Thanks for making this stuff.  It's really cool, and it's made me feel incredibly productive in the browser space that I have avoided for, like, since 1991 when I first saw a browser, so thanks a lot for both that and for coming on the show to talk to us about it today.</p>
+
+<p><strong>MICHA</strong>:     Sure.  Thank you.</p>
+
+<p><strong>ALAN</strong>:     And I said this, I think, the last time we talked about hoplon, but we have a really small, really helpful community, mostly in Slack, in the Clojurian Slack.  If you find yourself toying with this stuff and are stymied or just are curious to see what other people are doing, feel free to join us.  We're always happy to help and talk about what we're up to.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.  Good tip.  All right, guys.  We will call it an episode.  Thanks so much for being on.  This has been The Cognicast.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     You have been listening to The Cognicast.  The Cognicast is a production of Cognitect, Inc.  Cognitect are the makers of Datomic, and we provide consulting services around it, Clojure, and a host of other technologies to businesses ranging from the smallest startups to the Fortune 50.  You can find us on the Web at cognitect.com and on Twitter, @Cognitect.  You can subscribe to The Cognicast, listen to past episodes, and view cover art, show notes, and episode transcripts at our home on the Web, cognitect.com/podcast.  You can contact the show by tweeting @Cognicast or by emailing us at podcast@cognitect.com.</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Our guests today were Alan Dipert, on Twitter, @AlanDipert, and Micha Niskin, on Twitter, @MichaNiskin.  Episode cover art is by Michael Parenteau, audio production by Russ Olsen and Daemian Mack.  The Cognicast is produced by Kim Foster.  Our theme music is Thumbs Up (for Rock N' Roll) by Kill the Noise with Feed Me.  I'm your host, Craig Andera.  Thanks for listening.
+</code></pre></div></div>
+
+
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+              
+            
+          </div>
+          
+<div class="related">
+    
+  <span class="classifier">
+    <span class="content-cell related-title">
+    
+      <p>related</p>
+    
+    </span>
+    <span class="content-cell"><p class="recent-title">recent</p></span>
+  </span>
+  <div class="links left">
+    
+    
+     
+    <a href="/cognicast/162">
+      Craig Andera - Cognicast Episode 162<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/157">
+      Ed Wible and Justin Gehtland - Cognicast Episode 157...<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/124">
+      Mike Drogalis - Cognicast Episode 124<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/128">
+      Naoko Higashide - Cognicast Episode 128<span class="dash">—</span>
+    </a>
+     
+    <a href="/cognicast/166">
+      Mariel Pettee - Cognicast Episode 166<span class="dash">—</span>
+    </a>
+    
+    
+  </div>
+  <div class="links right">
+    
+     
+    <a href="/cognicast/172">
+      <span class="dash">—</span>Janet A Carr - Cognicast Episode 172
+    </a>
+     
+    <a href="/cognicast/171">
+      <span class="dash">—</span>Howard Lewis Ship - Cognicast Episode 171
+    </a>
+     
+    <a href="/cognicast/170">
+      <span class="dash">—</span>Michiel Borkent - Cognicast Episode 170
+    </a>
+     
+    <a href="/cognicast/169">
+      <span class="dash">—</span>Ed, Justin and Lindsey - Cognicast Episode 169
+    </a>
+     
+    <a href="/cognicast/168">
+      <span class="dash">—</span>Wilker Lucio - Cognicast Episode 168
+    </a>
+    
+  </div>
+</div>
+</div>
+
+          <div id="post-sidebar">
+
+            <div id="post-sidebar-container">
+              <!-- <div class="post-search right-block"></div> -->
+              <div class="post-email right-block">
+                <a href="/contact.html">Get In Touch</a>
+              </div>
+              <div class="post-authors right-block">
+                <ul>
+                  
+                  <li>
+                    <h2><a href="/authors/AlessandraSierra.html">Alessandra Sierra</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AlexMiller.html">Alex Miller</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/CarinMeier.html">Carin Meier</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DavidChelimsky.html">David Chelimsky</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DavidNolen.html">David Nolen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/GhadiShayban.html">Ghadi Shayban</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JebBeich.html">Jeb Beich</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JustinGehtland.html">Justin Gehtland</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/LynnGrogan.html">Lynn Grogan</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MarcPhillips.html">Marc Phillips</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MichaelNygard.html">Michael Nygard</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/NaokoHigashide.html">Naoko Higashide</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/PauldeGrandis.html">Paul de Grandis</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RichHickey.html">Rich Hickey</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RussOlsen.html">Russ Olsen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/StuartHalloway.html">Stuart Halloway</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/TimBaldridge.html">Tim Baldridge</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AaronBedra.html">Aaron Bedra</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ChrisRedinger.html">Chris Redinger</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/CraigAndera.html">Craig Andera</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/DonMullen.html">Don Mullen</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/GlennVanderburg.html">Glenn Vanderburg</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JaredPace.html">Jared Pace</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JasonRudolph.html">Jason Rudolph</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JonDistad.html">Jon Distad</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/LarryKarnowski.html">Larry Karnowski</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MichaelParenteau.html">Michael Parenteau</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/MunessAlrubaie.html">Muness Alrubaie</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RobSanheim.html">Rob Sanheim</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/SamUmbach.html">Sam Umbach</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/KimFoster.html">Kim Foster</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JaretBinford.html">Jaret Binford</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JoeSmith.html">Joe Smith</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ClintonDreisbach.html">Clinton Dreisbach</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/TimEwald.html">Tim Ewald</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/RobertRandolph.html">Robert Randolph</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/AlexRedington.html">Alex Redington</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/JoeLane.html">Joe Lane</a></h2>
+                  </li>
+                  
+                  <li>
+                    <h2><a href="/authors/ChristianRomney.html">Christian Romney</a></h2>
+                  </li>
+                  
+                </ul>
+              </div>
+            </div>
+          </div>
+        </div>
+    </section>
+  </div>
+  <div class="footer left">
+  <div class="w-container">
+    <ul class="menu-footer-menu">
+      <li>
+        <a class="footer-head" aria-current="page">Nu International</a>
+        <ul class="sub-menu">
+          <li><a href="https://international.nubank.com.br/about" target="_blank">About Nu <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://international.nubank.com.br/careers" target="_blank">Careers <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://international.nubank.com.br/newsroom" target="_blank">Newsroom <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://www.investidores.nu/en/" target="_blank">Investor Relations <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Nu Impact</a>
+        <ul class="sub-menu">
+          <li><a href="https://international.nubank.com.br/impact/environmental" target="_blank">Enviromental <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+          <li><a href="https://international.nubank.com.br/impact/social" target="_blank">Social <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+          <li><a href="https://international.nubank.com.br/impact/governance/" target="_blank">Governance <svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+            xmlns="http://www.w3.org/2000/svg">
+            <path fill-rule="evenodd" clip-rule="evenodd"
+              d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+              fill="white"></path>
+          </svg></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Global
+          Presence</a>
+        <ul class="sub-menu">
+          <li><a href="https://nubank.com.br" target="_blank">Brazil <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.mx" target="_blank">Mexico <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.co" target="_blank">Colombia <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://nu.com.ar" target="_blank">Argentina <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+      <li><a class="footer-head">Blogs</a>
+        <ul class="sub-menu">
+          <li><a href="https://building.nubank.com.br/" target="_blank">Building Nubank <span
+                class="external-arrow"><svg width="12" height="12" viewBox="0 0 12 12" fill="none"
+                  xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nubank.com.br/" target="_blank">Brazil <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nu.com.mx/" target="_blank">Mexico <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+          <li><a href="https://blog.nu.com.co/" target="_blank">Colombia <span class="external-arrow"><svg width="12"
+                  height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+                  <path fill-rule="evenodd" clip-rule="evenodd"
+                    d="M3.03697 0.285645H10.9532C11.1552 0.285645 11.349 0.365916 11.4919 0.508801C11.6348 0.651686 11.7151 0.84548 11.7151 1.04755V8.96298H10.1913V2.88679L1.8103 11.2677L0.731445 10.1904L9.1124 1.80945H3.03621V0.285645H3.03697Z"
+                    fill="white"></path>
+                </svg></span></a></li>
+        </ul>
+      </li>
+    </ul>
+  </div>
+  <div class="w-container">
+    <div class="footer-text">Copyright 2025, Cognitect, a Nu Holdings, Ltd. company
+      | <a class="footer-link-s" href="/privacy-policy.html">privacy-policy</a>
+      | <a class="footer-link-icon" href="https://github.com/cognitect" target="_blank"><i class="fa fa-github"
+          aria-hidden="true"></i> Github</a></div>
+  </div>
+</div>
+<script src="https://d3e54v103j8qbb.cloudfront.net/js/jquery-3.4.1.min.220afd743d.js?site=58dee1dd9c1826ba43796eb4"
+  type="text/javascript" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
+  crossorigin="anonymous"></script>
+<script src="/assets/js/webflow.js" type="text/javascript"></script>
+<!-- [if lte IE 9]><script src="https://cdnjs.cloudflare.com/ajax/libs/placeholders/3.0.2/placeholders.min.js"></script><![endif] -->
+  <!-- <script src="/assets/js/scale.fix.js"></script> -->
+  
+  <script>
+    (function () {
+      // This is the ugliest hack.
+      // Rouge highlighter puts a span element for the final white space (\n)
+      // This script splits on \n, so rouge coloured elements will end up with an extra line.
+      // So we process one fewer line if the pre element has more than one child.
+      var subtractor = 0;
+      var pre = document.getElementsByTagName('pre'),
+        pl = pre.length;
+      for (var i = 0; i < pl; i++) {
+        // detect if rouge
+        if (pre[i].childNodes[0].childNodes.length > 1)
+          subtractor = 1;
+
+        pre[i].innerHTML = '<span class="line-number"></span>' + pre[i].innerHTML + '<span class="cl"></span>';
+        var num = pre[i].innerHTML.split(/\n/).length;
+        for (var j = 0; j < num - subtractor; j++) { // num - subtractor = process one less if rouge
+          var line_num = pre[i].getElementsByTagName('span')[0];
+          line_num.innerHTML += '<span>' + (j + 1) + '</span>';
+        }
+      }
+    })(); 
+  </script>
+  <script>
+    audiojs.events.ready(function () {
+      var as = audiojs.createAll();
+    });
+  </script>
+</body>
+
+</html>
diff --git a/archive/techworks/manifest.tsv b/archive/techworks/manifest.tsv
index e8f5138..26122b2 100644
--- a/archive/techworks/manifest.tsv
+++ b/archive/techworks/manifest.tsv
@@ -80,3 +80,17 @@ wombat	wombat-dbd34f4-tar-gz	wombat-dbd34f4.tar.gz	git-snapshot	https://github.c
 2019-ocrug-interview	2019-ocrug-cdx	OCRUG distinct capture index	metadata	https://web.archive.org/cdx/search/cdx?url=ocrug.org/blog/2019/11/19/2019-11-19-interview-alan-dipert/	archive/techworks/items/2019-ocrug-interview/cdx.json	2026-08-09T19:51:43Z	4cee7dddb59d50de9c253f43481e2ce8c4f9db06280cb2dd7fadba7f782c2eed	369	repository-only	preserved	CDX rows collapsed by content digest
 2019-ocrug-interview	2019-ocrug-headshot-headers	OCRUG headshot replay response headers	metadata	https://web.archive.org/web/20220123191104id_/https://ocrug.org/img/DiperAlan_Interview_headshot.jpg	archive/techworks/items/2019-ocrug-interview/headshot.headers	2026-08-09T19:51:43Z	3ced799f7d1d7972530d496fd448c560d97e02f0654c266df205ebb20627e450	2903	repository-only	preserved	Internet Archive replay response metadata
 2019-ocrug-interview	2019-ocrug-timemap	OCRUG complete capture index	metadata	https://web.archive.org/web/timemap/json?url=https://ocrug.org/blog/2019/11/19/2019-11-19-interview-alan-dipert/	archive/techworks/items/2019-ocrug-interview/timemap.json	2026-08-09T19:51:43Z	c44f5ca43719a56aa8b4146dac88674026912bef67d01f7f7661184cd0b470b9	926	repository-only	preserved	All available page captures at retrieval time
+cognicast-052	cognicast-052-audio	Cognicast Episode 052 original audio	audio	https://s3.amazonaws.com/cognicast/shows/cognicast-052-alan-dipert.mp3	md/TechWorks/media/audio/cognicast-052.mp3	2026-08-09T19:57:32Z	ace070cf982b935b701a28b767194b82a59b2322986c065e7159aefdfab3dc58	59425020	public	preserved	Original 128 kbps MP3; no transcoding
+cognicast-052	cognicast-052-cover	Cognicast Episode 052 cover image	image	https://www.cognitect.com/assets/content/v1/5372821be4b0aefc6719057e/1405694508397-HOH07K4E5EZHYS2KGSDF/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/image-asset.jpeg	archive/techworks/items/cognicast/052-cover.jpg	2026-08-09T19:57:32Z	7355773d7c4efd3beefc0b75481b20722d33b75c5fb13a2802850eb493a24837	69823	repository-only	preserved	Original 1000x1000 source image
+cognicast-052	cognicast-052-headers	Cognicast Episode 052 response headers	metadata	https://www.cognitect.com/cognicast/052-alan-dipert	archive/techworks/items/cognicast/052.headers	2026-08-09T19:57:32Z	a85d3c8db5b8b03b215d958101912af1ed776c780ba1a4fcc5a05f1c7819beed	463	repository-only	preserved	HTTP response metadata
+cognicast-052	cognicast-052-page	Cognicast Episode 052 source page	web-page	https://www.cognitect.com/cognicast/052-alan-dipert	archive/techworks/items/cognicast/052.html	2026-08-09T19:57:32Z	33b3861b8d5deeb4596682207f44dbe534bcea015f25849d53f5d696c9decfec	38944	repository-only	preserved	Exact live page; no transcript was published
+cognicast-111	cognicast-111-audio	Cognicast Episode 111 original audio	audio	https://s3.amazonaws.com/cognicast/shows/cognicast-111-das-boot.mp3	md/TechWorks/media/audio/cognicast-111.mp3	2026-08-09T19:57:32Z	4562fcd751a5331289d86e3f40eb67870160e637b88b8ff3be0cf33524a1bc5a	76461056	public	preserved	Original 128 kbps MP3; no transcoding
+cognicast-111	cognicast-111-cover	Cognicast Episode 111 cover image	image	https://www.cognitect.com/assets/content/v1/5372821be4b0aefc6719057e/1476796491666-YOWI8KZV28Q9PVEZJP7S/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/110-dipert-niskin.jpg	archive/techworks/items/cognicast/111-cover.jpg	2026-08-09T19:57:32Z	2058ab1dd1f4ce00ad2dc7df9c5bab0bb2fec352de7264bafb4066cf92d67cd5	223773	repository-only	preserved	Original 1000x1000 source image
+cognicast-111	cognicast-111-headers	Cognicast Episode 111 response headers	metadata	https://www.cognitect.com/cognicast/111	archive/techworks/items/cognicast/111.headers	2026-08-09T19:57:32Z	592cd602f71f74cafbafc385156eaa90e1af01eb24373d4d53cb07642c2451f3	464	repository-only	preserved	HTTP response metadata
+cognicast-111	cognicast-111-page	Cognicast Episode 111 source page and transcript	web-page	https://www.cognitect.com/cognicast/111	archive/techworks/items/cognicast/111.html	2026-08-09T19:57:32Z	a36e25592798eb869f27aefea9fadaa00de5622ef5eb268edd335af69a03c36d	124446	repository-only	preserved	Exact live page including full transcript
+cognicast-111	cognicast-111-transcript	Cognicast Episode 111 transcript	transcript	https://www.cognitect.com/cognicast/111	md/TechWorks/Cognicast111.html	2026-08-09T19:57:32Z	9839ad172d31b2915e3eeb9cdf98830d4baf218fab8a5ff804ccedb17e6970d1	83509	public	preserved	Standalone reading copy extracted without changing transcript text
+cognicast-112	cognicast-112-audio	Cognicast Episode 112 original audio	audio	https://s3.amazonaws.com/cognicast/shows/cognicast-112-alan-and-micha-part-deux.mp3	md/TechWorks/media/audio/cognicast-112.mp3	2026-08-09T19:57:32Z	cff200708de3e324faa0e5a7cd4fce4beaaa9100921c47ac4d81bcb698e151f6	86666687	public	preserved	Original 128 kbps MP3; no transcoding
+cognicast-112	cognicast-112-cover	Cognicast Episode 112 cover image	image	https://www.cognitect.com/assets/content/v1/5372821be4b0aefc6719057e/1478187443066-I9CNDJJGDI0TWDPS5JJO/ke17ZwdGBToddI8pDm48kHldqyjDwaeS7kYSmaCmglZ7gQa3H78H3Y0txjaiv_0fDoOvxcdMmMKkDsyUqMSsMWxHk725yiiHCCLfrh8O1z5QHyNOqBUUEtDDsRWrJLTmTl_ALRZE0UkEheIF40jl8l-p-UjEfP0lrs6khMOijucIE9LbemCnC0mKIu4O-BCA/112-dipert-niskin.jpg	archive/techworks/items/cognicast/112-cover.jpg	2026-08-09T19:57:32Z	348263dc01b3b86799759f5bcbfce0afe32726a675580a520ddc7a39ca868d83	142804	repository-only	preserved	Original 1000x1000 source image
+cognicast-112	cognicast-112-headers	Cognicast Episode 112 response headers	metadata	https://www.cognitect.com/cognicast/112	archive/techworks/items/cognicast/112.headers	2026-08-09T19:57:32Z	ac5b60c328ac78786f03d96cf889ec4b236f5f0b5aa984e5d318ff6c644cc044	464	repository-only	preserved	HTTP response metadata
+cognicast-112	cognicast-112-page	Cognicast Episode 112 source page and transcript	web-page	https://www.cognitect.com/cognicast/112	archive/techworks/items/cognicast/112.html	2026-08-09T19:57:32Z	380d401a5861632a524375c92f278598dda20a84fd51110a394e5b8e56c95726	139869	repository-only	preserved	Exact live page including full transcript
+cognicast-112	cognicast-112-transcript	Cognicast Episode 112 transcript	transcript	https://www.cognitect.com/cognicast/112	md/TechWorks/Cognicast112.html	2026-08-09T19:57:32Z	e307e14633721e10ecdd576af6458d4b1409ddf6f9e42cf3daa4e15e7ffa9b8c	99141	public	preserved	Standalone reading copy extracted without changing transcript text
diff --git a/md/TechWorks/Cognicast111.html b/md/TechWorks/Cognicast111.html
new file mode 100644
index 0000000..a8d289c
--- /dev/null
+++ b/md/TechWorks/Cognicast111.html
@@ -0,0 +1,664 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Cognicast Episode 111: Solving problems and Boot</title>
+  <link rel="stylesheet" href="../style.css">
+</head>
+<body>
+  <main id="main">
+    <header class="site-head">
+      <a class="site-brand" href="../TechWorks.html">
+        <span class="site-brand-name">TechWorks</span>
+        <span class="site-brand-tagline">Selected work</span>
+      </a>
+      <nav class="site-nav" aria-label="Archive navigation">
+        <a href="../TechWorks.html">Works</a>
+        <a href="../TechWorksArchive.html">Archive</a>
+      </nav>
+    </header>
+    <article>
+      <h1>Cognicast Episode 111: Solving problems and Boot</h1>
+      <p><small>Published by The Cognicast on October 18, 2016. <a href="https://www.cognitect.com/cognicast/111">Visit the original episode page</a>.</small></p>
+      <p><audio controls preload="metadata" src="./media/audio/cognicast-111.mp3">Your browser does not support embedded audio.</audio></p>
+      <h2 id="transcript">Transcript</h2>
+
+<p><strong>CRAIG</strong>:     Hello, and welcome to Episode 111 of The Cognicast, a podcast by Cognitect, Inc. about software and the people who create it.  I'm your host, Craig Andera.</p>
+
+<p>Okay.  Well, in our notes today, things we want to make you aware of, includes a number of conferences.  The first one I'll mention is the FinDEVr's west coast conference.  That's happening Tuesday, October 18th through Wednesday, October 19th, 2016.  Our very own Timothy Baldridge will be presenting.  This is a technology conference about the technology side of FinTech.  If you happen to be in the Santa Clara area where that is being held and you can get there, then have a look.  Look for the FinDEVr Conference.  You'll find that.</p>
+
+<p>Of course I can't not mention EuroClojure.  That's coming up soon now, Tuesday, October 25th and 26th.  Tickets are still available at this point, but quite a few have already been sold.  We're getting into the later part of ticket sales, so if you're planning to go to EuroClojure in Bratislava, Slovakia, you should definitely go and pick up tickets.  You'll find those at the EuroClojure website.</p>
+
+<p>Michael Nygard, who has been on the show a bunch of times, one of my favorite guests, will be presenting at the DevOps Enterprise Summit in San Francisco, Monday, November 7th.  That's the conference is Monday, November 7th through Thursday, November 10th.  That again is in San Francisco, so you can look for the DevOps Enterprise Summit if you want to go to San Francisco and hear Mike Nygard talk.  He's always great to listen to as, if you've listened to the show, you're well aware.</p>
+
+<p>The O'Reilly Software Architecture Conference is also in San Francisco around the same time.  That's actually Sunday, November 13th and Monday, November 14th.  We will be holding a training course, a two-day training course also given by Mike Nygard.  The title is Architecture Without an End State.  This is not a Clojure specific course.  I don't really have the space to describe it here.  Again, look for the O'Reilly Software Architecture Conference and you'll be able to find details about it on their website.</p>
+
+<p>Finally, I'll mention the Clojure/conj.  That's coming up.  That's going to be Thursday, December 1st through Saturday, December 3rd.  I'll be there.  I'll be teaching the Intro to Clojure course immediately beforehand, the two days beforehand.  You can find all of the information about that at the Clojure/conj website at Clojure-conj.org.  Always fun.  Just a great time.  One of my favorite things during the year is to go to that.  Tickets are also still available for that, but there's no guarantee that will remain true forever.  We're about two months away.  It would not be a terrible idea to go and get your tickets for that.  Head on down to Austin and join us there.</p>
+
+<p>I think that's all I have for announcements.  We'll go ahead and go on.  Upcoming now is Episode 111 of The Cognicast.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Well, I think I'm set.  How are you guys?</p>
+
+<p><strong>ALAN</strong>:     Yeah, we're ready to go.</p>
+
+<p><strong>MICHA</strong>:     Ready to go.</p>
+
+<p><strong>CRAIG</strong>:     Excellent.  Excellent.  Excellent.  All right, then.  Here we go.</p>
+
+<p>All right.  Welcome, everybody.  Today is Friday, July 29th, 2016, and this is The Cognicast.  I am very pleased today to welcome back to the show two friends of mine, Alan Dipert and Micha Niskin.  Welcome to the show, guys.</p>
+
+<p><strong>ALAN</strong>:     Thank you.</p>
+
+<p><strong>MICHA</strong>:     Thanks.  Yeah, it's great to be here.</p>
+
+<p><strong>CRAIG</strong>:     They are both developers at Adzerk.  Alan is a former coworker of mine.  I will point out he was the first ever guest on The Cognicast, coming up on six years ago now, although we never actually aired that episode.  Alan is one of the mysterious lost episode guests.  Alan, I think you may have been the guest on every episode that we never aired for one reason or another.  Anyway, it's been quite a while since we've had you on, but really, really glad that you're back to talk to us again and super excited to talk to Micha as well.  You guys have done some really cool stuff that we will get into.</p>
+
+<p>But before we do that, we are going to throw to you the question that we always throw to our guests, which is, at the beginning we ask people to relate some experience of art, whatever that means to them.  Even though you told me approximately 30 seconds ago which one of you was going to do this question versus the one we ask at the end, I've already forgotten.  Which of you said that you would like to answer the art question?</p>
+
+<p><strong>MICHA</strong>:     Hey, this is Micha.  I will.  I'll do it.</p>
+
+<p><strong>CRAIG</strong>:     Excellent.</p>
+
+<p><strong>MICHA</strong>:     Two things, actually.  I saw the other day a picture of a newborn baby's skull without any flesh on it.  Seeing how the teeth are, you know, kind of cued up inside the jaw, man, I cannot get it out of my head.  I don't know if this is exactly art, but, man, it's an image that I can't stop thinking about.</p>
+
+<p>But, like, for actual art, there was a guy.  He would take, like, an aluminum, a big aluminum plate, like 20, 30 feet square and put an emulsion on it and then made a camera obscura where he would take a landscape shot and develop it on this plate.  You could go up to it, apparently, with like a magnifying glass and see more and more detail because it's like infinite depth of field.  That was super fascinating to me, the idea that you could have, like, this enormous image with just endless detail, as much as you could ever want.</p>
+
+<p><strong>CRAIG</strong>:     Now I feel like I want to do that, but for a baby's skull.  Both of those are super cool.  The baby's skull one obviously is a little – I don't know.  I guess I find it a little – I think if I saw it, I would have a hard time forgetting it too.  But to me, kind of art is something that someone does with the intention of making you feel something, and I could well imagine that falling into that category.  The camera obscura thing is also very neat.  We'll make sure that we drop a link to that in the show notes so people could check that out too.</p>
+
+<p><strong>MICHA</strong>:     I'll have to find it.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  No worries.  We can look for it too.  That's very, very cool.</p>
+
+<p>Well, so you guys have been doing cool things together for quite a while now.  Kind of the reason that I wanted to have you on is that, Alan, you actually were on the show over two years ago now.  At the time, we talked about boot and hoplon and javelin.  I feel like those were really good ideas then, and they are still really good ideas now.  But one of the things is that I've actually been starting to see more of them out in the Clojure universe.  People around here have been talking a lot about boot lately.</p>
+
+<p>I have actually personally switched over to using boot and hoplon and, of course, by extension, javelin.  We'll explain what all those things are, to our listeners who aren't familiar, in a minute.  I've been using all those for my personal projects lately, and I've really been digging it.  They're different from some of the other things that are out there right now, and I just thought what a great time to follow up with these guys to go back and revisit those topics to get more in-depth into them, especially now that I have a little more context and maybe I can actually ask slightly more intelligent questions.  Of course, like we always say, and this is always true, we'd love to hear about whatever is interesting to you, but are you guys up for a chat about some of those things on the way to whatever else we talk about?</p>
+
+<p><strong>ALAN</strong>:     Totally.</p>
+
+<p><strong>MICHA</strong>:     Yup.</p>
+
+<p><strong>CRAIG</strong>:     Excellent.  Maybe you could just start with talking about this triad.  I know that they are things that you can independently: boot, hoplon, and javelin.  But maybe you could just give us the tour for anybody that hasn't encountered them.</p>
+
+<p><strong>ALAN</strong>:     Well, I think I might take a tack with this that Micha took with a podcast he was recently on, the Defn podcast, which was a fun listen for me.  The way he began telling about the trilogy is basically how Micha and I met.  Micha and I met in a context that had nothing to do with computers.  In fact, we were maybe even starved for the keyboard.  In the Army we did work that had nothing to do with computers, but he was the only programmer I ever met, so we would often have conversations about computers and programming.  Micha was one of the few people I knew who had actual C programming experience, and I knew a lot of things about the Web that Micha didn't know, so we had a lot of interesting conversations.</p>
+
+<p>It's funny.  I feel like a lot of the most interesting conversations about computers and programming happen at times and in places when the keyboard and the computer and Wikipedia are far away because that's when you're really forced to imagine what could be.</p>
+
+<p><strong>MICHA</strong>:     Definitely.</p>
+
+<p><strong>ALAN</strong>:     We had a lot of those kind of conversations.  Then when we both left the Army later, we started to work together at places.  This is another kind of cool phenomenon in the professional computing world that I know a few groups like us who sort of do this, but basically you work at a company and then you can influence hiring.  You know who you work with well.  You look in your address book, and you call those people up.  You get them into a team.</p>
+
+<p>I think some company out west even started hiring teams.  Just flat out they would hire groups of two or three people.  I found that my professional trajectory has kind of orbited groups of people and individuals and one of those individuals is Micha.  The same is true for him.  We were working at places, and we would hook each other up with contract work or jobs at those places.</p>
+
+<p>As we worked together more, we started to develop – I wouldn't call it a philosophy since it's not formalized at all, but basically when you work with someone or a small group of people, you develop a way of working.  You develop a perspective on how you gather the information and materials together that you need to do work, the toolset and the outlook.  I think, after that, after you've done some things together in a small team or with another person, then you start to develop actual tools that you use to do these jobs that both people know how to use.</p>
+
+<p>Boot and hoplon and javelin are things that emerged from that collaboration.  They are more or less tools that followed conversations that Micha and I had.  We would independently go research things and build our own prototype things.  Show them to each other and argue about it, and then we ended up arriving that these set of tools, I guess, a few years ago is when we arrived at them.  Not much has changed about them since I last told you about them two years ago.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean we were basically, like, in it together, like doing – you know, working, trying to make money and there were problems that we needed to solve to be able to – you know, you don't want to solve the same problems all the time.  So, you know, little bit little, we were working on these problems.  Because there were two of us, and because we were always working on the same kind of things, we could be a little bit more ambitious.  You know what I mean?</p>
+
+<p>For us, we've solved some of these problems forever.  We're just going to use the things now and we do other things.  You know?</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.  Yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, I guess if we had a dynamic, it would be maybe the idealist and the skeptic.  I'm pretty idealistic about computers, and you know what a gift to humanity they are, and Micha is right there to cut me down.  He freely mentions how anything computers do instantly make worse and there's all kinds of holes in this idea.  But if you go back and forth like that with somebody, particularly if it's a friendly rapport, I feel like we've managed to make some decent decisions, or at least come up with a set of tools that we both like to use.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Go ahead.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  This is a roundabout way of getting to describing what boot, hoplon, and javelin are, but boot is a build tool, basically.  It's more a library of Clojure functions that help you craft your own build tool to match whatever your build scenario is for any definition of build that you have, which makes it difficult to explain, but we'll get into that, I'm sure.</p>
+
+<p>We came up with the idea  for boot after working on a Web framework called hoplon because the Web of today requires sophisticated tooling to get anything done just because there are so many technologies, file formats, and….</p>
+
+<p><strong>MICHA</strong>:     Yeah.  Not only that.  At the time, so this was in, like, 2012, ClojureScript was pretty rough then.  It was still awesome, but we needed different things.  Having our own – you could do a lot of things in the build process if you have a flexible enough environment to build in, and that's where we found.  We didn't have that, so we made it.</p>
+
+<p>In hoplon, originally, there were a lot of things that were actually going into the ClojureScript world and changing things around.  So implementing stuff that we wanted, but it doesn't make sense to go and try and get it into the ClojureScript compiler.  We just want to get work done.  If it works out, it could be, you know, upstream can take it.  But right now we want to get our work done.  You know?</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so boot basically filled in the holes that were missing for us in our workflow because we were very convinced that ClojureScript is the way to build stuff, especially when we need to build a single page app.  But the tools were not just immature.  They're more or less nonexistent.  The line cljs built predated what we were doing, but it was not used very widely, and ClojureScript, in general, wasn't.</p>
+
+<p>Then javelin is a ClojureScript library that was part of the hoplon framework.  They're all loosely related to each other through this goal of ours back in 2011, 2012, to come up with a solution for building Web apps.  But now they're usable separately from each other.  You can use boot without using hoplon.  You can use javelin without using either.  They're definitely separate pieces.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, and so of the three, I think boot is the one that people are most likely to encounter simply because the other two are ClojureScript specific.  Boot, of course, is usable even if you never touch ClojureScript.  I think it exists in the same space as Leiningen.  That's the tool that most people are using that if they go use boot, then they're no longer using Leiningen, which is what I've done.  It's kind of an either/or.  Although, I believe there is some.  Maybe you guys can talk later about what it would mean if anything is sensible to use both.</p>
+
+<p>But I've been using boot for this process of building.  The thing that I've been struck by, really–and this is something, Alan, that you explained to me last time, but that once you get a chance to use a tool that sometimes is what it really takes to kind of start to viscerally understand things–is that it really is quite a different approach in that it feels more like programming Clojure, about writing functions and passing data through functions than something else where you have like a DSL and you're building an interpreter over that DSL.  Right?  Does that make any sense?</p>
+
+<p><strong>ALAN</strong>:     Yeah, totally.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  The way I see it is the boot, I mean the reason why it's called boot is because all it really does, like the objective of boot is to bootstrap you to a place where you can program in Clojure.  It's like the minimum that you need to get Clojure, to make a Clojure program that will do something useful.  But then, additionally, it provides some functions that you can use, like namespaces, libraries, and whatnot that you can use to do things that you commonly want to do when you build stuff.  But primarily it just gets you to a place where you can start writing a program.  Then you can do anything.</p>
+
+<p><strong>CRAIG</strong>:     Right.  Of course, you guys do provide some.  Actually, that's a good question.  What does it look like to start a project in boot?  If I'm using Leiningen, I say "lein new" whatever and then I have a project CLJ.  Then I say "lein REPL," and now I've got a REPL, and I'm off and running.  I add dependencies in my project CLJ.  For people that haven't used boot yet, what is the process like for boot?  Then we can get into how you advance your project, like how you go beyond the default.  What is the sort of default introductory user experience?</p>
+
+<p><strong>MICHA</strong>:     What do you do?</p>
+
+<p><strong>ALAN</strong>:     Well, I think for the default – so, you know, project, I think is a pretty overloaded term because it can mean one of experiment, application, or library - in general.  An experiment is something where you don't even care to have a file.  You just want to see how some library works or try out some function idea you came up with on the train or whatever.  There are libraries where you already have some code or some idea for what you want to create.  It's going to be supporting some other application, which is a separate project.</p>
+
+<p>Then you may have an application, which is going to be code that's purpose built to solve a problem in the real world outside of the domain of programming, probably for your client or your boss.  All of those three things in boot have the same starting point, usually, which is the boot command.  You can start development on any of those three kinds of things just by typing "boot REPL," and that gets you to a Clojure REPL.</p>
+
+<p>The biggest distinction in the beginning part of a project between boot REPL and lein REPL or Clojure's native REPL is that boot has the ability for you to bring in dependencies from the REPL.  So you don't need to specify your dependencies in a file before starting the REPL.  At the REPL, you can bring them in.  This is analogous to, I think, a lein plugin that Ryan Neufeld wrote a couple years ago called lein-try, and the idea is you want a REPL with a dependency on it just to experiment.  That's where a lot of projects begin.  That's probably how most or at least how I start almost anything with boot.</p>
+
+<p>Then for an application or a library, you're going to probably have some idea ahead of time of what dependencies you need already.  You're not going to be dynamically discovering things trying libraries out.  You probably have an idea of what you want to work with, so you'll create a build.boot file.  That's analogous to pom.xml or project.clj.  The main difference is that a build.boot file is a Clojure program.  It's not a language other than Clojure.  It's interpreted by the Clojure evaluator.</p>
+
+<p><strong>MICHA</strong>:     Yeah, because the boot tasks are just functions – well, everybody always says everything is just functions, but anyway you can compose them like functions and call them like functions and stuff.  We have a library, this bootlaces library, but that's kind of what I do.  I pre-stage my own little workflow as prepackaged tasks.  I can pull that Maven and have it loaded.  Then I have the normal ways that I build jars and all that stuff, you know, configured the way I like it already set up.</p>
+
+<p><strong>ALAN</strong>:     Which is kind of analogous to the way that compile and run time are interleaved in Lisps traditionally in the sense that a defmacro and a defn can inhabit the same runtime.  You can defn something and then make a defmacro where you call that thing that you defn.  Then you make another defmacro, so the phases of macro, expand, compile, and run are interleaved over the lifetime of your execution.  This is the sequential evaluation model of Lisp interpreters.</p>
+
+<p>Boot kind of supports that, so you can create a boot task, run it, edit it, reload your build.boot file, try it again in a build tool that has a static build description language like Make or Maven.  You're going to need to edit that file, shut down your JVM, restart your JVM after you've edited the file.  I would say it's just Lisp-ier, in general.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  That's exactly one of the things that I've really been enjoying about it.  I think the one that hits me right away is the one you mentioned, which is the ability to pull in new dependencies dynamically and to really – I mean, you know we talk about you could sit down at a REPL and build your whole program, right?  You could just say, defn, defn, defn.  Oh, I'm going to redo that one.  I've got state.  Boom.  I have a running program.  I never saved a file, really.  I just typed it all in.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I think it's kind of the same way that you could do with boot.  Now the same way that you don't typically create production systems by opening up a REPL on the prod box and typing until the system is working, you would probably not create nontrivial systems with boot by simply building it up.  But you can, and then you can go from that to kind of capturing what you've come up with interactively and working with that.  I really, really like that approach.  It resonates with me very well.</p>
+
+<p>I think there's another thing I would like you guys to comment on is how much of this was planned, how much of it you think is an outcome of the philosophy that was happy accident.  It seems to me one of the places where boot really shines is actually hard to explain to beginners because it has to do with the wins that you get as you get into projects that are less trivial, that are more kind of industrial strength.</p>
+
+<p>Micha, you said, "The way that I like to work."  Well, you have these projects and, over time, you're like, oh, we have to have some special asset built, asset pipeline build because people from the documentation team are sending us Word docs, and we need to transform those somehow.  We want to integrate that all in.  You wind up with these extra bits that you need to do.  If you have the DSL approach, then you have to write an interpreter and find a way to express it or do some other type of integration.  Maybe it's a bash script.</p>
+
+<p>With boot, it's really – let's have an execution model so that, since my model is execution and it's in Clojure, I start right there.  I say, well, I have a process, it has steps, and it does things, not a language where I say things and then I have to write something that knows how to speak that language.  I don't know if that makes any sense.</p>
+
+<p><strong>ALAN</strong>:     It makes a lot of sense, and it actually gives me a thought of how to set up Micha to explain it.  I'll try this.  I'll try to–</p>
+
+<p><strong>MICHA</strong>:     Okay.  Hit me.</p>
+
+<p><strong>ALAN</strong>:     –pass it to Micha and then he can spike it.</p>
+
+<p><strong>CRAIG</strong>:     Bump.  All right, I did the bump.  You're doing the set.  Got it.  All right.</p>
+
+<p><strong>ALAN</strong>:     Okay.  Yeah, I'll set it up.  I heard Rich Hickey say, maybe in a talk when I was in the beginning of my Clojure learning five, six years ago, seven years ago, about why Java "won" and C++ "lost."  Now, of course, C++ hasn't lost.  A lot of people use C++, and there's definitely a space within application and library development where C++ is very much alive.</p>
+
+<p>I think 15 years ago or 20 years ago people saw Java and C++ as competitors in the development of large-scale applications where large-scale is some function of application size and team size.  He made the point that Java developed over time this library ecosystem where C++ more or less stagnated as far as libraries go.  His reasoning for that disparity was Java gave library authors the elements they needed to capture workflows in a way that could work universally.  One of those key things is probably garbage collection.</p>
+
+<p>You can't combine libraries that have different strategies for allocating and de-allocating memory because each of those strategies forms a lifecycle and it's very hard to interleave resource dependent lifecycles.  It's just a super hard problem coordinating IO like that, and that's basically the problem that garbage collection solves.  Obviously there are tradeoffs involved, but if you want to share workflows and combine them meaningfully, you definitely need garbage collection.</p>
+
+<p>What  garbage collection lets you do is have what you might call first class data structures in the sense that the system supports the tracking and management of anonymous structures, so functions can take managed structures that are managed invisibly by the garbage collections underlying part of the language run time, and they can also return these structures.  They don't need to manage them while they're using them.  That lets us bundle up solutions to problems in ways that are very easy to consume.</p>
+
+<p>I think one of the things we came to appreciate after working on boot, and I should say it's not like all the pieces of boot we just figured out in one of our conversations in the Army and then sat down and typed it out.  It's definitely been years of fumbling, hitting guardrails, slapping each other around, and eventually arriving at something that works.  But one of those things was identifying what are the parts, what are the aspects of build processes that are preventing us from doing this like programming?  What is preventing us from capturing workflows and sharing them in libraries like the way we do in the JVM or in Clojure?  I think the two things in boot that represent those first class structures are pods and file sets.</p>
+
+<p><strong>MICHA</strong>:     Yup.</p>
+
+<p><strong>ALAN</strong>:     Then, Micha, it's over to you now to spike it.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  A weird thing, well, a different thing about boot is that there's no dependency graph or anything like that.  Boot isn't going to do anything.  Boot doesn't try and figure out what you're trying to do, and it won't do anything unless you explicitly tell it to do it.  You need to call a function or compose some things together and then call that.  That's kind of different than any of the other things that I've really used in the past.</p>
+
+<p>But one of the things that means is that it gives you – I think it gives you a lot more flexibility and reach because, to the programmer when you're setting up a workflow, a pipeline, it's obvious to you what you need to do first and what you need to do next and so on.  But it might be very, very difficult for the computer to figure out what the dependencies really are.</p>
+
+<p>You might make a mistake and, when you do your build, you see immediately what went wrong, and you reorder things.  To a human it's pretty obvious what you want to do.  You just have to have a very direct way to tell it, to tell the computer to do it.  Lisp obviously gives you the best way to describe to a computer what you want it to do.  That's one part.</p>
+
+<p>Another part is that a lot of the more odd things in boot arise from the need to keep this JVM alive for as long as possible because it's expensive to keep restarting JVMs and stuff.  That means that we have to think really hard about how to manage the mutable JVM sub-strait and build things on top of it that you could still program with some of the affordances of immutability.  That's where pods and the file set kind of come in where you can isolate things that mutate.  In other words, you can make a pod that isolates classpath mutation, and you could have that pod creating files in an anonymous, temporary directory that only boot really knows where it's located.  Then you could take those files and add them to a file set, which is an immutable representation of the class path of the main pod that you're in.</p>
+
+<p>Yeah, I think a lot of it kind of immerged from the fact that there is a need to get incremental compilation and long-lived.  You know, like that's a lot of the reason why the REPL, why there was so much emphasis on everything being workable from the REPL because you have a long-lived REPL session and you want to leverage that.  You don't want to have to keep restarting it.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Right.  You mentioned a couple things in there.  A lot of super interesting stuff, but you mentioned, concretely, pods and file sets.  I have to say, as a relatively new user of boot, these are not actually things that I am smacked in the face with.  I know they're there, but I write a build boot file and I kind of say boot REPL and maybe a couple other things.  It's fairly easy for me to add my own steps into the build and whatnot.  I haven't really had to confront what a pod is, what a file set is, so educate me.  What are these things and how would I use them?  What am I missing out on by not taking advantage of them?</p>
+
+<p><strong>MICHA</strong>:     Man, you know, that's actually – that's a thing that I really – I like it when people say that because I think it's really great to have software that separates architecture from building an actual application.  Meaning this is what we try and achieve with hoplon as well where you make a bunch of libraries where the actual functionality is, but you should be able to assemble an application out of those components just by composition without knowing too much about the internals.  If it's really done well, then there are so many ways that you could compose them that you could stay out of that world unless you need to do something novel.</p>
+
+<p>I'm glad you said that.  It makes me feel good.</p>
+
+<p><strong>CRAIG</strong>:     Good.  Yeah.  I have quite enjoyed it.  We'll talk more about my experience because I've been primarily using it with hoplon, and maybe when we talk about hoplon.  But explain to me what–?  Given that I don't have or have not yet had to know, I still am enjoying boot enough that I'm like, well, at  some point I'm probably going to want this stuff.  Arm me.  Arm me with the knowledge of what pods and file sets are so that when I have a problem, I will go ah-ha, that is a file set shaped problem.</p>
+
+<p><strong>MICHA</strong>:     Sure.  Maybe I'll do file sets and then Alan can do pods.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I guess it's worth saying that kind of the three pillars of boot are probably tasks, file sets, and pods.  Tasks came first, and those are the things that are just functions.  Pods and file sets came after when we really wanted for tools to do functional programming in the build setting.  It turned out the tools….</p>
+
+<p><strong>MICHA</strong>:     …build large projects too.</p>
+
+<p><strong>ALAN</strong>:     Yeah.   Yeah, and it turned out the tools we needed to work with these things were not functions.  We had functions up the wazoo.  We were composing them and calling them.  But the problem is, to do functional programming, you need not just functional – not just functions.  You need really immutable collection types and immutable aggregates that you can build on incrementally, immutably, and efficiently.  I think pods and file sets are really the values that you work with, with tasks, which are functions.</p>
+
+<p><strong>MICHA</strong>:     Yeah, so maybe we do file sets first because pods are more useful when you're using them kind of with file sets.</p>
+
+<p><strong>ALAN</strong>:     Yeah, or we could do a problem approach, like you're building a thing and you want to do some kind of processing, and how do you do it.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean for file sets, though, at the high level what you want to do in a build is you have a bunch of artifacts, which is things that are on the classpath in the JVM and things that might end up in some kind of packaged artifact like a JAR file or just a directory that has a bunch of files.  Whatever you want at the end, like when boot stops running, you're going to want to have something, usually.  It might be something that you ship to S3, so maybe it never exists on your disk, but there's this concept of having an artifact that you're creating.  In order to create that, you take some source files that are usually in Git or something.  These are the files that are owned by you that you're working on.  Then you run this build process on it, which performs a number of transformations and does a number of steps sequentially and, at the end, produces these artifacts.</p>
+
+<p>Working in the JVM and in Clojure, you're going to need to manage the classpath, which means you could pull in JAR files and things like that, which are treated more or less immutably by the JVM, meaning once a class loader has loaded a JAR in there, you can't really unload it.  But there's also immutable classpath, which is you could add a directory to a class loader.  You could add, remove, or change files from there, and it doesn't cache them.  It doesn't cache the byte code that was generated from them.</p>
+
+<p>Part of what boot does is manage the classpath for you.  The reason why you'd want to do this is because one task might create some files that need to be on the classpath for the next task because traditionally all the actual Java machinery that you're going to use, like the Java compiler, the ClojureScript, the Google Closure Compiler, all these big, giant projects that predate Clojure, boot, and everything expect to find things on the classpath and they put things back somewhere in a directory, usually.</p>
+
+<p>We needed to work within that world.  We don't want to throw away everything from the JVM.  That means that when a task is doing its work, its input is generally going to be on the classpath and its output is going to go into some directories or something.  Then we're going to want to take the output, maybe, and merge it into the classpath.  That's where the file sets come in.</p>
+
+<p>The file set is an immutable snapshot of all the files related to this build.  Some of them are on the classpath.  Some of them are not.  They're organized in different ways.  But it's like an immutable snapshot of the file system and its physical manifestation, sort of, is a record type, so a Clojure record, which is an immutable data structure.  Given a file set object, this immutable record, you can call methods on it to sync it with the file system, say, which means make the real file system and the real classpath and so on like my file set object.  You can also do Git-like operations, so you can say, add all the files in this directory here to the file set.</p>
+
+<p><strong>ALAN</strong>:     Underneath it is the implementation of it is more or less Git, content address stuff.</p>
+
+<p><strong>MICHA</strong>:     Yep.  Yeah, so you can add files and then commit them.  When you commit them, they get synced to the file system.  Then you can pass.  You can hold onto a file set, so if somebody passes you a file set, you do some work, maybe create a new file set, give that to someone else, but you can still hold onto the one that you had, which is the benefit of immutable data, right?  If you want to roll back time and reset the file system to where it was when you first started, you can just commit the file set object that you've saved.  The file system will be just like it was in that state.</p>
+
+<p>The idea is that a task gets a file set given to it.  It's an immutable representation of the state of the file system.  Then it does some work, which is for side effects, creating files and things like that.</p>
+
+<p><strong>ALAN</strong>:     Compiling stuff.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Less Java, AOT, Clojure, whatever.</p>
+
+<p><strong>MICHA</strong>:     Making ERB files into HTML files, whatever it is.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Then it takes the output of that and adds it back into the files to a new file set and then passes that to the next task.  This is good for, like, the incremental build cycle because the pipeline is a bunch of nested middleware, kind of like a transducer, and it can keep calling itself.  Each step can call the next step one time, zero times, or many times–however they want–and pass it, you know, a saved file set.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.  Right.  That's the pipeline aspect.  Right?</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Yup.</p>
+
+<p><strong>MICHA</strong>:     So the file set was necessary for the pipeline to work properly because you need to be able to rewind to any step in the pipeline to rerun it - if that makes sense.</p>
+
+<p><strong>CRAIG</strong>:     Actually, I don't quite follow that bit.  What is the–?  Maybe you can help me with an example of where I would need to rerun some step of this process.</p>
+
+<p><strong>MICHA</strong>:     Sure.  I made a task recently.  I wanted, in ClojureScript, to be able to do refer all and use accept.  You know what I mean?</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     In other words refer all the names.  I don't want to distinguish between macros and so I thought it could be done.  I was like the first thing I'll do is I'll make a boot task to transform a file into a different ClojureScript file, right?  I have foo.cljs in my source directory of my repo, and I put NS+ instead of NS.  I make a boot task that looks for every CLJS file in my project and, if it sees that the first form is NS+, it's going to perform this transformation, which finds out which things are macros, which aren't, and adds them and transforms it into a regular ClojureScript NS macro.</p>
+
+<p>What I want to do, though, is I want to replace the file that was there.  If I made foo.cljs in my project, I want it to just replace that with the modified one so that it can go through the compilation, the rest of the pipeline, which includes maybe the ClojureScript compiler and stuff like that.  They won't even know that this transformation took place.</p>
+
+<p>In order to do that, you really need to have some kind of immutable representation of the file system because you're actually replacing a file with a different one.  If I'm running an incremental build where every time I change a file it rebuilds things that have changed, so whenever I type in foo.cljs and I save it, it's going to run this thing, this pipeline again.  And so it needs to be able to start off, to undo the changes that were done by subsequent tasks.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.  Yep, that makes sense.</p>
+
+<p><strong>MICHA</strong>:     You know what I mean?</p>
+
+<p><strong>CRAIG</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     I mean because you're doing destructive actions, mutating all over town however you want, and so you need to be able to roll back those commits.  Reset minus, minus hard, is basically what it is.</p>
+
+<p><strong>CRAIG</strong>:     Yep.  That makes a lot of sense.  That example is a good one, I think, because you mentioned the NS macro.  That's actually a tough one to do any other way, right?</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, the NS macro is maybe the one thing in Clojure that the user has no control over the operation of.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     It's funny.  Over the years since we started on hoplon, we've added all kinds of cool features to Clojure like multiline strings.  What else?  All kinds of automatic refer stuff because basically we'd be working on these big applications and it's like, man, who wants to copy a 20-line NS thing into every single file that they're working on?  This is where the build tool needs to help us because the language can't.  You know just the way Clojure works, we can't draw that up.</p>
+
+<p>Historically, we've been pretty skeptical of features going into Clojure that solve these problems because our view is kind of if the build tool can solve it then the language should not because every time something goes into language, everyone has to use it.  But we're kind of–</p>
+
+<p><strong>MICHA</strong>:     And the administrative overhead of, like, you know, just discussing with hundreds of people when you could just have your own – you know what I mean?  Like ES6 versus making a macro that gives you let in five minutes.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     We wanted to be able to just make whatever crazy thing that maybe is unwise, but we could do it inside of our build task.  Nobody needs to care.</p>
+
+<p><strong>ALAN</strong>:     Yeah, we needed no approval.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Interesting.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so we have kind of this suite of experiments, really, extending the language syntactically, semantically, in various weird ways.  Boot is a great way to do that, and I would encourage people to explore that aspect of using Clojure because I think if you've used it for more than a few months, you probably have gripes and you might be able to craft it into something that you like more.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  I think the analogy is if you're working in a language like Java, there are a lot of things you can't do and you wind up repeating yourself a lot.  Then people say, well, why do you like Clojure?  It's like, well, because of that.  Right?  Because I don't have to do almost any of that any more.  I can mutate the language to fit my needs.  I think what you're saying is that although boot is not limited to that, it gives you even more power to do that when the language can't or doesn't.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  It gives you a limited form of syntactic extension of Clojure, which is traditionally poo-poo’ed.  But we know when you own the files that the syntax is in, you can do whatever you want to them before you hand it to the Clojure compiler.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     We found doing that was pretty useful.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, you use it to good effect in hoplon, which I hope we will – I might have to have you guys on again at this point because this is super interesting and I want to move on yet.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     You certainly use it to good effect in hoplon where you have crazy stuff like you write what looks like HTML, what any designer could pick up and look and say that looks very, very familiar.  Yet at some point it turns into something else.  It's very cool.</p>
+
+<p><strong>ALAN</strong>:     Yeah, we're kind of calling off that experiment, though.</p>
+
+<p><strong>CRAIG</strong>:     Interesting.  Okay.  All right, well, we'll have to talk about that.  I actually haven't gone down that road, but anyway.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Let's not lose track.  File sets I understand.  Great explanation.  I get why you'd want to have that.  I think it's pretty straightforward.</p>
+
+<p>The other thing we wanted to talk about, though, was pods.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I can maybe try and do that one.</p>
+
+<p><strong>MICHA</strong>:     Yes, please.</p>
+
+<p><strong>ALAN</strong>:     The JVM is a very compelling platform for many, many reasons, but maybe one of the most underappreciated and misunderstood and maybe even hated feature is this concept of the classpath and the business with class loaders.  This is like mid level to advanced sort of Java person adventure at some point if someone interacts with class loaders and dynamically adding Java classes or resources to the classpath depending on various situations.  It's something people will run up against at some point in their usage of the JVM platform regardless of what language they're on.</p>
+
+<p>They're one of those things that are very unwieldy, but it's also very powerful.  Once you understand how class loaders work, you can do some pretty powerful things.  Java application servers are examples of things that people have built that are based on the utility of the class loader, the idea that you can have a JVM, for instance, serving multiple different Web applications, and each of those Web applications is its own set of dependencies.  Maybe a different version of the same dependency.  The way you can do that is with class loaders.</p>
+
+<p>The class loader thing is not – I'm not aware of any other language run times.  I don't know much about the CLR.  I'm not sure if it has a class loader type thing.  But the really weird, compelling thing about class loaders in the JVM that distinguishes them is that they are values, more or less.  They're first class in the sense that you can create a variable that contains a class loader where a class loader is effectively a global scope for some execution context.</p>
+
+<p>Code that runs inside that class loader can see things that code running outside of it can't necessarily see.  It's almost like you're running JVMs within JVMs for a lot of values in JVM.  So it's a scoping mechanism.  It's basically a first class global scope.</p>
+
+<p>But because it's so difficult and tricky to work with traditionally, few people, even if they need them, sort of shy away from working directly with class loaders.  There are some gotchas, some historical things about class loaders that make them kind of daunting.  But any JVM language makes good use of class loaders, and anybody who is doing any kind of application server type stuff where they have some kind of container for other kinds of app is going to do class loader stuff.</p>
+
+<p>Pods in boot are basically the working person's practical class loader.  It is a set of functions that give you the ability to create a class loader, more or less, and to run code inside of it, and to get and to ship data to and from this isolated environment.  It's like a very lightweight container.</p>
+
+<p><strong>MICHA</strong>:     Clojure runtime specifically.</p>
+
+<p><strong>ALAN</strong>:     What's that?</p>
+
+<p><strong>MICHA</strong>:     Specifically Clojure.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, so each pod is an instance of the Clojure runtime running inside the same JVM that the creator of the pod is running in.  But it's a totally different Clojure runtime.  For instance, if you do def X1 in the parent Clojure runtime, but then in the pod you do def X2, and then you evaluate code in both places, in the runtime where you created the pod X is going to be 1.  Inside the pod, X is going to be 2.</p>
+
+<p>They're different Clojure runtimes, but they're also different JVMs to the extent that you can use boot's dependency resolution set to load dependencies into pods that sibling pods or parent pods will not see.  And so the utility of this is, I guess, one of the reasons I use pods a lot is we do a lot of stuff on AWS.  When I can, I use Clojure libraries that add niceties to working with AWS Java APIs.  The problem, though, is that a lot of these different Clojure libraries depend on different versions of the AWS SKD, which is a massive dependency, and you can run into weird problems if you load it multiple times, different versions of it.</p>
+
+<p>One mitigation is you can add.  You can create a pod, so you create a Clojure instance.  Then you add dependencies to it.  For instance, the AWS SDK and then maybe Bandalore, which is a library for working with SQS that depends on the SDK.</p>
+
+<p>Now inside that pod you can run Clojure code that uses Bandalore, uses that version of the AWS SDK, but is not impacted by whatever version of either of those libraries you load into the parent pod or the parent environment in which you've created the pod.  It's a way for you basically to program as if you're spawning new JVMs with totally different sets of dependencies and then communicate with these runtimes.  That really reduces the likelihood of you running into strange dependency problems.  They're, I guess, a mitigation tool, a tool for mitigating classpath issues.</p>
+
+<p><strong>CRAIG</strong>:     Would you use this at development time for an exploratory program, or is this something that you would deploy?  What's the use case here?</p>
+
+<p><strong>ALAN</strong>:     I guess there are two.  The first use case that it was developed for primarily was, say you're writing a task.  Say you're writing – say Micha ships a library that has this NS+ library in it.  He depends on some other library.  What would be one that you would depend on?  Tools namespace or–</p>
+
+<p><strong>MICHA</strong>:     Sure.</p>
+
+<p><strong>ALAN</strong>:     –ClojureScript Analyzer.</p>
+
+<p><strong>MICHA</strong>:     Anything from Apache with a million dependencies.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  StringUtils from IO Commons or whatever he uses in there.  Let's say he distributed this not as a boot task, but as a library, just a Clojure function and a Clojure project with dependencies in Maven and a single function that maybe let's say it takes a file and it rewrites it into one of Micha's NS augmented files and ClojureScript files.</p>
+
+<p>I would look at this.  I would be like, well, I want to use Micha's thing.  I have a build going on over here in boot, but I see he depends on, like, all kinds of stuff from IO Commons and whatever that conflicts with things that are already in my application.  The question is, how can I integrate Micha's cool function for transforming files into my build without messing up my build time dependencies and potentially my runtime dependencies depending on what I'm doing?  The answer there is I write a boot task and, inside the boot task, I maintain a pod that contains an instance of Micha's library that's totally isolated from everything else in my application, and I can feed it files to transform, and I can get files back from it that have been transformed.  But that is totally isolated from a dependency perspective from the rest of my JVM or my runtime.</p>
+
+<p>In the build context, pods are a way to use libraries from the Internet from Maven that do useful things, integrate them into your build process without imposing on yourself any kind of classpath pollution or overwriting or general classpath problems.  Basically, you bring them in scot-free.  That's kind of the reason we came up with them.</p>
+
+<p>The second reason you might use them, which is rarer, is if boot is the entry point to your application in production.  In most cases people are –say you're building a Web app with boot.  What you'll do is you'll work with the Web app locally with the boot REPL or you start a local ring jetty or you'll use the Web serve task to work on it locally.</p>
+
+<p>But at the end of the day, you want to ship a WAR file.  That's going to go up to Heroku, Beanstalk, or your own Tomcat, whatever.  In the local development case, the entry point to your application is you typing boot development and whatever your task name is.  In production, the entry point to your application is the servlet entry point that was produced by the WAR task.</p>
+
+<p>In the local case where boot is the entry point, all of the boot runtime stuff is available for you to use like pods and file sets.  But in the production setting where Tomcat selects and uses the entry point to your function, the boot runtime stuff is not available there because, in order to make pods work, we need to run Java code before we run any Clojure stuff.  Basically, we set up the pods before starting any Clojure instances.  It's kind of a hand-wavy technical description of the issue.</p>
+
+<p><strong>MICHA</strong>:     Yeah, like all Clojure code needs to run in a pod and, if it's not running in a pod, then it kind of ruins it for the rest of us.  Yeah, the boot executable starts with the Java program that constructs the first pod where your code is going to run.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     But if there is no phase distinction between build and run, like they're just kind of interleaved and production boot is your entry point, which it might be if you're running–I don't know–we've done this in Docker.  You can run boot in Docker and then boot is your entry.  Then all the boot runtime stuff is available, and then you can use pods at runtime.</p>
+
+<p>I've done this in the past with this Bandalore library.  I was using dependencies at runtime to interact with SQS, and I didn't want to suffer their transitive dependencies.  In retrospect, maybe ill-advised.  I don't know.  Maybe it's good to–</p>
+
+<p><strong>MICHA</strong>:     I think it works out well with Docker because, with Docker, you can bake the Maven cache into the….</p>
+
+<p><strong>ALAN</strong>:     Right, yeah.  That's right.  The problem with doing it at runtime is the Maven resolution then also happens at runtime, which means that you're potentially pushing something into production that can't yet run.</p>
+
+<p><strong>CRAIG</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     It still needs to talk to Maven central or whatever to download the stuff.  Yeah, if you're working in Docker, you can build your image separately from deploying it and, as part of the build step, you can cache the dependencies you're going to need at runtime.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and being able to use pods, like if you run into some problem, you could spend a long time messing around with dependencies and trying to figure out a way out of it–</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     –by negotiating amongst all the libraries.  It's like the U.N.  You could just throw a pod at it and the fire is out, at least.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, that's interesting.  I've definitely dealt with that problem of kind of different fiefdoms, right?  It's worse than the U.N. because at least there you have national borders.  This is like, well, I'm going to take the U.S. and overlap it with Canada.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     There are two St. Louises or two towns that want to occupy the same piece of ground.  How are we going to do that?</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Yeah, St. Louis 1.0 and 2.0, and they're incompatible.  Yeah.  No, that makes a lot of sense to me.  Okay.  Very cool.  This is such good stuff.</p>
+
+<p>I am quite happy with what you said, Micha, which is being able to use boot without having to have had a really deep understanding of this stuff.  But I'm certainly glad we had this discussion about it.  It's funny.  We've been talking for close to an hour now, and very usefully, I think, and yet when I step back, and maybe this is me being naïve, but I don't think so.  It really is a fairly smallish thing, right?</p>
+
+<p>You mentioned tasks, file sets, and pods.  I've only really had to kind of vaguely understand one of those things to be useful with it.  That's pretty cool.  I always like it when that happens with software that I write, although I can't claim to have done anything as elegant as what you guys have pulled off.</p>
+
+<p><strong>ALAN</strong>:     Thank you.</p>
+
+<p><strong>MICHA</strong>:     Thanks.  Yeah, that's–</p>
+
+<p><strong>ALAN</strong>:     That's very high praise indeed.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Well, man, I really do want to talk about hoplon.  I think we're going to wind up abbreviating the discussion, but it's just something I've been working on lately, working with lately, rather.  Maybe we can at least–</p>
+
+<p>Well, I guess maybe I should stop there and say, is there anything else that we should say about boot?  Is there another important part of the boot story that we haven't discussed?</p>
+
+<p><strong>ALAN</strong>:     I would say a couple things about boot.  First of all, the barrier to trying it is super low.  It's as low as it ever has been.  We have a number of – for a long time a lot of people didn't like boot or at least were discouraged from using boot because it was a real pain to use in Windows.  We still don't support Windows 7 and below and never will because of limitations of the file system API.  But actually Sean Corfield, who is a heavy boot user and contributor and sort of friend to the cause, has been happily using boot on Windows 10.  As far as we know, it works very well on Windows 10.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     And on Mac and Linux, those are the platforms we use boot on every day, so it's in really good shape there.  It's really easy to install.  The second thing I would say is that we have probably one of the most friendly and knowledgeable communities out there in the Clojure world, maybe even in the open source at large, and particularly on the Clojurian Slack thing in the boot channel.  I guess we can make a liner note for this.</p>
+
+<p>We have a boot channel in there of people who have written tasks.  There are people who are using boot for Web development.  There are people who are using boot to work with.  One guy did it – they used it in stuff like protobuf.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     All kinds of interesting things going on and people are very friendly.  Like I said, the barrier to entry is very low and it's very easy to get help if you're stuck.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and Martin and Juho work on the ClojureScript front.</p>
+
+<p><strong>ALAN</strong>:     Yeah, there is a tremendous momentum in the ClojureScript world, and a lot of it is boot centric.  Basically people extending boot and, well, not even boot.  Basically creating and sharing and integrating libraries to sweeten the ClojureScript development experience in a boot based app.  There are a lot of directions, somebody interested in learning about boot, could go with it, but I think you'd be hard pressed to come up with some kind of application that you're going to do on the JVM that boot wouldn't help you do it somehow.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, I've certainly had no trouble doing the things that I've wanted to do, and I've done so far one, I would say, definitively non-trivial application.  Nothing at a client yet, nothing kind of that kind of environment, but I've shipped a single page Web app that's a real piece of software.  It's not one weekend hacking or anything like that.</p>
+
+<p><strong>ALAN</strong>:     Awesome.</p>
+
+<p><strong>CRAIG</strong>:     I had no trouble whatsoever with boot.  Boot never – I shouldn't say that.  I think I have a very small amount of times where I had to go read the wiki to overcome some minor thing, but I don't remember any time where I was like, oh, my God.  I just spent an entire day just getting files to compile or something that should be trivial, so it was a good experience.</p>
+
+<p><strong>ALAN</strong>:     Cool.</p>
+
+<p><strong>MICHA</strong>:     That's really awesome.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.  I really want to talk about hoplon, so let's do that.  We are going to wind up cutting it short.  There's no question because I think hoplon is another very interesting piece of kit and given that we just spent an hour talking about boot, which is also interesting.  But given the relative surface areas, I suspect that we would wind up with a three-hour show, which we attempt not to inflict on our listeners.</p>
+
+<p>I think maybe if we could at least get you guys to mention what hoplon and, of course, javelin are, I do have a couple quick things I'd like to touch on and then we'd have to figure out a time it makes sense for you to come back and for us to really devote the time to it that it would deserve.</p>
+
+<p><strong>ALAN</strong>:     Sure.  Well, I guess, I would say we can cover.  We can get into it here, but there's also a hoplon channel in Clojurian Slack that has an active user base.  We're there, so anyone who is listening to this and is wanting for more on hoplon or any of the things we're about to discuss, they can always find us there.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  You know what?  I have to say that all these things, for me anyway, is like the main – it's really – I don't know.  For me, Clojure is very unique in my experience.  Hoplon, boot, and all these things, they're very – it's kind of like – it's very rewarding to me because they are things that, as far as my use of them professionally to make money and to get actual work done, they're pretty much done.  They do everything we need them to do, and we're moving on.  We're thinking about other problems now, and we don't need to keep solving these problems.  I've never experienced that before using Clojure.</p>
+
+<p>Using other languages, I'd always end up – I could never form the abstractions that were durable and composable enough to be used in the next project.  I would always end up having to rewrite something or solve the same problem over and over again.  I'd never experienced actually solving a problem before or even thinking that it was something that was worth spending your time on trying to do, like trying to solve a problem of making websites once and for all.  That's all due to Clojure, I think.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  I have had the same experience with a couple and I mean two different things that I've written.  I've got this little Stochastic Markov chain thing, and it's like it's done, right?  If anybody asks me, should I use that, I'd be like, yeah.  Go for it.  It's good.</p>
+
+<p>If they say, is there anything that you could change?  I'm like, well, sure.  I've got a laundry list, but do I need to bother?  Eh.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     It's great.  It's a great feeling.</p>
+
+<p><strong>ALAN</strong>:     Then people have so much power to pave over whatever omissions you made too, thanks to Clojure's dynamism and stuff.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Cool.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.  We are actually going to save hoplon and javelin for another time because I really don't want to shortchange them.  I think you could probably explain them in five minutes, but people can go over to the Web page for that.  I think there's useful, extended conversation we could have.  Let's save that up.  Let's have you back on and have that discussion some other time rather than attempting to shortchange these technologies now.  What do you think?</p>
+
+<p><strong>ALAN</strong>:     Sounds like a good idea.</p>
+
+<p><strong>MICHA</strong>:     Sounds good.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Cool.  Awesome.  That's great.  I just got you to agree to come on again, which is fantastic.</p>
+
+<p>Cool, so I guess I will say, though, even though we're not going to spend an hour on hoplon, I always reserve time at the end of the show, as much as makes sense, as much as we need, to talk about anything else.  We often have a main topic in mind.  Today we certainly did.  But is there anything else?</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Here we are, right?  It's a good opportunity.  What else is going on that we should talk about today?</p>
+
+<p><strong>ALAN</strong>:     There was something that I wanted to mention.  It's funny you brought up earlier in our conversation the production on the Pluralsight course.  There is a project that I have started with Daniel Higginbotham.</p>
+
+<p>Daniel Higginbotham, author of Clojure for the Brave and True, man about town in really every single way, he's made his brave Clojure thing.  He's got a Clojure jobsite now.  The dude is–</p>
+
+<p><strong>MICHA</strong>:     Also works at Adzerk.</p>
+
+<p><strong>ALAN</strong>:     Works at Adzerk, a great person, working on all kinds of fun stuff, very enthusiastic.  He and I collaborated, I guess, two years ago on his Clojure for the Brave and True book.  By saying we collaborated on it, really I'm taking way more credit than I deserve because he had it basically written before he went to a publisher.</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>I had the opportunity to be the technical editor and even write the foreword, and I kind of developed a cool working relationship with Daniel.  He and I both have a lingering interest in the concept of education, or at least we're just so excited about Clojure that we feel like it's something we should do.  I don't know.  I feel like a lot of Clojure people have this inclination.  It's like I know this awesome thing.  How do I tell other people about it without getting slapped?  
+</code></pre></div></div>
+
+<p>He and I started on this project called MX Go, mxgo.io.  The concept is basically online learning, short courses modeled more after talk length things than course length things.  I guess the TLDR would be what if Strange Loop had a baby with Pluralsight.</p>
+
+<p>[Laughter]</p>
+
+<p><strong>ALAN</strong>:     The site isn't up as of this recording, but that's something we're going to be developing.  I think, by the time that this goes out, we'll have that up, so mxgo.io.  If it's something you're interested in, either producing content for or subscribing to, then I would encourage you to check that out.  That's kind of been ramping up in my world.  Then hopefully I can convince Micha to come on and do the boot course.  Maybe you can do the hoplon course.  Then instead of recording another Cognicast, we can just tell people to subscribe to MX Go.</p>
+
+<p><strong>CRAIG</strong>:     There you go.  Is this all going to be–?  I mean obviously you and Daniel are both huge fans of Clojure.  Is it going to be specific to Clojure and related technologies?</p>
+
+<p><strong>ALAN</strong>:     That's a really good question and a cool thing about it is that it's not specific to Clojure.  Like I said, one of the main inspirations for it is the Strange Loop sort of….  The world filled with inquisitive minds, and there's a lot out there in computing going on outside of Clojure and outside of functional programming.  A lot of times people are – you don't know what you want to learn, right?  How do you find things that you would like to learn?  Well, you kind of need to be exposed to things that you weren't looking for.</p>
+
+<p>No, the content will not be limited to Clojure.  We've got some ideas lined up for different kinds of languages and CS topics.  We hope to mine the papers we love presenters.  We're really attracted to the idea of getting people to produce content who have already given a talk and encouraging them and helping them to convert their talk into a set of 20-minute explications with exercises on that topic.  Yeah, hopefully we have a pretty diverse set of topics.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  You just said "with exercises," which I think is a key point because people might say, well, YouTube.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I can go watch ten million conference talks, no problem.</p>
+
+<p><strong>ALAN</strong>:     Yeah, the big difference, I think, will be exercises, but also very few things actually go through the edit repeat cycle, which I experience in real time with you when you and I were making the Pluralsight Clojure course.</p>
+
+<p><strong>CRAIG</strong>:     Yes, you did.</p>
+
+<p><strong>ALAN</strong>:     I can lay down a track and in my mind it was amazing.  But if you look at like, you know, you forgot to talk about this.  You said this word three times.  There's a typo on line 25.  Not to disparage people who make content on YouTube because I think that's a great way to find new material too and just see awesome stuff, but it's free for a reason.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Addition definitely makes a difference.  You mentioned that you and I spent a week together producing a video.  I think that video was a total of maybe 3 or 4 hours, and it was two people for 40.  I mean it wasn't 40 hours.  You and I worked like at least one 10-hour day, right?  It was a boatload of work to produce, and there was no video.</p>
+
+<p><strong>ALAN</strong>:     That's true.</p>
+
+<p><strong>CRAIG</strong>:     It was slides and voice, so it's just a lot of work to do video.  There's no question about it.</p>
+
+<p><strong>ALAN</strong>:     That's why we're hoping we can cut down the size of the deliverable and then hopefully authors can leverage the fact that they've probably already given a talk or at least have notes on the topic, so then that cuts down on prep time too.  We don't want the production side to be too daunting.</p>
+
+<p><strong>CRAIG</strong>:     Right, and I think there are a lot of things you can do there for sure.  The comment was more aimed at the fact that when you see something polished there's a difference.</p>
+
+<p><strong>ALAN</strong>:     Totally.</p>
+
+<p><strong>CRAIG</strong>:     It's one thing to aim a camera that keeps tipping over at somebody standing at the front of a room full of people and hopefully you can hear them in whatever, versus oh, yeah, I can make out what all this, and there's bookmarks or whatever it is.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, totally.  Absolutely.  Cool.  Awesome.  Yeah, that's great.  I'm actually super excited to check that out.  I'm looking forward to seeing what you guys have to offer.  I mean one of the reasons I go to Strange Loop is exactly what you're talking about.  Just a world full of cool stuff and, quite frankly, I'm not aware of a lot of it.  Just being around people who are essentially a list of what's exciting is awesome.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I think it's super cool that, in our profession, you can meet – like at one Strange Loop I had the chance to meet Chuck Moore, which was like one of the formative experiences in my computing adventure.  Meeting Chuck Moore, holy cow, this is one of the names in computers and will be forever.  The fact that our profession is small enough and that the celebrities are usually friendly enough that you can meet really cool people and hear about really cool ideas.</p>
+
+<p><strong>MICHA</strong>:     I wonder if Larry Wahl was there.</p>
+
+<p><strong>ALAN</strong>:     I don't think he was, but he gave that talk that you linked me to at some other conference recently that I ended up watching.  It was really awesome too.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  All right.  Awesome.  Anything else that we should make sure to get to?  Micha, you have anything you wanted to share?</p>
+
+<p><strong>MICHA</strong>:     Well, I mean I have like a little reflection on boot, or are we past that time?</p>
+
+<p><strong>CRAIG</strong>:     No, it's all good.</p>
+
+<p><strong>MICHA</strong>:     Okay.  Yeah, so one thing that I think is good about it is maybe that it exposes the Java primitive, the JVM primitives to you in kind of a direct way, like when you make a pom.xml separately from the rest of the packaging.  What I think is good about this is, like, I'm not a big fan of Java, the language, but looking at java.util.concurrent, for me that was like a computer science education.  The way Maven is engineered, it's great that I knew that when I started working on node.JS stuff because then I was like in NPM land and I could see exactly why things were not going well.</p>
+
+<p>I think for beginners, they might be exposed to a lot of the JVM things, but I think that that's actually good because the JVM, the parts that we have to deal with, at least in Clojure, are super well engineered.  If you need to get stuff done reliably and people are depending on you, you can't go wrong with all those things.  I think boot exposes it to you, which lets you learn about them in kind of a friendly way.</p>
+
+<p><strong>ALAN</strong>:     We definitely – the JVM, the Java language are very conservative and well thought out approaches to managing change and improvement in their APIs.  Clojure, of course, does a spectacular job of basically never removing things.  Things will be added to the Clojure language, but things are never removed.  It's an extremely stable runtime environment.</p>
+
+<p>Then we kind of try to do the same thing with boot.  We haven't had a breaking boot in two-ish years, a year and a half.  Basically, it's a huge goal of ours to not introduce breaking changes to boot because we have dozens of services that are boot based that we would like to upgrade periodically, and we do not want to suffer for it.  Yeah, the whole stack, I think is like Micha says, can be daunting.  But once you learn it, you'll know it for a long time and it'll give you the ability to look at other systems and work with other systems in a new and powerful light, for sure.</p>
+
+<p>I totally just hijacked your moment.</p>
+
+<p><strong>MICHA</strong>:     No, I'm in agreement, dude.</p>
+
+<p><strong>ALAN</strong>:     Oh, okay.  All right.  I felt like I kind of swooped in.</p>
+
+<p><strong>MICHA</strong>:     Well, that's what I was going to say.</p>
+
+<p><strong>ALAN</strong>:     Okay.  Cool.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  All right, well, that sounds like as good a place to wrap up as any.  Assuming you agree, then, Alan, I will throw it to you for our final question, the one we always ask at the end of the show.  We ask our guest or guests to give us a piece of advice.  This can be of any form that they prefer, whether it's advice that you've been given or that you like to give.  I often throw in the addendum, it could be good advice or bad advice.  I don't think I've had anybody take me up on the bad advice one yet, but what do you got for us, Alan?</p>
+
+<p><strong>ALAN</strong>:     Well, so I found this really challenging because I have a conflicted – I'm conflicted about the very nature of giving and taking advice.  I don't know.  I look at a lot of things, and I see someone got very lucky.  It seems like the luckier someone is, the more freely they give advice.  But what does their advice mean?</p>
+
+<p>It's like getting number suggestions for the lottery from the lottery winner.  Is that going to help you?  Is that meaningful to you?  Maybe.</p>
+
+<p>I wracked my brain for, like, okay, this is a computer podcast.  What are some – who are the lottery winners and what–?</p>
+
+<p><strong>MICHA</strong>:     Give advice on being tall.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     Tell people how to be tall.</p>
+
+<p><strong>ALAN</strong>:     Yeah, how to be tall.</p>
+
+<p><strong>MICHA</strong>:     You obviously know the secret.</p>
+
+<p><strong>CRAIG</strong>:     I have a bit of advice about being tall.</p>
+
+<p><strong>ALAN</strong>:     Sure.</p>
+
+<p><strong>CRAIG</strong>:     Can I inject it?  So I am myself nothing like your height, Alan, but I always wanted to be taller just so I could use this line where someone walks up to you, and I'm sure you've had someone ask you, "Oh, do you play basketball?"  I always wanted to be tall enough to get that question so I could respond, "No, do you play mini golf?"</p>
+
+<p>[Laughter]</p>
+
+<p><strong>CRAIG</strong>:     I hope you'll use that sometime.  Anyway, back to your advice.</p>
+
+<p><strong>ALAN</strong>:     Oh, man.  I need to get a Google glass or something so I can record that moment and send it to you because I do get asked that question a couple times a year.</p>
+
+<p>Anyway, I wracked my brain for what is some advice that I've really taken to heart or has really paid off for me.  Then I thought, well, you know, in Matthew 25 Jesus' Parable of the Talents, is that the direction we want to go with this, you know, go religious with it?  I thought, well, probably no.  It needs to be like a computer thing.</p>
+
+<p>I thought, well, you know, it's really dumb, but one of the best pieces of advice ever was given to me by my drill sergeant in basic training, which was, if you're going to do something important tomorrow, get everything ready the night before.  That's something that never really came naturally to me, preparing for things that are important, but it's a very simple thing, especially if it's going to be early in the morning.  It's very simple.  You just lay out the clothes you're going to change into.  Or if you have a test, you study for it.  A very simple piece of advice, but I feel like I personally was never good at preparing for things, so I just had great faith that it's going to work out for me every time.  That was a piece of advice that I reflect on sometimes and I think is very simple and good.  Be prepared for things that are happening tomorrow.</p>
+
+<p><strong>CRAIG</strong>:     Well, we're all Clojurists.  We like simple, and that does not – as we are well aware, something being simple does not prevent it from being correct, profound, or any one of a number of other desirable qualities, so I definitely appreciate the advice.  As a father of two smallish children, you know, things like that need to be said to you at some point in your life.  It's not obvious automatically, so I'll have to maybe bring that….</p>
+
+<p><strong>ALAN</strong>:     Yeah, well, I guess as a new father, I can say it's definitely paid off too with bottle prep and clothing prep.  There's a lot of costume changes when they're two months old.</p>
+
+<p><strong>MICHA</strong>:     You waited until the night before to prepare for your kid?</p>
+
+<p><strong>ALAN</strong>:     Yes.</p>
+
+<p><strong>MICHA</strong>:     Laid out some clothes – ready.  Done.</p>
+
+<p><strong>ALAN</strong>:     Well, you know.  What is it?  Amazon.  There was Amazon Prime, but now there's Amazon – what is the hourly one?</p>
+
+<p><strong>MICHA</strong>:     Oh, yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Just in time.  I need a crib.  I need a box of diapers stat.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  You just install Amazon Echo or whatever it's called, the thing that listens, and it hears you swearing and the next thing there's a knock on your door with a bunch of diapers or whatever you need.</p>
+
+<p><strong>MICHA</strong>:     Oh, the button.  Right, right.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  Cool.  Well, all right.  We've degenerated into puns and computer jokes, but I do appreciate.  The advice is very good, and I thank you for sharing it with us.</p>
+
+<p><strong>ALAN</strong>:     Sure.</p>
+
+<p><strong>CRAIG</strong>:     I love the fact that it came from a drill sergeant.  That just makes it so much better in my opinion.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  His version of it was a little more obscene, so I toned it down.</p>
+
+<p><strong>CRAIG</strong>:     Appreciate that.  I appreciate that.  I'm converting it back in my head right now, but I won't share it.  Anyway, like I said, clearly people know that I've worked with you a lot, Alan.  You've worked with Micha a lot.  Micha and I have hung out a bit, so rather than make people listen to our idle banter for the next 45 minutes, I'm going to wrap it up there.  But I will stop to thank you both very much for coming on.  I really, genuinely enjoyed the conversation, learned a lot.  Thanks for the tools, too, by the way.  I really have been digging using this stuff.  Change is always fun, but I've also found it productive, useful, and enabling, so thanks on both counts, guys.</p>
+
+<p><strong>ALAN</strong>:     Thank you.</p>
+
+<p><strong>MICHA</strong>:     Thank you.</p>
+
+<p><strong>ALAN</strong>:     Yeah, really fun to be here.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  All right.  We'll wrap it up there, then.  This has been The Cognicast.</p>
+
+<p><strong>MICHA</strong>:     Bye.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Thanks.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     You have been listening to The Cognicast.  The Cognicast is a production of Cognitect, Inc.  Cognitect are the makers of Datomic, and we provide consulting services around it, Clojure, and a host of other technologies to businesses ranging from the smallest startups to the Fortune 50.  You can find us on the Web at cognitect.com and on Twitter, @Cognitect.  You can subscribe to The Cognicast, listen to past episodes, and view cover art, show notes, and episode transcripts at our home on the Web, cognitect.com/podcast.  You can contact the show by tweeting @Cognicast or by emailing us at podcast@cognitect.com.</p>
+
+<p>Our guests today were Alan Dipert on Twitter @AlanDipert and Micha Niskin on Twitter @MichaNiskin.  Episode cover art is by Michael Parenteau, audio production by Russ Olsen and Daemian Mack.  The Cognicast is produced by Kim Foster.  Our theme music is Thumbs Up (for Rock N' Roll) by Kill the Noise with Feed Me.  I'm your host, Craig Andera.  Thanks for listening.</p>
+    </article>
+  </main>
+</body>
+</html>
diff --git a/md/TechWorks/Cognicast112.html b/md/TechWorks/Cognicast112.html
new file mode 100644
index 0000000..167d3d6
--- /dev/null
+++ b/md/TechWorks/Cognicast112.html
@@ -0,0 +1,904 @@
+<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>Cognicast Episode 112: Solving problems and Boot, part II</title>
+  <link rel="stylesheet" href="../style.css">
+</head>
+<body>
+  <main id="main">
+    <header class="site-head">
+      <a class="site-brand" href="../TechWorks.html">
+        <span class="site-brand-name">TechWorks</span>
+        <span class="site-brand-tagline">Selected work</span>
+      </a>
+      <nav class="site-nav" aria-label="Archive navigation">
+        <a href="../TechWorks.html">Works</a>
+        <a href="../TechWorksArchive.html">Archive</a>
+      </nav>
+    </header>
+    <article>
+      <h1>Cognicast Episode 112: Solving problems and Boot, part II</h1>
+      <p><small>Published by The Cognicast on November 3, 2016. <a href="https://www.cognitect.com/cognicast/112">Visit the original episode page</a>.</small></p>
+      <p><audio controls preload="metadata" src="./media/audio/cognicast-112.mp3">Your browser does not support embedded audio.</audio></p>
+      <h2 id="transcript">Transcript</h2>
+
+<p><strong>CRAIG</strong>:     Hello, and welcome to Episode 112 of The Cognicast, a podcast by Cognitect, Inc. about software and the people who create it.  I'm your host, Craig Andera.</p>
+
+<p>Well, we have a bunch of Cognitects that will be out and about in the world.  I want to mention a few of the places they'll be this month.  This is all in 2016, November of 2016 specifically.</p>
+
+<p><strong>First up, there's a meet-up</strong>:  Clojure PDX in Portland, Oregon.  Stu Halloway will be there.  Rather, he'll be giving a remote presentation on agility and robustness in clojure.spec.  That's November 3rd.  The venue for that is Portland.  Although, like I said, it's a remote presentation.</p>
+
+<p>Mike Nygard will be doing a bunch of stuff in November.  He'll be all over the place, actually, doing a lot of cool talks.  The first stop for him is the DevOps Enterprise Summit, which is in San Francisco.  That's happening November 7th through the 10th at the Hilton San Francisco Union Square.  He will be presenting at that conference.</p>
+
+<p>He will be doing training at the O'Reilly Software Architecture Conference also in San Francisco.  That's happening November 13th and 14th.  The title there is Architecture without an End State.  It's a two-day course, again taught by Mike Nygard.  This, by the way, is not Clojure specific.  You can search on that for more info.</p>
+
+<p>We've got a lot of things to talk about today, so I'll leave you to discover those on the Internet.</p>
+
+<p>More Mike Nygard in Iceland at G/O Digital.  This is November 16th at the Hilton Reykjavik Nordica.  He will be speaking there at that conference.</p>
+
+<p>Carin Meier will be speaking at Ohio DevFest, which this is happening Saturday, November 19th at the Tangeman University Center.</p>
+
+<p>Of course, the Clojure/conj is coming up.  That is, I suppose, technically in December, although the training course is happening immediately before.  We have a Datomic course.  I'll be teaching the Clojure course.  Those are at the very end of November.  The conference itself is December 1st, 2nd, and 3rd.  This is happening in Austin, Texas.  Still tickets available.  You should go to Clojure-conj for information about the speaker lineup, which has been posted, and to buy tickets.  Sponsorship opportunities are still available, so lots of good stuff at Clojure-conj.org.</p>
+
+<p>Finally, I want to mention InClojure.  This is India's first ever Clojure conference - very exciting.  This is November 26th at the Hotel Novotel in Pune, India.  We've actually had a whole episode where we talked about our producer Kim Foster's visit to India and about the Clojure scene there.  Obviously that's coming along very nicely since they are now having a conference.  You can check that out at InClojure.org.  Definitely check that out.  That looks to be exciting.  We're certainly psyched that that's happening there.</p>
+
+<p>But that's a lot of stuff, so we will leave it with that and go on to Episode 112 of The Cognicast.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     Okay.  Are you ready?</p>
+
+<p><strong>ALAN</strong>:     Yep.  Ready.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, you were ready all along.  I was the one that clearly wasn't ready.  So here we go.</p>
+
+<p>Welcome, everybody.  Today is Tuesday, October 18th in the year 2016, and this is The Cognicast.  We are very, very pleased to welcome back, right back in fact, as it turns out.  We just shipped their episode, their previous episode today.  We're recording again right after the release of that.  I'm talking, of course, about Micha Niskin and Alan Dipert.  Welcome to the show, Micha and Alan.</p>
+
+<p><strong>ALAN</strong>:     Hey.  Thank you, Craig.</p>
+
+<p><strong>MICHA</strong>:     Good to be back.</p>
+
+<p><strong>CRAIG</strong>:     It's really great that you were able to record again.  I mean it's not that soon for us.  We recorded that episode way back a couple months ago, but it's perfect timing, in my opinion, to have you back on.  You know we just got done talking about – our audience will have just, in the last couple weeks, have heard you talking about boot.  They're well aware then that that conversation – we left off before we could talk about javelin and hoplon, which are two other extremely interesting technologies that I have been using in my free time projects quite extensively over the last few months.</p>
+
+<p>Of course, we will cover other things as they come up.  The two of you are both just endless fonts of interesting information, anecdotes, high jinks, so forth and so on.  So I'm sure we will have another great conversation.  I'm looking forward to it.</p>
+
+<p>But, of course, before we get into that, we always ask at the beginning of the show a question about art.  Specifically, we ask for our guests to share with us some experience of art, whatever they think that means.  Since we had Micha go last time, which resulted in, I think it's safe to say, the creepiest cover we've ever had on any of our episodes ever – it was also awesome, by the way–</p>
+
+<p><strong>MICHA</strong>:     Bam!</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  We had you go last time.  That resulted in that.  This time we're going to ask Alan to answer the art question.  Alan, would you like to share with us an experience of art?</p>
+
+<p><strong>ALAN</strong>:     Sure.  Maybe it's a kind of performance art.  I mean everything is art.  Nothing is art.  But I would call this art.</p>
+
+<p>As you know, I'm kind of fascinated with space travel and space exploration and, you know, the heyday of space travel, the Apollo program, stuff like that.  I've always been interested in that and, when I was a kid, I wanted to be an astronaut and a pilot, but I think, in my adult life, I was sort of reinitiated with Russ Olsen's incredible talk about sort of the developer engineer legacy and the relationship of that to the space race.  I'm sure you know what I'm talking about.</p>
+
+<p><strong>CRAIG</strong>:     Oh, yeah.  That talk is excellent.  People should go look up Russ Olsen's To the Moon to see exactly what you're talking about.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Amazing.  I was really fortunate to have seen it live, and it was just really moving to hear the story told from someone who was there, who was there as a child, you know, a particularly imaginative, engaged child talking about what it was like to be in the same world while that was going on.  As someone who existed in the future, I've always had this sense of nostalgia about it, so it's like ten times more awesome probably than it ever was.</p>
+
+<p>But obviously you know the space program is not really a work of art.  But I think, like any big endeavor, there are works of art performed routinely.  One of the neater things that I've seen related to the space program that was kind of an artistic interaction was – and this is kind of – the astronauts actually have some artistic flexibility, especially in the '60s because the astronauts would be on TV, and they would be on the radio.  NASA, amazingly, did not really script what they were going to say.  They gave the astronauts a fair amount of leeway into what they were going to say on these shows, which is pretty incredible, I think.  The first humans doing this basically are just given an open mic and asked, "How do you feel about this?" because everybody really wanted to know, like, what's it like to be further away from earth than any human ever has been.  And what would a person say to that?</p>
+
+<p>I think, by and large, the astronauts were performers and artists because they were probably the only people in the world who were capable of both doing that mission and also having, like, that casual tongue in cheek kind of test pilot sort of worldview.  So they could be like, you know, flying into the sun to their doom and crack some joke, you know.</p>
+
+<p><strong>CRAIG</strong>:     Is it warm in here?</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Is that just me?  Did someone turn it up, or are we going to die in ten seconds?  You know?</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     And I'd always admired that kind of humor and that kind of affect.  If you've read The Right Stuff by Wolfe, he talks about that a lot and the whole Chuck Yeager personality meme.  That's kind of the context.</p>
+
+<p>The piece of art in particular that I'm thinking of, there was a mission Apollo 8, which was in December of 1968.  We landed on the moon in, I think, May of 1969.</p>
+
+<p><strong>CRAIG</strong>:     July, I believe.</p>
+
+<p><strong>ALAN</strong>:     July?  That's right.  Apollo 8 was one of the precursor missions.  It was the first mission to orbit the moon.  They did not land on the moon, but they went all the way out there.  They orbited it, went around the dark side, and came back.</p>
+
+<p>As I understand it just from history books and stuff, 1968 was a tough year for everybody with Tet Offensive and RFK assassination and Martin Luther King was assassinated in that year too, so everyone was on edge - a very crappy year.  These astronauts on this Apollo 8 mission were kind of in a weird spot because they were supposed to say something nice, and it happened that they were headed to the moon on Christmas Eve of 1968, so everyone was tuned in anticipating what they were going to see and, I imagine, hoping to be distracted.</p>
+
+<p><strong>There was an interview, later I saw, where they explained why they made the selection.  But basically the astronauts chose to read from the Book of Genesis, like from the beginning.  And there's this very moving piece of video where they had the spacecraft camera aimed at earth with an odometer that was rising</strong>:  172,000 miles, 173,000 miles.  You can tell they're going at super fast speeds.  The guy is just reading from the beginning of the Book of Genesis.  In the beginning there was nothing and then God moved over the face of the waters and so on.</p>
+
+<p>It's kind of – I don't know.  It's music video like in that it seems almost too beautiful to have happened for real.  I don't know.  It was an artistic experience, and I definitely would count the astronauts who had that idea as artists because I would have no idea what to say.  They said, hey, you're going to the moon.  What do you tell the folks back at home?</p>
+
+<p>Yeah, I don't think art is necessarily an artifact that you make because art, I think it's more like when you look at something, you might consider it to be art because of what it does.  So a cool part of it is there is kind of an artifact because there is somebody who recently made a music video that mashes up a kind of spacey, upbeat tune with the NASA footage of the dude saying this.  The artist is Lindstrom.  He's like a Norwegian – Norwegian space disco is the genre.</p>
+
+<p>But there's this kind of weird, spacey, futuristic music playing and then the astronaut reading from Genesis, and it's pretty surreal.  If you search for, I think, Lindstrom space Apollo 8 on YouTube, you'll hit it.  It's a very crazy, interesting video.</p>
+
+<p><strong>CRAIG</strong>:     Very cool.  We will, of course, put a link to that in the show notes so people can find it easily that way too.  Well, it's interesting to me.  I mean, so I agree with your statement at the beginning there, Alan.  It's like, well, what is art?  Art is everything.  Art is nothing.</p>
+
+<p>But the definition I always kind of reach for just to have something to hang onto is something whose intent is or effect perhaps is to make you feel something, to make the observer or participant feel something.  The space program is clearly, clearly, like, a very strong intersection of emotion and technology for many people.  I mean it's the pinnacle of technology in many ways, and yet people also have this really strong kind of emotional attachment too.  I think your example is a great, you know, almost the pinnacle of that, right?  Like how could you – that's clearly something that is definitely about the feel of something, the emotional impact of a moment combined with technology.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Admittedly, technology that is less powerful than what we all have in our pockets right now, but more impressive nonetheless.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  Yeah, no, I think by that definition, you know, something meant to impart a feeling.</p>
+
+<p><strong>ALAN</strong>:     I don't necessarily think the intent is at all relevant.  I think it's the effect that makes it art, not the intent.</p>
+
+<p><strong>CRAIG</strong>:     I'll buy that.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean there's multiple definitions.  I mean some things, some things you can call art retroactively.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, sure.</p>
+
+<p><strong>ALAN</strong>:     I think that, yeah, for me anyway, I think that's the necessary and sufficient condition.  I don't think you can actually make art.  I think it can be art, you know, if a person experiences it in a certain way.  You know?</p>
+
+<p><strong>MICHA</strong>:     You're saying it's like eye of beholder kind of thing.</p>
+
+<p><strong>ALAN</strong>:     Yeah, just like, you know – yeah.  I mean I think we have math and science and whatnot to explain the world, but we have art to explain ourselves.  That has to be, I think, an internal thing that the person experiences that.  You can't really describe it in terms of logical systems.</p>
+
+<p><strong>CRAIG</strong>:     The distinction that comes to my mind when you say that is – so this is what I talk to my kids about is I think there's a confusion a lot of times.  I'm not saying that this is something that either of you is doing, but just as an interesting phenomenon between kind of an artifact and an event.  Like I said, well, let's say that we all sat down and played a game of Monopoly.  Then we put the game in the box, and we put the game on the shelf.</p>
+
+<p>I would say, "Well, where is the game?"<br />
+They would say, "Well, it's on the shelf."<br />
+And I said, "No, no.  I mean the game we just played."  Right?</p>
+
+<p>Like we all sat around and we can talk about that.  We played at this time.  We played at that time.  Where is that?  Of course, the answer doesn't make any sense, but I think that there are times.  That's kind of the point of that exercise that I ran through with them is to be able to differentiate between artifacts and events because sometimes we talk about things like where is this thing, but really it was an event.  It was a process, and it doesn't make sense for it to be in a place.  Like where does the light go when you turn it off?  That type of question.</p>
+
+<p>Anyway, sorry.  No, that's a really cool story, Alan, I mean a really cool – I'm glad you related that.  That's very good and it's good observations from the both of you on that.</p>
+
+<p>I love this part of the show, but we do, of course, have other things that we would like to talk about as well.</p>
+
+<p><strong>ALAN</strong>:     No, no, no.  Let's keep going with this.</p>
+
+<p><strong>CRAIG</strong>:     We could.  I know we definitely could.</p>
+
+<p><strong>ALAN</strong>:     No, no.  Let's please not.</p>
+
+<p><strong>CRAIG</strong>:     The only thing that stops me from doing that is that we were in the middle of what I thought was a really interesting conversation last time.</p>
+
+<p><strong>ALAN</strong>:     Yes.</p>
+
+<p><strong>CRAIG</strong>:     We didn't get a chance to finish it, and so as much as this is interesting, I'd love to loop back to that.</p>
+
+<p><strong>ALAN</strong>:     No, totally.  I'm just kidding.  Yeah.</p>
+
+<p><strong>CRAIG</strong>:     No, but right.  I get that.  Alan, you're a funny guy.  Funny guy, Alan - real funny guy.</p>
+
+<p><strong>ALAN</strong>:     I'll shut up now.</p>
+
+<p><strong>CRAIG</strong>:     No, no, don't shut up.  That's kind of the point is for you not to shut up.  If you shut up, the show gets really–</p>
+
+<p><strong>ALAN</strong>:     I'll shut up and then Micha can talk.</p>
+
+<p><strong>CRAIG</strong>:     Well, that'd be okay.  That'd be okay.  Anyway–</p>
+
+<p><strong>MICHA</strong>:     Alan, can you do anything right?</p>
+
+<p><strong>CRAIG</strong>:     The last time on the show we basically covered the first leg of the tripod of technologies that I kind of had you on to talk about, which the three are boot, hoplon, and javelin.  I don't know if that's the right order, but we talked about boot first, which makes sense to me.  It's kind of, in my opinion, the right place to start.  But we didn't get a chance, because there was so much interesting stuff to go through, to talk about javelin and hoplon.</p>
+
+<p>Now, if I was going to guess, I would imagine that it makes sense to sort of jump over to javelin first, but maybe you, as the creators of these technologies, have a different opinion.  I'll leave it to the two of you to decide how we should approach that.  What we would like to do, I think, is maybe explain what it is for anybody that hasn't had  a chance to encounter it or not.  But then I have a bunch of questions I want to ask you about it since I've been using it a bunch.</p>
+
+<p>So all of which is a long way to–</p>
+
+<p><strong>ALAN</strong>:     So, yeah.</p>
+
+<p><strong>CRAIG</strong>:     Go ahead.  Go ahead.  Go ahead.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     No, I have a thought about how to lead into this.</p>
+
+<p><strong>CRAIG</strong>:     Okay.</p>
+
+<p><strong>ALAN</strong>:     The last time, if I remember correctly, we talked a little bit about the origin story to, like, set up the background and the kind of things we were facing that resulted in the thing.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     I feel like I told most of that story, but I feel like in this case Micha kind of owns the origin story because he's the one who did the original work on this technology at the Fresh Diet.  I think he probably went through the most evolutions of it.  I'm talking about the white labeling problem and stuff.</p>
+
+<p><strong>MICHA</strong>:     Yeah, yeah, yeah.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.</p>
+
+<p><strong>MICHA</strong>:     Sure.</p>
+
+<p><strong>ALAN</strong>:     Maybe Micha could start there and then I could.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  I love origin stories.  Go for it.</p>
+
+<p><strong>ALAN</strong>:     All right, cool.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     Yeah, so originally I was working with Ray Willig at the Fresh Diet.  He also, like, we started using Clojure there, and we had really, really good – a good experience with Clojure.  This was in, like, maybe 2012, something like that.</p>
+
+<p>The specific problem that we had, the company delivered fresh, gourmet meals all around the country, so we had kitchens all over the place in all these different cities, and we did the entire stack from sourcing fresh ingredients.  We had our own deliveries.  We did routing, everything, and we had, like a very full featured interface that the customers could use to figure out which.  We would publish menus that had lots of choices, and they could choose different things that they wanted.  They could also adjust them saying they didn't like things or, if they did like things, they could have extra, like extra peppers, whatever.</p>
+
+<p>Also, there were a ton of more and more complex promotional, like marketing promotions.  They would involve things like you can order a plan for a month, so it's a month's worth of food.  But you don't have to consume it all.  You could only get, like, a day here and then, like, next week you get two days of food and so on.  So you could order 30 days worth of food and then, if you want to quit within the first week, we prorate it according to this formula, and then if you want to quit with the second week.</p>
+
+<p>Anyway, they kept making more and more complex marketing type models that we would have to implement.  Also, they were reaching the size where they had to start modularizing the business because they already were doing a lot of direct business with customers, but there was a lot of money also in being the backend to other people, so like celebrity chefs, for example, would want to make their own front end and use our services because we had the domain knowledge to actually make the food and deliver it, which is pretty complicated.  Anyway, so our system was this, like, 250,000 line PHP application that basically mediated every single aspect of operations of the company.</p>
+
+<p>They're like, "Hey, Micha.  Can we, like, just white label this stuff?"  There's no way.  You cannot.  It was all, like, HTML being admitted by PHP with, like, hundreds of CSS things coming in and out, so it was just not possible.</p>
+
+<p>We had to think about how to make a system that would be flexible enough to allow different customers to have different workflows.  An example of a specific case of this was we had a customer who wanted to use us with a nutrition focus rather than the focus that the Fresh Diet had.  That means that the user interface would be kind of centered around nutritional, like this nutrition database view of your meals, which was unlike what the Fresh Diet itself was doing.</p>
+
+<p>And so how do you start to reconcile the two?  It's not just changing CSS or making colors different or whatever.  It's an actual workflow change.  And so we wanted to think of a way to make basically a framework for making applications on top of our service.  It had to be done such that we could make a new white label site within a certain amount of time in order to get the deal, you know?</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     We looked around at all the different things that were available and tried experiments.  We did a lot of weird things too like using Jekyll to generate a static site, which then used Knockout to talk to the backend - weird stuff like that.  We ended up realizing that we needed to separate completely the workflow part, which is basically the state of the application and the application as a state machine from the user interface, the presentation, or what you see on the screen because a lot of the aspects of the workflow are business logic, business concerns.  Those are constant.  Those will be in any implementation, but they have to be in the client too.  In other words, a person needs to select whether they're vegetarian or not before they can look at their menu, for instance, or something like that.  These aspects of the workflow are universal, and they always need to be maintained by the system.  We ended up eventually using ClojureScript, and hoplon basically came out of that.</p>
+
+<p><strong>ALAN</strong>:     And I think the influence of the spreadsheet model, too, it seemed like.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Because, yeah, I think one of the things that – so when Micha did most of this thinking and initial implementation, I did not work at The Fresh Diet, but I was communicating with him on the side channel.  It seemed like one of the things that he arrived at was the idea that you needed to separate the workflow, in other words the business.  You have a business, and there's domain knowledge with the business.  There are certain operations that are valid or invalid given some configuration of domain data.  That's a separate thing from what the person can see and how they're allowed to influence that workflow.</p>
+
+<p>One of the things that Micha ran into that he very excitedly told me about, if I remember right, was that that's basically what a spreadsheet is.  If you consider a spreadsheet and charts based on a spreadsheet as a workflow and views into that, like mediated views into the underlying workflow.  What you end up with, and I think an example he said in a previous talk–I remember Micha talking about–is like if you're at a business and someone comes up with a spreadsheet.  Let's say someone in the accounting department comes up with a spreadsheet, and the spreadsheet has the financials for the past three quarters.</p>
+
+<p>But then someone in the marketing department wants to make charts for their presentation.  They don't understand the accounting bit, but they can look at the existing spreadsheet and hook up new, different kinds of charts.  I guess the modern term for this is mash-ups.  Like you mash up the data you got from the accounting department with data you get from the business analysis team or whatever, and you come up with a derivative diagram.  What you end up with is a directed acyclic graph of data and dependencies and visualizations.  The visualizations are the leaves.  Those are the things that the end user sees.  But underneath is a DAG of views into the state of the workflow.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Then the part that spreadsheets don't have as much, I mean they do have this if you are willing to tango with PB scripts, but an input thing other than manipulating the cells directly.  Adding buttons and behaviors to initiate workflows.  That's something that we take on with hoplon and javelin too.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I think there's an interesting division between.  There's probably an official word for this, but I think of it as resident programs and applications that perform work.  The backend of our application, for example, the thing that runs on the server, it's the request response type of model.  It's not a resident program that's containing a bunch of state that can be inspected individually.</p>
+
+<p>A user interface, though, or an editor or something like that I think of as like a resident system in that there's all this state that's in there and the user might be looking at a lot of it at once.  With a request response like a database, say, you get all these requests coming in and you want everything to be lazy rather than eager.  In other words, I'm not going to – like in a database you have views, and views are not really tables, usually.  Usually there's some kind of like compiled query because you don't want to do the work of updating every view when a new row comes into the database because that would be very expensive.  Whereas with, like, a user interface or a resident type of program, you actually do want to do that work because you don't know what the user is looking at.</p>
+
+<p><strong>ALAN</strong>:     Right.  I think maybe the difference between them is the entry points or the things that you choose to make visible or not.  Like when you have a service that multiple users are going to be using, like your multi-tenant or multi-client, it's important that you don't expose all of the data to any one peer or client as opposed to in the JVM or Emacs where you have no idea which pieces of data that the program has accumulated that they're going to want to look at or not.  You make no effort to protect or hide data from people, at least in sane systems.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean I think for the two types of applications that you have, you have two different types of sort of stateflow models.  For a user interface where a lot of state needs to be accessible, you have a situation where you have a database that's updating the views as soon as new information comes in.  Meaning it's pushing it out.</p>
+
+<p>For example, well, I guess we could look at the other side now.  The other side is sort of on the backend like a database, say.  You don't actually want to do that.  If you have a million users and each user can see their own stuff in the database, every time a new piece of information comes in you don't want to update every view for every user.  Even if a piece of data might affect a bunch of users, you wait until they make a query.  I think that's kind of the separation.</p>
+
+<p>If you have a situation where you want to eagerly push out changes everywhere, which is, I think, what you want to do in a UI, then you could use something like javelin.  Whereas if you're on the other end where you want to resolve those things lazily, that's something, a place where core.async would be good because you're feeding data down a pipe, so that's where you want queues and things like that.</p>
+
+<p>But on the other end, in the UI, you don't really want a queue.  The thing needs to fan out and constraints need to be satisfied.  You have a bunch of constraints, so I think that's basically how we ended up with javelin was the need to not use queues in the front end because what we really needed was the spreadsheet.</p>
+
+<p><strong>CRAIG</strong>:     Let's dig down that a little bit because there's a couple things in there that I'd like to unpack.  What is it about queues that's inherently bad?  We do asynchronous things in the front end all the time, even in a reactive metaphor like javelin.  Certainly when we're talking off the box, right, that's inherently asynchronous.</p>
+
+<p>But even when I've written UIs, and I'm far from an expert, so I'm more than willing to believe that I'm doing something wrong, I do in fact employ queues.  I mean Web workers, I use those in my UI to get certain properties.  Maybe that's not quite what you're talking about, though.</p>
+
+<p><strong>MICHA</strong>:     No.</p>
+
+<p><strong>CRAIG</strong>:     I'm curious, though.</p>
+
+<p><strong>MICHA</strong>:     I don't mean to say that queues are bad because, of course, a queue is like one of the fundamental building blocks that we use to build applications.  But I think there are times when you need to push out changes and there's times when you want to pull changes.  I guess that's not – I'll give an example.  With a spreadsheet, for example, when you change a cell, it pushes updates to all the other cells, which are satisfying constraints.  All the formulas are kind of like a constraint solver.  It pushes out, all the formulas update, the state sort of atomically changes from one state to the next, and all of your charts update themselves.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     What that eliminates is the type dependency.  You don't care necessarily – like all the cells know when they need to update.  In fact, at the end of the day, it's as if they had all updated atomically in one instant because no cell can see any other cell other than in the latest state that it was in.  For example, if I have cells A and B that are input sells, and then I have some cell C, which contains the sum of A and B, C will never see A in an older state than B, say.</p>
+
+<p><strong>CRAIG</strong>:     Right, right.</p>
+
+<p><strong>MICHA</strong>:     I guess if I update – yeah, so each cell only sees the things that it depends on, the cells it depends on, after they've already updated, if they're going to update.</p>
+
+<p><strong>CRAIG</strong>:     It's really about atomicity and, of course, if you have a queue, you can't guarantee that, right?  You've gone from–</p>
+
+<p><strong>MICHA</strong>:     Right.  If you have three queues, how long do you wait until all the results are in before you act on it, say?</p>
+
+<p><strong>CRAIG</strong>:     Right.  Right, right, right.</p>
+
+<p><strong>MICHA</strong>:     Right?</p>
+
+<p><strong>CRAIG</strong>:     Okay.  Okay.</p>
+
+<p><strong>ALAN</strong>:     Yeah, I have experienced this.  Well, before Micha started working on javelin and caught the spreadsheet bug, I was actually at Relevance where I was working on a system that was an online video conferencing system.  The metaphor we picked for modeling state transitions in the UI, which I think it was CoffeeScript in a browser at the time, was the EventBus, which is kind of the classical pattern for modeling events in a UI.  I think that's when I sort of hit on this problem of suddenly time becomes important again in consuming – like a queue consumer is kind of like an infinite loop in the sense that it's a process that has its own lifecycle because it's consuming from this queue.  Suddenly it becomes important, you know, how close the messages are to each other, like flash messages for example, like places in this UI would put a message on a queue if they wanted to show the error connecting dialog.</p>
+
+<p>Now obviously we don't want to spam the user to fill up their screen with these error connecting dialogs.  If one exists already, then we shouldn't show a new one.  What that means is now we have a little accumulator in there, a stateful accumulator that says, "If there's a thing showing when I receive a message, re-enqueue this message to show up in 30 seconds," or whatever, which was less than ideal.  I mean granted I may have been just doing it wrong at the time, but it was definitely evident to me that there was this temporal, like once I admitted queues or, in this case, a bus, which I think they have the same properties as far as UIs go in that there was no implicit ordering of events, you need to bring the ordering yourself.</p>
+
+<p>You needed to do that by accumulating things in places and then have time out policies and stuff like that.  Instead of being a nice graph of dependencies, the state associated with the way the UI looks becomes a graph of accumulators and policies and retry policies.  It was ungainly.</p>
+
+<p><strong>CRAIG</strong>:     Okay.</p>
+
+<p><strong>MICHA</strong>:     A lot of the real strengths of queues is when you need to farm out work to independent, separate processes that don't necessarily know about each other.  You have workers, like a Web worker or whatever.  Things like that are great when you have some process that can be done by any anonymous worker, and you just need to make sure it gets done.  That's what's really great about queues.  Then you can get back pressure, and you can manage all these other little threads or processes or whatever.</p>
+
+<p>But with user interfaces, that's not the case a lot of times.  A lot of times, like the place that's showing you this flash message or whatever is a particular place.  It's not like any element can just pick up this job of showing an error.  It's like it has to be in that particular place.</p>
+
+<p><strong>ALAN</strong>:     Right.  It's not necessarily.  This is, I think, inherent in the problem of the UI is that the UI is a singleton thing.  The human being can only perceive so much stuff, and that stuff constitutes one single place per the application.  The place in the UI where the flash message shows, for the purposes of the user's visual field, that is a singleton place.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     It is a single place in the person's field of view where a thing may or may not appear.  That's just not appropriate.  Queues aren't appropriate there because they're applicable when, like Micha said, you have work that needs to get done, but you don't care when it's done.  With UIs, it's more important when it's done.</p>
+
+<p><strong>CRAIG</strong>:     True.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and also the progression of state needs to be – I think you need to think a lot about – that's mostly what I think about when I make a UI is like how to state progress.  And so it can progress either from – well, so the user interface, at any given time when you load the page, it'll be quiescent.  It will have loaded everything that it needs to initialize and then it waits for the user to interact with it, usually, unless there's some kind of connection with the backend that might do things.  The UI is at rest.  The only thing that will transition it to a new state is something from the outside world, from the environment, so either the user interacts with it or the backend or some interaction with, you know, your database or whatever.</p>
+
+<p>I think, when you have a system like that also, and all the elements that are on the screen, all the widgets, they're stateful as far as the user is concerned.  Those states are satisfying some constraint, meaning they have some relationship to the state that's in the front end.  Now the state might change, so in other words the user might do something and some interaction might happen with the backend.  Maybe the two of those, together, interact with each other.  Meaning the user says they want to create – they want to buy a shoe, and maybe the backend says there's no shoes available or something like that.  But that's when it becomes really useful to have formulas that have the dependency graph because that can allow you to not do extra work.  I guess the guarantees of javelin, we're kind of getting into what the guarantees are.</p>
+
+<p><strong>CRAIG</strong>:     That's cool.  Yeah.</p>
+
+<p><strong>ALAN</strong>:     Well, and I guess javelin, too, it's a ClojureScript library that you use from ClojureScript, and it gives you this spreadsheet like computing environment for building and arranging these state machines/spreadsheet-like constructs that are aligned with this philosophy that we're unveiling.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     We should go over the–</p>
+
+<p><strong>CRAIG</strong>:     Please.</p>
+
+<p><strong>MICHA</strong>:     –what are the constraints or the features of a spreadsheet.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, yeah.  Please, go ahead.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so your average spreadsheet, it's important to make a distinction between the spreadsheet that you have in mind right now, which is this grid of cells, and what we say when we talk about spreadsheet, which is like the underlying computation model.  A typical spreadsheet like Excel, it has a field, X and Y dimensions, and that's your namespace, more or less.  That's how you enter values and see values.</p>
+
+<p>Then there's the computing model underneath that, which is the relationship between these cells and the constraints that mediate the relationship between the cells.</p>
+
+<p><strong>CRAIG</strong>:     Right, which isn't rectangular even a little bit.</p>
+
+<p><strong>ALAN</strong>:     Right.  Right.  Yeah, it's sort of incidental that it's a rectangle.  I mean it could be a hypercube.  Whatever.</p>
+
+<p><strong>CRAIG</strong>:     Arguably it is if you consider tabs where you can have formulas on one tab, so it's not strictly rectangular, right?  It goes beyond that.  I think you can even pull in data from other sources.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     Anyway, we're kind of going outside the useful bit.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I'll throw it back to you.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  No, but you're absolutely right.  As a computing environment, the average desktop spreadsheet, it takes on variables and namespaces.  It takes on dependency or propagation of new values throughout the thing.  The part that we talk about when we say spreadsheet is the part that propagates the value.</p>
+
+<p>Now, in ClojureScript, when you're using this javelin library, there's nothing grid-like about it.  Your values, your input cells are going to be named either locals or top level definitions, just like any other ClojureScript program.  And what javelin does is it gives you a way to connect those places in a way similar to the way that you connect cells in a spreadsheet.  So you can have the same expectations about what data will appear where when these inputs change.</p>
+
+<p>You're welcome to make a grid of these if you want.  It's pretty straightforward to make a spreadsheet when you have javelin, and probably even easier now that there's ClojureScript, and ClojureScript is pretty easily available.  You can very easily make a spreadsheet in ClojureScript, a ClojureScript spreadsheet.  We haven't.  I don't think we've done that.  I'm not sure anyone has done that, but that's because we already have awesome spreadsheets.</p>
+
+<p><strong>MICHA</strong>:     But, yeah, some of the things that are interesting about a spreadsheet is that first you have two kinds of cells.  There are input cells and formula cells.  Input cells are the ones that you edit.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     A formula cell is like in Excel.  You type equal and then you type a formula.  That formula is like an in – I can't think of this word.  It's really killing me.  Invariate?</p>
+
+<p><strong>ALAN</strong>:     Invariant?</p>
+
+<p><strong>MICHA</strong>:     Invariant.  Yes.  Thank you.</p>
+
+<p><strong>ALAN</strong>:     Yes, or a constraint.</p>
+
+<p><strong>MICHA</strong>:     Right.  Right, so this is like an invariant.  A formula is an invariant.  You specify that if you have a formula, so let's say you have two cells: A1 and B1 in Excel.  You're just going to type numbers into that.  Then you have cell C1, which is =A1+B1.  That says that cell will never be its value.  The value associated with that cell will never not equal the sum of the value in A plus B.  Additionally, there is a guarantee that the formula will update only once.  In other words, if you make one – when you change input cells, formulas will not update more than once or unnecessarily.</p>
+
+<p>If the value – if the things – if the cells that they depend on have not changed their values, no updating will occur, so work does not need to be done.  And if work does need to be done, it'll be performed only once.  This is pretty important because you can imagine sort of a naïve way to make a spreadsheet would be to, you know, you have your cells.  And whenever anything changes–kind of like how macro expansion works in Clojure–you keep evaluating all the formulas until they stop changing.</p>
+
+<p>Originally I had a simple thing that worked like this.  We kind of devised – that's called glitches in, like, spreadsheet parlance kind of – so glitch elimination is important because you have situations like we called it the pregnancy test, which was, say you have a form.  And the form has your sex, which could be male or female.  Then, if you're female, you could be pregnant or not.  Every time you click in this – and so this is in, like, a user interface in a form.  Any time you modify this form, it should send the current state of the form to the backend, but such that it is always valid.  Meaning, if you're male, you're never pregnant and so on.</p>
+
+<p>If you don't have glitch elimination, it's pretty much impossible to do this without building glitch elimination into your system because, suppose you're female and pregnant and you change your sex to male.  It has to know to uncheck the female part.  Sorry, the pregnant part.  With javelin, we make that a formula cell and stuff.</p>
+
+<p><strong>ALAN</strong>:     Cells together in javelin can constitute a type, like a ClojureScript def type.  But even cells in a normal spreadsheet, they have a contract, which is, every cell has a value at all times.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     And that maps up really well with the way Clojure works and Clojure's philosophy of state and time because, in Clojure, there's a rigorous separation of looking at something versus changing it.  Like every reference type in Clojure, you have the ability to de-reference it.  You can see its value at a point in time.</p>
+
+<p><strong>MICHA</strong>:     And to add a watch.</p>
+
+<p><strong>ALAN</strong>:     Right.  So you can – these reference types, atoms are the most popular, but there are agents, refs, various–</p>
+
+<p><strong>CRAIG</strong>:     Agents, vars.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Yeah, var.  Yeah, all of these things.  You can see their value and hold onto that value for the rest of the program.  You don't need to worry about what happens to the underlying container, the box.  And javelin cells work like that too.  Both the input cell and formula cell types support de-reference.  And this de-reference, because we do the propagation eagerly and in dependency order, the de-reference is going to give you a consistent view.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.  Yeah, so in working with javelin, it was actually one of the things that got me using hoplon for the little side project I've been using it for is that, you know, I'm a backend guy.  I don't really do the front end stuff very much, although I've been doing more of it recently.  Kind of it's always a question of when you roll up to a new library or framework, what do you need to know?</p>
+
+<p>For me, to a first approximation, the thing I needed to know in order to understand javelin, which is an important part of doing a hoplon application, was atoms and watches, which are very familiar concepts to me as a backend programmer.  Now, of course there's more, right?  You guys were talking about the fact that you can have chains of dependencies, and there is an atomicity guarantee.  But to a first order, it seemed very comfortable.  It's like, oh, there's a thing and I can look at it, and there is an API for changing its value, which is actually swap and reset.  Hey, that looks a lot like an atom, so that part was all very familiar.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I think the stuff that you were saying about the model makes a lot of sense.  I do want to make sure that we talk as well about hoplon because javelin is very cool, and I found it a very comfortable, familiar, easy to acquire way to model my programming, not without some onboarding, but it didn't take very long.  But, you know, it wasn't bad.  I think most people would roll up to it, so I'm curious then to talk more about – well, I don't want to cut you off.  If there's more interesting to say, we should say it.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  No, I see the way you want to go, and it's a good direction.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, yeah.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so javelin has nothing to do with the browser or the DOM or HTML, which is part of the reason I think that we feel like it's done as a library.  It occupies a part of the hoplon framework and our workflow in which it's done.  We're not going to add anything to it, and we're not going to deprecate anything.  It's done as a library.  Which also, if that was all there was, it would be useless because, like, how do you make a webpage with it?</p>
+
+<p><strong>CRAIG</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Well, there is no inherent way in doing that, so there is a linkage, conceptual and software, between javelin and the browser.  That is traditionally we call that hlisp, and there are library components of it that are in the hoplon boot task, but it is a set of conventions for working with the native DOM elements that allows you to use native DOM elements to provide views into your javelin spreadsheets.</p>
+
+<p>I don't know.  Does that seem like a good–?</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I mean hoplon originally, like in 2012, doing stuff in ClojureScript was a lot more difficult than it is now.  And so a lot of this stuff that is hoplon was to make that easier too.  Then when we made boot, we incorporated them into the boot tasks.</p>
+
+<p>Hoplon itself is a library, a ClojureScript library that you can use in any application.  It doesn't need boot or anything like that.  But the boot task does things like creating the actual HTML file in which you're going to run your JavaScript.  You know, pre-rendering stuff, which means you can run your application in PhantomJS to generate the HTML.  Stuff like that.</p>
+
+<p>There's hoplon the library and then there's the stuff that boot does, which is optional, but me myself, I find it useful.  I don't want to be hand coding HTML files any more, so my applications are kind of more like just JavaScript that I want to launch into somebody's browser.  The only way I can do that is if an HTML file is generated somehow.</p>
+
+<p>Hoplon itself, it's sort of meant to be a foundation for something more useful, to write something more useful on top of it.  It doesn't actually do very much at all.  It just allows you to wire up javelin cells to DOM elements.  You can think of DOM elements as, well, first of all in hoplon, all of the DOM elements that appear on the user's screen in the browser are created via JavaScript.  Meaning they're JavaScript objects first, and then they go into the DOM.  They're not HTML.  They're not DOM elements that are created from HTML.</p>
+
+<p>When you think about it that way, the goal of it is to provide a platform that you could hook up your application state, which is expressed as these cells, these formula cells, input cells, and so on, to widgets that you make by composing these DOM elements.  And so, like, if you think about a JavaScript, the JavaScript representation of a DOM element, you have properties and methods on them.  You can call set attribute and so on.</p>
+
+<p>My kind of intuitive view, the way I think about is attributes are like methods on the DOM element.  Kind of like a world line of this, of the method, so if you take like the class attribute of an element and you hook it up to a javelin cell that might contain different values over time, meaning the class might change over time, you could sort of consider that to be a method that's called every time the value in the cell changes.</p>
+
+<p><strong>ALAN</strong>:     It would be as if, say, you had the class string in an atom.  Then separately you created a DOM object.  Then you made a watch, an add watch with a function that set the new value on the thing every time it changed.</p>
+
+<p><strong>MICHA</strong>:     That's precisely what hoplon is actually doing.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     It just makes it easy for you to express it as attributes when you type your source code.</p>
+
+<p><strong>CRAIG</strong>:     Right.  In Alan's example the nice convenience is that you don't have to link up the cell or the atom and the attribute via some piece of code that runs.  You just say the value of this attribute is the javelin cell, and then the wiring happens.</p>
+
+<p><strong>ALAN</strong>:     Right.  Conceptually, you can think of attributes as continuous, basically.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     As opposed to one shot things that you have to set manually.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  I think of it like a world line of a method or something.  You have this object that has a method, and it's going to be called with different values over time.</p>
+
+<p><strong>ALAN</strong>:     Right.  But you don't care about that plumbing, really.</p>
+
+<p><strong>MICHA</strong>:     Right.  The thing that represents the values, which will be used over time is the cell.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Yep.  Yep.</p>
+
+<p><strong>MICHA</strong>:     That's what – so in hoplon you have the hoplon element, these DOM elements.  They have attributes, which are like methods on the object, and they have children.  Children have a special relationship in the browser so elements can contain other elements, obviously.  And so the children can also change over time.  That's really it.  There's not much more.  Hoplon, what we wanted to do with it is we wanted to make a foundation that we could build UI kits on top of.</p>
+
+<p><strong>ALAN</strong>:     This comes back to the original motivation with the white labeling with the Fresh Diet.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     This was kind of – we've arrived at the problem we, well, set out to solve originally, which was how do we describe an application in terms of both its workflows and its UI in separate pieces such that we can modify one or the other without necessarily modifying the other.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and to be able to – so the goal, the end goal would be that you identify some widget that's going to be useful to you.  Say – let me think of – just take an input, like a text input.</p>
+
+<p><strong>ALAN</strong>:     Auto-completing.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     I actually have an example from a side project that I think might be what you're talking about, and you can tell me whether you think it's–</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>CRAIG</strong>:     If you like, I can share and you can tell me whether you think this is what you're talking about.</p>
+
+<p><strong>MICHA</strong>:     Absolutely.</p>
+
+<p><strong>CRAIG</strong>:     I used hoplon to write a weather generator for my – my own hobby is flight sims.  I'm making weather for this game that I fly in.  It's random.  It has neat features.  You can control things about it.  It doesn't matter.</p>
+
+<p>I fly with other people online, and I would like the weather to be a surprise.  Right?  I don't want them to know that when we come back to the air base that they're going to have to land in the middle of a thunderstorm necessarily, right?  But at the same time, you know, we're interested in this experience where you can see what the weather is because, hey, they could stick their head out the window when they take off, right, and they kind of know.  And so I'd like to provide them with a weather forecast.</p>
+
+<p>I have the same data, like I had this model that I can manipulate.  I have a set of controls for doing that so I can step forward in time and say, okay, yep.  The storm is going to arrive at 3 o'clock.  That's about when we'll be landing.  But then I want to also give them that same exact data, like the whole model is parametric, and so everything is completely deterministic.  But I don't want them to be able to go past takeoff time because, if it were the real world, they would know what the weather was, but they wouldn't know what it's going to be.</p>
+
+<p><strong>MICHA</strong>:     Mm-hmm.</p>
+
+<p><strong>CRAIG</strong>:     And so it's the same data, the same computation, but it's a different view.  It has limitations.  It's not the same.  If you were looking at it without knowing anything about the internals, it's not the same application even though the underlying data is.  And not only data, but computation is identical.  Is that kind of what you guys are talking about?</p>
+
+<p><strong>MICHA</strong>:     Yeah, I think that's – well, what's interesting about that is that there's a separation of the presentation from the sort of state machine that describes the different things that get presented in the context of your widget, right?</p>
+
+<p><strong>CRAIG</strong>:     I didn't quite follow that.  Explain further, please.</p>
+
+<p><strong>MICHA</strong>:     Well, so you have a widget there that is going to display the weather for the user, but they won't be able to see the weather for the future, right?</p>
+
+<p><strong>CRAIG</strong>:     I've got two sets of users.  One is me, the weather designer.  I've got tons of controls where I can say it's 30% likely to rain.  It's like the winds are this, blah, blah, blah, blah.  Then I'm like, great.  I know the weather for all time, including the future.</p>
+
+<p>Then I want to be able to say, take that same data, some other user, and get a different view on the same information, but that's limited in terms of how they can interact with it.  They can't change things.  Maybe they can change a few things like where they are in time, but even there maybe not past a certain point that I specify.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I was just really wondering if that's kind of what you were getting at around saying, well, there's still a workflow.  There's still, when time goes from 2 o'clock to 3 o'clock, the following things change in the underlying. Like the data is the same, but the way I interact with that, what I can see, what I can interact with is different.</p>
+
+<p><strong>MICHA</strong>:     Yeah, that's actually a good example because I could imagine the situation when maybe you are going from your view to, like, the pilot view also or something like that.  And so you could be turning things on and off inside of your widget, like certain controls are only visible if you are in God mode versus pilot mode or something like that.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     And so you might design a widget that has those that exposes them as attributes.  You could have an external state machine that tells it which state it's in.  The presentation part, the widget, the thing that's in the DOM would be controlled maybe – you know, the different configurations of it are via attributes, just like in the normal DOM elements, you know.  You change the configuration of the built in DOM elements by adjusting the values of these attributes.</p>
+
+<p>The idea in hoplon was to expose the same exact interface.  You can make your own widget that exposes the same ways, means of controls, like these attributes and children, you know, that you could do the same thing on yours.  The components that you make are not different than the ones that come in the browser like, you know, text area or whatever.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  I think your example is great from another perspective too, which is you have this underlying process, which in your case is parametric and very well defined.  But the magic to it, the purpose for its being is that not all of the users can see into all of it.  Not everybody has full fidelity.  Different kinds of users have different levels of access, kind of.</p>
+
+<p>I can imagine in your case, you have the God mode view and then you have the pilot view.  Let's say you have a widget for each of these, or maybe a set of javelin cell values that determine what certain widgets show or don't.  Like I'm imagining your God mode thing you have a slider from the past into the future by some number.  The pilot has a slider from the past to the present.  That's managed.  Whether or not the user can see the weather in the future depends on whether the God mode cell is true or false.</p>
+
+<p>But maybe the God mode cell is not really that.  Maybe it's named like the user level cell, and it can be one of God, you know keywords here, keyword "God," keyword "pilot," or maybe keyword "ECWACS," you know.  What are those planes with the big saucer?</p>
+
+<p><strong>MICHA</strong>:     Mm-hmm.</p>
+
+<p><strong>CRAIG</strong>:     The AWACS.</p>
+
+<p><strong>ALAN</strong>:     The AWACS.  The AWACS weather guy has more fidelity than the pilot, but not as much as God.  Maybe his maps are higher quality.</p>
+
+<p><strong>MICHA</strong>:     He's a lesser god.</p>
+
+<p><strong>ALAN</strong>:     Yes, a demigod.  But we find the exact same thing in our business applications that we build with this stuff, which is, there are all these different concerns, and they're usually oriented around the way the person is supposed to interact with the system, whether it's constraints based on the kind of user they are or constraints based on what the way that's most efficient for them to work with the system is.  Yeah, the separation of the widget behavior from the underlying model behavior is, I think, the way of building these things that gives you the most flexibility to do that.  Especially, I mean, the key thing is being able to add, remove, and modify these perspectives over time.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  The really key thing is that, well, I think, and we've pretty much achieved this with the application that we have at work is that there should be sort of two completely separate phases of development.  Not even phases because they happen at the same time, but you have widgets that you're working on, so you develop these widgets.  Then your application is actually just an assembly of widgets, which is different than – I mean it becomes an application.  But by assembly I mean you only use composition, essentially, to construct it.</p>
+
+<p><strong>ALAN</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     So you make all these components, and the way you compose them – the way you build an application from all of these separate components is exclusively composition.  I mean obviously there's going to be, like, a few little conditionals here and there, but if you were to look at the source for, you know, the Adzerk UI, all of the views are simple composition of these components.  The big advantage there is, like, if you consider for example – like we did a lot of work around forms and how to handle forms.  By that I mean things that talk to the backend and also interact with the user.  We develop a really – I think it's a really good system where we have a state machine that describes talking to the backend.  And so we have this RPC framework that we use.</p>
+
+<p><strong>ALAN</strong>:     Castra.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     The library, ClojureScript, Clojure.</p>
+
+<p><strong>MICHA</strong>:     Yeah, and so the state machine on the front end is an object.  It's a def record, and there are methods on this object that you can call, which might cause it to change state.  It might not.  But you can call them to command a change, and it exposes its state as javelin cells.</p>
+
+<p>If you think about, like, you have, say, a login form is pretty simple.  You have username and password.  There will be – you construct a form machine for that form and maybe tell it the schema so it knows you have these two fields.  But then it'll expose to you an error cell for the username and an error cell for the password.  And it'll expose the data cell for the user name and the data cell for the password because there might be some default there or you might have already edited, whatever.</p>
+
+<p>The machine has this.  And you can wire those cells up to DOM elements on one end, and whenever you change them – so the way we like to do it – there are many different ways to make the state machine, but the one that we settled on is you can edit a form as much as you want as a user.  When you first click submit, that's when validation happens.  Then thereafter, as you type, the validation is done as you type.  The validation is actually all done on the backend to simplify, to simplify our whole model.  So every time you type, it's validating on the backend.  And the error cells are being populated.</p>
+
+<p>The error cells, or there's also like a general state for the state machine that is exposed to the cell.  But the benefit here is imagine I'm actually making the widget now for this form.  I can have a widget, a sub-widget that displays an error, right?  I could have a widget that accepts input from the user.  These things are completely decoupled from the state machine because they're going through this common interface now of attributes.  So for example I might have–</p>
+
+<p><strong>ALAN</strong>:     And cells.</p>
+
+<p><strong>MICHA</strong>:     Right, and cells.  So I might have, like – so we in fact do have this.  We have our own text input, which does certain things and displays itself in certain ways.  Whatever.  So you do text input and then colon value, which is the way you set attributes, and you give it the data cell from the form machine.  Now whenever you type in there, the form machine is getting that updated data because it also, you know, knows about this cell.  Likewise, the error gets passed as an attribute to the little widget that we make that displays the errors.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     And you know, I think, if people listening to this are coming from a JavaScript background, they'll recognize some of the affordances of this setup and the idea of a promise, which is a kind of trending JavaScript idea.  But a promise, if you're not familiar, it's basically a value that you can get or an object that you can get that will contain a value.  Clojure has them too, incidentally.  And a value can be delivered to the promise once.  When the value is delivered, there's an API for a function being called.  It's kind of like a one shot atom.  Where a promise is a one shot atom, a cell is like a continuous promise, again because it doesn't just fire once when the value changes.  Whatever thing is looking at it, you can use stuff in javelin to make happen whenever the value changes, forever.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     So–</p>
+
+<p><strong>MICHA</strong>:     Well, the difference there, though, is that javelin does maintain the dependency graph.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     So like if you have a web of promises–</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     –that's where you get into trouble.</p>
+
+<p><strong>ALAN</strong>:     Right, right.  Yeah, unless you're very diligent.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, and so like I said, I've built applications, and this makes sense to me.  In fact, it was kind of the first UI framework that I tried that I did really connect with.  And I mean, to be fair, I didn't give all of the others as much of a run as I've now given hoplon.  But still–</p>
+
+<p><strong>ALAN</strong>:     Oh, I know that you were a huge spreadsheet fan originally, too, right?</p>
+
+<p><strong>CRAIG</strong>:     I do love spreadsheets, actually.</p>
+
+<p><strong>ALAN</strong>:     I imagine we suckered you in a little with that.</p>
+
+<p><strong>CRAIG</strong>:     Yeah.  No, there's definitely – I am a huge fan of spreadsheets.  However, there's an xkcd where there's like an amusing graph of complexity and, at the left end, is a two line bash script, and at the right end is some spreadsheet that's been being maintained for 20 years to maintain the scheduling on some church in Georgia, right?  That's the joke in the slide in the comic.  I'll have to post the link to that.</p>
+
+<p>The point, though, is that there exists some extremely sophisticated spreadsheets in the universe.  I think something that some of our audience will have been exposed to is this common task, which is, well, I've made a spreadsheet.  Now the spreadsheet is inadequate, and so now I have to turn it into a "real program."</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>CRAIG</strong>:     I guess what I'm trying to ask is I could kind of imagine that the cell model where you have this potentially very wide graph of interconnected bits of computation to have a sort of complexity ceiling.  Now I've only used hoplon to solve smallish problems.  I mean I think the thing that I did actually is nontrivial.  The things that I've done are nontrivial.</p>
+
+<p>But, you know, they're small compared to anything that I would have done if I were working on it day in and day out like you have been doing with your work at Adzerk.  Have you experienced limitations of the cell model?  If I squint, I could convince myself that you would fall off a complexity cliff eventually there.  Has that been your experience?</p>
+
+<p><strong>ALAN</strong>:     I guess I would say there are two kinds of ceilings.  One is easily navigable and the other is, I guess, sort of open – open, and we could talk about this thing called UI.  But cells definitely have straightforward, technical limitations just because of the way the browser works.  The foremost of these is that they're not automatically garbage collected by the JavaScript runtime because of the way we maintain the dependency graph and because JavaScript doesn't have a weak reference and probably never will for security reasons.  It's possible using cells naïvely, and people do this regularly, to have memory leaks.  And so there's a certain diligence that comes with working with cells, and I think it's easy to learn.  It's, in practice, not a huge problem.  But it's a definite hard technical limitation.  You can easily drive yourself crazy trying to if you sort of have the wrong mindset.  You can sort of correct the way that you're thinking about using cells and easily get yourself out of this.</p>
+
+<p>The other limitation, which is kind of the open problem, is cells presume so little about – cells and hoplon presume so little about how you're going to build your application.  Micha talked about this a little earlier when he said that, you know, our goal is to get you to the place where you can start to solve the problem.  We don't presume to solve the problem completely for you at all.  I think how you approach that is going to be application dependent, and whether or not you reached the complexity ceiling is kind of on you.</p>
+
+<p>I don't know.  Maybe this is a good time to talk about the UI library.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean–</p>
+
+<p><strong>CRAIG</strong>:     I would love to hear about that, actually.</p>
+
+<p><strong>ALAN</strong>:     Okay, or maybe Micha.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean I don't actually see – like, we have really big hoplon applications now.  Big meaning like many, many different screens and a lot of complex workflows and back-ends.  You know, so the one that we're building at Adzerk is a pretty complex application and complex workflows.  We really haven't – like, I don't really see that we're even approaching any kind of – I don't see a complexity growing at all.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     The reason is because, just like in a spreadsheet – like, the reason why spreadsheets get unmanageable, I think, is mostly because, like, the names.  In other words being in the grid with A1 and B7 and so on, like that's okay if it's small.  But, you know, if you're making a bigger – if you're making an application with spreadsheets, you kind of want to have names for things.</p>
+
+<p><strong>ALAN</strong>:     Right, and you can't have anonymous cells in a spreadsheet, of course.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     You can't make self-contained machinery.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Everything is global.</p>
+
+<p><strong>MICHA</strong>:     Yeah, so this isn't something you run into with javelin.  Also, like with javelin, the formulas that you do have end up being pretty small.  If you see a formula starting to get large, you just break it up into smaller ones, just like you would do in a normal spreadsheet.  And I think that has – I mean, for me anyway, it just happens naturally that most of the formulas I have are very small, and they all just kind of mesh together.  And because of the glitch elimination, it's not like – like, we don't even really have any debugging tools for javelin.  You know?  There's no – like Alan, I know, made the graph view of it.  We keep losing it and so on.  I just never really found it necessary.</p>
+
+<p><strong>ALAN</strong>:     Well, see, I think that can still be a thing.  I think that could be a thing.  Some of the best criticism we've gotten about hoplon is from Daniel Higginbotham, a great friend of mine, awesome guy who worked at Adzerk part time on this hoplon system.  He did point out that, you know, figuring out what's going on is less than easy if you're the people who made it.  I think we can improve there, but we've gotten pretty far without having that.</p>
+
+<p>What I imagine, in my copious free time, doing at some point is making a layer or an extension for Chrome that gives you a visual graph representation of the cells.  Then you can click on the cells and see the source code for the cell or its value.  I think that would be awesome.  It's attainable now because we can put metadata on vars in ClojureScript.  I think that's just a matter of time.</p>
+
+<p>To Micha's point, it's a conceptually simple model.  And Micha mentioned that you can split up a big cell into smaller cells, and you can do that because of our glitch elimination, because of the consistency properties of the model.  You can basically, by rote, break a cell into a set of smaller cells, and you don't have to reason again about the states of these cells.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  When I need to debug something, I just make a cell that has a print def in it that prints out the value of a cell, and I very quickly – I can pretty much bisect any weird javelin issue, I mean, and because the types of issues that you might have are actually computing problems rather than timing issues.  You know what I mean?</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     They're not likely to be race conditions like you would have if you were using a bunch of promises.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     Like a web of promises.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     Right, so these are all, like, you're just getting the wrong value in some cell.  So tracking down how that value arrived there is way simpler than saying, like, is it getting the wrong value because things happened in the wrong order?</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     That's the kind of thing that's, like, time consuming.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, absolutely.</p>
+
+<p><strong>MICHA</strong>:     For the next step, there's this thing called hoplon UI.  Jessie has been working on it.   He's been doing a ton of work on it.  His goal there is to make the next level foundation, which provides basically a sane and well factored platform for building user interfaces as opposed to, like, documents.</p>
+
+<p><strong>ALAN</strong>:     Basically a new browser.  He's building – it's basically a browser API on top of javelin and the conventions in hoplon that we've established.  Like where today if you take the stock hoplon stuff and you make an application, you're interacting more or less with stock CSS stuff, stock JavaScript script things, DOM things, which is great because that means there are really no surprises.  You can stack overflow, search for things.</p>
+
+<p><strong>CRAIG</strong>:     Yes.  I've done so much of that.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, so it's all the native stuff, so it's Googleable.  But you're not really escaping the inherent complexity of the browser environment by doing that.  You're choosing to live in it, for better or worse.</p>
+
+<p>The idea with UI, as I understand it, is Jessie has been using hoplon for years, almost as long as we have, and built a series of applications, and identified in his own work patterns and practices.  He has put a lot of effort into codifying those into this library UI, which is a higher level starting point that doesn't make you give up too much about being in the browser, if anything.  So the fidelity is still there, but the complexity is reduced, which is – I mean that's a big value proposition.  But I think it's really impressive work.  Micha probably knows more about how it works and stuff than I do.</p>
+
+<p><strong>CRAIG</strong>:     Okay.</p>
+
+<p><strong>MICHA</strong>:     Yeah, I mean, like an interesting thing that you can do with hoplon is, instead of using CSS in CSS style sheets or, you know, style tags, whatever, you can manipulate attributes from cells to set the properties directly.</p>
+
+<p><strong>CRAIG</strong>:     Yes.  That's actually super interesting that you can do stuff with that that you really can't do easily any other way.</p>
+
+<p><strong>MICHA</strong>:     Right, so like even SCSS or LESS or Sass, those things are computing CSS statically and emitting a CSS file.  But with hoplon, you can have a javelin cell that represents the styles for your element that updates via ClojureScript at runtime.  Meaning, constantly it's a first class.  It gives you first class access.  What Jessie has done is, on top of that, he's using that to rebuild.  So he's had experience doing Flex and all kinds of action script stuff.</p>
+
+<p><strong>ALAN</strong>:     AIR?  Is that one of the things?</p>
+
+<p><strong>MICHA</strong>:     Yeah.  He's done like a ton of basically all the different ways you can make user interfaces.  From that he's sort of collected a core set of functionality.  One of the main things is that, in the DOM, you have documents and user interfaces.  The two are not really very well separated.  There's a lot of concerns for, like, making a newspaper that are conflicting with concerns for making–</p>
+
+<p><strong>ALAN</strong>:     Gmail.</p>
+
+<p><strong>MICHA</strong>:     Gmail.  Exactly.  And so that's really kind of what he's attacking.  He's attacking the user interface side.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>ALAN</strong>:     Another example of a simplification he made, which is one of those, like, makes total sense in retrospect things, and it's just we're constantly fighting with since we started working with JavaScript seriously is the fact that there are so many different kinds of elements in HTML.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Like &lt;div&gt;, &lt;p&gt;.  Now there's &lt;section&gt;, &lt;header&gt;.  These are the concerns of the newspaper imposing themselves on the concerns of the people who make things like Gmail in 2016.  It's insane.  And they all have different default styling attributes and behaviors and different flow properties, have different implications on the positioning model, and so what sold me on the UI concept was he just has a single kind of thing, the LM, ELEM function.  It's a general purpose object that can represent a piece of the user interface.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>ALAN</strong>:     You can put them inside each other.  They all have the same number and kind of attributes.  They all have the same positioning and style, default style properties.  Yeah, that's just an example of the….</p>
+
+<p><strong>MICHA</strong>:     Yeah, and some of the stuff that – so it's also a low level library in that it doesn't necessarily give you the components that you will actually use to build an application.  It provides the underlying primitive that you need to build a user interface.  And so the kinds of things that it does is make an element that fills the screen and put inside of it children who fill its parent, who fill their parent, but in a certain way.  Meaning like the middle one should be 10%, the one on the left should be 20% of the width, and the one on the right should just fill the rest of it.  Or you might have the one on the right actually contains two others that themselves are each 50% of the remainder.</p>
+
+<p><strong>CRAIG</strong>:     Mm-hmm.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     Things like that, so it's essentially – you know, it's kind of ParEdit, but there's one type.  So there's the LM, but there are also special form.  The different form elements, like an input box, things like that, those need to be special cases just because of all the concerns of–</p>
+
+<p><strong>CRAIG</strong>:     Sure.</p>
+
+<p><strong>MICHA</strong>:     –user interaction like when the persons have completes and all that stuff.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     So you want those to be – a lot of times the browser, like, you need to choose a particular element.  You can't make your own.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     But–</p>
+
+<p><strong>ALAN</strong>:     But he investigated doing that.  I mean I remember him talking about his early work where he thought, you know, what if we do the browser visually from first principles?  Why can't I just use SVGs for everything?</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     You know, whatever.</p>
+
+<p><strong>CRAIG</strong>:     It's interesting you say that.  I was thinking about this, and I would say the things that I've been gravitating towards as I've been building my applications are div, SVG, and flexbox, which actually sounds like a poor man's version of what you're talking about.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Yep.  That's exactly what Jessie did as well.</p>
+
+<p><strong>ALAN</strong>:     Yeah, so just do that for five years–</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     –and you'll have UI.</p>
+
+<p><strong>CRAIG</strong>:     Let me get started.  I gotta go.</p>
+
+<p><strong>MICHA</strong>:     Yeah, yeah.  He did a full–</p>
+
+<p><strong>ALAN</strong>:     You're on the bat, yeah.</p>
+
+<p><strong>MICHA</strong>:     He has a lot of interesting stuff to say about flexbox.  I remember when he was like – yeah, he made everything out of divs for a while.</p>
+
+<p><strong>ALAN</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     Yep.</p>
+
+<p><strong>ALAN</strong>:     I mean designers frequently do the same thing.  I mean for a long time a hallmark of any serious, large, single page app was the reset.css.  It's like, okay, let's turn off everything in the browser so we have a place to start with that's predictable.</p>
+
+<p><strong>MICHA</strong>:     Yep.  So what's interesting about UI is that this LM, this generic component is actually three – it's constructed from three divs.  There's like an outer one, a middle one, and an inner one.  Each one of them has its own role to play because of the way padding and margin and width and so on work in the browser.  He realized that you need three of them in order to get a consistent – in order to be able to consistently–</p>
+
+<p><strong>ALAN</strong>:     And to satisfy every aspect of the–</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     –positioning and styling model that he wanted to support, which is his view of how you should do it.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.</p>
+
+<p><strong>MICHA</strong>:     Right, and so you would think that you'd end up with like a ton of three times as many components in your application.  But in fact, I think we're finding that there are way fewer elements compared to, say, a bootstrap.  You know, like bootstrap, the Twitter bootstrap is one way that you can – you know these CSS frameworks–</p>
+
+<p><strong>CRAIG</strong>:     Sure.</p>
+
+<p><strong>MICHA</strong>:     –that are sort of trying to accomplish the same thing, give you a kit, a UI kit that you can use to construct your application from.  But they actually end up with, like, a lot more elements because kind of the only way they can fix things is by adding more structure because I think, fundamentally, like the LM that Jessie has developed is a really good, fundamental unit that's worked out at a low level.</p>
+
+<p><strong>ALAN</strong>:     It's the ultimate div.</p>
+
+<p><strong>MICHA</strong>:     Right, so, like, in order to fix some weird padding issue in a bootstrap thing, you'd have to add more wrappers, you know, like maybe a clear div, whatever.</p>
+
+<p><strong>CRAIG</strong>:     Yep.</p>
+
+<p><strong>MICHA</strong>:     You're like adding more and more stuff.  Then that compounds itself when you compose those with other and so on.  It's really very interesting.  I think that we're finally reaching an age, like in web, you know, the way people use the web that a lot of business stakeholders are not going to – they don't care about, like, inventing some new user interface concept.  We've already figured out how to interact with the user to get information and give information to them.  What's really important, I think, to people now is the workflow.  In other words, if somebody comes onto my application, they're like a business user and they want to actually get something done and their time is precious, they don't care if it's all just gray.  You know?  Nobody cares what it looks like any more.  Nobody is going to be impressed with, like, some fancy drop shadow or something.  They want to know that you can get in, do their work reliably, and get out.</p>
+
+<p><strong>ALAN</strong>:     Well, that's the big difference between these.  This is kind of the dual, the two faces of the web.  And they're always at odds because I don't think people recognize them as totally different concerns.  The newspaper, like are you going to make a killer above the fold, catch people's eye brochure site, or are you going to make an application that people are going to live in for eight hours a day?  Within the first 30 minutes of serious use, they're not going to even notice what the colors of the things are.  And the primary concern is usability, not necessarily flashiness.</p>
+
+<p>Sorry to cut in.  I just–</p>
+
+<p><strong>MICHA</strong>:     Yeah, totally.</p>
+
+<p><strong>ALAN</strong>:     But, yeah, that's kind of – like in the world that we seem to live in, building large sites with JavaScript, we're definitely on the user experience side, not the new media or design side.  Granted there is still some give and take there, but for the most part people seem to be interested in what Micha said: the workflow, like, is this an efficient place for someone to live and work in all day long, like one does in Gmail?</p>
+
+<p><strong>MICHA</strong>:     Yeah, so I can totally imagine something built on hoplon UI, which implements all of the – like I'm pretty sure that we can now enumerate all of the types of widgets we're going to need to make business applications.  And we can make, you know, instances of them, and we can also make, you know, sort of a zoo of state machines that can be composed to form the really responsive workflows that you need, the really efficient workflows.  In other words, the workflows that help the user accomplish their task more directly.</p>
+
+<p><strong>CRAIG</strong>:     Well, you guys just blew my mind.  I definitely have to check out hoplon UI.  And, you know–</p>
+
+<p><strong>ALAN</strong>:     Oh, but an important caveat.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, please.</p>
+
+<p><strong>ALAN</strong>:     Jessie says we shouldn't use it yet.</p>
+
+<p><strong>CRAIG</strong>:     Okay.  Cool.</p>
+
+<p><strong>ALAN</strong>:     But go ahead and use it.</p>
+
+<p><strong>MICHA</strong>:     Yeah.  Yeah, everybody has been using it.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     And he has, like, 10,000 warnings.</p>
+
+<p><strong>ALAN</strong>:     Yeah, the Read Me is just warning after warning, you know, this is unstable.  Don't use it.  But of course there are businesses using it now, so.</p>
+
+<p><strong>CRAIG</strong>:     Yeah, well, I could kind of imagine that I've got completely broken, 10% versions of what he's already doing, and so his 90% semi-broken version might be a vast improvement for what I'm trying to do.</p>
+
+<p><strong>ALAN</strong>:     Well, in my case I used it as a reference or a Rosetta Stone to figure out how to do a CSS thing.  He's got the distilled knowledge in there, so there was some CSS3 feature I needed to use on some side project recently, and I was able to figure out how to do it from his code, so it's useful there too.</p>
+
+<p><strong>CRAIG</strong>:     Well, guys, I don't want to cut off the conversation because I think – in fact, I know we could keep going, and I for one would be sitting here fascinated, but I think there may be people in our audience that need to use the restroom.</p>
+
+<p><strong>ALAN</strong>:     Okay.  Well, they can wait for just one more little point I want to make.</p>
+
+<p><strong>CRAIG</strong>:     Absolutely.  Absolutely.</p>
+
+<p><strong>ALAN</strong>:     Which is, another hoplon community guy, Thomas Herman, he gave a screencast, which I'm really – I feel bad that we didn't record because it was incredible.  But he demonstrated the power of working entirely in code instead of trying to straddle document and code in terms of making an application.  He's a heavy Cursive user.  Colin Fleming, another Clojure community superstar, has this tool: Cursive.  It's a great Clojure and ClojureScript environment for IntelliJ.</p>
+
+<p>I don't use it personally, but I have a lot of friends that do and they love it.  And it turns out that when everything in your application is ClojureScript code, then you can start to use your ClojureScript IDE as a design tool.</p>
+
+<p><strong>CRAIG</strong>:     Mmm.</p>
+
+<p><strong>ALAN</strong>:     Thomas Herman is building a site using UI and, in his demo, screencast, he like hovered over the attributes in one of these LM things, and the Cursive tool tip popped up with all the color values that it could take at that place in the code because this was, you know, code inference that incidentally was style inference because all the style is happening in code.  And, you know, he was defining sets of colors and defining maps of class names to colors that Cursive was smart enough to track down and show in the editor, which seemed like a quick little peek into the future of the design tools.</p>
+
+<p><strong>CRAIG</strong>:     Oh, yeah.  I mean I know this is only a corner of what you're talking about, but I totally want now to go back and put into my little apps that CSS code because the means of abstraction there are garbage.  And I'm not using Less or  Sass, right, but it's just terrible, right?  You have to say the same thing six times, and it's static, and blah, blah, blah.  And so I think even just that little piece of what you're talking about, to me, looking at it as a front end newb, I'm like, man, that seems like an obvious win.  Why don't we have that normally?</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Yeah, and you know, I guess I wouldn't go so far as to say that Less and Sass are bad.</p>
+
+<p><strong>CRAIG</strong>:     No.  Sorry.  That's not what I was saying.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  No, no.</p>
+
+<p><strong>CRAIG</strong>:     I was saying I'm not using them, but CSS itself lacks abstraction.</p>
+
+<p><strong>ALAN</strong>:     Right.  They're great for brochure sites.  They're great for designers who are making media.  But for programmers, not so good.</p>
+
+<p><strong>CRAIG</strong>:     I see what you're saying now.  Okay.  Yeah, I gotcha.  Yeah.</p>
+
+<p><strong>ALAN</strong>:     But, yeah.  Okay.  I'm done with my thing.</p>
+
+<p><strong>CRAIG</strong>:     Cool.</p>
+
+<p><strong>ALAN</strong>:     You may go to the bathroom.</p>
+
+<p><strong>CRAIG</strong>:     Yes.  It is a podcast.  There's a pause button.</p>
+
+<p><strong>ALAN</strong>:     That's true.</p>
+
+<p><strong>CRAIG</strong>:     Anyway, yeah.</p>
+
+<p><strong>ALAN</strong>:     It didn't occur to me.</p>
+
+<p><strong>CRAIG</strong>:     No, but I do think it probably would make sense to wind down.</p>
+
+<p><strong>MICHA</strong>:     You can just hit mute.</p>
+
+<p><strong>CRAIG</strong>:     There you go.</p>
+
+<p><strong>MICHA</strong>:     You'll be fine.</p>
+
+<p><strong>CRAIG</strong>:     Mute my part.  Mute my part.  I'm not saying anything interesting.  But I do want to kind of bring it to a close here, and I want to make sure that we have – I mean, Alan, obviously you said you wanted one more thing, and that thing was very worth hearing.  I'd like to make sure we give Micha the same opportunity.  Micha, is there anything else that you think we should touch on before we wind down to the final question?</p>
+
+<p><strong>MICHA</strong>:     No, I think we're good.</p>
+
+<p><strong>CRAIG</strong>:     Cool.  Yeah, this was awesome, guys.  Yeah, I really enjoyed our last conversation.  And, as I was coming to this one today, I'm like, okay, cool.  We talked about boot.  We'll talk about javelin and hoplon.  That'll be good.  That'll be good.  Clearly there is a lot to talk about here, a lot of really interesting, really important stuff to say, so much so that I will feel comfortable in saying that we will have you back on again.</p>
+
+<p>I don't think we'll do a third part to the show, but at some point in the future, the not too distant future, we'll have you back on.  It'd certainly be great to hear more about what's happening in the hoplon, boot, javelin, Adzerk, Alan, Micha universe.  Always good stuff happening there.</p>
+
+<p>But I do of course have one more question for Micha, which is, we'd like to close the show with a piece of advice.  I'll go ahead and say that use hoplon is now obvious.  Maybe that was your piece of advice, or at least try it, I suppose, would be the better way to put that.  But I'm imagining you have something else in mind.  What advice would you like to share with our audience today, Micha?</p>
+
+<p><strong>MICHA</strong>:     Can it be like a little pro tip kind of thing?</p>
+
+<p><strong>CRAIG</strong>:     Literally anything you like.</p>
+
+<p><strong>MICHA</strong>:     Oh, well, I really enjoy – I have a paintbrush in my bag, and I use it to clean off my monitor and my keyboard constantly.  Not obsessively, but just whenever there is stuff on my keyboard, and I really enjoy it.</p>
+
+<p><strong>CRAIG</strong>:     Hmm.  So it'll get, like, between the keys, all the crumbs and everything that wind up in there or whatever?</p>
+
+<p><strong>MICHA</strong>:     Totally!</p>
+
+<p><strong>CRAIG</strong>:     Huh.</p>
+
+<p><strong>MICHA</strong>:     Yeah.</p>
+
+<p><strong>ALAN</strong>:     Well, at one point you compared yourself to an umpire.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Kind of a similar habit.</p>
+
+<p><strong>MICHA</strong>:     Yeah, sweeping off the plate, getting ready to go.</p>
+
+<p><strong>ALAN</strong>:     Right.</p>
+
+<p><strong>MICHA</strong>:     And I only mention it because now there's like three paint brushes around the office or something.</p>
+
+<p><strong>ALAN</strong>:     Yeah.</p>
+
+<p><strong>MICHA</strong>:     Generally, people enjoy it, so maybe, you know–</p>
+
+<p><strong>ALAN</strong>:     Yeah, everyone seems to crack their knuckles.</p>
+
+<p><strong>MICHA</strong>:     Right.</p>
+
+<p><strong>ALAN</strong>:     Pull out their paintbrush.  Dust off their screen and keyboard.  And then–</p>
+
+<p><strong>CRAIG</strong>:     Well, I have to say I will take that one to heart because I have been known to be on the phone with somebody and to kind of flip my keyboard over and bang it on the desk.  As a result, like, drop it on the floor and hang up a call.  And so I think the paintbrush is a much, much better way to handle that.  I like that a lot.</p>
+
+<p><strong>ALAN</strong>:     Yeah.  Elegant.</p>
+
+<p><strong>CRAIG</strong>:     All right.  Well, look, guys.  Thanks a ton for coming back on.  I'm actually really psyched that we were able to do this so soon, at least in podcast time, after the last show.  I think they complement each other really, really well, and I've been really into your tech.  I said last show, but I'll say it again.  Thanks for making this stuff.  It's really cool, and it's made me feel incredibly productive in the browser space that I have avoided for, like, since 1991 when I first saw a browser, so thanks a lot for both that and for coming on the show to talk to us about it today.</p>
+
+<p><strong>MICHA</strong>:     Sure.  Thank you.</p>
+
+<p><strong>ALAN</strong>:     And I said this, I think, the last time we talked about hoplon, but we have a really small, really helpful community, mostly in Slack, in the Clojurian Slack.  If you find yourself toying with this stuff and are stymied or just are curious to see what other people are doing, feel free to join us.  We're always happy to help and talk about what we're up to.</p>
+
+<p><strong>CRAIG</strong>:     Awesome.  Good tip.  All right, guys.  We will call it an episode.  Thanks so much for being on.  This has been The Cognicast.</p>
+
+<p>[Music: "Thumbs Up (for Rock N' Roll)" by Kill the Noise and Feed Me]</p>
+
+<p><strong>CRAIG</strong>:     You have been listening to The Cognicast.  The Cognicast is a production of Cognitect, Inc.  Cognitect are the makers of Datomic, and we provide consulting services around it, Clojure, and a host of other technologies to businesses ranging from the smallest startups to the Fortune 50.  You can find us on the Web at cognitect.com and on Twitter, @Cognitect.  You can subscribe to The Cognicast, listen to past episodes, and view cover art, show notes, and episode transcripts at our home on the Web, cognitect.com/podcast.  You can contact the show by tweeting @Cognicast or by emailing us at podcast@cognitect.com.</p>
+
+<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Our guests today were Alan Dipert, on Twitter, @AlanDipert, and Micha Niskin, on Twitter, @MichaNiskin.  Episode cover art is by Michael Parenteau, audio production by Russ Olsen and Daemian Mack.  The Cognicast is produced by Kim Foster.  Our theme music is Thumbs Up (for Rock N' Roll) by Kill the Noise with Feed Me.  I'm your host, Craig Andera.  Thanks for listening.
+</code></pre></div></div>
+    </article>
+  </main>
+</body>
+</html>
diff --git a/md/TechWorks/media/audio/cognicast-052.mp3 b/md/TechWorks/media/audio/cognicast-052.mp3
new file mode 100644
index 0000000..d91c828
--- /dev/null
+++ b/md/TechWorks/media/audio/cognicast-052.mp3
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ace070cf982b935b701a28b767194b82a59b2322986c065e7159aefdfab3dc58
+size 59425020
diff --git a/md/TechWorks/media/audio/cognicast-111.mp3 b/md/TechWorks/media/audio/cognicast-111.mp3
new file mode 100644
index 0000000..cee2780
--- /dev/null
+++ b/md/TechWorks/media/audio/cognicast-111.mp3
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4562fcd751a5331289d86e3f40eb67870160e637b88b8ff3be0cf33524a1bc5a
+size 76461056
diff --git a/md/TechWorks/media/audio/cognicast-112.mp3 b/md/TechWorks/media/audio/cognicast-112.mp3
new file mode 100644
index 0000000..4b5a638
--- /dev/null
+++ b/md/TechWorks/media/audio/cognicast-112.mp3
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cff200708de3e324faa0e5a7cd4fce4beaaa9100921c47ac4d81bcb698e151f6
+size 86666687
diff --git a/md/TechWorksArchive.md b/md/TechWorksArchive.md
index 36235be..dd89817 100644
--- a/md/TechWorksArchive.md
+++ b/md/TechWorksArchive.md
@@ -35,6 +35,14 @@ These are the best available copies from the original hosts. Captions are includ
 | Web Programming with Hoplon | [Video](./TechWorks/media/video/wVXjExRiFy0.mp4) | [English](./TechWorks/media/video/wVXjExRiFy0.en.vtt) |
 | Flapjax lightning talk | [Video](./TechWorks/media/video/xaxF5RDdVRE.mp4) | [English](./TechWorks/media/video/xaxF5RDdVRE.en.vtt) |
 
+## Podcasts
+
+| Episode | Listen | Transcript |
+|:--------|:-------|:-----------|
+| Cognicast 112: Solving problems and Boot, part II | [Audio](./TechWorks/media/audio/cognicast-112.mp3) | [Read](./TechWorks/Cognicast112.html#transcript) |
+| Cognicast 111: Solving problems and Boot | [Audio](./TechWorks/media/audio/cognicast-111.mp3) | [Read](./TechWorks/Cognicast111.html#transcript) |
+| Cognicast 52: Hoplon | [Audio](./TechWorks/media/audio/cognicast-052.mp3) | Not published |
+
 ## Sites
 
 | Site | Browse |
diff --git a/tools/extract_cognicast.py b/tools/extract_cognicast.py
new file mode 100644
index 0000000..28ed9be
--- /dev/null
+++ b/tools/extract_cognicast.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+"""Build a standalone local transcript from a preserved Cognicast page."""
+
+from __future__ import annotations
+
+import argparse
+from pathlib import Path
+
+
+def main() -> None:
+    parser = argparse.ArgumentParser()
+    parser.add_argument("source", type=Path)
+    parser.add_argument("destination", type=Path)
+    parser.add_argument("--title", required=True)
+    parser.add_argument("--date", required=True)
+    parser.add_argument("--original-url", required=True)
+    parser.add_argument("--audio-path", required=True)
+    args = parser.parse_args()
+
+    source = args.source.read_text(encoding="utf-8")
+    start = source.index('<h1 id="transcript">')
+    end = source.index('<div class="related">', start)
+    transcript = source[start:end].rstrip()
+    if not transcript.endswith("</div>"):
+        raise SystemExit("unexpected Cognicast transcript structure")
+    transcript = transcript.removesuffix("</div>").rstrip()
+    transcript = transcript.replace(
+        '<h1 id="transcript">TRANSCRIPT</h1>',
+        '<h2 id="transcript">Transcript</h2>',
+        1,
+    )
+
+    page = f'''<!doctype html>
+<html lang="en">
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>{args.title}</title>
+  <link rel="stylesheet" href="../style.css">
+</head>
+<body>
+  <main id="main">
+    <header class="site-head">
+      <a class="site-brand" href="../TechWorks.html">
+        <span class="site-brand-name">TechWorks</span>
+        <span class="site-brand-tagline">Selected work</span>
+      </a>
+      <nav class="site-nav" aria-label="Archive navigation">
+        <a href="../TechWorks.html">Works</a>
+        <a href="../TechWorksArchive.html">Archive</a>
+      </nav>
+    </header>
+    <article>
+      <h1>{args.title}</h1>
+      <p><small>Published by The Cognicast on {args.date}. <a href="{args.original_url}">Visit the original episode page</a>.</small></p>
+      <p><audio controls preload="metadata" src="{args.audio_path}">Your browser does not support embedded audio.</audio></p>
+      {transcript}
+    </article>
+  </main>
+</body>
+</html>
+'''
+    args.destination.write_text(page, encoding="utf-8")
+
+
+if __name__ == "__main__":
+    main()