I've been saying I'm itching to open source Ooloi, but waiting for the complete software felt increasingly artificial. The documentation tells the real story – twenty-five years of architectural evolution from Igor Engraver through AWS systems thinking to this closure in Clojure.
So here it is: the complete Ooloi documentation collection, released publicly ahead of the software itself. What you'll find:
This represents my attempt to walk the talk after critiquing FP drawbridge syndrome. These guides serve dual purpose: they document sophisticated music notation architecture whilst teaching functional programming concepts through examples that actually matter. The timewalker guide alone demonstrates transducers, lazy sequences, and functional composition through orchestral score traversal. The polymorphic API guide teaches multimethods through musical type systems. The concurrency patterns show STM coordination through collaborative editing. Twenty-five years of thinking, distilled into something that I hope proves useful beyond music software. The architecture is complete; the foundations are solid. Now you can see why I've been eager to share this work. An organism evolved, indeed. Explore the complete documentation: https://github.com/PeterBengtson/Ooloi-docs /Peter
0 Comments
Now that the backend engine is complete, architecturally speaking, I'm getting increasingly eager to open the source. Itching, in fact. But as that will take a while, the least I can do for you is give you the WELCOME.md file from the source repo. / Peter Welcome to OoloiGreetings, and welcome to Ooloi, the spiritual successor to Igor Engraver. If you're seeking yet another conventional music notation software, I'm afraid you've taken a wrong turn. Ooloi aims to be something rather different — and there's a story behind why that matters.
A Quarter-Century in the Making Twenty-five years ago, I created Igor Engraver, which became rather successful in the music notation world. When that project ended, it left something unfinished – not just the software, but the understanding of what music notation software could truly become. Ooloi represents the completion of that circle, built with decades of accumulated insight about both music and programming. In the intervening years, I became an AWS Solutions Architect Professional and created systems like Ocean and OpenSecOps. I have always thought in systems — this shift simply allowed me to give that instinct full rein, to focus entirely on designing foundations that can handle complexity and scale over time through elegant abstraction layers. I've spent the better part of a year on Ooloi distilling everything I've learned into an architecture that doesn't just work, but works elegantly. This isn't my first attempt at solving these problems, but it's the first time I've had the right tools – functional programming, immutable data structures, enterprise-scale systems thinking, and the kind of patience that comes with experience – to solve them properly. What is Ooloi? Ooloi is open-source music notation software, designed from the ground up to handle complex musical scores with both finesse and power. Built in Clojure, it represents a fundamental rethinking of how music software should work. What makes it different:
Why Ooloi Matters The world of music notation software has been rather stagnant for too long, content with incremental updates and feature bloat. Most existing software suffers from fundamental architectural problems that can't be fixed with patches – they require starting over with better foundations. Ooloi solves problems that have plagued music software for decades: proper temporal synchronization, efficient collaborative editing, memory-efficient handling of large scores, and clean extensibility. These aren't just nice features – they're qualitatively different capabilities enabled by choosing the right abstractions. The Architecture You'll Inherit What you'll find here is the result of taking time to get the abstractions right. The backend is conceptually complete, with over 15,000 tests proving it works correctly. The temporal coordination system, the pure tree data structures, the STM-based concurrency – these represent solutions to genuinely hard problems. But here's the thing: good architecture should be invisible to those who use it. The complexity is handled for you, hidden behind interfaces that make difficult things simple. You can focus on the problems you want to solve – whether that's creating plugins, improving the user interface, or adding new musical capabilities. How You Can Contribute If you're here, you probably have an interest in music, programming, or ideally both. Here's how you can be part of this:
Getting Started
What You're Joining This isn't just another open-source project. It's the culmination of decades of understanding what music notation software needs to be, combined with the architectural discipline to build it right. You're joining something that's designed to outlast its creator, to enable work that hasn't been imagined yet, to solve problems that matter to musicians and developers alike. The foundations are solid; now we build the future on top of them. The architecture is complete, but the work is just beginning. There are plugins to write, interfaces to design, capabilities to add. Most importantly, there are problems to solve that only emerge when you put powerful tools in the hands of creative people. A Personal Note At 64, carrying more than five decades of programming experience and a parallel career as a composer, I've tried to encode into this architecture not just technical solutions, but the aesthetic judgments and performance intuitions that come from actually making music. The creative energy that might have gone into another opera has found expression in software architecture. It's a different kind of composition – one that enables other people's creative work rather than expressing my own. In many ways, it's more satisfying. This is what happens when you take the time to get it right, when you resist the urge to rush, when you're willing to solve the hard problems properly. The result is something that can grow and evolve through the contributions of others while maintaining its essential character. Now, let's make some music. On all levels. / Peter Bengtson I wrote this as the final pieces of Ooloi's backend architecture were falling into place. What began as a meditation on infrastructure and isolation turned into something more personal about mastery, loss, and the strange kind of solitude that comes with finishing something no one else can see. This isn't documentation. It's a reflection. / Peter There's a peculiar melancholy that settles over you when you near the completion of something genuinely complex, something that has consumed many months of concentrated thought and represents the synthesis of decades of accumulated understanding. I find myself in precisely this position with Ooloi's backend architecture, and the psychological reality proves a bit more complicated than I'd anticipated. It's rather like the post-coital moment after particularly intense sex: that strange combination of satisfaction, exhaustion, and existential emptiness when the driving urgency suddenly lifts. You've achieved something profound, yet find yourself staring at the aftermath wondering what, precisely, comes next. I'm smoking a conceptual cigarette, as it were, contemplating the peculiar loneliness that follows architectural completion. In a matter of days, I'll complete the final piece: the endpoint resolution system for slurs and ties that uses the framework I've spent months building. Once that's finished, the backend will be conceptually complete – 15,000+ tests passing, STM transactions handling 100,000+ operations per second, Vector Path Descriptors enabling elegant client-server communication, and a transducer-based piece-walker that coordinates musical time with mathematical precision. The piece-walker literally performs the musical score, traversing it in time just as I once performed Vierne at the organ. To anyone versed in these technical domains, that represents serious work. To everyone else, it's incomprehensible gobbledygook happening 'under the hood' of something they might one day use to write music. And therein lies the first layer of loneliness: having solved genuinely difficult problems that almost nobody can fully appreciate. The Weight of Invisible Architecture Software architecture, when done properly, is invisible to its eventual users. They should never know about the STM transaction coordination that keeps their concurrent edits from colliding, or the VPD system that allows them to reference musical elements without direct object pointers, or the careful functional design that ensures their work remains consistent across complex operations. This invisibility is precisely the point – and precisely the problem. I've spent months solving challenges that required rather more thought than I'd initially anticipated, creating abstractions that handle the full complexity of musical notation whilst remaining elegant enough to extend indefinitely. Yet once complete, this work vanishes into infrastructure. The better I've done my job, the less visible it becomes. There's something profoundly isolating about completing work that embodies your best thinking but can never be fully shared. The musicians who will eventually use Ooloi might appreciate its responsiveness or reliability, but they'll never see the polymorphic dispatch system that makes complex musical operations feel effortless, or understand why the pure tree structure with ID references elegantly solves problems that have plagued notation software for decades. Clojure for ClosureThe choice of Clojure wasn't merely technical: it was also psychological. Having started programming in Lisp in 1976, having built Common Lisp compilers and interpreters, having spent $7.5 million of investor money and then having unresolved feelings about Igor Engraver's death for a quarter of a century, returning to a Lisp dialect feels like completing a circle that's been open far too long. Clojure for closure, if you will. But this completion reveals its own complexity. I'm 64, carrying more than five decades of programming experience and a parallel career as an internationally performed composer – an intersection that doesn't exactly suffer from overcrowding. The same mind that wrote what apparently is the internationally most played Swedish opera now architects STM concurrency patterns. The same hands that have performed French romantic organ works now implement temporal traversal through transducers. This convergence of domains should feel like triumph. Instead, it often feels like exile – not belonging entirely to the musical world I've moved beyond, nor quite fitting into the tech world that didn't shape me. I don't belong anywhere, really. The isolation isn't just professional; it's existential. The Economics of Art and Pragmatism I must confess something that still sits uneasily: I've essentially given up composing, despite international success, because conditions in Sweden for composers have deteriorated to the point where I had to prioritise my pension. There's an unwritten opera I'd like to complete – I have the text ready – but it will likely never come to fruition. Whether this represents economic necessity or conscious rejection of a cultural environment I found increasingly superficial and performative, I honestly can't say. Perhaps both. The exact proportion remains unclear even to myself, and I've learned to be comfortable with that ambiguity. Life rarely offers the clean motivations we prefer in retrospect. What I can say is this: the creative energy that might have gone into that final opera has found other expression. The same understanding of temporal flow, structural relationship, and expressive possibility that shaped my musical work now manifests in software architecture. It's sublimation in the deepest sense: not compromise, but transformation. The Paradox of CompletionHere's what nobody tells you about completing something genuinely substantial: the moment of architectural completion isn't triumph, it's vertigo. All those months of wrestling with complex problems, of holding intricate systems in your head, of solving puzzles that demanded your full intellectual capacity – suddenly that pressure lifts, and you're left staring at what you've built with a strange mixture of satisfaction and emptiness. The backend is nearly finished. The hard problems are solved. The foundation is solid. And now comes the work that should be 'easier': creating user interfaces, handling the cultural and aesthetic dimensions of human interaction, making decisions about visual design and workflow that seem trivial after months of STM transaction coordination but are actually far more treacherous. Technical problems have logical solutions. Human interface problems have cultural solutions, psychological solutions, aesthetic solutions; domains where being right isn't enough, where the same mind that can architect transducer pipelines struggles with questions like 'should this button be blue or green?' not because the technical challenge is greater, but because the criteria for success shift from mathematical to cultural. The Transition ChallengeMoving from backend completion to frontend implementation isn't just a technical transition. It's a psychological one. After months of building infrastructure that only I can see, I must now create experiences that others will judge. After solving problems where elegance and correctness align, I must now solve problems where user perception and technical reality often diverge. The loneliness of architectural completion isn't just about having done complex work in isolation. It's something else entirely. The 'easy' work ahead may be harder in ways that have nothing to do with computational complexity. It's about moving from mathematical elegance to human messiness, from logical purity to cultural compromise. Most acutely, it's about the strange position of being someone who carries irreplaceable knowledge – the synthesis of decades in both musical and computational domains – and wondering how to encode that understanding into forms that others can inherit and extend. Not just the technical patterns, but the aesthetic judgements, the performance intuitions, the hard-won understanding of how creative work actually happens. What Comes NextIn a couple of weeks, when the final endpoint resolution system is working and the backend architecture is truly complete, I'll begin the gRPC implementation that bridges backend and frontend. Then comes the 'Hello World' window – Ooloi's first visible manifestation, however simple.
The psychological challenge isn't technical uncertainty. I've built user interfaces before, in a previous technological era. It's the weight of transition: from solving invisible problems to creating visible experiences, from mathematical elegance to cultural navigation, from the loneliness of architectural completion to the different loneliness of human interface design. The work continues, but its nature changes completely. After months of building the engine, it's time to build the car. And to discover what new forms of isolation await when mathematical precision meets human perception. For now, I sit with the strange melancholy of nearly completing something that matters enormously but whose full significance can be communicated to virtually no one. It's a peculiar form of creative isolation – not the romantic loneliness of the misunderstood artist, but the technical loneliness of someone who happens to carry knowledge that exists at intersections most people never visit. Clojure for closure, indeed. But it turns out that closure reveals as much as it resolves. Time for a smoke. How solving a real music notation problem revealed the perfect transducer use case The Problem That Started It All I found myself confronting what appeared to be a deceptively simple requirement for Ooloi: 'Resolve slur endpoints across the musical structure'. Rather straightforward, one might assume: simply traverse the musical structure and locate where slurs terminate. But then, as so often is the case, the requirements revealed added complexity:
It became apparent that I needed a general-purpose piece traversal utility: something handling temporal coordination whilst remaining flexible enough for multiple applications. Rather than construct something bespoke (and likely regrettable), I researched the available approaches within Clojure's ecosystem. That's when I recognised this as precisely what transducers were designed for. The Architecture RecognitionAllow me to demonstrate the pattern I anticipated avoiding. Without a general traversal utility, each application would require its own approach: Three functions, identical traversal logic, different transformations. Exactly the architectural smell I wanted to avoid from the outset. This was precisely Rich Hickey's transducer insight made manifest: "What if the transformation was separate from the collection?" The Transducer RevelationWhat if I could write the temporal traversal once, then apply different transformations to it? Objective achieved: one traversal algorithm, many applications. But its architectural reach turned out to be even more profound. The Architectural InsightThe design decision hinged upon recognising that I was conflating two distinct concerns: the mechanism of traversal and the logic of transformation. This wasn't merely about avoiding the tedium of duplicated code (though that would have been reason enough) but rather about establishing clean architectural boundaries that would serve the system's long-term evolution. Consider the conceptual shift this separation enabled: Rather than thinking in terms of specific operations upon musical structures:
The transducer approach encouraged thinking in terms of composed processes:
The traversal thus became reusable infrastructure, whilst the transformation became pluggable logic. This distinction would prove invaluable as the system's requirements expanded. The Broader ApplicationsWhat I hadn't anticipated was how broadly applicable the resulting abstraction would prove. After implementing the piece-walker for attachment resolution, I discovered it elegantly supported patterns I hadn't originally considered, each demonstrating the composability that emerges naturally from separating traversal concerns: Each is built from simple, testable pieces. And they all inherit the same temporal coordination guarantee. This composability emerged naturally from the transducer design: a pleasant architectural bonus. The Performance Characteristics As one would expect from a well-designed transducer, memory usage remained constant regardless of piece size: a particularly crucial consideration when dealing with the sort of orchestral scores that might contain hundreds of thousands of musical elements. Consider the alternative approach, which would create intermediate collections at each processing step: The transducer version processes one item at a time: Same result, constant memory usage. This exemplifies what Rich meant by 'performance without compromising composability'. Demystifying Transducers Transducers suffer from an unfortunate reputation for complexity, often relegated to 'advanced topics' when they needn't be. This is particularly galling given that they're fundamentally straightforward when you encounter the right use case, which the musical domain provides in abundance. Think of transducers as 'transformation pipelines' that work with any data source, much as one might design AWS data processing workflows that operate regardless of whether the data arrives from S3 buckets, database queries, or API streams: The pipeline stays the same. The data source changes. In Ooloi: Why This Matters Beyond MusicThe piece-walker solved a universal software problem: How does one avoid duplicating traversal logic whilst maintaining performance and composability? This pattern applies everywhere:
Transducers provide the infrastructure for "traverse once, transform many ways." The Bigger PictureBuilding the piece-walker demonstrated that transducers aren't an abstract functional programming concept. They're a practical design pattern for a specific architectural problem: separating the concerns of traversal from transformation. The musical domain made this separation particularly clear because the temporal coordination requirements are so explicit. When you need the same traversal logic applied with different transformations, transducers provide the elegant answer. This separation makes code:
What's Next?The piece-walker is documented thoroughly in our Architecture Decision Record for those wanting technical details. But the real value lies not in the musical specifics but in observing how transducers address genuine architectural challenges with apparent effortlessness. The next time you find yourself contemplating similar data processing logic across multiple contexts, you might ask: 'What if the transformation was separate from the collection?' You may well recognise your own perfectly suitable transducer use case. References and Further ReadingRich Hickey's Essential Talks
Official Documentation
Educational Resources
Advanced Topics
![]() One of the central design principles behind FrankenScore/Ooloi is modularity. There is a small core, written in Clojure, and then there are plugins which can be written in any JVM language such as Java, Kotlin, Scala, JRuby, Jython, etc. This architecture has far-reaching consequences for contributors. For instance, the open-source core can be contributed to and extended natively in Clojure – which expert Clojurians will appreciate. This way, contributors have full access to all aspects of the core engine. But if you instead want to contribute to Ooloi using its plugin architecture, you can use any JVM language and production methodology. The API you'll be using lets you focus entirely on the musical task to be accomplished. You don't even have to know about things like transactions, concurrency, or memory management. You can safely work with the powerful musical abstractions the API gives you and let the efficient engine handle the rest. And commercial entities will also appreciate that Ooloi's plugin mechanism supports paid, close-source plugins. And as there is no loss in efficiency or speed, much of the Ooloi functionality will be implemented using plugins, including advanced playback, MusicXML support, virtual instruments, tablature, jazz notation, and much more. Read more about it in the updated and extended Development Plan. 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... ;)
It's been five months since my last update on Ooloi – or FrankenScore, as it's still known in its pre-release incarnation. This silence wasn't planned; rather, it happened because life got in the way. A demanding day job, a significant career change – we had to liquidate Delegat AB and I had to find a new job as a principal-level AWS Cloud Architect – and other responsibilities all conspired to slow Ooloi's momentum. I won't bore you with excuses – sometimes one simply must pause to change course, and I really needed to devote all time and mind space to finding what I hope is my final employment. Now that I've secured a great position with HiQ in Stockholm, I can return to Ooloi with full force. Where We StandDespite the public quiet, work has continued, albeit at a more measured pace. The foundational architecture – that robust, high-performance platform for ACID-compliant transactions – remains solid. I've made incremental improvements to the core API, particularly in how it handles complex musical structures through our vector path descriptor (VPD) system. The polymorphic API is now fully mature, offering a consistent interface whether used internally in the backend or remotely by the frontend. This uniformity will prove invaluable both for our own development and for future JVM plugin creators, who'll benefit from the significant abstraction it provides. File persistence using Nippy has been fully implemented, creating a solid foundation for saving and loading pieces. This might seem a mundane milestone, but anyone who's worked with complex software knows that solid persistence mechanisms are like plumbing – unglamorous but absolutely essential, and you certainly notice when they're missing. File persistence, like high-quality printing, should be implemented early in the development cycle as they can be devilishly difficult to just tack on later. They also provide an acid test for the whole architecture. A Bit of ReflectionFive months of relative silence offers time to think. Perhaps there's value in stepping back from the constant pressure to show visible output. In such moments, the architecture is refined not through frantic coding but through careful consideration. The journey from Igor Engraver to Ooloi spans decades, and a few months of slower progress hardly register on such a timescale. What matters is that the vision remains clear and the foundation solid. After all, the whole purpose of the Ooloi project is not to "disrupt the market". Like Octavia Butler's ooloi aliens, we're neither aggressive nor competitive. What is important, however, is doing this right using modern tools. The idea is to create an architecture and a platform that'll last and that musicians and publishers will want to use. It's also to provide a powerful environment that can be easily extended through any JVM language. Ooloi has a tight, lean and efficient core, organically and seamlessly augmented by a flora of plugins for any vertical. This would include jazz, early music, tablature, etc - but also commercial plugins to support things like virtual instruments, extremely intelligent playback, or perhaps GenAI used for musical purposes. The idea is to shift the initiative to the users, not to a central committee trying to anticipate user needs. Ooloi is designed for flexibility and efficiency. Uniting these two aspects sucessfully requires careful architectural design. (And a language like Clojure for the core and the JVM for the plugins.) Community BuildingWith the core architecture stabilising, I'm thinking more about community. Ooloi is intended as an open-source project, a collaborative effort that will benefit from diverse perspectives and expertise. The extensive documentation work completed earlier – including the architecture decision records, READMEs, and technical specifications – was not merely for my benefit. It prepares the ground for future collaborators, creating a clear map of the territory for those who will join us. The website, this blog, and the growing collection of documentation all serve as beacons for those who might be interested in contributing. They signal our commitment to transparency and proper communication – essential ingredients for any successful open-source project. Looking ForwardSo what comes next? The gRPC layer for communication between frontend and backend remains a priority. This is the bridge that will allow the beautiful architecture we've built to manifest in a usable form for musicians and composers. Following that, the initial frontend work – that "Hello World" window that will serve as proof of concept – beckons. While the backend architecture is undoubtedly important, it's through the frontend that users will experience Ooloi. Getting this right is crucial. The SMuFL integration for standard music font layout continues to progress, ensuring that Ooloi will render beautiful notation with consistency across platforms. Challenges and OpportunitiesEvery project faces challenges, and Ooloi is no exception. Time constraints remain the most significant hurdle, as this is still predominantly a one-person effort with limited hours available. There's also the natural tension between getting it right and getting it done. The perfectionist tendency can be both a blessing and a curse in software development. While it drives us towards excellence, it can also delay progress if not properly balanced. The task here is to create a platform for music processing and notation. This balance has to be exactly right so that contributors can treat Ooloi like a music notation OS rather than just a bunch of API endpoints. I think the balance is right; it's looking very promising. Yet within these challenges lie opportunities. The time spent refining the architecture will pay dividends in the long run, creating a more solid foundation for future development. A Call to Potential CollaboratorsAs Ooloi progresses toward its eventual public release, I'm increasingly aware of the need for collaborators. If you're a Clojure programmer with an interest in music notation, or a musician with programming skills, your perspective could be invaluable. While we're not yet at the point of opening the repository – though a "soft release" isn't out of the question – I welcome conversations with those who might be interested in contributing once we do. The journey from FrankenScore to Ooloi – from private project to open-source collaboration – will be richer for having diverse voices involved from the early stages. Closing ThoughtsFive months of comparative quiet doesn't mean I've abandoned ship; it simply reflects the natural ebb and flow of a project undertaken alongside life's other commitments. Ooloi continues to grow, perhaps not as swiftly as in those heady initial weeks, but with steady purpose nonetheless.
I'm reminded of how musical compositions themselves develop – sometimes in great creative bursts, other times through careful refinement of existing material. Both approaches have their place. To those following Ooloi's progress, thank you for your patience. The work continues, and updates will come more regularly as we approach the milestone of public release. The vision of a modern, efficient, and elegant music notation system – one built on sound architectural principles and open to community collaboration – remains as compelling as ever. Until next time (which will be considerably less than five months hence), / Peter
![]() An Architecture Decision Record (ADR) is a point-in-time document that records architectural decisions and the reasoning behind them. And since communicating architectural ideas clearly to collaborators is extra important in open-source, I've just added a bunch of ADRs to the Documentation page. They cover various aspects of the FrankenScore architecture, from high-level design decisions to specific technical choices. They are:
In the past weeks, I've been focused on FrankenScore's core architecture. I'm not rushing to open-source this; instead, I'm taking my time to craft a solid platform that will do the heavy lifting for future users and collaborators. All the complexities involving data representation and manipulation in a multi-threaded environment must be solved so collaborators can concentrate on the essentials. Clojure is ideal here, just as Common Lisp was the clear choice for Igor Engraver back in 1996.
Key developments: 1. The API is now fully polymorphic and can be used in the same way internally in the backend as in the frontend. There is a system of pointerless vector path descriptors (VPDs) implemented for this purpose that all API operations can accept as part of their polymorphic setup. I wouldn't be surprised if core collaborators will use the API for internal purposes as well, as it is highly efficient and exposes the underlying functionality in an abstract, domain-specific way. There should be little need to go directly to the underlying data structures, at least not for speed - and certainly not for expressivity. This also bodes well for plugin development in other languages than Clojure, which is an important feature. 2. This beast is fast. Clojure's STM facilities ensure high-speed ACID-compliant transactions with automatic retries. They are also composable. This means that plugins can bombard the backend with hundreds of thousands of mutation requests, for instance to implement MusicXML, with the same efficiency as the pure Clojure backend. 3. Piece Manager Implementation: There's now a Piece Manager, providing functions for storing, retrieving, and resolving pieces from IDs. This allows for multiple clients to work simultaneously on the same piece in a distributed arrangement. The FrankenScore backend can run in the cloud with multiple people collaborating on the same piece. Multiple pieces can be open simultaneously to allow copy-and-paste operations between them. My next steps involve implementing file persistence (saving and opening music files), as well as tackling printing. These are foundational features, not mere add-ons. Persistence forces a clear definition of the data model and enables easier testing. Printing isn't just about output; it's about representation and serves as a sanity check on the entire system design. Both will likely inform further refinements of the core architecture, potentially revealing oversights or opportunities for optimisation. Additionally, sequencing is a crucial part of the core platform. And by sequencing I mean support for converting musical representations to timed sound events - though not necessarily via MIDI; a software synth may use direct means of control, for instance. The core sequencer can be used by plugins to generate MIDI, or to input MIDI, but the actual MIDI implementation will be done in the plugin layer. But that's a whole blog post of its own. |
AuthorPeter Bengtson –composer, organist, programmer, cloud architect. Currently windsurfing through parentheses. Archives
July 2025
Categories
All
|
|
Ooloi is a modern, open-source music notation software designed to handle complex musical scores with ease. It is designed to be a flexible and powerful music notation software tool providing professional, high-quality results. The core functionality includes inputting music notation, formatting scores and their parts, and printing them. Additional features can be added as plugins, allowing for a modular and customizable user experience.
|