OOLOI.ORG
Menu

FRANKENSCORE

A Body Resurrected.

OVERVIEW

DOCUMENTATION

From CLOS to closure in Clojure

30/9/2024

0 Comments

 
Picture
​​When I started programming in Lisp in 1979, after reading an article in BYTE Magazine, I hardly imagined that 45 years later I'd be embarking on a new Lisp adventure. Yet here we are, with FrankenScore (to be renamed Ooloi upon open-source release) – a modern music notation software built with Clojure. It's a project that brings together all my lifelong passions: music, programming, and the pursuit of elegant solutions to complex problems.

The Path from Common Lisp to Clojure

Picture
My journey with Lisp began in an era when optimising Common Lisp compilers were cutting-edge technology. I cut my teeth implementing Common Lisp interpreters and compilers (as one did in those days), delving into the intricacies of a truly original programming language. This experience shaped my understanding of what a powerful, flexible programming language could be.

And now in 2024 I find myself in the world of Clojure, a modern Lisp dialect that runs on the Java Virtual Machine. The transition feels both familiar and novel. Clojure's emphasis on immutability and its handling of concurrency through Software Transactional Memory (STM) aligns with the functional programming principles I've long appreciated in Lisp.

But it's not just about the language. The ecosystem around Clojure – the JVM, the interoperability with Java libraries, the rich set of tools and frameworks – provides a robust foundation that we could only dream of back in the Common Lisp days.

​CLOS Thinking in a Clojure World

Picture
One of the more interesting aspects of this transition has been adapting CLOS-style thinking to Clojure's more data-centric approach. CLOS, with its powerful multiple inheritance and method combination features, encouraged a certain way of modelling problems. In FrankenScore, I've found myself reaching for these familiar patterns, but implementing them in Clojure's more functional style.

For instance, the use of Clojure's protocols and multimethods, combined with hierarchies and the Methodical library, allows us to achieve CLOS-like polymorphism. It's a different approach, but one that feels natural once you embrace Clojure's philosophy.

Clojure's deliberate avoidance of traditional object-oriented features felt immediately familiar and refreshing. It resonates with CLOS's approach, which many, including myself, have long regarded as transcending traditional OOP. Composition over inheritance, a principle I always valued even in the CLOS days, is not just a best practice in Clojure but the very fabric of its design philosophy. This alignment between CLOS's advanced features and Clojure's functional paradigm makes the transition feel natural and even inevitable.

​Changes in Thinking

Perhaps the most significant shift has been in embracing Clojure's emphasis on immutable data structures and pure functions. While these concepts weren't foreign in Common Lisp, they're central to Clojure's design. This shift encourages a style of programming that's inherently more thread-safe and easier to reason about – crucial for a complex application like FrankenScore.

Another major change has been adapting to Clojure's more minimalist standard library compared to Common Lisp. This has led to a greater appreciation for carefully chosen, interoperable libraries and a more modular design approach.

Similarities

Despite the differences, there are of course similarities in the overall approach. The emphasis on interactive development, the power of macros for domain-specific languages and the elimination of boilerplate code, plus the satisfaction of working in a dynamic, expressive language – these are all as present in my Clojure work as they were in my Common Lisp days.

Moreover, the focus on solving complex problems through abstraction and composition remains. Whether it's CLOS or Clojure, the goal is still to create systems that are powerful, flexible, and pleasant to work with.
Picture

Closing Thoughts

This journey from Common Lisp to Clojure, from Igor Engraver to FrankenScore/Ooloi, is both challenging and rewarding. It's a testament to the enduring power of Lisp's ideas and the continued evolution of programming languages.

As I continue to develop FrankenScore, I'm captivated by the possibilities that Clojure and its ecosystem offer. While creating a powerful music notation software is the immediate goal, the project's scope extends far beyond that. It's an exploration of the synergies between music, technology, and open-source collaboration – a playground where these elements intersect and interact in novel ways.

To those considering a similar journey, I'd say: embrace the change, but don't forget the lessons of the past. The parentheses may look familiar, but the world inside them is ever-evolving.
0 Comments

Ghosts of Competitions Past

16/9/2024

0 Comments

 
Picture
A recent question in the Clojurians Slack channel caught me off guard when I was asked to compare FrankenScore to Sibelius. This request for a direct comparison not only made me pause but also brought back memories of Igor Engraver's rivalry with Sibelius – a competition that once saw Sibelius's own CEO defect to our side. However, that was a long time ago. Now, as FrankenScore carries forward Igor's legacy, I was challenged to articulate our unique value proposition in this new era.

​Here's how I responded:


NN:
Hey, that looks promising! What are the advantages it will have compared to Sibelius?

Peter Bengtson:
Wow, that's actually a pretty multi-faceted question. While we're still in development and can't yet offer a feature-by-feature comparison with Sibelius, I can highlight some key advantages we're aiming for:
​
  1. Open-source: FrankenScore will be open-source, allowing for community-driven development and customisation. This should enable faster evolution and adaptation to user needs.
  2. Modern architecture: Built with Clojure, it leverages functional programming paradigms that offer benefits in areas like concurrency and data processing. This leads to better performance, especially for complex scores. FrankenScore is explicitly designed to support very large scores.
  3. Truly cross-platform: Frankenscore will run on Mac, Windows, and Linux.
  4. User experience focus: We're recreating the intuitive interface and multi-modal input mode that Igor Engraver was well known for (and which Sibelius partly copied – unsuccessfully – after Igor's demise). This allows a musician to input music easily and very quickly just like with pen and paper, without switching between tools. The result is an enhanced creative process that flows naturally, rather than one hindered by arbitrary technological barriers.
  5. Extensible plugin system: FrankenScore consists of a small, highly efficient core, augmented with plugins. It will support both open-source and commercial closed-source plugins, written in any JVM language. Plugins run on the same terms as the core and are an important and integral part of the architecture, not an afterthought. The API is highly abstract and takes care of all the low-level details such as transactions and thread-safety so that plugin developers can concentrate on functionality. Writing plugins for FrankenScore should be a doddle.
  6. Full SMuFL font support: Unlike Sibelius, FrankenScore makes full use of the capabilities of SMuFL music fonts.
  7. Collaborative features: We're exploring real-time collaboration possibilities to enhance how musicians work together on scores. This is possible since FrankenScore uses a server/client architecture.

​Importantly, as an open-source project, FrankenScore will be free to use. Many music departments struggle with excessive license costs.
​
For those interested in more details, ooloi.org contains a wealth of information about the project, its goals, and its technical underpinnings.
0 Comments

Booooring, Franz?

10/9/2024

0 Comments

 
Picture
No, documentation doesn't have to be boring. Well, it can of course be a soul-numbing, Kafkaesque exercise, but then, can't everything?

In an open-source project, good documentation is a must; everything needs to be explained and discussed properly for the benefit of all interested, and particularly for collaborators.

And not writing documentation in a group endeavour will land you in precisely the situation Josef K enjoyed so very much. Even in agile Prozesse – it's a myth that agile discourages documentation. It's all about the appropriate level. But then, isn't it always?

Ultimately, writing – and reading – documentation is all about the proper conservation of energy. It's just a question of finding the point where the curves intersect.

Anyway, here are a few additions to the Documentation section you might like. Feel free to evaluate them as lazily as you wish:

Architecture Decision Log
  • Now expanded with a bunch of additional ADRs.

Backend src README
  • Read all about it! Well, perhaps not all about it, but at least about the backend architecture, code organisation, principles, conventions, and of course the general programming paradigm.

Development Plan
  • Quod factum est, quod fit, quod fiet.
​
​License
  • Mozilla Public License (MPL) 2.0, with a couple of small twists.

Code of Conduct
  • Our Code of Conduct. Because not having one is being naive.
0 Comments

Architectural Decision Records (45 rpm)

2/9/2024

0 Comments

 
Picture
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:
​
  • ADR-0000: Choice of Clojure as the Primary Programming Language
  • ADR-0001: Separation of Frontend and Backend into Distinct Clojure Applications
  • ADR-0002: Adoption of gRPC for Communication Between Frontend and Backend
  • ADR-0003: Integration of Plugins as a Core Architectural Component
  • ADR-0004: Implementation of Software Transactional Memory (STM) for Concurrency
  • ADR-0005: Selection of JavaFX and Skija for the Frontend GUI
  • ADR-0006: Adoption of SMuFL (Standard Music Font Layout) for Music Notation
  • ADR-0007: Implementation of Nippy for File Persistence
  • ADR-0008: Implementation of Vector Path Descriptors (VPDs)
  • ADR-0009: Implementation of Real-Time Collaborative Features

0 Comments

FrankenScore Update: Working on the Foundations

1/9/2024

0 Comments

 
Picture
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.
0 Comments

Ooloi? Oi? Ooloi? WTF?

10/8/2024

0 Comments

 
Picture
​FrankenScore is our current working title. It's fitting for now, as I'm essentially stitching together old ideas with new ones in a highly charged electrical atmosphere somewhere in a metaphorical Transsylvania. But as the project progresses, it's clear this isn't just resurrecting or recombining; it's the creation of something rather different.

When we go open-source, the project will become Ooloi.

For those unfamiliar with Octavia Butler's work, the Ooloi are alien beings with a knack for genetic manipulation and transformation. It's a decent metaphor for what we're doing: taking the DNA of music notation software and turning it into something new. 

This future name change isn't mere whimsy. Where FrankenScore suggests our current closed-source phase of experimentation, Ooloi represents what comes next. It's organic, sci-fi, modern, mind-bending. A bit like the software itself, one hopes.

Ooloi is also just a good name. It's odd, memorable, and stands out in a field not exactly known for its naming creativity. 

So, there it is. When this project eventually emerges from its closed development, it'll do so as Ooloi. A name that, with any luck, will suit the software it represents.

The metamorphosis is coming. Eventually.

Picture
0 Comments

Road Map

8/8/2024

0 Comments

 
Picture
FrankenScore is still private. There is a number of things that need to be in place before the project can go public and I can start inviting collaborators, so let's touch a little on names, releases and versions.

At this stage I'm finalising the robust, high-performance platform for ACID-compliant transactions which forms the basis of everything in FrankenScore and is manifested through the backend API.

FrankenScore becomes Ooloi when released as open source. But the first release doesn't need to be Ooloi 1.0, which by definition would be feature-complete. In fact, it should be Ooloi 0.n with an n as low as possible, meaning it's best to go public as early as possible, yet feature-complete enough so Ooloi's promise is immediately apparent.

Here's a very rough project plan:
  1. Finalise the API (nearly done)
  2. Implement File Persistence using Fressian (saving and loading pieces)
  3. Implement gRPC Layer and Event Handling (for communication between the backend and the frontend)
  4. Create Initial Frontend with Hello World Window (proof of concept)
  5. Implement printing in the frontend client (of the Hello World Window)
  6. Implement enough of the frontend/backend interaction so that a score can be set up and simple elements can be entered and manipulated. This is an complex. multi-step process that also involves setting up event handling in the frontend. It's the basis for everything that is to come and must be rock solid.
  7. Implement measure reformatting locally for measures according to a simple linear method that will be upgraded later
  8. Implement backend reformatting and reflow of measures over systems and pages
  9. Iteratively add more notational elements and features until Ooloi 0.n can be released, meaning that the project is released as open source.
  10. After the release, adding more notational elements continues in parallel with the remaining points:
  11. Implementation of a more advanced measure formatting algorithm
  12. Implementation of the plugin system.
  13. Implementation of an open source plugin for simple MIDI in- and output.
  14. Implementation of an open source plugin for reading and writing MusicXML files.
  15. When all notational elements are supported, Ooloi 1.0 can be released.

​So, point 9 represents the point where the project goes public and Ooloi 0.n appears. It remains to be seen how feature-complete the notation must be to confidently take that step.

However. There might of course be room for collaborators in the project before the public release as open source, as there are points in the above list that cover isolated features that could be delegated to an experienced Clojure programmer. Hmm. Let's think about that.
0 Comments

Why resurrect Igor Engraver now?

7/8/2024

2 Comments

 
Picture
Twenty-five years ago, I embarked on a journey to revolutionise music notation software with Igor Engraver. Today, I'm resurrecting that spirit with FrankenScore. But why now? Why breathe new life into a project that's been dormant for a quarter-century?

A Vision Deferred

Igor Engraver was always meant to be freeware, a tool for musicians and composers to express their creativity without financial barriers. Commercial considerations, however, steered us away from that vision. Now, with FrankenScore, we're returning to those roots by embracing open-source development. This aligns with my original intentions and the spirit of accessibility that drove Igor Engraver's creation.

The Tech Landscape: Then and Now

Back in '96, when Igor Engraver was born, the technological landscape was vastly different:
  • OS X hadn't been released
  • Most computers were single-core
  • Software was largely platform-specific
  • Clojure, our chosen language for FrankenScore, didn't exist

Today, we have multi-core processors, cross-platform development tools, and languages like Clojure that offer powerful abstractions and concurrent programming models. These advancements allow us to build FrankenScore as a more robust, efficient, and flexible tool than was possible with Igor Engraver.

The State of Music Notation Software

Igor Engraver was conceived because the available options at the time – Finale (as user-friendly as a cactus) and Sibelius (marginally better) – weren't up to the task. They fell short in usability, flexibility, and output quality.

I hated using Finale (and I've written an entire opera in it). Instead of enhancing your creativity – which, at the end of the day, is what a music processor should do – Finale and all other similar programs hampered your creativity.

Surprisingly, a quarter-century later, the field hasn't progressed as much as you might expect. While there have been improvements – some of them clearly inspired by Igor Engraver! – there's still a significant gap between what's available and what's possible.

Why FrankenScore, Why Now?

The time is ripe for FrankenScore, and I can't help but feel a sense of excitement and purpose. We're at a unique intersection of technological readiness and persistent unmet needs in the music notation world. The tools and platforms available to us now make it possible to build something truly revolutionary – a modern, efficient, and cross-platform solution that was merely a dream when Igor Engraver was conceived.

What strikes me is how, despite the passage of time, the music notation software landscape still leaves much to be desired, especially in terms of usability and flexibility. It's both frustrating and motivating. But here's the kicker – we now have this thriving open-source ecosystem at our fingertips. It's the perfect environment for collaborative development and continuous improvement, something I could only have wished for back in the day.

There's also a personal element to this timing. I feel a renewed focus, unburdened by the commercial constraints that ultimately derailed Igor Engraver. We can, as a community, now pour our energy into creating the best possible tool for musicians and composers, staying true to the original vision of accessibility and innovation. And you know what? Those years weren't wasted. The experiences from Igor Engraver – our successes, our setbacks, the lessons learned – they're all invaluable insights that we're bringing to FrankenScore's development. It's like we're picking up where we left off, but with 25 years of additional wisdom and technological advancements in our toolkit.

FrankenScore isn't just a revival; it's a reimagining. We're taking the core ideas that made Igor Engraver revolutionary and implementing them with modern technology and development practices. Our goal is to create a music notation tool that's not just incrementally better, but fundamentally transforms how musicians interact with notation software.

We're excited to embark on this journey, and we invite you – musicians, developers, and enthusiasts – to join us in shaping the future of music notation software. Together, let's bring Igor Engraver's vision to life in FrankenScore.

Picture

(Oh, and by the way, FrankenScore is just a pre-release working name. When we open the repo, make it open source and invite collaborators to participate, we will switch to Ooloi, just like the domain you're on right now. I'll explain the reasons in a later blog posting.)

2 Comments

Working with AI

6/8/2024

1 Comment

 
Picture
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:
  1. Analyse and describe the project,
  2. Converse about architectural choices,
  3. Assist with project planning and open-source strategies,​
  4. Judge how well the project embodies best Clojure practices,
  5. Generate, with guidance, Clojure code and tests, and
  6. Produce meaningful documentation and READMEs.

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.

1 Comment

Elegant weapons for a more civilised age

1/8/2024

0 Comments

 
Picture
​As I windsurf through parentheses on my holiday, reviving the spirit of Igor Engraver in the form of FrankenScore, I'm struck by a profound realisation: this is how programming should always feel. Free. Uplifting. Intellectually stimulating. A far cry from being shackled to the oars of enterprise galleys, with some middle manager shouting "ATTACK SPEED!" at bewildered code monkeys.

But why should this freedom be a holiday exception? As programmers (not "developers," please!), we should be grounded in computer science thinking. We need to regularly return to these ancient founts of wisdom, like Lisp, and apply their lessons to our everyday work. Otherwise, we're just highly paid button-pushers in a digital sweatshop.

Remember when computer science curricula started with Scheme? It wasn't about the language; it was about learning to think algorithmically. Then Oracle, in its infinite wisdom (read: hunger for "cannon fodder"), saw Scheme replaced by Java Enterprise. And thus began the great shitshow that's lasted for decades.

Yet, for all its faults, we must tip our hats to Java for gifting us the JVM. And here's where Clojure enters, marrying Lisp's elegance with the JVM's robustness and interoperability. It's like finding out your eccentric uncle and strait-laced aunt had a brilliant love child. But thanks to the JVM, your weird uncle can now fit into the enterprise world. 

Diving into Clojure led me to Rich Hickey's talks. The man veers into philosophical territory faster than a Silicon Valley startup pivots to blockchain. He ponders things like what names are, and why we use them - essential musings for any first-class programmer. It reminds me of my friend Niklas Derouche, architect and coder extraordinaire, who insists you must read Derrida to be a proper architect. Because nothing says "I understand this codebase" like a healthy dose of deconstruction theory. And he is right. Make no mistake.

In three weeks of holiday hacking, I've made more progress and felt more fulfilled than in months of enterprise work. It's a stark reminder of what's possible when we shed unnecessary constraints and return to first principles.

So, fellow coders, I challenge you: When was the last time you felt truly free in your programming? Perhaps it's time we all took a holiday to rediscover the Lisp arts. Who knows, you might just find your programming parentheses - I mean, paradigms - shifted.

​
P.S. If you're about to comment that 'modern' languages and frameworks are just as good, save your breath. I'd sooner believe in the tooth fairy than in the supposed superiority of JavaScript or the 'agility' of SAFe.

P.P.S. If you missed the Ben Hur reference (you uncultured git), this is sprint execution according to SAFe, with the CTO watching:
0 Comments
<<Previous

    Author

    Peter Bengtson –composer, organist, programmer, cloud architect. Currently windsurfing through parentheses.

    View my profile on LinkedIn

    Archives

    June 2025
    April 2025
    March 2025
    September 2024
    August 2024
    July 2024

    Categories

    All
    Architecture
    Clojure
    CLOS
    Common Lisp
    Documentation
    Finale
    FrankenScore
    Franz Kafka
    Functional Programming
    Generative AI
    Igor Engraver
    Jacques Derrida
    JVM
    Lisp
    Ooloi
    Python
    Rich Hickey
    Road Map
    Scheme
    Sibelius
    Site

    RSS Feed

Home
​Overview
Documentation
About
Contact
FrankenScore 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, extremely 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.​
  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Introduction for Anti-Capitalists
    • Technical Comparison
  • Documentation
    • Architectural Decision Log >
      • Choice of Clojure
      • Separation of Frontend and Backend
      • Adoption of gRPC
      • Plugins
      • STM for Concurrency
      • JavaFX & Skija
      • SMuFL
      • Nippy
      • Vector Path Descriptors
      • Collaborative Features
      • Trees and Circles
      • Shared Structure
      • Persisting Pieces
      • Slur Formatting
      • Piece Walker
    • Backend src README
    • Development Plan
    • License
    • Code of Conduct
  • About
  • Contact
  • Home
  • Overview
    • Background and History
    • Project Goals
    • Introduction for Musicians
    • Introduction for Programmers
    • Introduction for Anti-Capitalists
    • Technical Comparison
  • Documentation
    • Architectural Decision Log >
      • Choice of Clojure
      • Separation of Frontend and Backend
      • Adoption of gRPC
      • Plugins
      • STM for Concurrency
      • JavaFX & Skija
      • SMuFL
      • Nippy
      • Vector Path Descriptors
      • Collaborative Features
      • Trees and Circles
      • Shared Structure
      • Persisting Pieces
      • Slur Formatting
      • Piece Walker
    • Backend src README
    • Development Plan
    • License
    • Code of Conduct
  • About
  • Contact