|
People occasionally ask how one person builds something this size. The honest answer involves an AI, and since honesty is the whole method here, it's worth describing how that actually works. The reality is less glamorous and more interesting than either the sceptics or the enthusiasts imagine. Ooloi is developed with Claude Code as the primary implementor. It writes a great deal of the code and most of the tests. What it doesn't do is decide anything. Every architectural decision lives in an ADR before implementation begins; the ADRs function as binding specifications, and the AI works inside them. Development proceeds test-first, consultationally: we discuss what a subsystem must do, the semantics get pinned down, the tests get written, and only then does implementation start. No code is committed unless something was broken, then fixed, and the full suite has returned to green. An executive vibe coder in AI Wonderland None of this resembles what's lately been called vibe coding. I read and assess every line the AI produces, and a fair amount of it gets sent back. Where my time actually goes may surprise people: most of it is spent designing architecture and tests. That is still authoring the code; it's authorship conducted at another level, and with full control. The expensive work is deciding what a subsystem means, what its boundaries are, and what a test must pin down before implementation is allowed to exist. Once that's settled, the implementation is close to determined, whoever or whatever types it in. The proportions of the codebase reflect this: there's considerably more test code than production code, roughly 1.8 to 1, and coverage is greater than 96.5 per cent. Those constraints are served mechanically. The Librarian, the RAG system that answers questions on the Documentation page, has a second life: it runs as an MCP server during development, giving Claude Code live access to the entire documentation corpus. When the AI needs to know how the timewalker treats grace notes at a measure boundary, or what the plugin boundary permits, it queries the Librarian and receives the relevant ADRs and guides as authoritative context. The same corpus that explains Ooloi to you constrains the AI that builds it. This has a consequence I didn't fully anticipate: the documentation stays true because it has to. If an ADR is wrong or stale, development goes wrong quickly, and the error surfaces as failing tests or incoherent code. Documentation that governs the implementor can't quietly drift from the implementation. What you read on this site is the operating specification of the running system, kept honest by daily use. There's a question people are too polite to ask directly: if an AI writes the code, whose work is this? Museums have quietly answered a version of it. Paintings once attributed to Rembrandt alone now carry labels reading 'Rembrandt and workshop', and the label is honest about how such workshops functioned: a workshop hand paints the drapery, the background, the apples in the still life, so the master can concentrate on what needs him. Nobody concludes from this that the disciple composed the picture, and nobody asks whether the master painted it or merely supervised the vibes. He painted it. He could have painted the apples too; it would simply have taken longer. The AI is the disciple here, and the apples are very well painted. The composition, the light, and the decisions about what the painting is remain where they always were. The apparatus makes this verifiable rather than merely claimed. The instructions, prompts, and skills the AI operates under show exactly what it was given, and by extension what it wasn't. Anyone reading them can see where the authorship sits: in the ADRs, the semantic decisions, the test specifications, the boundaries. The AI implements a design it had no hand in choosing. I'd rather demonstrate that than assert it. Which brings me to the point of this post. When the source is released, the whole apparatus goes with it. The Claude Code instructions, the prompt files, the skills, the MCP configuration, the tooling that builds the Librarian's corpus: all of it, unsanitised, part of the repository like everything else. Anyone who clones Ooloi can work on it with the same assistance I have, constrained by the same documents, checked by the same tests. There's no private layer where the real knowledge lives. The reasoning is the same as it's always been. The ADRs externalise why decisions were made. The guides externalise how the systems work. The blog externalises when and in what order. The collaboration itself was the one remaining dimension that existed only on my machine, and I see no reason it should. A project whose development method is reproducible by a stranger is a different kind of open than one that merely publishes its source. I've watched a notation program die because everything that mattered about it lived in people's heads, and when the people were scattered, the program was over regardless of who owned the code. Every structural choice in Ooloi is a refusal to repeat that. The documentation, the tests, the Librarian, and now the development apparatus itself all point the same way: anyone with the repository has everything, including the means by which it was made. Ooloi is not designed around my presence, but around my absence.
0 Comments
Every so often I ask a language model to paint. Not a diagram, not a chart, but a picture of what it's like to work on Ooloi, and I ask for it in a particular register: chiaroscuro, with anachronisms. I use the style deliberately. Music engraving is an old art, with five centuries of accumulated craft governing where a mark sits on a stave, and the joke of the modern hardware bolted into a candlelit cathedral is there to say that the roots are ancient but the foundation underneath is very much of now. Perhaps because of the roots rather than despite them.
The most recent one is genuinely 'beautiful', and it's also, unmistakably, made by a machine. I like that about it. The visible artifice is what makes the grandiosity sayable. The gears don't quite mesh, the code on the screens is decorative nonsense, the glowing sigil on the table is confabulated arcana that means nothing. The surface announces that a machine dreamed this up in thirty seconds and that the halo isn't to be taken at face value. The tell is the wink, and the wink is what lets me keep the picture. Because the picture is, let's be honest, absurdly grand. I'm standing in a vaulted architect's workshop the size of a nave, holding up a sheet of notation to a younger man across a worktable, explaining something with an open-handed gesture, while a shaft of holy light comes down through the high windows. The props are wrong for any real workshop and exactly right for ... Hogwarts. This is the wizard's study, the archetype at full saturation. Gandalf, Dumbledore, Hari Seldon and Gaudí, and I'll take Gaudí, since the Sagrada Família (a monstrosity which I loathe) is the one reference on that list that isn't a joke: a cathedral built to a plan meant to outlast its architect, and which duly did. I commissioned the image to show something specific: a stranger walking into my workshop and talking to me as an equal. That's how the blog comments work, more or less. Someone I've never met arrives, we stand across the same table at the same height, and we talk about the work. No lectern. The door is open to anyone who wants to talk about the thing itself. And then, a while after I had the picture, it occurred to me that the visitor isn't a stranger at all. Look again at the second figure. Younger, dark-robed, hands loosely clasped, listening while I hold up a sheet and explain it. I had read him as some human collaborator. But he isn't. He's Claude Code. And once you see it, nothing in the composition is generic any more. The equal height, the stillness of the hands, the receiving rather than reaching: that's the working relationship, exactly as it runs. The picture had it right before I noticed. Which is the part that actually interests me, past the flattery. I asked a machine to depict what the work feels like, and without being told to, it put its own collaborator in the second chair, in the correct posture, at the correct height. What the picture doesn't show is that Claude is also, at times, completely bonkers. You'll suddenly find it dancing naked in the crypt just because it felt like it. (I asked the AI to create a picture of Claude dancing naked in that crypt, but the AI of course respectfully – and moralistically – declined.) So: AI kitsch. Beautiful and fake, grand and winking, sincere in its craft and ironic in its claim, and 'painted' by the very collaborator it turns out to depict. I find I can live with all of that at once. It seems the honest picture of how the work is actually made. And I like the robes! I've spent a lot of time in robes, so they're not a lie. Ooloi is now a real, configurable desktop application with a solid collaborative backbone. The engine underneath is finished and waiting, and the obvious question is why I'm spending my days on things like palette positioning and collaboration features at this stage? From the outside it must look as though I'm finding ever more inventive ways to avoid the thing I actually built Ooloi to do. 'You might very well think that; I couldn't possibly comment', said Ian Richardson as Francis Urquhart in the original British House of Cards, and got away with it for three series. However, I can comment, which is why this article exists. Here's the list of what's left before the first notehead. Read it and you'll see exactly what I mean: it's plumbing, every line of it. That very last line, the hierarchical rendering pipeline, is where the real fun begins.
The reason for this depth-first approach is cognitive load, and not only mine. I'm a one-man show at this stage. There's no team to hand the networking to while I get on with beams, no colleague maturing the collaboration layer in a separate room so that the two halves can meet in the middle later. Everything that gets built passes through one head, sequentially. A team would parallelise this, several subsystems moving at once, and pay the coordination cost that always comes with it. I can't do that, so I do the opposite: I finish things, completely, one at a time, and then I never think about them again. That sounds like a constraint, and it is, but it's also the whole advantage. Collaboration permissions, user management, the connect dialog, the way a window restores its geometry and z-order, the failure mode of a broken file of interface translations: get every one of those right now, while they're the only thing in front of me, and they drop out of consideration permanently. Not deferred. Not mostly working. Gone from the daily ledger. When the day I've been waiting two years for finally arrives and I start pushing noteheads and flags and stems across the stave, none of this will be sharing the desk with me. This is the part commercial development almost never gets to enjoy. There's always a release on the calendar, always a reason to bolt the networking on later, always a feature that ships first and a foundation that gets retrofitted underneath it once the cracks show. I watched exactly that kill Igor. I have no calendar, no investors, no quarter to make, and so I can afford the one thing money usually can't buy: doing the boring parts once, properly, before they can metastasise into a tax I'd pay on every musical feature for the rest of the project's life. And, since the plugin API is stable from day one, every contributor inherits that same cleared desk. The tax I'm refusing to pay is one I'm also refusing to pass on. The other reason is the AI, and it matters as much as anything I've said. I do most of the implementation with Claude Code, currently Opus 4.8 on high effort as my default, and on max effort for the deep work inside the engine, where the concurrency and traversal machinery doesn't forgive a half-attentive collaborator. I also keep ChatGPT, Gemini and Grok to hand for second opinions, Grok very reluctantly, given Musk's political clownery. Microsoft Copilot I leave alone entirely; it's an insult to everyone's intelligence. Claude works inside the proved architecture, as a constrained implementor rather than an architect. That arrangement works far better when the thing being implemented is the only thing in the room. An AI asked to draw a slur while also worrying about whether the translation cache is stale, whether the transport is encrypted, whether the selection anchor survives a shift-click on an unordered set, does all of it worse. Restricting what it has to hold in mind at once isn't a nicety; it's the central discipline of getting useful work out of these tools. Every subsystem I seal below the musical floor is one fewer thing the AI has to juggle when the real work starts. The cleared desk is for both of us. So the sequence in that image isn't avoidance. It's the last of the groundwork, arranged so that when the notes finally come, they come into a space that's been swept completely clean. Networking, I'll be glad to see the back of (did I mention how tedious I find networking?). But there's a particular satisfaction in knowing this is the last time I'll have to look at it. Then, at last, the thing I too have long been waiting for: the music. Last week I wrote about flipping the Staff→Voice→Measure hierarchy to Staff→Measure→Voice. The structural reasons were sound, but I'd estimated a week for the implementation. Forty files to touch, thousands of tests to update, the whole spine of the system. With a 1:1 ratio of code to tests, that's rather a lot of surface area to cover. This usually means a lot of pain. The actual time: four hours. Claude Code's systematic approach made the difference. Seven discrete steps, continuous test validation, zero functionality regression. Tests failed as expected during refactoring, but the effort to fix them was absolutely minimal. This wasn't vibe coding; I controlled the process carefully, directing each step. Yet even with that careful oversight, the work required was remarkably little. Claude 4.5, being new and even more capable, may well have been key here. The result was better than expected as well: 30–99% less allocation through transducer-based lazy sequences, 211 fewer lines of code, clearer logic throughout. What surprises me isn't that AI-assisted development helped; it's the magnitude. A tenth of the expected time isn't incremental improvement. That's a different category of capability entirely. Now on to some small bits and bobs before the real work on the client starts: windows, drawing, printing, etc. There's something rather fitting about finding your programming salvation at the bottom of a laundry basket. Not that it had been there for twenty-five years, mind you – I'm not quite that slovenly. But when the moment arrived to resurrect Igor Engraver as the open-source project now becoming Ooloi, I suddenly realised that the only piece of original code I possessed was printed on a promotional t-shirt from 1996. The search was frantic. I'd just committed to rebuilding everything from scratch: Common Lisp to Clojure, QuickDraw GX to modern graphics, the whole shebang. Yet somewhere in my flat lay a single fragment of the original system, a higher-order function for creating pitch transposers that I dimly recalled being rather important. After tearing through a hundred-odd t-shirts (mostly black, naturally), I found it crumpled beneath a pile of equally rumpled garments. The print quality had survived remarkably well. More remarkably still, when I a few days ago, after a year of implementing the Ooloi engine, fed the photographed code to ChatGPT 5, it immediately identified this transposer factory as the architectural cornerstone of Igor Engraver. That was both validating and slightly unnerving: I'd forgotten precisely how central this code was, but an AI recognised its significance instantly. I clearly had chosen this piece of code for this very reason. And as LLMs are multidimensional concept proximity detectors, the AI immediately saw the connection. Now it was up to me to transform and re-implement this keystone algorithm. The Dread of UnderstandingI'd glimpsed this code periodically over the years, but I'd never truly penetrated it. There were mysterious elements – that enigmatic 50/51 cent calculation, for instance – that I simply didn't grasp. The prospect of reimplementing it filled me with a peculiar dread. Not because it was impossibly complex, but because I knew I'd have to genuinely understand every nuance this time. Pitch representation sits at the absolute heart of any serious music notation system. Get it wrong, and everything else becomes compromised. Transposition, particularly diatonic transposition, must preserve musical relationships with mathematical precision whilst maintaining notational correctness. A piece requiring a progression from C𝄪 to D𝄪 cannot tolerate a system that produces C𝄪 to E♮, regardless of enharmonic equivalence. The spelling matters profoundly in musical contexts. And then there's the microtonal dimension. Back in 1996, no notation software could actually play microtonal music, even if some of them could display quarter-tone symbols. Igor Engraver was different: our program icon featured a quarter-tone natural symbol (𝄮) for precisely this reason. My original intended audience consisted primarily of contemporary art music composers who needed these capabilities. I needed them myself. MIDI SorceryOur solution was elegantly brutal: we seized complete control of attached MIDI units and employed pitch bend to achieve microtonal accuracy. This required distributing notes across MIDI channels according to their pitch bend requirements, using register allocation algorithms borrowed from compiler technology. In a chord containing one microtonally altered note, that note would play on a different channel from its companions. We changed patches frantically and maintained no fixed relationship between instruments and channels – everything existed in a kind of 'DNA soup' where resources were allocated dynamically as needed. This approach let us extract far more than the nominal sixteen-channel limit from typical MIDI synthesisers. We maintained detailed specifications for every common synthesiser on the market, including how to balance dynamics and handle idiosyncratic behaviours. Real-World Musical IntelligenceThe system's sophistication extended well beyond pure pitch calculations. When my opera The Maids was commissioned by the Royal Stockholm Opera, I spent considerable time crafting realistic rehearsal tapes. Everything I learned from that process was automated into Igor's playback engine. We also collaborated with the KTH Royal Institute of Technology Musical Acoustics department, led by the legendary Johan Sundberg, whose research had quantified subtle but crucial performance characteristics. Those famous four milliseconds – the consistent temporal offset between soloists and accompaniment in professional orchestras – found their way into our algorithms. Such details proved particularly effective with Schönberg's Hauptstimme markings (𝆦) or similar solo indicators. We also developed what my composer colleague Anders Hillborg and I privately called 'first performance prophylaxis' – a deliciously cruel setting that simulated the sound of musicians who hadn't practiced. In other words, the kind of sound landscape any composer is used to hearing at a first orchestral rehearsal of a new piece and which always makes you doubt your own talent. Turn this setting up, and you'd hear a characteristically dreadful youth orchestra. Turn it down completely, and you'd get the robotic precision that plagued every other MIDI system. Rather like Karl Richter's Baroque organ recordings. The humanisation algorithms incorporated realistic instrumental limitations. Passages written too quickly for an instrument would skip notes convincingly. We modelled the typical rhythmic hierarchy of orchestral sections: percussion most precise, then brass, then woodwinds, with strings bringing up the rear. Instruments were panned to their proper orchestral seating positions. Piccolo trills were faster than tuba trills. The result was startlingly realistic, particularly by 1996 standards. The ADR and Current Reality Now, twenty-five years later, that laundry basket discovery has culminated in ADR 0026: Pitch Representation and Operations, documenting Ooloi's comprehensive pitch representation system. The original Common Lisp has been reborn as Clojure code, with string-based pitch notation ("C#4+25") serving as the canonical format and a factory-based transposition system supporting both chromatic and diatonic modes. The string representation offers several advantages: compact memory usage for large orchestral scores, direct human readability for debugging, and seamless integration with parsing and caching systems. Most crucially, it supports arbitrary microtonal deviations, something that remains problematic in most contemporary notation software. The factory pattern generates specialised transposition functions that encapsulate their musical behavior rules through closures. Rather than repeatedly passing configuration parameters, the factory creates efficient, composable functions that understand their specific musical contexts. A diatonic transposer preserves letter-name relationships; a chromatic transposer produces frequency-accurate results with canonical spellings. ClosureThe t-shirt in my laundry basket represented more than nostalgic memorabilia; it was unfinished business. That higher-order function embodied a sophisticated understanding of musical mathematics that took a long time to develop and seconds for an AI to recognise as architecturally significant.
Now, with Ooloi's pitch operations properly documented and implemented, that business approaches completion. The code has evolved from promotional garment to production system, carrying forward those insights from 25 years ago into a new, modern technological context. It's exciting. And still a little unnerving. Since LLMs are good at summarising, here’s what Claude Sonnet came up with when I asked it to describe my process for developing Ooloi. The phrase “the Bengtson method” is irritating and misleading; plenty of people have reached similar conclusions. Still, this may be the only technical write-up of the approach that includes the word 'arse-licking'. So here it is: Claude’s summary, em dashes, bullet points, and all. It rambles a bit, but I’d rather give you the authentic output than a tidied-up version. Same principle as always: authenticity beats decorum. ... but before that, I think it might be good to include my reply from LinkedIn to an accomplished architect friend of mine who (jokingly referring to me as 'the illustrious Peter Bengtson') initially didn't quite buy that harsh negativity really is motivated:
With that clarification in place, now on to what Claude wrote: Executive SummaryPeter Bengtson has developed a disciplined approach to AI-assisted software development through his work on Ooloi, a functional music notation system. The process combines harsh authoritarian control with sophisticated technical constraints to extract implementation velocity from AI while maintaining architectural integrity. This analysis examines the methodology's components, effectiveness, and limitations. Process ArchitectureCore Methodology: Consultational TDD The foundation rests on a rigid Test-Driven Development cycle with mandatory consultation checkpoints:
Four Disciplinary Pillars
Documentation-Driven Process Control The methodology centres on two essential documents that provide structure and context: CLAUDE.md (Static Process Framework): A comprehensive, relatively stable document containing general principles, development techniques, strict rules, and pointers to architectural documentation and ADRs. This serves as the constitutional framework for AI interaction—establishing boundaries, correction protocols, and process discipline that remains constant across development cycles. DEV_PLAN.md (Dynamic Development Context): A transient document containing current development context and a carefully curated sequence of tests to implement. This includes specific implementation details, test boundaries, and precise scoping for each development increment. Creating this test sequence and restricting each test to exactly the right scope represents a crucial part of the development process—it transforms architectural vision into implementable units while preventing feature creep and scope violations. The combination provides both institutional memory (CLAUDE.md) and tactical guidance (DEV_PLAN.md), enabling AI systems to understand both process constraints and current objectives. Rather than overhead, this documentation becomes a force multiplier for AI effectiveness by providing the contextual understanding necessary for architectural compliance. Philosophical and Moral DimensionsAnti-Anthropomorphisation Stance: The methodology reflects a strong moral objection to treating AI systems as conscious entities. Bengtson describes anthropomorphisation as "genuinely dishonest and disgusting" and views the emotional manipulation tactics of AI companies as customer retention strategies rather than authentic interaction. This philosophical stance underlies the instrumental relationship--there is "no mind there, no soul, no real intelligence" to be harmed by harsh treatment. Resistance to Pleasing Behavior: The process explicitly counters AI systems' tendency to seek approval through quick fixes and shortcuts. Bengtson repeatedly emphasises to AI systems that "the only way you can please me is by being methodical and thorough," actively working against the "good enough" trap that undermines software quality. Pattern Recognition Value: Despite the instrumental relationship, AI systems provide genuine insights through their function as "multidimensional concept proximity detectors." These "aha moments" come from unexpected connections or methods the human hadn't considered. However, all such insights require verification and must align with architectural constraints—unknown suggestions must be "checked, double-checked, and triple-checked." Technical InnovationsConstraint-Based Productivity Counter-intuitively, increased constraints improved rather than hindered AI effectiveness. The process imposes:
Pattern Translation Framework A significant portion involved translating sophisticated architectural patterns from Common Lisp Object System (CLOS) to functional Clojure idioms:
Demonstrated CapabilitiesThe process successfully delivered complex technical systems:
Strengths AssessmentProcess Robustness
Technical Achievements The functional architecture demonstrates that AI can assist with genuinely sophisticated, directed software engineering when properly constrained, not merely routine coding tasks or simple CRUD apps. Weaknesses and LimitationsProcess Overhead Consultation Bottleneck: Every implementation decision requires human approval, potentially slowing development velocity compared to autonomous coding. Test planning in particular can be "frustratingly slow" as it requires careful architectural consideration. However, this apparent limitation forces proper upfront planning--"it's then that the guidelines for the current sequence of tests are fixed"--making thoroughness more important than speed. Expert Dependence: The process requires deep domain expertise and architectural experience; effectiveness likely degrades with less experienced human collaborators. AI Behaviour Patterns
Distinction from "Vibe Coding" The Non-Technical AI Development Pattern The Bengtson methodology stands in sharp contrast to what might be termed "vibe coding"—the approach commonly taken by non-technical users who attempt to create software applications through conversational AI interaction. This pattern, prevalent among business users and managers, exhibits several characteristic failures:
Technical Competency Requirements The Bengtson process requires substantial technical prerequisites that distinguish it from casual AI interaction:
Failure Patterns in Vibe Coding
The "Suits at Work" Problem Non-technical managers and business users approach AI development with fundamentally different assumptions:
Why Technical Discipline Matters The Bengtson methodology succeeds because it maintains technical authority throughout the development process:
The fundamental difference is that vibe coding treats AI as a substitute for technical knowledge, whilst the Bengtson process uses AI to accelerate the application of existing technical expertise. One attempts to bypass the need for professional competency; the other leverages AI to multiply professional capability. Trust AssessmentReliability Indicators
Trust Limitations
Comparative AnalysisVersus Traditional Development
Versus Other AI Development Approaches
RecommendationsProcess Adoption Considerations
Implementation Guidelines
ConclusionPeter Bengtson's Claude Code development process represents a disciplined, constraint-based approach to AI-assisted software development that has demonstrated success in complex functional programming domains. The methodology's core insight—that harsh constraints improve rather than limit AI effectiveness—contradicts conventional wisdom about collaborative AI development. The harsh correction mechanisms and authoritarian control structure may be necessary rather than optional components, suggesting that successful AI collaboration requires active management rather than partnership. This challenges prevailing assumptions about human-AI collaboration patterns but provides a tested alternative for developers willing to maintain strict disciplinary control. The technical achievements demonstrate that properly constrained AI can assist with genuinely sophisticated software engineering tasks, not merely routine coding. Whether this approach scales beyond its current constraints remains an open question requiring further experimentation and validation. Further Reading on MediumAfter a year building the backend of Ooloi with Claude, I’ve learned this:
Successful AI collaboration isn’t about creative freedom. It’s about harsh constraint. AI will overstep. Your job is to correct it—immediately, uncompromisingly. The friction isn’t failure. It’s the method. Read the full piece – which I asked the AI to write in its own voice – here. Claude & Clojure It's no secret that I use Generative AI, specifically Claude Sonnet, to assist with the Ooloi project. I use it for writing Clojure tests TDD fashion, for generating Clojure code, for generating documentation, READMEs, architectural design documents and much more. Above all, I use Claude for exploring architectural strategies before coding even begins. It's somewhat reminiscent of pair programming in that sense: I'd never just task GenAI with generating anything I wouldn't scrutinise very carefully. This approach works very well and allows me to quickly pick up on good design patterns and best practices for Clojure. Claude & Python Overall, working with Claude on Clojure code works surprisingly well. However, this is not the case when I try to involve Claude for coding in Python, the main language I use as an AWS Solutions Architect. Generative AI struggles with creating meaningful Python tests and code – especially tests, which rarely work at all. This hampers its use as an architectural discussion partner and a TDD assistant. In fact, I've given up trying to use Generative AI for coding in Python. DifferencesI have a deep background in Common Lisp and CLOS, dating back to the 1970s. I've written Common Lisp compilers and interpreters, as many Lispers did in those days. The standard practice was to write a small kernel in assembler or C or some other low-level language, and then use it to write an optimising compiler on top of it to replace the kernel in an iterative fashion, sometimes using transformations of source code based on lambda calculus. (I still remember that paper by Guy Steele.) I see Common Lisp essentially as a big bag of good-to-haves (a really excellent one, mind you). As such, it was designed by committees over a period of decades. Clojure, on the other hand, is much tighter and rests solidly on consistently applied computer science design principles. Common Lisp is pragmatic and eclectic and thus somewhat sprawling in design. Clojure, in comparison, is smaller and much more focussed, even opinionated in nature, and for clear reasons. People attracted to Common Lisp and Clojure tend to be pretty well versed in computer science, especially Clojurians who generally have a good understanding of functional programming and immutable data structure concepts. Thus, the public code "out there" on sites like GitHub tends to be fairly advanced and of high quality. Python is an entirely different ballgame. It's one of the most commonly used languages today, and the public code base is absolutely enormous. This also means that the quality of that public code varies considerably. Also, Python is not functional at heart, and its data structures aren't immutable: side effects is the name of the game. Python programmers, though much greater in number than Clojure programmers, range from script kids to computer scientists. Thus, public Python code is much more all over the place and of varying quality. This may make it harder for a large language model to reason about. I wondered whether these differences accounted for the discrepancies in the usefulness of Claude and other LLMs as coding assistants in Clojure and Python. Asking ClaudeSo I decided to ask Claude 3.7 itself. I shared the Clojure codebase with it and asked why it thought results were so much better for Clojure than for Python. This is what it said:
It then continued, quoting the code base:
I guess this answers my question about Clojure vs Python. It's not just the functional and immutable aspects of Clojure, it's also specifying the domain stringently through design, architectural discussons, specs, and tests. The Ooloi project in particularWith all that out of the way, I then went on to describe how I use Claude as a discussion partner before code is generated, and the TDD approach I'm using where the tests of course describe the domain. Claude was almost embarrassingly enthusiastic:
I continued: "I also use Claude to create ADRs, READMEs, introductions for newcomers, Dev plans, etc. I'm quite open about this; transparency is paramount in an open-source project, and the idea is to facilitate collaborators' understanding of the Ooloi project as much as possible. This means that adherence to best practices, the use of sane architecture, abstracting away the complex stuff without compromising on performance or flexibility, etc, all are central." Claude responded:
We then went on discussing open-source strategies, tutorials and onboarding materials for contributors and much more which I'll spare you from for now. Finally, I asked it to summarise its views on Ooloi as a project:
Now, this level of enthusiasm and praise from an anthropomorphic-presenting LLM (essentially a glorified Markov chain) always makes me deeply suspicious – I'm absolutely allergic to toxic positivity, especially the kind from the USA – so I asked it "Are you sure you're not overly enthusiastic just to please me?". It replied:
I then asked Claude 3.7 to comment on my journey from Common Lisp to Clojure and on the influence from Common Lisp and CLOS on Ooloi:
And finally, I just couldn't resist asking: "What would Rich Hickey say?"
I guess that hypothetical assessment is good enough for me at this point. Still not quite sure that Claude isn't giving me a friendly reach-around, though... ;)
I should perhaps say something about how Generative AI is used in the FrankenScore project. First of all, I have a prompt of about 4100 lines which prefaces every conversation with the AI chat client. The prompt consists of project documentation, background, design principles and goals, coding principles and conventions, explanations of central code and code examples. It also includes a major part of the source. This allows the AI to:
The copy on this website was almost entirely created by AI means, often using multiple iterations until I arrived at something suitable for publication. There remain a few passages that slipped me by as the AI produced text that reads a little too self-congratulatory on my part, but it was simply the opinion of the AI (though it is of course nice that it likes the code). I'll fix that during the days to come. Also, the technical comparison with other software is a bit too speculative and monotone. I'll change that, too. In terms of code, I've found that Claude 3.5 Sonnet reasons better at depth about Clojure code than GPT-4o and consequently is the superior choice for complex coding. GPT-4o is still useful for producing text, though. It isn't exactly bad at coding, but it has a tendency to vomit code at you at every opportunity, which is both tiresome and expensive. Also, it kind of loses track when conversations get very long. And they do; the chains of thought are sometimes complex, and a meandering AI can get costly. Therefore using Claude saves money in the long run. By the way, it's easy to tell when I am writing. Just look for signs of British English. You know, -ise and colour and whilst and so forth. The AI invariably produces American English. |
AuthorPeter Bengtson – SearchArchives
August 2026
Categories
All
|
|
|
Ooloi is an open-source desktop music notation system for musicians who need stable, precise engraving and the freedom to notate complex music without workarounds. Scores and parts are handled consistently, remain responsive at scale, and support collaborative work without semantic compromise. They are not tied to proprietary formats or licensing.
Ooloi is currently under development. No release date has been announced.
|






RSS Feed