{"id":1860,"date":"2024-12-03T20:23:29","date_gmt":"2024-12-03T20:23:29","guid":{"rendered":"https:\/\/exponentialdecay.co.uk\/blog\/?p=1860"},"modified":"2025-06-26T20:22:52","modified_gmt":"2025-06-26T20:22:52","slug":"code-as-memory","status":"publish","type":"post","link":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/","title":{"rendered":"Code as memory?"},"content":{"rendered":"<p>It is very poetic to think about code as it containing the memory of its maintainers. I don&#8217;t entirely disagree with the idea, but it&#8217;s overly poetic and the reality of maintenance on systems that have become too unwieldy is anything but poetic.<\/p>\n<p><!--more--><\/p>\n<p>I am currently polishing off a small demo script that I wrote a year ago. The code takes a Whatsapp export and reformats it to HTML that can be skinned. For fun I&#8217;ve used a <a href=\"https:\/\/nostalgic-css.github.io\/NES.css\/\" target=\"_blank\" rel=\"noopener\">NES stylesheet<\/a> which has neat dialogs to represent a conversation \u00e0 la Whatsapp where the speech bubbles on the left are your friends or colleagues and those on the right are you.<\/p>\n<p><a href=\"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/whatsmapper-nes.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1958\" src=\"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/whatsmapper-nes.png\" alt=\"Demonstration of Whatsmapper using a group chat from Whatsapp\" width=\"1040\" height=\"770\" srcset=\"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/whatsmapper-nes.png 1040w, https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/whatsmapper-nes-500x370.png 500w, https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/whatsmapper-nes-1024x758.png 1024w, https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/whatsmapper-nes-768x569.png 768w\" sizes=\"auto, (max-width: 1040px) 100vw, 1040px\" \/><\/a><\/p>\n<p>The script is largely whimsical, but it has given me plenty to think about if I want to turn this into a production project in the future.<\/p>\n<p>But what does &#8220;production&#8221; mean here?<\/p>\n<p>All of the code I write professionally these days is heavily tested. The code is organized well, adopts the single responsibility principle, and uses a range of <a href=\"https:\/\/exponentialdecay.co.uk\/blog\/linting-as-understanding\/\" target=\"_blank\" rel=\"noopener\">linting tools<\/a> to make sure the code layout is idomatic and gotchas are addressed early, e.g. linting will often highlight insecure or fragile code.<\/p>\n<p>And I follow the same principles for the most part for the code that I write for myself.<\/p>\n<p>Except for when I am writing fast for fun. Like in the case of <a href=\"https:\/\/github.com\/ross-spencer\/whatsmapper\/\" target=\"_blank\" rel=\"noopener\">Whatsmapper<\/a>, Take this innocuous example:<\/p>\n<p><a href=\"https:\/\/github.com\/ross-spencer\/whatsmapper\/blob\/e438dcd9913f617a3ef7cb94a79874d8121e943d\/src\/whatsmapper\/whatsmap.py#L257C1-L266\" target=\"_blank\" rel=\"noopener\">https:\/\/github.com\/ross-spencer\/whatsmapper\/blob\/e438dcd9913f617a3ef7cb94a79874d8121e943d\/src\/whatsmapper\/whatsmap.py#L257C1-L266<\/a><\/p>\n<p><code> try:<\/code><br \/>\n<code>\u00a0 if line.startswith(\"[\"):<\/code><br \/>\n<code>\u00a0 \u00a0 individual = line.split(\"] \")[1].split(\": \", 1)[0]<\/code><br \/>\n<code>\u00a0 \u00a0 chat_text = \"\".join(line.split(individual)[1:])<\/code><br \/>\n<code>\u00a0 \u00a0 if individual not in individuals:<\/code><br \/>\n<code>\u00a0 \u00a0 \u00a0 individuals.append(individual)<\/code><br \/>\n<code>\u00a0 else:<\/code><br \/>\n<code>\u00a0 \u00a0 chat_text = line<\/code><br \/>\n<code>except IndexError:<\/code><br \/>\n<code>\u00a0 chat_text = line<\/code><\/p>\n<p>In this example I make three different decisions about what the &#8220;chat_text&#8221; variable needs to be set to. But what are these decisions?<\/p>\n<p>I can tell you 48 hours separated from the code that each new message in a Whatsapp message begins with <code>[DATE TIMESTAMP] NAME: MESSAGE<\/code> e.g.\u00a0<code>[[9\/14\/24, 13:06:47] ~\u202fAlfred Stewart: g'day!<\/code>.<\/p>\n<p>We need to tokenize these values, and so we try and do that in the code above. If a line doesn&#8217;t begin with a square bracket it is assumed to be part of a multi-line message and it will be added to the chat text variable.<\/p>\n<p>The code is nested in a try-catch if something goes wrong while slicing the string, but do we need it?<\/p>\n<p>Honestly I already can&#8217;t recall and I am loathe to get rid of it just yet. And I only changed this code two days ago.<\/p>\n<p>My mistakes are that I don&#8217;t have all the sample data that I used to start the script a year ago and I don&#8217;t have tests that show me example inputs and outputs as I would like them to be. The code isn&#8217;t separated from the primary loop into a single responsibility function where that responsibility is nicely described by the function name and its documentation (<a href=\"https:\/\/betterprogramming.pub\/3-different-docstring-formats-for-python-d27be81e0d68\" target=\"_blank\" rel=\"noopener\">docstring<\/a>) e.g.<\/p>\n<p><code>def tokenize_message(msg: str) -&gt; list:<\/code><br \/>\n<code>\u00a0 \u00a0\"\"\"Split the first line of a Whatsapp message into date, time, individual,<\/code><br \/>\n<code>\u00a0 \u00a0and message string.<\/code><br \/>\n<code>\u00a0 \u00a0\"\"\"<\/code><\/p>\n<p>For the simplest of decisions, I already have a maintenance problem. I have to make a decision at some point: When do I take this code from fun proof of concept to something serious? When do I start adding tests?<\/p>\n<p>What I want to say to those developing their own tooling in digital preservation is that you need to start writing the tests from the very beginning.<\/p>\n<p>If I write tests it frees me and others from a number of coding prisons:<\/p>\n<ol>\n<li>remembering what myself five-years ago wrote.<\/li>\n<li>guaranteeing that what I wrote works if I change something.<\/li>\n<li>code becomes less complex and easier to follow and it makes it easier for others to jump into the code.<\/li>\n<li>guarantees that the work someone else does works with the legacy code.<\/li>\n<\/ol>\n<p>We work on a lot of formats in digital preservation and we know from experience or anecdotally that a lot of these formats have &#8220;quirks&#8221;, e.g. written across multiple specifications or interpretations of complex specifications, or having no specification at all. We need to encode these quirks in our code and in our tests so that we can continue to maintain the incredibly useful scripts that we are writing today.<\/p>\n<address><em>Note. formats are easy to pick on because they represent the fundamental aspects of programming but it applies to all and any code we write, e.g. writing manifests for packages; restriction mechanisms for access servers; repository software, and so on.\u00a0<\/em><\/address>\n<p>As this script evolves, the different branches that I create that ensure different variations of Whatsapp export are parsed correctly (earlier versions, or those with different export formats, for example) the level of complexity in the code <a href=\"https:\/\/en.wikipedia.org\/wiki\/Programming_complexity\" target=\"_blank\" rel=\"noopener\">increases exponentially<\/a> and the ability to reason about decisions made in the code becomes more and more difficult over time.<\/p>\n<p>As scripts become software becomes systems this gets even more important. Good coverage protects us from the risks and costs of the impact of different types of error (and regression of fixes one day in the future). The fewer errors systems have the greater the reputation of those systems. And the easier it is to maintain them, the cheaper those systems can become to maintain, meaning that focus can be shifted to new features, initiatives, or tooling.<\/p>\n<p>It is a hope of mine that one day we can audit our different systems for different metrics such as <a href=\"https:\/\/en.wikipedia.org\/wiki\/Code_coverage\" target=\"_blank\" rel=\"noopener\">test coverage<\/a> or <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cyclomatic_complexity\" target=\"_blank\" rel=\"noopener\">cyclometric<\/a> or <a href=\"https:\/\/www.sonarsource.com\/blog\/5-clean-code-tips-for-reducing-cognitive-complexity\/\" target=\"_blank\" rel=\"noopener\">cognitive<\/a> complexity among other measures (such as ability to perform <a href=\"https:\/\/github.com\/xen0n\/gosmopolitan\" target=\"_blank\" rel=\"noopener\">localization<\/a>) to provide an indication of the quality of the foundations of the software that we use to maintain our digital legacy.<\/p>\n<p>Code doesn&#8217;t represent the memory of its maintainers, it&#8217;s just the scratch pad. Memory requires reinforcement and the confidence that it&#8217;s accurate, tests are the reinforcement and the confidence; tests <strong><em>are<\/em><\/strong> the memory of the maintainers. Without tests, code is just ephemeral.<\/p>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_1860\" class=\"pvc_stats total_only  \" data-element-id=\"1860\" style=\"\"><i class=\"pvc-stats-icon small\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"excerpt":{"rendered":"<p>It is very poetic to think about code as it containing the memory of its maintainers. I don&#8217;t entirely disagree with the idea, but it&#8217;s overly poetic and the reality of maintenance on systems that have become too unwieldy is anything but poetic.<\/p>\n<div class=\"link-more\"><a href=\"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &ldquo;Code as memory?&rdquo;<\/span>&hellip;<\/a><\/div>\n<div class=\"pvc_clear\"><\/div>\n<p id=\"pvc_stats_1860\" class=\"pvc_stats total_only  \" data-element-id=\"1860\" style=\"\"><i class=\"pvc-stats-icon small\" aria-hidden=\"true\"><svg aria-hidden=\"true\" focusable=\"false\" data-prefix=\"far\" data-icon=\"chart-bar\" role=\"img\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 512 512\" class=\"svg-inline--fa fa-chart-bar fa-w-16 fa-2x\"><path fill=\"currentColor\" d=\"M396.8 352h22.4c6.4 0 12.8-6.4 12.8-12.8V108.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v230.4c0 6.4 6.4 12.8 12.8 12.8zm-192 0h22.4c6.4 0 12.8-6.4 12.8-12.8V140.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v198.4c0 6.4 6.4 12.8 12.8 12.8zm96 0h22.4c6.4 0 12.8-6.4 12.8-12.8V204.8c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v134.4c0 6.4 6.4 12.8 12.8 12.8zM496 400H48V80c0-8.84-7.16-16-16-16H16C7.16 64 0 71.16 0 80v336c0 17.67 14.33 32 32 32h464c8.84 0 16-7.16 16-16v-16c0-8.84-7.16-16-16-16zm-387.2-48h22.4c6.4 0 12.8-6.4 12.8-12.8v-70.4c0-6.4-6.4-12.8-12.8-12.8h-22.4c-6.4 0-12.8 6.4-12.8 12.8v70.4c0 6.4 6.4 12.8 12.8 12.8z\" class=\"\"><\/path><\/svg><\/i> <img loading=\"lazy\" decoding=\"async\" width=\"16\" height=\"16\" alt=\"Loading\" src=\"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/plugins\/page-views-count\/ajax-loader-2x.gif\" border=0 \/><\/p>\n<div class=\"pvc_clear\"><\/div>\n","protected":false},"author":1,"featured_media":1955,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"federated","footnotes":""},"categories":[49,114,3,20,374],"tags":[61,256,96,147,115,71,29,17,166,173,42,254,97],"class_list":["post-1860","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-digital-humanities","category-digital-literacy","category-digital-preservation","category-just-code","category-software-preservation","tag-code","tag-code-hygiene","tag-coding","tag-digipres","tag-digital-literacy","tag-digital-preservation","tag-file-format","tag-file-formats","tag-foss","tag-maintenance","tag-open-source","tag-software","tag-software-development","entry"],"a3_pvc":{"activated":true,"total_views":111,"today_views":0},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Code as memory? - ross spencer :: exponentialdecay.digipres :: blog<\/title>\n<meta name=\"description\" content=\"Code doesn&#039;t represent the memory of its maintainers; it requires reinforcement. We need tests. Without tests, code is simply ephemeral.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Code as memory? - ross spencer :: exponentialdecay.digipres :: blog\" \/>\n<meta property=\"og:description\" content=\"Code doesn&#039;t represent the memory of its maintainers; it requires reinforcement. We need tests. Without tests, code is simply ephemeral.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/\" \/>\n<meta property=\"og:site_name\" content=\"ross spencer :: exponentialdecay.digipres :: blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-12-03T20:23:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-26T20:22:52+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/silver-birch-in-ravensburg-scaled.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2560\" \/>\n\t<meta property=\"og:image:height\" content=\"1069\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Ross Spencer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@beet_keeper\" \/>\n<meta name=\"twitter:site\" content=\"@beet_keeper\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Ross Spencer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/\"},\"author\":{\"name\":\"Ross Spencer\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/4cae0a954400f42b9c1b70c699837716\"},\"headline\":\"Code as memory?\",\"datePublished\":\"2024-12-03T20:23:29+00:00\",\"dateModified\":\"2025-06-26T20:22:52+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/\"},\"wordCount\":948,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/4cae0a954400f42b9c1b70c699837716\"},\"image\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/silver-birch-in-ravensburg-scaled.jpg\",\"keywords\":[\"Code\",\"code hygiene\",\"Coding\",\"digipres\",\"digital literacy\",\"Digital Preservation\",\"File Format\",\"File Formats\",\"FOSS\",\"maintenance\",\"Open Source\",\"software\",\"Software Development\"],\"articleSection\":[\"Digital Humanities\",\"Digital Literacy\",\"Digital Preservation\",\"Just Code\",\"Software Preservation\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/\",\"url\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/\",\"name\":\"Code as memory? - ross spencer :: exponentialdecay.digipres :: blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/silver-birch-in-ravensburg-scaled.jpg\",\"datePublished\":\"2024-12-03T20:23:29+00:00\",\"dateModified\":\"2025-06-26T20:22:52+00:00\",\"description\":\"Code doesn't represent the memory of its maintainers; it requires reinforcement. We need tests. Without tests, code is simply ephemeral.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#primaryimage\",\"url\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/silver-birch-in-ravensburg-scaled.jpg\",\"contentUrl\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2024\\\/12\\\/silver-birch-in-ravensburg-scaled.jpg\",\"width\":2560,\"height\":1069,\"caption\":\"Silver birth tree in Ravensburg featuring its characteristic eye-like bark.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/code-as-memory\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Code as memory?\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/\",\"name\":\"ross spencer :: exponentialdecay.digipres :: blog\",\"description\":\"Digital preservation analyst, researcher, and software developer\",\"publisher\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/4cae0a954400f42b9c1b70c699837716\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/#\\\/schema\\\/person\\\/4cae0a954400f42b9c1b70c699837716\",\"name\":\"Ross Spencer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/avatar-scaled.png\",\"url\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/avatar-scaled.png\",\"contentUrl\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/avatar-scaled.png\",\"width\":2560,\"height\":2560,\"caption\":\"Ross Spencer\"},\"logo\":{\"@id\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/06\\\/avatar-scaled.png\"},\"description\":\"Digital preservation domain expert and full-stack software developer.\",\"sameAs\":[\"http:\\\/\\\/www.exponentialdecay.co.uk\\\/blog\",\"https:\\\/\\\/www.instagram.com\\\/b33tk33p3r\\\/\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/ross-spencer-b6b9b758\\\/\",\"https:\\\/\\\/x.com\\\/beet_keeper\"],\"url\":\"https:\\\/\\\/exponentialdecay.co.uk\\\/blog\\\/author\\\/exponentialdecay\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Code as memory? - ross spencer :: exponentialdecay.digipres :: blog","description":"Code doesn't represent the memory of its maintainers; it requires reinforcement. We need tests. Without tests, code is simply ephemeral.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/","og_locale":"en_US","og_type":"article","og_title":"Code as memory? - ross spencer :: exponentialdecay.digipres :: blog","og_description":"Code doesn't represent the memory of its maintainers; it requires reinforcement. We need tests. Without tests, code is simply ephemeral.","og_url":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/","og_site_name":"ross spencer :: exponentialdecay.digipres :: blog","article_published_time":"2024-12-03T20:23:29+00:00","article_modified_time":"2025-06-26T20:22:52+00:00","og_image":[{"width":2560,"height":1069,"url":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/silver-birch-in-ravensburg-scaled.jpg","type":"image\/jpeg"}],"author":"Ross Spencer","twitter_card":"summary_large_image","twitter_creator":"@beet_keeper","twitter_site":"@beet_keeper","twitter_misc":{"Written by":"Ross Spencer","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#article","isPartOf":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/"},"author":{"name":"Ross Spencer","@id":"https:\/\/exponentialdecay.co.uk\/blog\/#\/schema\/person\/4cae0a954400f42b9c1b70c699837716"},"headline":"Code as memory?","datePublished":"2024-12-03T20:23:29+00:00","dateModified":"2025-06-26T20:22:52+00:00","mainEntityOfPage":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/"},"wordCount":948,"commentCount":1,"publisher":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/#\/schema\/person\/4cae0a954400f42b9c1b70c699837716"},"image":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#primaryimage"},"thumbnailUrl":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/silver-birch-in-ravensburg-scaled.jpg","keywords":["Code","code hygiene","Coding","digipres","digital literacy","Digital Preservation","File Format","File Formats","FOSS","maintenance","Open Source","software","Software Development"],"articleSection":["Digital Humanities","Digital Literacy","Digital Preservation","Just Code","Software Preservation"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/","url":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/","name":"Code as memory? - ross spencer :: exponentialdecay.digipres :: blog","isPartOf":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#primaryimage"},"image":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#primaryimage"},"thumbnailUrl":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/silver-birch-in-ravensburg-scaled.jpg","datePublished":"2024-12-03T20:23:29+00:00","dateModified":"2025-06-26T20:22:52+00:00","description":"Code doesn't represent the memory of its maintainers; it requires reinforcement. We need tests. Without tests, code is simply ephemeral.","breadcrumb":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#primaryimage","url":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/silver-birch-in-ravensburg-scaled.jpg","contentUrl":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2024\/12\/silver-birch-in-ravensburg-scaled.jpg","width":2560,"height":1069,"caption":"Silver birth tree in Ravensburg featuring its characteristic eye-like bark."},{"@type":"BreadcrumbList","@id":"https:\/\/exponentialdecay.co.uk\/blog\/code-as-memory\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/exponentialdecay.co.uk\/blog\/"},{"@type":"ListItem","position":2,"name":"Code as memory?"}]},{"@type":"WebSite","@id":"https:\/\/exponentialdecay.co.uk\/blog\/#website","url":"https:\/\/exponentialdecay.co.uk\/blog\/","name":"ross spencer :: exponentialdecay.digipres :: blog","description":"Digital preservation analyst, researcher, and software developer","publisher":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/#\/schema\/person\/4cae0a954400f42b9c1b70c699837716"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/exponentialdecay.co.uk\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/exponentialdecay.co.uk\/blog\/#\/schema\/person\/4cae0a954400f42b9c1b70c699837716","name":"Ross Spencer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2025\/06\/avatar-scaled.png","url":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2025\/06\/avatar-scaled.png","contentUrl":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2025\/06\/avatar-scaled.png","width":2560,"height":2560,"caption":"Ross Spencer"},"logo":{"@id":"https:\/\/exponentialdecay.co.uk\/blog\/wp-content\/uploads\/2025\/06\/avatar-scaled.png"},"description":"Digital preservation domain expert and full-stack software developer.","sameAs":["http:\/\/www.exponentialdecay.co.uk\/blog","https:\/\/www.instagram.com\/b33tk33p3r\/","https:\/\/www.linkedin.com\/in\/ross-spencer-b6b9b758\/","https:\/\/x.com\/beet_keeper"],"url":"https:\/\/exponentialdecay.co.uk\/blog\/author\/exponentialdecay\/"}]}},"views":1178,"_links":{"self":[{"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1860","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=1860"}],"version-history":[{"count":30,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1860\/revisions"}],"predecessor-version":[{"id":2004,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/posts\/1860\/revisions\/2004"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/media\/1955"}],"wp:attachment":[{"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=1860"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=1860"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/exponentialdecay.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=1860"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}