<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Thomas Cothran</title><link>https://thomascothran.tech/</link><description>Recent content on Thomas Cothran</description><generator>Hugo</generator><language>en</language><copyright>2023, Thomas Cothran</copyright><lastBuildDate>Fri, 17 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thomascothran.tech/index.xml" rel="self" type="application/rss+xml"/><item><title>Pavlov for the Web</title><link>https://thomascothran.tech/2026/04/pavlov-for-the-web/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2026/04/pavlov-for-the-web/</guid><description>Pavlov brings behavioral programming to web development</description></item><item><title>Avoid with-redefs in tests</title><link>https://thomascothran.tech/2025/04/avoid-with-redefs/</link><pubDate>Mon, 07 Apr 2025 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2025/04/avoid-with-redefs/</guid><description>The use of with-redefs in tests indicates a poor understanding of good testing practices</description></item><item><title>What do I want from a codebase?</title><link>https://thomascothran.tech/2024/11/what-do-i-want-from-a-codebase/</link><pubDate>Wed, 27 Nov 2024 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2024/11/what-do-i-want-from-a-codebase/</guid><description>&lt;p&gt;Carson Gross&amp;rsquo; &lt;a href="https://htmx.org/essays/codin-dirty/"&gt;&amp;ldquo;Codin&amp;rsquo; Dirty&amp;rdquo;&lt;/a&gt; essay is designed to provoke controversy. Although I will critique the essay, I want to make it clear that I am (on this Thanksgiving eve) grateful for Carson Gross&amp;rsquo;s work.&lt;/p&gt;
&lt;p&gt;Gross writes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I’m &amp;hellip; not trying to convince you to code dirty with this essay. Rather, I want to show that it is possible to write reasonably successful software this way and, I hope, offer some balance around software methodology discussions.&lt;/p&gt;</description></item><item><title>Bthreads: A Simple and Easy Paradigm for Clojure</title><link>https://thomascothran.tech/2024/10/a-new-paradigm/</link><pubDate>Wed, 30 Oct 2024 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2024/10/a-new-paradigm/</guid><description>Can bthreads make event-driven programs both simple and easy?</description></item><item><title>Behavioral Programming in Clojure</title><link>https://thomascothran.tech/2024/09/in-clojure/</link><pubDate>Tue, 24 Sep 2024 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2024/09/in-clojure/</guid><description>Behavioral programming is a relatively new programming paradigm that excels at isolating behavior in event-driven systems. What would it look like in Clojure?</description></item><item><title>The Ocelot Game</title><link>https://thomascothran.tech/2024/09/the-ocelot-game/</link><pubDate>Wed, 11 Sep 2024 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2024/09/the-ocelot-game/</guid><description>&lt;p&gt;The ocelot game works like this: a developer has written a feature, and presents it to an ocelot.&lt;/p&gt;
&lt;p&gt;Not a real ocelot. Ocelots are playful. But they&amp;rsquo;re wild animals. Their claws easily poke holes in things. We want to poke holes in code.&lt;/p&gt;
&lt;p&gt;The ocelot is a role played by a developer who tries to poke holes in another developer&amp;rsquo;s code. Specifically, they try to change the code in such a way that the feature breaks while still passing the unit tests.&lt;/p&gt;</description></item><item><title>Top-Down Imperative Clojure Architectures</title><link>https://thomascothran.tech/2024/07/top-down-imperative-clojure-architectures/</link><pubDate>Mon, 22 Jul 2024 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2024/07/top-down-imperative-clojure-architectures/</guid><description>&lt;p&gt;When I first became interested in functional programming, a more experienced engineer told me: &amp;ldquo;you know functional programming doesn&amp;rsquo;t really amount to much more than procedural programming.&amp;rdquo; As I insisted on the benefits of &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;filter&lt;/code&gt; and &lt;code&gt;reduce&lt;/code&gt;, he simply shook his head. &amp;ldquo;You&amp;rsquo;re thinking in the small. Go look at a large real-world application.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;It took some time for me to see what he meant. My preferred language, Clojure, is a functional language. But too often it is used to build top-down, imperative applications. This negates the value proposition of functional programming: isolating side effects, local reasoning, and system composition.&lt;/p&gt;</description></item><item><title>MPAs vs SPAs: The False Dichotomy</title><link>https://thomascothran.tech/2024/01/the-false-dichotomy-mpas-spas/</link><pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2024/01/the-false-dichotomy-mpas-spas/</guid><description>&lt;p&gt;&lt;em&gt;This is the second post in the series &amp;ldquo;Have Clojure UIs Taken the Wrong Path?&amp;rdquo;. The first post is &lt;a href="https://thomascothran.tech/2023/11/clojure-uis-hypermedia-and-rpc-1/"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;How do we choose between building an application using a hypermedia approach versus the client-side SPA? This post won&amp;rsquo;t answer that question. But it will say how &lt;em&gt;not&lt;/em&gt; to make that choice.&lt;/p&gt;
&lt;p&gt;A common heuristic is the spectrum that stretches between old fashioned &amp;ldquo;Multi Page Apps&amp;rdquo; (MPAs) for basic use cases, to Single Page Applications for rich client interactivity.&lt;/p&gt;</description></item><item><title>Have Clojure UIs Taken the Wrong Path? Part 1</title><link>https://thomascothran.tech/2023/11/clojure-uis-hypermedia-and-rpc-1/</link><pubDate>Fri, 24 Nov 2023 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2023/11/clojure-uis-hypermedia-and-rpc-1/</guid><description>&lt;p&gt;The Clojure community has focused on React-based solutions for complex front-end clients such as Reagent, Rum, Om, Re-frame, and Fulcro.&lt;/p&gt;
&lt;p&gt;For all their differences, they follow a very similar architecture, making heavy use of client-side state and using RPC for client-server communication. We will call this the “React+” approach.&lt;/p&gt;
&lt;p&gt;But is this the right choice?&lt;/p&gt;
&lt;p&gt;I will suggest the answer may be negative. My suspicion is that as web UI libraries advance, the problems they solve are not essential. Rather, the problems are accidental; they are generated by the React+ architecture.&lt;/p&gt;</description></item><item><title>The Wrong Kind of Readability</title><link>https://thomascothran.tech/2023/11/readability/</link><pubDate>Sun, 05 Nov 2023 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2023/11/readability/</guid><description>Andy Hunt and Dave Thomas tell us: &amp;#39;it’s critical that you write code that is readable and easy to reason about.&amp;#39; This seems uncontroversial; it is the rare point on which software engineers typically agree. Or do they?</description></item><item><title>The Library Locker - An Antipattern</title><link>https://thomascothran.tech/2023/08/library-locker/</link><pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2023/08/library-locker/</guid><description>The library locker antipattern occurs when we try to add functionality to a library function, but do so without separating concerns.</description></item><item><title>Brittle Clojure: Creating Legacy Clojure Systems</title><link>https://thomascothran.tech/2023/07/brittle-clojure/</link><pubDate>Sun, 23 Jul 2023 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2023/07/brittle-clojure/</guid><description>Avoid writing brittle Clojure with tactics for flexibility and robustness.</description></item><item><title>Distributed Merges and Continuous Integration</title><link>https://thomascothran.tech/2023/07/distributed-merges/</link><pubDate>Fri, 14 Jul 2023 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2023/07/distributed-merges/</guid><description>Feature branching with large monoliths causes merge hell. Microservices promise independent deployability. But sometimes you get distributed merge hell</description></item><item><title>Don't Be a Cremonini</title><link>https://thomascothran.tech/2023/07/dont-be-cremonini/</link><pubDate>Sun, 09 Jul 2023 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2023/07/dont-be-cremonini/</guid><description>Are debates about software just differences of opinion? Or do we have the evidence necessary to identify what works and what doesn&amp;#39;t? How the Annual Devops Report can resolve questions about the best practices in software development</description></item><item><title>Haskell's Triangle</title><link>https://thomascothran.tech/2017/07/haskells-triangle/</link><pubDate>Mon, 17 Jul 2017 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2017/07/haskells-triangle/</guid><description>The polymath Blaise Pascal envisaged a triangle built of numbers. Pascal’s triangle — as it is usually called, despite the fact that its discovery predated Pascal by centuries — has the interesting property that each number is the sum of the two numbers directly above it.</description></item><item><title>Recursion Made Simple with Roman Numerals</title><link>https://thomascothran.tech/2017/07/recursion-with-roman-numerals/</link><pubDate>Mon, 17 Jul 2017 00:00:00 +0000</pubDate><guid>https://thomascothran.tech/2017/07/recursion-with-roman-numerals/</guid><description>A procedure is recursive if it invokes itself. This article explains recursion in a simple way by examining functions that convert between Arabic and roman numerals.</description></item></channel></rss>