Concept

Common Lisp and CLOS

Why Mora is built from generic functions, classes, and macros in a running Lisp image, and what "metaobject" means at each level of the system.

Common Lisp is not only a notation host for Mora. It supplies the working environment in which the language is developed and performed, and the Common Lisp Object System (CLOS) supplies its extension mechanisms. This page explains how those pieces divide the work and how far the resulting protocol reaches.

Lisp is the working language

Mora’s terse pattern notation is embedded in Common Lisp. Functions, variables, macros, exact ratios, objects, and generic functions are available in the same running image as the patterns. When a composition needs to become a new instrument or language feature, ordinary functions, macros, classes, generic functions, and the inspector are already available.

Mora retains a designated set of semantically operative evaluated constructs as CLOS objects, and its scheduler and tools obtain behavior through open protocols. Extending the system can mean defining another pattern class or specializing a protocol method, rather than adding another case to a central list of recognized types.

defpattern and deftransform provide concise extension routes; they are not the only routes. See Extending Mora.

Generic functions name the extension boundaries

In CLOS, a generic function can have methods specialized for different classes. Mora uses this to separate concerns such as temporal interpretation, structural observation, construction, composition policy, and shader emission.

An extension can implement the operation it actually needs. A pattern can define a temporal query strategy; an annotation can select a merge policy; a visual operator can add shader interpretation. Each is a separate operation.

Classes give strategies names and inspectable state

Functional representations can also support arbitrary-span queries and sophisticated pattern operators. Mora chooses named classes and generic operations so that representation, strategy, and state can be inspected and specialized in the running image.

Macros provide compact authoring forms

Pattern literals and channel forms use Common Lisp macros to make repeated musical actions concise. Literal contexts can interpret symbols as sample names or values, while an explicit ($ expression) escape returns to ordinary Lisp evaluation. See Pattern literals.

Macros are an authoring mechanism: a concise form does not guarantee that every source construct survives as a distinct runtime object. See What is and is not retained.

The image remains a development environment

Functions, classes, and methods can be defined while working. Studio provides a listener, object inspection, documentation, definition navigation, and remote development facilities; see Studio overview and Remote development and performance. Ordinary Lisp variables and functions can hold reusable musical and visual material instead of requiring a separate configuration language; see Scenes and reusable material.

Live redefinition has engineering limits: native graphics resources and concurrent reloads need lifecycle control.

Metaobjects are relative to a language level

Mora-level pattern objects participate in implementing the pattern language. CLOS classes, generic functions, and method objects implement that object system. Those are different levels of description.

LevelExamplesRelationship
Authored pattern program(>> (s "bd sn") (fast 2))Constructs a temporal program.
Mora’s retained implementation objectsA speed-pattern instance, events-in, applicable methodsInterpret and expose that temporal program.
CLOS implementation facilitiesClasses, generic functions, methodsSupply the metalanguage in which Mora is built.

The important distinction is the level of the protocol. CLOS implements Mora. A Mora pattern object can be a metaobject relative to the pattern language without being a CLOS class metaobject, and without Mora extending the whole CLOS metaobject protocol.

Mora opens selected parts of its pattern-language implementation through an object protocol written in CLOS. Construction helpers and transient transform objects need not all be retained to support that runtime protocol.

The protocol is deliberately bounded

SurfaceRepresentative operationsScope
Retained temporal interpretationevents-inAnswers event queries.
Structural observationpattern-children, pattern-summary, pattern-metadataSupports inspection and tools.
Tooling estimatepattern-periodEstimates visible repetition; it is not an exact metrical clock.
Open construction and compositionapply-transform, normalize-clause, apply-clause, pattern-merge-styleBuilds and combines behavior; some construction objects are transient.
Adjacent visual interpretationemit-glslApplies to the visual-operator subset, not every arbitrary pattern class.

A few of these surfaces need care:

  • pattern-period is a bounded estimate for tools. It is not an exact period and does not substitute for authored meter; see Authored meter and pacing.
  • stack polyphony is not equivalent to the historical :voice merge-policy keyword. See Pipelines and composition.
  • emit-glsl gives visual operators an adjacent shader interpretation. It applies to the visual-operator subset, not every arbitrary pattern class; see Shader composition.

Source references

Repository-relative paths in the Mora source where these mechanisms are implemented.

  • src/core/pattern.lisp
  • src/core/combinators.lisp
  • src/mini/defpattern.lisp
  • src/mini/deftransform.lisp
  • src/mini/transforms.lisp
  • src/mini/clauses.lisp

Documentation

Search the documentation

Results update as you type. Use the up and down arrow keys to choose a result and Enter to open it.