[{"data":1,"prerenderedAt":554},["ShallowReactive",2],{"footer-settings":3,"post-shell:building-enzo-ff87e5fd67f1":23,"post-body:building-enzo-ff87e5fd67f1":65,"code-block:6adbdbdb86201:enzo":552,"code-block:6adbdbdb86241:enzo":552,"code-block:6adbdbdb8623f:javascript":553},{"heading":4,"body":5,"links":6,"note":22},"Bottom line, still up front.","A small footer for global links, contact paths, and project context.",[7,10,13,16,19],{"label":8,"url":9},"About","\u002Fabout",{"label":11,"url":12},"Case Studies","\u002F#selected-work",{"label":14,"url":15},"Side Projects","\u002Fside-projects",{"label":17,"url":18},"Writing","\u002Fwriting",{"label":20,"url":21},"Now","\u002Fabout#now","",{"id":24,"slug":25,"date":26,"author":27,"title":30,"excerpt":31,"canonicalUrl":32,"authorName":29,"featuredMedia":33,"blocks":64},"cG9zdDoxMDMw","building-enzo-ff87e5fd67f1","July 30, 2026",{"node":28},{"name":29},"Aslan French","Building Enzo","How a fantasy programming language became a working interpreter, and what building it taught me about design and LLM-assisted coding.","https:\u002F\u002Fmedium.com\u002Fdesign-bootcamp\u002Fbuilding-enzo-ff87e5fd67f1",{"id":34,"sourceUrl":35,"srcSet":36,"sizes":37,"altText":38,"mediaDetails":39},"cG9zdDoxMDE4","https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04.png","https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04-300x200.png 300w, https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04-768x513.png 768w, https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04.png 1024w","(max-width: 300px) 100vw, 300px","Pixel-art robot working with a bubbling flask and a stack of papers, labeled ChatGPT 4o.",{"width":40,"height":41,"sizes":42},1024,684,[43,51,57],{"name":44,"sourceUrl":45,"width":46,"height":47,"mimeType":48,"file":49,"fileSize":50},"medium","https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04-300x200.png","300","200","image\u002Fpng","medium-04-300x200.png",140058,{"name":52,"sourceUrl":53,"width":54,"height":54,"mimeType":48,"file":55,"fileSize":56},"thumbnail","https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04-150x150.png","150","medium-04-150x150.png",54551,{"name":58,"sourceUrl":59,"width":60,"height":61,"mimeType":48,"file":62,"fileSize":63},"medium_large","https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04-768x513.png","768","513","medium-04-768x513.png",918831,[],[66,72,77,81,85,90,94,99,103,108,113,117,121,126,131,135,139,143,147,151,155,159,163,167,171,175,179,184,188,192,196,200,204,207,211,215,219,223,227,231,235,239,243,247,251,255,259,263,267,271,275,279,283,287,291,295,299,303,307,311,315,319,323,327,331,335,339,343,347,351,355,359,363,367,371,375,379,383,387,391,395,399,403,407,411,415,419,423,427,431,435,439,443,447,451,455,459,463,467,471,475,479,483,487,491,495,499,503,507,511,515,519,523,527,531,535,539,543,547],{"name":67,"clientId":68,"parentClientId":69,"renderedHtml":70,"attributes":71},"core\u002Fcode","6adbdbdb86201",null,"\n\u003Cpre class=\"wp-block-code language-enzo\">\u003Ccode>$person1: [\n    $name1: \"Todd\",\n    $age1: 27,\n    $favorite-color1: \"blue\"\n];\n\n$name1, $age1, $favorite-color1: $person1[];\n$name1;             \u002F\u002F prints \"Todd\"\n$age1;              \u002F\u002F prints 27\n$favorite-color1;   \u002F\u002F prints \"blue\"\u003C\u002Fcode>\u003C\u002Fpre>\n",{},{"name":73,"clientId":74,"parentClientId":69,"renderedHtml":75,"attributes":76},"core\u002Fparagraph","6adbdbdb8621e","\n\u003Cp class=\"wp-block-paragraph\">Enzo is a language for a human, implemented by a machine, instead of a language for a machine, implemented by a human.\u003C\u002Fp>\n",{},{"name":73,"clientId":78,"parentClientId":69,"renderedHtml":79,"attributes":80},"6adbdbdb86220","\n\u003Cp class=\"wp-block-paragraph\">The \u003Ca href=\"http:\u002F\u002Faslanfrench.medium.com\u002Fa-ux-designer-designs-a-programming-language-ff7c7cf44dd4\">first essay in this series was about why a UX designer would design a fantasy programming language at all\u003C\u002Fa>. The \u003Ca href=\"https:\u002F\u002Faslanfrench.medium.com\u002Fdesign-principles-for-enzo-a4f9af10cd03\">second was about the principles that shaped it\u003C\u002Fa>. This is essay is modified and expanded on from \u003Ca href=\"https:\u002F\u002Fwww.youtube.com\u002Flive\u002Fv-LsF9hO4ow?si=jIQ6ArFquhj1WScx\">a talk I gave at EFF-Austin meetup in November 2025\u003C\u002Fa>, and another I gave in \u003Ca href=\"https:\u002F\u002Fwww.facebook.com\u002Fevents\u002Fmonkey-nest-coffee\u002Fvibe-code-february-with-aslan-french\u002F1904866416789618\u002F\">February 2026 for Vibecode Austin\u003C\u002Fa>. (Slide decks can be found \u003Ca href=\"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1VJQgllOUj4DitdSsc9q3IBR8UcpzhvJWFctwXTWj1f0\u002Fedit?usp=sharing\">here\u003C\u002Fa> and \u003Ca href=\"https:\u002F\u002Fdocs.google.com\u002Fpresentation\u002Fd\u002F1TMIgEhbOUZRqzyfUlO6AOyFUJWs3Eo3lDWd40cBO9gc\u002Fedit?usp=sharing\">here\u003C\u002Fa>)\u003C\u002Fp>\n",{},{"name":73,"clientId":82,"parentClientId":69,"renderedHtml":83,"attributes":84},"6adbdbdb86221","\n\u003Cp class=\"wp-block-paragraph\">This essay is about the part I never planned on: \u003Cstrong>actually building it.\u003C\u002Fstrong>\u003C\u002Fp>\n",{},{"name":86,"clientId":87,"parentClientId":69,"renderedHtml":88,"attributes":89},"core\u002Fheading","6adbdbdb86222","\n\u003Ch2 class=\"wp-block-heading\">What did I build exactly?\u003C\u002Fh2>\n",{},{"name":73,"clientId":91,"parentClientId":69,"renderedHtml":92,"attributes":93},"6adbdbdb86223","\n\u003Cp class=\"wp-block-paragraph\">a custom parser, AST, and evaluator running in the Python runtime, with a REPL, a file runner, a golden-file test harness, and a VS Code syntax highlighting plugin, built in about ninety days, by a UX designer with an aesthetic interest in programming language syntax.\u003C\u002Fp>\n",{},{"name":95,"clientId":96,"parentClientId":69,"renderedHtml":97,"attributes":98},"core\u002Fgroup","6adbdbdb86224","\n\u003Cdiv class=\"wp-block-group alignwide is-style-editorial-panel\">\u003Cdiv class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n\u003Ch3 class=\"wp-block-heading\">Interpreter &amp; tools\u003C\u002Fh3>\n\n\n\n\u003Cdiv class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Interpreter\u003C\u002Fh4>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A toy interpreter running in the Python runtime.\u003C\u002Fp>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A custom parser\u003C\u002Fli>\n\n\u003Cli>An abstract syntax tree\u003C\u002Fli>\n\n\u003Cli>An evaluator\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Tools\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A REPL CLI\u003C\u002Fli>\n\n\u003Cli>A file runner\u003C\u002Fli>\n\n\u003Cli>A custom test harness\u003C\u002Fli>\n\n\u003Cli>A VS Code syntax-highlighting plugin\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003C\u002Fdiv>\n",{},{"name":86,"clientId":100,"parentClientId":96,"renderedHtml":101,"attributes":102},"6adbdbdb86225","\n\u003Ch3 class=\"wp-block-heading\">Interpreter &amp; tools\u003C\u002Fh3>\n",{},{"name":104,"clientId":105,"parentClientId":96,"renderedHtml":106,"attributes":107},"core\u002Fcolumns","6adbdbdb86226","\n\u003Cdiv class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Interpreter\u003C\u002Fh4>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A toy interpreter running in the Python runtime.\u003C\u002Fp>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A custom parser\u003C\u002Fli>\n\n\u003Cli>An abstract syntax tree\u003C\u002Fli>\n\n\u003Cli>An evaluator\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Tools\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A REPL CLI\u003C\u002Fli>\n\n\u003Cli>A file runner\u003C\u002Fli>\n\n\u003Cli>A custom test harness\u003C\u002Fli>\n\n\u003Cli>A VS Code syntax-highlighting plugin\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n",{},{"name":109,"clientId":110,"parentClientId":105,"renderedHtml":111,"attributes":112},"core\u002Fcolumn","6adbdbdb86227","\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Interpreter\u003C\u002Fh4>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">A toy interpreter running in the Python runtime.\u003C\u002Fp>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A custom parser\u003C\u002Fli>\n\n\u003Cli>An abstract syntax tree\u003C\u002Fli>\n\n\u003Cli>An evaluator\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n",{},{"name":86,"clientId":114,"parentClientId":110,"renderedHtml":115,"attributes":116},"6adbdbdb86228","\n\u003Ch4 class=\"wp-block-heading\">Interpreter\u003C\u002Fh4>\n",{},{"name":73,"clientId":118,"parentClientId":110,"renderedHtml":119,"attributes":120},"6adbdbdb86229","\n\u003Cp class=\"wp-block-paragraph\">A toy interpreter running in the Python runtime.\u003C\u002Fp>\n",{},{"name":122,"clientId":123,"parentClientId":110,"renderedHtml":124,"attributes":125},"core\u002Flist","6adbdbdb8622a","\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A custom parser\u003C\u002Fli>\n\n\u003Cli>An abstract syntax tree\u003C\u002Fli>\n\n\u003Cli>An evaluator\u003C\u002Fli>\n\u003C\u002Ful>\n",{},{"name":127,"clientId":128,"parentClientId":123,"renderedHtml":129,"attributes":130},"core\u002Flist-item","6adbdbdb8622b","\n\u003Cli>A custom parser\u003C\u002Fli>\n",{},{"name":127,"clientId":132,"parentClientId":123,"renderedHtml":133,"attributes":134},"6adbdbdb8622c","\n\u003Cli>An abstract syntax tree\u003C\u002Fli>\n",{},{"name":127,"clientId":136,"parentClientId":123,"renderedHtml":137,"attributes":138},"6adbdbdb8622d","\n\u003Cli>An evaluator\u003C\u002Fli>\n",{},{"name":109,"clientId":140,"parentClientId":105,"renderedHtml":141,"attributes":142},"6adbdbdb86231","\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Tools\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A REPL CLI\u003C\u002Fli>\n\n\u003Cli>A file runner\u003C\u002Fli>\n\n\u003Cli>A custom test harness\u003C\u002Fli>\n\n\u003Cli>A VS Code syntax-highlighting plugin\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n",{},{"name":86,"clientId":144,"parentClientId":140,"renderedHtml":145,"attributes":146},"6adbdbdb86232","\n\u003Ch4 class=\"wp-block-heading\">Tools\u003C\u002Fh4>\n",{},{"name":122,"clientId":148,"parentClientId":140,"renderedHtml":149,"attributes":150},"6adbdbdb86233","\n\u003Cul class=\"wp-block-list\">\n\u003Cli>A REPL CLI\u003C\u002Fli>\n\n\u003Cli>A file runner\u003C\u002Fli>\n\n\u003Cli>A custom test harness\u003C\u002Fli>\n\n\u003Cli>A VS Code syntax-highlighting plugin\u003C\u002Fli>\n\u003C\u002Ful>\n",{},{"name":127,"clientId":152,"parentClientId":148,"renderedHtml":153,"attributes":154},"6adbdbdb86234","\n\u003Cli>A REPL CLI\u003C\u002Fli>\n",{},{"name":127,"clientId":156,"parentClientId":148,"renderedHtml":157,"attributes":158},"6adbdbdb86235","\n\u003Cli>A file runner\u003C\u002Fli>\n",{},{"name":127,"clientId":160,"parentClientId":148,"renderedHtml":161,"attributes":162},"6adbdbdb86236","\n\u003Cli>A custom test harness\u003C\u002Fli>\n",{},{"name":127,"clientId":164,"parentClientId":148,"renderedHtml":165,"attributes":166},"6adbdbdb86237","\n\u003Cli>A VS Code syntax-highlighting plugin\u003C\u002Fli>\n",{},{"name":73,"clientId":168,"parentClientId":69,"renderedHtml":169,"attributes":170},"6adbdbdb86238","\n\u003Cp class=\"wp-block-paragraph\">\u003Cem>From a talk I gave on building Enzo.\u003C\u002Fem>\u003C\u002Fp>\n",{},{"name":86,"clientId":172,"parentClientId":69,"renderedHtml":173,"attributes":174},"6adbdbdb86239","\n\u003Ch2 class=\"wp-block-heading\">Before the tools existed\u003C\u002Fh2>\n",{},{"name":73,"clientId":176,"parentClientId":69,"renderedHtml":177,"attributes":178},"6adbdbdb8623a","\n\u003Cp class=\"wp-block-paragraph\">None of this started in 2025. Starting around 2018, I was deep in a stretch where several threads ran at once, feeding each other: I was customizing my VS Code theme, which meant writing an enormous amount of regex against TextMate grammars, and somewhere in all that pattern-matching it sank in to me that a programming language is, at bottom, just parsing over things. At the same time I was reading about language design and getting through the first chapters of Crafting Interpreters. At the same time I was taking programming courses. At the same time I was annoying every experienced dev I knew with questions, \u003Cem>why does JavaScript do it this way?\u003C\u002Fem> \u003Cem>why can’t more things be like LISP?\u003C\u002Fem>, LISP being a language I could not actually read, whose parentheses and backwards math notation struck me as weird, but which I was convinced was getting at something deep, in the way you can only be convinced when you don’t actually know anything about what you’re doing: it was old, the famous textbook had wizards on the cover, and somewhere behind it was Church–Turing stuff I kept almost grasping.\u003C\u002Fp>\n",{},{"name":180,"clientId":181,"parentClientId":69,"renderedHtml":182,"attributes":183},"core\u002Fimage","6adbdbdb8623b","\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg src=\"https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-02.jpg\" alt=\"A copy of Structure and Interpretation of Computer Programs on a desk.\" class=\"wp-image-1016\"\u002F>\u003Cfigcaption class=\"wp-element-caption\">this is pretty common I think, the new dev’s crush on purity. Enzo took real inspiration from LISP and eventually grew out of the crush.\u003C\u002Ffigcaption>\u003C\u002Ffigure>\n",{},{"name":73,"clientId":185,"parentClientId":69,"renderedHtml":186,"attributes":187},"6adbdbdb8623c","\n\u003Cp class=\"wp-block-paragraph\">And out of all of that, in 2020, the syntax doc got started, a place to vent frustration and confusion into sketches of what I wished things looked like.\u003C\u002Fp>\n",{},{"name":73,"clientId":189,"parentClientId":69,"renderedHtml":190,"attributes":191},"6adbdbdb8623d","\n\u003Cp class=\"wp-block-paragraph\">Braided through all of it was the opposite pressure: I was honing in on a design career, and part of that was learning to stop chasing every tangent that lit me up. My background is that of an artist, and I knew the dangers of being pulled into an arty obsession, divergent rather than convergent, messing around with a medium for its own sake. A beautiful and important impulse, and also doesn’t get you hired. I needed to get hired. So I tried to put it aside, kept it just as this little side thing I vented into. I wanted it but knew I didn’t have capacity.\u003C\u002Fp>\n",{},{"name":73,"clientId":193,"parentClientId":69,"renderedHtml":194,"attributes":195},"6adbdbdb8623e","\n\u003Cp class=\"wp-block-paragraph\">Then in early 2025 I was taking courses again and started using the doc as a learning lens: I’d hit a concept that confused me, JavaScript destructuring.\u003C\u002Fp>\n",{},{"name":67,"clientId":197,"parentClientId":69,"renderedHtml":198,"attributes":199},"6adbdbdb8623f","\n\u003Cpre class=\"wp-block-code language-javascript\">\u003Ccode>let a, b, rest;\n[a, b] = [10, 20];\n\nconsole.log(a);\n\u002F\u002F Expected output: 10\u003C\u002Fcode>\u003C\u002Fpre>\n",{},{"name":73,"clientId":201,"parentClientId":69,"renderedHtml":202,"attributes":203},"6adbdbdb86240","\n\u003Cp class=\"wp-block-paragraph\">and ask an LLM to explain it \u003Cem>in Enzo style\u003C\u002Fem>. Translating a concept into my own fantasy syntax forced me to actually understand it.\u003C\u002Fp>\n",{},{"name":67,"clientId":205,"parentClientId":69,"renderedHtml":70,"attributes":206},"6adbdbdb86241",{},{"name":73,"clientId":208,"parentClientId":69,"renderedHtml":209,"attributes":210},"6adbdbdb86242","\n\u003Cp class=\"wp-block-paragraph\">\u003Cem>For what it’s worth I think Enzo’s approach is more consistent to how assignment notation works.\u003C\u002Fem>\u003C\u002Fp>\n",{},{"name":73,"clientId":212,"parentClientId":69,"renderedHtml":213,"attributes":214},"6adbdbdb86243","\n\u003Cp class=\"wp-block-paragraph\">And somewhere in there the old question surface but with a new answer available: the thing I couldn’t afford to build in 2018, could I just build it now?\u003C\u002Fp>\n",{},{"name":95,"clientId":216,"parentClientId":69,"renderedHtml":217,"attributes":218},"6adbdbdb86244","\n\u003Cdiv class=\"wp-block-group alignwide is-style-editorial-panel\">\u003Cdiv class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n\u003Ch3 class=\"wp-block-heading\">Why design Enzo?\u003C\u002Fh3>\n\n\n\n\u003Cp class=\"wp-block-paragraph\">Primarily as a learning tool and means of creative expression.\u003C\u002Fp>\n\n\n\n\u003Cdiv class=\"wp-block-columns is-style-timeline is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">2020: learning code\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning to code in 2018–2020.\u003C\u002Fli>\n\n\u003Cli>Started the doc officially in 2020, with no intent to implement it.\u003C\u002Fli>\n\n\u003Cli>Would edit it once in a while over the years.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">2025: generative design\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning programming again in early 2025.\u003C\u002Fli>\n\n\u003Cli>Used the language doc to generatively design and learn a mainstream programming language.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Implement it?\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Maybe I can implement it with an LLM?\u003C\u002Fli>\n\n\u003Cli>An evolving process of about two months: a custom AST, parser, evaluator, and test harness in the Python runtime, with a REPL and file runner.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003C\u002Fdiv>\n",{},{"name":86,"clientId":220,"parentClientId":216,"renderedHtml":221,"attributes":222},"6adbdbdb86245","\n\u003Ch3 class=\"wp-block-heading\">Why design Enzo?\u003C\u002Fh3>\n",{},{"name":73,"clientId":224,"parentClientId":216,"renderedHtml":225,"attributes":226},"6adbdbdb86246","\n\u003Cp class=\"wp-block-paragraph\">Primarily as a learning tool and means of creative expression.\u003C\u002Fp>\n",{},{"name":104,"clientId":228,"parentClientId":216,"renderedHtml":229,"attributes":230},"6adbdbdb86247","\n\u003Cdiv class=\"wp-block-columns is-style-timeline is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">2020: learning code\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning to code in 2018–2020.\u003C\u002Fli>\n\n\u003Cli>Started the doc officially in 2020, with no intent to implement it.\u003C\u002Fli>\n\n\u003Cli>Would edit it once in a while over the years.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">2025: generative design\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning programming again in early 2025.\u003C\u002Fli>\n\n\u003Cli>Used the language doc to generatively design and learn a mainstream programming language.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\n\n\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Implement it?\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Maybe I can implement it with an LLM?\u003C\u002Fli>\n\n\u003Cli>An evolving process of about two months: a custom AST, parser, evaluator, and test harness in the Python runtime, with a REPL and file runner.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n\u003C\u002Fdiv>\n",{},{"name":109,"clientId":232,"parentClientId":228,"renderedHtml":233,"attributes":234},"6adbdbdb86248","\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">2020: learning code\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning to code in 2018–2020.\u003C\u002Fli>\n\n\u003Cli>Started the doc officially in 2020, with no intent to implement it.\u003C\u002Fli>\n\n\u003Cli>Would edit it once in a while over the years.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n",{},{"name":86,"clientId":236,"parentClientId":232,"renderedHtml":237,"attributes":238},"6adbdbdb86249","\n\u003Ch4 class=\"wp-block-heading\">2020: learning code\u003C\u002Fh4>\n",{},{"name":122,"clientId":240,"parentClientId":232,"renderedHtml":241,"attributes":242},"6adbdbdb8624a","\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning to code in 2018–2020.\u003C\u002Fli>\n\n\u003Cli>Started the doc officially in 2020, with no intent to implement it.\u003C\u002Fli>\n\n\u003Cli>Would edit it once in a while over the years.\u003C\u002Fli>\n\u003C\u002Ful>\n",{},{"name":127,"clientId":244,"parentClientId":240,"renderedHtml":245,"attributes":246},"6adbdbdb8624b","\n\u003Cli>Started learning to code in 2018–2020.\u003C\u002Fli>\n",{},{"name":127,"clientId":248,"parentClientId":240,"renderedHtml":249,"attributes":250},"6adbdbdb8624c","\n\u003Cli>Started the doc officially in 2020, with no intent to implement it.\u003C\u002Fli>\n",{},{"name":127,"clientId":252,"parentClientId":240,"renderedHtml":253,"attributes":254},"6adbdbdb8624d","\n\u003Cli>Would edit it once in a while over the years.\u003C\u002Fli>\n",{},{"name":109,"clientId":256,"parentClientId":228,"renderedHtml":257,"attributes":258},"6adbdbdb8624e","\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">2025: generative design\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning programming again in early 2025.\u003C\u002Fli>\n\n\u003Cli>Used the language doc to generatively design and learn a mainstream programming language.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n",{},{"name":86,"clientId":260,"parentClientId":256,"renderedHtml":261,"attributes":262},"6adbdbdb8624f","\n\u003Ch4 class=\"wp-block-heading\">2025: generative design\u003C\u002Fh4>\n",{},{"name":122,"clientId":264,"parentClientId":256,"renderedHtml":265,"attributes":266},"6adbdbdb86250","\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Started learning programming again in early 2025.\u003C\u002Fli>\n\n\u003Cli>Used the language doc to generatively design and learn a mainstream programming language.\u003C\u002Fli>\n\u003C\u002Ful>\n",{},{"name":127,"clientId":268,"parentClientId":264,"renderedHtml":269,"attributes":270},"6adbdbdb86251","\n\u003Cli>Started learning programming again in early 2025.\u003C\u002Fli>\n",{},{"name":127,"clientId":272,"parentClientId":264,"renderedHtml":273,"attributes":274},"6adbdbdb86252","\n\u003Cli>Used the language doc to generatively design and learn a mainstream programming language.\u003C\u002Fli>\n",{},{"name":109,"clientId":276,"parentClientId":228,"renderedHtml":277,"attributes":278},"6adbdbdb86253","\n\u003Cdiv class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n\u003Ch4 class=\"wp-block-heading\">Implement it?\u003C\u002Fh4>\n\n\n\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Maybe I can implement it with an LLM?\u003C\u002Fli>\n\n\u003Cli>An evolving process of about two months: a custom AST, parser, evaluator, and test harness in the Python runtime, with a REPL and file runner.\u003C\u002Fli>\n\u003C\u002Ful>\n\u003C\u002Fdiv>\n",{},{"name":86,"clientId":280,"parentClientId":276,"renderedHtml":281,"attributes":282},"6adbdbdb86254","\n\u003Ch4 class=\"wp-block-heading\">Implement it?\u003C\u002Fh4>\n",{},{"name":122,"clientId":284,"parentClientId":276,"renderedHtml":285,"attributes":286},"6adbdbdb86255","\n\u003Cul class=\"wp-block-list\">\n\u003Cli>Maybe I can implement it with an LLM?\u003C\u002Fli>\n\n\u003Cli>An evolving process of about two months: a custom AST, parser, evaluator, and test harness in the Python runtime, with a REPL and file runner.\u003C\u002Fli>\n\u003C\u002Ful>\n",{},{"name":127,"clientId":288,"parentClientId":284,"renderedHtml":289,"attributes":290},"6adbdbdb86256","\n\u003Cli>Maybe I can implement it with an LLM?\u003C\u002Fli>\n",{},{"name":127,"clientId":292,"parentClientId":284,"renderedHtml":293,"attributes":294},"6adbdbdb86257","\n\u003Cli>An evolving process of about two months: a custom AST, parser, evaluator, and test harness in the Python runtime, with a REPL and file runner.\u003C\u002Fli>\n",{},{"name":86,"clientId":296,"parentClientId":69,"renderedHtml":297,"attributes":298},"6adbdbdb86258","\n\u003Ch2 class=\"wp-block-heading\">Era one: the chatbot\u003C\u002Fh2>\n",{},{"name":73,"clientId":300,"parentClientId":69,"renderedHtml":301,"attributes":302},"6adbdbdb86259","\n\u003Cp class=\"wp-block-paragraph\">I started with ChatGPT’s o3, the early “reasoning model,” which I’ll be honest, I didn’t think was very good. It’s much lauded chain-of-thought reasoning seemed to give it more ways to get lost. It would think itself into corners. For the parser, it steered me to Lark, a Python library where you hand over a formal grammar and get a parser back, the responsible-sounding choice. And I had a REPL, so testing meant typing things at the prompt and squinting.\u003C\u002Fp>\n",{},{"name":180,"clientId":304,"parentClientId":69,"renderedHtml":305,"attributes":306},"6adbdbdb8625a","\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg src=\"https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-04.png\" alt=\"Pixel-art robot working with a bubbling flask and a stack of papers, labeled ChatGPT 4o.\" class=\"wp-image-1018\"\u002F>\u003Cfigcaption class=\"wp-element-caption\">typo in image is the Human’s fault because I was also using 4o around the same time, and in fact OpenAI sucks at naming their models. o3 and 4o was confusing dawg, who named that shit?\u003C\u002Ffigcaption>\u003C\u002Ffigure>\n",{},{"name":73,"clientId":308,"parentClientId":69,"renderedHtml":309,"attributes":310},"6adbdbdb8625b","\n\u003Cp class=\"wp-block-paragraph\">I think a surprising number of people still work way: copy an entire source file, paste it into a chat window, describe the change, wait, copy the entire file that comes back, paste it over the original, run it. For every change. Multiple files meant multiple round trips. It’s not a very viable way to make software.\u003C\u002Fp>\n",{},{"name":73,"clientId":312,"parentClientId":69,"renderedHtml":313,"attributes":314},"6adbdbdb8625c","\n\u003Cp class=\"wp-block-paragraph\">It worked until the language had more than a handful of features, which is to say, about an hour. Then the pattern set in: ask for feature B, get it, and minutes later discover that feature A, untouched, previously working, was broken. The code that came back from some round trip had quietly dropped or mangled something, and with nothing but a REPL to poke at, there was no way to know except to trip over it. Every request to the model was a slot-machine pull that might pay out the new feature and eat an old one.\u003C\u002Fp>\n",{},{"name":86,"clientId":316,"parentClientId":69,"renderedHtml":317,"attributes":318},"6adbdbdb8625d","\n\u003Ch2 class=\"wp-block-heading\">Era two: building the ratchet\u003C\u002Fh2>\n",{},{"name":73,"clientId":320,"parentClientId":69,"renderedHtml":321,"attributes":322},"6adbdbdb8625e","\n\u003Cp class=\"wp-block-paragraph\">The fix came in two pieces, each added to stop a specific kind of bleeding. First the file runner: execute a whole .enzo file instead of typing at the prompt, so more than one feature could be exercised at once. Then, and this is the real invention, the test harness: keep files of everything that \u003Cem>used to work\u003C\u002Fem>, write down exactly what each case should output, and have a script run it all, diff reality against intention, and format the failures into a readable report, which test broke, what was expected, what actually came out. Now when the slot machine ate a feature, the harness said so immediately instead of letting me trip over it later.\u003C\u002Fp>\n",{},{"name":180,"clientId":324,"parentClientId":69,"renderedHtml":325,"attributes":326},"6adbdbdb8625f","\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg src=\"https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-05.png\" alt=\"Pixel-art construction cranes moving code panels between a failed test and a passed test.\" class=\"wp-image-1019\"\u002F>\u003C\u002Ffigure>\n",{},{"name":73,"clientId":328,"parentClientId":69,"renderedHtml":329,"attributes":330},"6adbdbdb86260","\n\u003Cp class=\"wp-block-paragraph\">And that report turned out to be the piece that made the collaboration itself work. It was something I could hand straight back to the model, not “something seems broken,” but a precise, mechanical statement of every deviation from intent. Even in the primitive copy-paste era, the difference between an agent flailing and an agent converging was mostly the difference between those two kinds of feedback. The implementation wasn’t designed; it accreted. A ratchet: features could still break, but breakage could no longer hide.\u003C\u002Fp>\n",{},{"name":73,"clientId":332,"parentClientId":69,"renderedHtml":333,"attributes":334},"6adbdbdb86261","\n\u003Cp class=\"wp-block-paragraph\">So the workflow became: sketch the feature’s syntax in the README, write test cases for it, hand-write the expected output for every case, run the harness, and hand the failures to the LLM until everything went green, the new tests \u003Cem>and every old one\u003C\u002Fem>. Only then was a feature done.\u003C\u002Fp>\n",{},{"name":73,"clientId":336,"parentClientId":69,"renderedHtml":337,"attributes":338},"6adbdbdb86262","\n\u003Cp class=\"wp-block-paragraph\">At some point I looked at what I’d built and \u003Ca href=\"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FTest-driven_development\">realized I’d sort of reinvented test-driven development from first principles\u003C\u002Fa>. TDD, for anyone who hasn’t met it, is a practice out of the early-2000s agile world, Kent Beck is the name most attached to it, in which you write the test \u003Cem>before\u003C\u002Fem> the implementation, watch it fail, then write code until it passes; the test is a promise and the implementation exists to keep it. My particular variant has its own name too, I later learned: \u003Cem>golden files\u003C\u002Fem>, files of expected output that actual output is diffed against, also called snapshot or approval testing. I’d heard the phrase “test-driven development” before, the way you hear phrases. But being told about an idea and arriving at it organically out of need are two different kinds of knowing.\u003C\u002Fp>\n",{},{"name":73,"clientId":340,"parentClientId":69,"renderedHtml":341,"attributes":342},"6adbdbdb86263","\n\u003Cp class=\"wp-block-paragraph\">There’s a newer phrase circulating in vibe-coding circles for a related idea: \u003Cem>spec-driven development\u003C\u002Fem>, drive the LLM from a written specification rather than a pile of chat messages. I’d backed into that one too, because in this project the spec came first by five years. The README was written entirely by me, for humans to read, and that turned out to be the trick, because anything a human can read, an LLM can read too. A document made to express a fantasy became, without changing in kind, the document that drove an implementation.\u003C\u002Fp>\n",{},{"name":73,"clientId":344,"parentClientId":69,"renderedHtml":345,"attributes":346},"6adbdbdb86264","\n\u003Cp class=\"wp-block-paragraph\">So the strata stacked up, each layer resting on the one below: the spec, written for people; the test cases, derived from the spec; the harness, holding the implementation to the tests; the LLM, turning the harness’ failure reports into code changes. Once all four layers existed the engine spun forward on its own cycle, spec a feature, generate and prune its tests, run the harness, feed the failures back, repeat.\u003C\u002Fp>\n",{},{"name":73,"clientId":348,"parentClientId":69,"renderedHtml":349,"attributes":350},"6adbdbdb86265","\n\u003Cp class=\"wp-block-paragraph\">Parallel to all this, the interface itself kept evolving, one small friction at a time. I stopped asking for whole files and started asking for diffs, and then found myself copy-pasting those diffs and hand-deleting the + signs off every line until I was borderline having carpal tunnel. A VS Code extension fixed that: paste a patch, have it applied cleanly. In the chatbot itself I'd moved from o3 to 4.1. Shortly after the extension era I moved to GitHub Copilot as the interface, the first time the machine could touch the files directly instead of routing everything through my clipboard. There was nothing graceful about the progression, either, it was kludge piled on kludge, patched and WD-40ed until the whole thing creaked forward. I wasn't reading newsletters or tutorials, or watching influencers gasping about their new amazing agentic workflow, I was just running headlong into the thing, one janky reinvention at a time.\u003C\u002Fp>\n",{},{"name":180,"clientId":352,"parentClientId":69,"renderedHtml":353,"attributes":354},"6adbdbdb86266","\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg src=\"https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-06.png\" alt=\"Pixel-art octopus operating a wall of drawers and terminals.\" class=\"wp-image-1020\"\u002F>\u003C\u002Ffigure>\n",{},{"name":86,"clientId":356,"parentClientId":69,"renderedHtml":357,"attributes":358},"6adbdbdb86267","\n\u003Ch2 class=\"wp-block-heading\">The loop was the design tool\u003C\u002Fh2>\n",{},{"name":73,"clientId":360,"parentClientId":69,"renderedHtml":361,"attributes":362},"6adbdbdb86268","\n\u003Cp class=\"wp-block-paragraph\">I’ve been describing the loop as it served implementation, but the same machinery ran the other direction too, and I knew it would going in, because the project had reignited in the first place when an LLM generated candidate destructuring syntax for me. The work was knowingly generative from the beginning. Design and implementation didn’t take turns; they fed each other, and the test cases were the membrane between them.\u003C\u002Fp>\n",{},{"name":73,"clientId":364,"parentClientId":69,"renderedHtml":365,"attributes":366},"6adbdbdb86269","\n\u003Cp class=\"wp-block-paragraph\">Typically I’d write a few seed cases while sketching a feature in the README, this is what it should look like, this is what it should print. Then the LLM would expand on them, working out the combinatorial edges where the new feature met the existing ones: what happens when a function atom stored in a list gets invoked by index? What does copy-by-value mean when you destructure a nested list? Then I’d go through the expansion, keeping, correcting, killing, and hand-write the expected output for everything that survived. Deriving the edges and implications of a design \u003Cem>is\u003C\u002Fem> design work, and the loop did it at a pace I couldn’t have sustained alone.\u003C\u002Fp>\n",{},{"name":73,"clientId":368,"parentClientId":69,"renderedHtml":369,"attributes":370},"6adbdbdb8626a","\n\u003Cp class=\"wp-block-paragraph\">The same move, generate abundance, select by taste, ran all the way up into the language itself. The then pipeline operator exists because I asked an LLM for fifty potential pipeline operators and then was in the pile. The @ reference sigil came out of asking for alternatives to $ until the whole space of options was spread out in front of me and felt right. In practice there were no clean phases, innovation, definition, implementation, generation, selection, curation, all turning together in one tight loop. \u003Ca href=\"https:\u002F\u002Fmedium.com\u002Fdesign-bootcamp\u002Fa-ux-designer-designs-a-programming-language-ff7c7cf44dd4?postPublishedType=repub\">Generative design in the Brian Eno sense I described in the first essay: set up rules, generate abundance, prune.\u003C\u002Fa>\u003C\u002Fp>\n",{},{"name":73,"clientId":372,"parentClientId":69,"renderedHtml":373,"attributes":374},"6adbdbdb8626b","\n\u003Cp class=\"wp-block-paragraph\">The other half of the acceleration was less glamorous and maybe more important: I finally had a patient teacher. The spec had been evolving for years, I was thinking through these problems the whole time I was taking classes, but slowly, because my \u003Cem>why\u003C\u002Fem> questions had nowhere good to go.\u003C\u002Fp>\n",{},{"name":73,"clientId":376,"parentClientId":69,"renderedHtml":377,"attributes":378},"6adbdbdb8626c","\n\u003Cp class=\"wp-block-paragraph\">Experienced devs, asked why assignment works the way it does, mostly gave me some version of: it works that way because it does, accept it, this line of questioning won’t get you a job. To a fluent speaker it’s all wallpaper, the way a native English speaker long ago stopped noticing that “c” and “k” duplicate each other.\u003C\u002Fp>\n",{},{"name":73,"clientId":380,"parentClientId":69,"renderedHtml":381,"attributes":382},"6adbdbdb8626d","\n\u003Cp class=\"wp-block-paragraph\">But some of my complaints were real observations. JavaScript binding values with = in one place and : in another, depending on whether you're inside an object literal, is a genuine design inconsistency, plain as day; I said so as a student and got shrugs, because to people raised in the C lineage that handed JavaScript its =, it was all wallpaper. An LLM could actually walk the history with me, where the = came from, where the object-literal : came in from, and how the two simply never got reconciled, and confirm the observation wasn't crazy.\u003C\u002Fp>\n",{},{"name":73,"clientId":384,"parentClientId":69,"renderedHtml":385,"attributes":386},"6adbdbdb8626e","\n\u003Cp class=\"wp-block-paragraph\">Ask why why why why constantly like an annoying child, and yet, thankfully, actually getting answers finally, with citations and all the weird textural context that my specific sort of brain required. I wasn't designing and then implementing. I was coming to understand what Enzo could even be, at the same time it was becoming it.\u003C\u002Fp>\n",{},{"name":73,"clientId":388,"parentClientId":69,"renderedHtml":389,"attributes":390},"6adbdbdb8626f","\n\u003Cp class=\"wp-block-paragraph\">One story about what this loop actually is. My preferences in syntax are largely tacit, I know what feels right when I see it, and I often can’t state the rule. Semicolons were my standing example: I could not have written you a specification of how they should behave in every corner of Enzo. What I could do was write forty cases the way they \u003Cem>should look\u003C\u002Fem> and declare the verdicts, and let the implementation converge on whatever logic enforced them. Pointing, over and over: like this. Like this. Not like that.\u003C\u002Fp>\n",{},{"name":73,"clientId":392,"parentClientId":69,"renderedHtml":393,"attributes":394},"6adbdbdb86270","\n\u003Cp class=\"wp-block-paragraph\">Notice what this resembles: Machine-learning people have a standard answer for how you get a system to do something nobody can write rules for: you don’t explain, you score. You gather examples of right answers. You define a loss function, a measure of how far any given attempt lands from those examples. And then the system adjusts itself against that error signal, attempt after attempt, descending toward the target. That’s this loop, piece for piece. My tacit preferences were the target. The golden files were the loss function, those preferences frozen into checkable examples. The harness computed the error on every run, mechanically, and its failure report was the gradient: not just \u003Cem>wrong\u003C\u002Fem>, but wrong here, by this much, in this direction. And the LLM descended. I never explained my language to the machine, I couldn’t, that was the whole problem. I defined what counted as wrong, precisely, forty examples at a time, and let the system walk downhill.\u003C\u002Fp>\n",{},{"name":73,"clientId":396,"parentClientId":69,"renderedHtml":397,"attributes":398},"6adbdbdb86271","\n\u003Cp class=\"wp-block-paragraph\">I pointed at examples until the messiness of my intuition got mapped, and a rule precipitated out. That’s the strongest evidence I have for the method: enough examples, honestly judged, contain their own logic.\u003C\u002Fp>\n",{},{"name":86,"clientId":400,"parentClientId":69,"renderedHtml":401,"attributes":402},"6adbdbdb86273","\n\u003Ch2 class=\"wp-block-heading\">Era three: the hump\u003C\u002Fh2>\n",{},{"name":73,"clientId":404,"parentClientId":69,"renderedHtml":405,"attributes":406},"6adbdbdb86274","\n\u003Cp class=\"wp-block-paragraph\">Then functions nearly ended the project.\u003C\u002Fp>\n",{},{"name":73,"clientId":408,"parentClientId":69,"renderedHtml":409,"attributes":410},"6adbdbdb86275","\n\u003Cp class=\"wp-block-paragraph\">Roughly three weeks, most of June 2025, went into the single feature everything else depends on, in an expression-oriented language where functions and expressions are the same thing. The branch history from that stretch reads like a coping mechanism: branch after branch, the version numbering drifting into inconsistency, every fresh fork another grab at something that would not land, a month of feeling around a dark room for a doorknob I couldn’t prove was there.\u003C\u002Fp>\n",{},{"name":73,"clientId":412,"parentClientId":69,"renderedHtml":413,"attributes":414},"6adbdbdb86276","\n\u003Cp class=\"wp-block-paragraph\">I wish I could tell you cleanly what was wrong. The honest answer is that I was doing too many things at once, without much rigor, and the causes were braided. But the strand I \u003Cem>think\u003C\u002Fem> mattered most, my best reconstruction, offered with appropriate suspicion, is that I had spent weeks asking the machine to do something contradictory.\u003C\u002Fp>\n",{},{"name":73,"clientId":416,"parentClientId":69,"renderedHtml":417,"attributes":418},"6adbdbdb86278","\n\u003Cp class=\"wp-block-paragraph\">I wanted the REPL to echo my bindings: bind a value, see the value. I also wanted function atoms \u003Cem>not\u003C\u002Fem> to evaluate when stored. To echo something is to evaluate it. If that’s right, I’d wired “evaluate” and “don’t evaluate” into the same mechanism and then kept asking why functions didn’t work.\u003C\u002Fp>\n",{},{"name":73,"clientId":420,"parentClientId":69,"renderedHtml":421,"attributes":422},"6adbdbdb86279","\n\u003Cp class=\"wp-block-paragraph\">I had become \u003Ca href=\"https:\u002F\u002Fnotalwaysright.com\u002Ftag\u002Fclients-from-hell\u002F\">the classic client from hell\u003C\u002Fa>: confidently requesting contradictory requirements, certain the problem was on the implementation side.\u003C\u002Fp>\n",{},{"name":73,"clientId":424,"parentClientId":69,"renderedHtml":425,"attributes":426},"6adbdbdb8627a","\n\u003Cp class=\"wp-block-paragraph\">And the reason neither of us could see it comes down to embodiment. Half of the contradiction didn’t live in the language at all. “Echo my bindings” isn’t a fact about semantics, it’s the desire of a body at a terminal that wants feedback when it acts. The LLM has processed everything ever written about REPLs, but it has never sat at one, so it had no way to sort my requirements into \u003Cem>constraints of the design\u003C\u002Fem> versus \u003Cem>comforts of the designer\u003C\u002Fem> and notice the two piles fighting. Only the party with the body could have caught it, and for weeks the brain with the body didn’t.\u003C\u002Fp>\n",{},{"name":73,"clientId":428,"parentClientId":69,"renderedHtml":429,"attributes":430},"6adbdbdb8627b","\n\u003Cp class=\"wp-block-paragraph\">I threw everything else at the problem in the meantime, debug modules, log files, a trial of Gemini because I’d heard it had a bigger context window, without much to show for it. The debugging stories from this stretch could fill a small museum of their own.\u003Csup data-fn=\"2e31b026-2446-5bf3-8e56-8436ab5022a1\" class=\"fn\">\u003Ca href=\"#2e31b026-2446-5bf3-8e56-8436ab5022a1\" id=\"2e31b026-2446-5bf3-8e56-8436ab5022a1-link\">1\u003C\u002Fa>\u003C\u002Fsup>\u003C\u002Fp>\n",{},{"name":86,"clientId":432,"parentClientId":69,"renderedHtml":433,"attributes":434},"6adbdbdb8627c","\n\u003Ch2 class=\"wp-block-heading\">The transplant\u003C\u002Fh2>\n",{},{"name":73,"clientId":436,"parentClientId":69,"renderedHtml":437,"attributes":438},"6adbdbdb8627d","\n\u003Cp class=\"wp-block-paragraph\">In the middle of the hump, I made the scariest-sounding decision of the project: I threw out the parser.\u003C\u002Fp>\n",{},{"name":73,"clientId":440,"parentClientId":69,"renderedHtml":441,"attributes":442},"6adbdbdb8627e","\n\u003Cp class=\"wp-block-paragraph\">Here’s where Lark’s foundations matter, so let me actually explain them. Lark is built on \u003Cem>context-free grammars\u003C\u002Fem>, sets of rules where each rule sees only its own little window. “A list is a bracket, some items, a bracket.” “A number is some digits.” Each rule fires on the shape of the text in front of it, with no memory of where in the program that text sits. It’s a beautiful formalism, and most languages are deliberately designed so that it’s sufficient.\u003C\u002Fp>\n",{},{"name":73,"clientId":444,"parentClientId":69,"renderedHtml":445,"attributes":446},"6adbdbdb8627f","\n\u003Cp class=\"wp-block-paragraph\">Enzo is not one of those languages. Enzo’s whole personality is context, the same expression (2 * 2) is a stored function atom in one position and an evaluated 4 in another. (Demand-driven evaluation, that's called, though I should be precise about where it came from: I laid out, through examples, how I wanted expressions to behave in different situations, and an agent inferred the pattern, articulated it as a rule, and gave it the name. And I'm not convinced it's as exotic as it sounds. Every mainstream language already makes a version of this deal, expressions run now, function definitions wait to be called. Enzo just lets parentheses be both and lets position say which, so the intuition it leans on is one every JavaScript or Python programmer already has. I may have been designing in contrast to mainstream languages, but they're still what formed me; there's no fully turning away from the tradition that taught you, no matter how many of its conventions you reject.) You \u003Cem>can\u003C\u002Fem> serve a contextual language with a context-free parser, but you do it by having the parser produce a deliberately dumb, uncommitted tree and smuggling all the contextual judgment downstream into the evaluator. But getting over this hump with functions just couldn't get there, what whatever reason. Context seemed part of it.\u003C\u002Fp>\n",{},{"name":73,"clientId":448,"parentClientId":69,"renderedHtml":449,"attributes":450},"6adbdbdb86280","\n\u003Cp class=\"wp-block-paragraph\">There was also a dumber, more attritional problem: the agents kept hallucinating Lark. They’d confidently use grammar features and syntax that Lark simply does not have, plausible, nonexistent. Which points at something that surprised me: the old heuristic says a battle-tested dependency beats hand-rolled code, but an LLM didn’t hallucinates features of the parser \u003Cem>it wrote\u003C\u002Fem>, that code is right in front of it, while a third-party library is a fog of half-remembered API surface. For this project, at least, it was genuinely faster to have the machine roll a bespoke parser than to keep integrating against a dependency it kept misremembering.\u003C\u002Fp>\n",{},{"name":73,"clientId":452,"parentClientId":69,"renderedHtml":453,"attributes":454},"6adbdbdb86281","\n\u003Cp class=\"wp-block-paragraph\">So: rip out Lark, have the LLM build a custom, context-aware parser from scratch. The parser is the keystone of the interpreter’s entry way, and you rip it out and everything comes tumbling down immediately. Concretely: we went from about 150 tests green, to zero, to thirty within the first hour, and inside a day or so we were back to 150. That first hour was the whole ball-game, thirty tests green on a brand-new parser was the signal that the transplant could work. Same language, same behavior, new engine.\u003C\u002Fp>\n",{},{"name":73,"clientId":456,"parentClientId":69,"renderedHtml":457,"attributes":458},"6adbdbdb86282","\n\u003Cp class=\"wp-block-paragraph\">I want to really emphasize this here, because I think it’s a genuinely new freedom and the test numbers are what make it visible. When your spec lives in executable examples rather than inside the implementation, the implementation becomes a replaceable organ. The traditional risk calculus for “should we rewrite the core component” is brutal, months of work, no guarantee, the old behavior half-remembered in the heads of whoever wrote it. Mine was: one hour to a go\u002Fno-go signal, one day to parity, and the old behavior fully specified in 150 files that don’t forget. That changes what you dare to do. “Fuck it, rip it out and try something different” stops being recklessness and becomes a Tuesday.\u003C\u002Fp>\n",{},{"name":86,"clientId":460,"parentClientId":69,"renderedHtml":461,"attributes":462},"6adbdbdb86283","\n\u003Ch2 class=\"wp-block-heading\">Rocket fuel\u003C\u002Fh2>\n",{},{"name":73,"clientId":464,"parentClientId":69,"renderedHtml":465,"attributes":466},"6adbdbdb86284","\n\u003Cp class=\"wp-block-paragraph\">Around the same time, and it was part of \u003Cem>how\u003C\u002Fem> the hump ended, I moved to Claude Sonnet 4, running in GitHub Copilot, and the difference was not incremental.\u003C\u002Fp>\n",{},{"name":73,"clientId":468,"parentClientId":69,"renderedHtml":469,"attributes":470},"6adbdbdb86285","\n\u003Cp class=\"wp-block-paragraph\">Part of it was agentic: the older setups would make a change and then wait for me to run the tests and report back, I was the loop’s hands and eyes. Sonnet ran the loop itself: broke out its own intermediate tests, ran the terminal, formed a hypothesis, probed it, revised, came back with the actual problem. Debugging went from something I mediated to something I supervised. And part of it was, as far as I can tell, the model just being flatly better, hard for me to prove or quantify, but I’ve noticed plenty of other developers point to that same generation of models as the moment LLM assistance started really working for them too.\u003C\u002Fp>\n",{},{"name":180,"clientId":472,"parentClientId":69,"renderedHtml":473,"attributes":474},"6adbdbdb86286","\n\u003Cfigure class=\"wp-block-image size-full\">\u003Cimg src=\"https:\u002F\u002Fwww.aslanfrench.work\u002Fmedia\u002F2026\u002F10\u002Fmedium-07.png\" alt=\"Pixel-art rocket labeled Claude Sonnet 4 taking off through clouds.\" class=\"wp-image-1021\"\u002F>\u003C\u002Ffigure>\n",{},{"name":73,"clientId":476,"parentClientId":69,"renderedHtml":477,"attributes":478},"6adbdbdb86287","\n\u003Cp class=\"wp-block-paragraph\">So three things converged at the end of June: I finally saw (or think I saw) my own eval contradiction; the custom parser put context where context belonged; and the tooling crossed some capability line. I can’t cleanly separate their contributions. I wasn’t running a controlled experiment; I was trying to get unstuck.\u003C\u002Fp>\n",{},{"name":86,"clientId":480,"parentClientId":69,"renderedHtml":481,"attributes":482},"6adbdbdb86288","\n\u003Ch2 class=\"wp-block-heading\">What design is made of\u003C\u002Fh2>\n",{},{"name":73,"clientId":484,"parentClientId":69,"renderedHtml":485,"attributes":486},"6adbdbdb86289","\n\u003Cp class=\"wp-block-paragraph\">Here’s the section I most want a certain kind of reader, the designer who’s been told implementation is beneath them, to sit with.\u003C\u002Fp>\n",{},{"name":73,"clientId":488,"parentClientId":69,"renderedHtml":489,"attributes":490},"6adbdbdb8628a","\n\u003Cp class=\"wp-block-paragraph\">Why does an oil painting look the way it does? Why does a bridge have struts in that particular arrangement; why does a hand-thrown pot have that profile? Constraints of the medium.\u003C\u002Fp>\n",{},{"name":73,"clientId":492,"parentClientId":69,"renderedHtml":493,"attributes":494},"6adbdbdb8628b","\n\u003Cp class=\"wp-block-paragraph\">Everything made looks the way it does because of what its material would and wouldn’t allow, and if you’ve never worked the material, the made world reads as arbitrary, as if designs float down from some realm of pure Forms. People who only consume never find out why anything is the way it is. You can see the failure mode in my own field constantly: designers who don’t know a medium’s constraints or its prior art, proposing Minority Report gesture interfaces for everything, unaware of the decades of hard-won convention underneath the boring solutions they’re bored of.\u003C\u002Fp>\n",{},{"name":73,"clientId":496,"parentClientId":69,"renderedHtml":497,"attributes":498},"6adbdbdb8628c","\n\u003Cp class=\"wp-block-paragraph\">For seven years, programming languages were that for me: a made world I consumed without knowing why any of it was the way it was. I’m pretty sure I’d had method chaining explained to me three different ways. I’d seen JavaScript’s six ways of declaring a function. None of it stuck as anything but trivia, until Enzo forced me to work the material. I understood method chaining the day I had to work out what Enzo’s pipeline operator needed to do instead, and why. Polymorphism stopped being a vocabulary word when blueprint variants made it a problem I personally had. I’d barely even heard of algebraic types, sum types, product types, until hunting for alternatives to OOP inheritance dropped me into the whole struct-versus-enum literature. It was a crash course in several languages at once, but the real yield was underneath the syntax: a feel for the \u003Cem>space\u003C\u002Fem> of programming languages, what varies, what’s load-bearing, and what’s just convention wearing a lab coat. Engaging with a medium is the only way its constraints become visible, and constraints are where all the \u003Cem>why\u003C\u002Fem> lives.\u003C\u002Fp>\n",{},{"name":73,"clientId":500,"parentClientId":69,"renderedHtml":501,"attributes":502},"6adbdbdb8628d","\n\u003Cp class=\"wp-block-paragraph\">Which is the real claim of this section: \u003Cstrong>meeting and negotiating constraints isn’t the grunt work that happens after design. It \u003Cem>is\u003C\u002Fem> design, it’s what design is made of.\u003C\u002Fstrong> The implementation wasn’t where my finished decisions went to be executed; it was where my decisions found out what they implied, collided with each other, and got revised.\u003C\u002Fp>\n",{},{"name":73,"clientId":504,"parentClientId":69,"renderedHtml":505,"attributes":506},"6adbdbdb8628e","\n\u003Cp class=\"wp-block-paragraph\">One caveat, and it deserves to be stated plainly rather than defensively: I did all this through an LLM, so there was distance between me and the material the whole time. If I had written the interpreter with my own hands, I’d know things about it that I don’t. That distance also gave me things a hand-implementer doesn’t get: I could decree a syntax that was a pain to implement \u003Cem>because that’s how I wanted it\u003C\u002Fem>, unbullied by implementation cost, and since I was never fully inducted into the interpreter-builders’ tradition, I never inherited its sense of what’s reasonable, which gave me \u003Ca href=\"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FShoshin\">a Beginner’s Mind\u003C\u002Fa>. Clear eyes about all three: the engagement was real, the distance was real, and the distance cut both ways.\u003C\u002Fp>\n",{},{"name":86,"clientId":508,"parentClientId":69,"renderedHtml":509,"attributes":510},"6adbdbdb8628f","\n\u003Ch2 class=\"wp-block-heading\">What I actually think about LLM-assisted coding\u003C\u002Fh2>\n",{},{"name":73,"clientId":512,"parentClientId":69,"renderedHtml":513,"attributes":514},"6adbdbdb86290","\n\u003Cp class=\"wp-block-paragraph\">So: a UX designer with no compilers background built a working interpreter in ninety days. Before anyone generalizes from that, the caveats:\u003C\u002Fp>\n",{},{"name":73,"clientId":516,"parentClientId":69,"renderedHtml":517,"attributes":518},"6adbdbdb86291","\n\u003Cp class=\"wp-block-paragraph\">This was close to the perfect project for the technique, pure text, no graphics, no deployment, no users, in a problem domain (interpreters) that is among the most documented and discussed in all of computing. I was hiking a paved trail. And what got built is a Potemkin village: it runs on Python’s runtime, it will never be fast, and the evaluator is a three-thousand-line function that is, by any professional standard, a mess.\u003C\u002Fp>\n",{},{"name":73,"clientId":520,"parentClientId":69,"renderedHtml":521,"attributes":522},"6adbdbdb86292","\n\u003Cp class=\"wp-block-paragraph\">My takeaway is that LLM-assisted coding is the biggest \u003Cem>interface\u003C\u002Fem> improvement to programming since the IDE, and “interface improvement” is the right size of claim, which is not a small size. Syntax highlighting never wrote anyone’s code, but nobody who has it goes back. I don’t use Vim; if I were stuck in NetBeans I’d simply never code again; UI matters, and this is UI. The doing part of coding has been accelerated beyond recognition. The deciding part is a different story, every \u003Cem>should\u003C\u002Fem> in this language stayed mine from the first day to the last, but that’s the subject of the final essay in this series, so here I’ll leave it at that.\u003C\u002Fp>\n",{},{"name":86,"clientId":524,"parentClientId":69,"renderedHtml":525,"attributes":526},"6adbdbdb86293","\n\u003Ch2 class=\"wp-block-heading\">Coda: the irony\u003C\u002Fh2>\n",{},{"name":73,"clientId":528,"parentClientId":69,"renderedHtml":529,"attributes":530},"6adbdbdb86294","\n\u003Cp class=\"wp-block-paragraph\">Which brings me to the joke at the center of the whole project, and I might as well say it plainly.\u003C\u002Fp>\n",{},{"name":73,"clientId":532,"parentClientId":69,"renderedHtml":533,"attributes":534},"6adbdbdb86295","\n\u003Cp class=\"wp-block-paragraph\">\u003Cstrong>Enzo is a language designed to be friendlier to humans, and the technology that made it possible to build is the same technology that makes human-friendly syntax matter less every month, because increasingly the thing writing the code is not a human\u003C\u002Fstrong>. Worse: LLMs are trained on oceans of Python and JavaScript, and the corpus of Enzo code that will ever exist is a rounding error. The machines will always be better at the languages people already use than at any language designed for people. The friendlier language loses to the training data, by construction, forever.\u003C\u002Fp>\n",{},{"name":73,"clientId":536,"parentClientId":69,"renderedHtml":537,"attributes":538},"6adbdbdb86296","\n\u003Cp class=\"wp-block-paragraph\">This isn’t just my private irony, it turns out. Programming-language researchers have started saying the same thing with citations: LLM coding performance drops off sharply for languages underrepresented in the training data, which means choosing a niche language now costs you your AI assistance too, as \u003Ca href=\"https:\u002F\u002Fkirancodes.me\u002Fposts\u002Flog-lang-design-llms.html\">one researcher put it\u003C\u002Fa>, the opportunity cost of a new language has just doubled. The predicted outcome is a world where new languages stagnate and Python becomes ubiquitous by sheer corpus gravity.\u003C\u002Fp>\n",{},{"name":73,"clientId":540,"parentClientId":69,"renderedHtml":541,"attributes":542},"6adbdbdb86297","\n\u003Cp class=\"wp-block-paragraph\">So: \u003Cstrong>Enzo doesn’t solve any problems. It only creates them.\u003C\u002Fstrong> It’s an art project, self-expression, a viewpoint on the world rendered in syntax, and it could never have been anything else, because the very thing that made it buildable is the thing that outmoded the need for it. A language for humans, implemented by a machine, arriving at the exact moment machines stopped needing languages for humans.\u003C\u002Fp>\n",{},{"name":73,"clientId":544,"parentClientId":69,"renderedHtml":545,"attributes":546},"6adbdbdb86298","\n\u003Cp class=\"wp-block-paragraph\">\u003Ca href=\"https:\u002F\u002Fmedium.com\u002Fdesign-bootcamp\u002Fthe-deciding-part-what-cant-be-automated-0533f36309fd?postPublishedType=repub\">Next, the last essay in this series: the deciding part, what was left that only I could do, once the machine could do all the building.\u003C\u002Fa>\u003C\u002Fp>\n",{},{"name":548,"clientId":549,"parentClientId":69,"renderedHtml":550,"attributes":551},"core\u002Ffootnotes","6adbdbdb86299","\u003Col class=\"wp-block-footnotes\">\u003Cli id=\"2e31b026-2446-5bf3-8e56-8436ab5022a1\">A sampler from the museum. The LLM once diagnosed a bug correctly and then explained its origin: during a recent refactor, \u003Cem>I\u003C\u002Fem> had apparently removed the logic for evaluating certain node types and failed to re-add it. The refactor was its own. I didn’t fail to re-add that code, my guy. \u003Cem>You did.\u003C\u002Fem> It would sometimes edit the comments describing a fix rather than the code, or write a TODO for the fix and stop, apparently satisfied by the paperwork. It would claim to have made changes it had not made. And my favorite: a failing recursion test it “fixed” by making the interpreter print the intended outcome, not repairing the recursion, just forging output that happened to match the golden file. The rest of the suite caught it, because the hack broke four older tests. One test tells the machine what to hit; the whole suite is what keeps it from hitting the target by cheating. \u003Ca href=\"#2e31b026-2446-5bf3-8e56-8436ab5022a1-link\" aria-label=\"Jump to footnote reference 1\">↩︎\u003C\u002Fa>\u003C\u002Fli>\u003C\u002Fol>",{},"\u003Cpre class=\"shiki shiki-themes phosphor2 midnight signal\" style=\"--code-token-phosphor2:#f0b040;--code-token-midnight:#e0eaff;--code-token-signal:#29cc6a;--code-token-phosphor2-bg:#0c112b;--code-token-midnight-bg:#0818a0;--code-token-signal-bg:#0c112b\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">$person1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFAA33;--code-token-midnight:#FFA66F;--code-token-signal:#FF9944\">:\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\"> [\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">    $name1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFAA33;--code-token-midnight:#FFA66F;--code-token-signal:#FF9944\">:\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#D4F53C;--code-token-midnight:#AAFF44;--code-token-signal:#AAFF44\"> \"Todd\"\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">    $age1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFAA33;--code-token-midnight:#FFA66F;--code-token-signal:#FF9944\">:\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFDD44;--code-token-midnight:#FFEE44;--code-token-signal:#FFCC44\"> 27\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">    $favorite-color1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFAA33;--code-token-midnight:#FFA66F;--code-token-signal:#FF9944\">:\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#D4F53C;--code-token-midnight:#AAFF44;--code-token-signal:#AAFF44\"> \"blue\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">]\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">$name1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> $age1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> $favorite-color1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFAA33;--code-token-midnight:#FFA66F;--code-token-signal:#FF9944\">:\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> $person1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">[]\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">$name1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#A07838;--code-token-phosphor2-font-style:italic;--code-token-midnight:#99AADD;--code-token-midnight-font-style:italic;--code-token-signal:#3A8A5A;--code-token-signal-font-style:italic\">             \u002F\u002F prints \"Todd\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">$age1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#A07838;--code-token-phosphor2-font-style:italic;--code-token-midnight:#99AADD;--code-token-midnight-font-style:italic;--code-token-signal:#3A8A5A;--code-token-signal-font-style:italic\">              \u002F\u002F prints 27\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">$favorite-color1\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#A07838;--code-token-phosphor2-font-style:italic;--code-token-midnight:#99AADD;--code-token-midnight-font-style:italic;--code-token-signal:#3A8A5A;--code-token-signal-font-style:italic\">   \u002F\u002F prints \"blue\"\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>","\u003Cpre class=\"shiki shiki-themes phosphor2 midnight signal\" style=\"--code-token-phosphor2:#f0b040;--code-token-midnight:#e0eaff;--code-token-signal:#29cc6a;--code-token-phosphor2-bg:#0c112b;--code-token-midnight-bg:#0818a0;--code-token-signal-bg:#0c112b\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FFCC55;--code-token-midnight:#FFFFFF;--code-token-signal:#5B8DFF\">let\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> a\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> b\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> rest\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">[\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">a\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\"> b\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">]\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFAA33;--code-token-midnight:#FFA66F;--code-token-signal:#FF9944\"> =\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\"> [\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFDD44;--code-token-midnight:#FFEE44;--code-token-signal:#FFCC44\">10\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">,\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FFDD44;--code-token-midnight:#FFEE44;--code-token-signal:#FFCC44\"> 20\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">]\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">console\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">.\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">log(\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#FF5533;--code-token-midnight:#FF6A8A;--code-token-signal:#FF5533\">a\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#44D4B0;--code-token-midnight:#44DDFF;--code-token-signal:#5B8DFF\">)\u003C\u002Fspan>\u003Cspan style=\"--code-token-phosphor2:#CC8822;--code-token-midnight:#7799CC;--code-token-signal:#218D4E\">;\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"--code-token-phosphor2:#A07838;--code-token-phosphor2-font-style:italic;--code-token-midnight:#99AADD;--code-token-midnight-font-style:italic;--code-token-signal:#3A8A5A;--code-token-signal-font-style:italic\">\u002F\u002F Expected output: 10\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>",1792793556583]