[1] This is in contrast with some older object oriented extensions of Lisp that allow each object to function as a (proto)type for a new one.

[2] Consider the choice of this type of primitive musical object here as an arbitrary one, we just need one such object in our examples. Later we will show the mechanisms to extend the simple note concept implemented here.

[3] A MIDI key number between 0 and 127, counting in semitones, with 60 defined as middle-C. A table of MIDI key numbers can be found in ??. [to do: Make a picture of keyboard + pitchnames + midi numbers) add ref in footnote]

[4] Later we will provide it with some more elaborate syntax.

[5] In the object-oriented style so called methods are used instead of functions. But that will be explained later.

[6] A proposal for similar constructs ,called Sim and Seq, can be found in the composition language Nyquist Dannenberg (1993)

, and in other formal languages for representing music, like (Balaban, 1992)

, where they are notated as | and -.

[7] Later we will add a class that allows the specification of individual start times of its components.

[8] The play commands will be illustrated in common music notation for readers who have no access to the software that accompanies this book.

[9] In our scores in common music notation we will only use sharp signs, even where the fragment induces a key and another notation would be easier to read.

[10] Or hole if it were a true pianola roll.

[11] Apart from using the Yamaha convention that C3 is middle-C is 60.

[12] An interesting extension would be to allow for key specific transpositions. What extra information would you need then, and where would you allocate it?

[13] To prevent the system from complaining that an ordinary function is redefined as a generic one, we can first remove the old function definition with fmakunbound.

[14] As an exercise, try to think of other attributes for rests?

[15] This makes the outside of the program look more like a functional program, so beware!

[16] Which cannot really be assumed to know that a rest can be transposed without knowing the transposition interval.

[17] Specific removal of individual methods is possible as well, as will be demonstrated later.

[18] Note that these dynamic changes of class definitions are handled correctly by the system without recompilation of other parts. Even existing objects are updated to reflect the changed definitions of their class.

[19] Knowledge is a great word for such mundane procedures, but whenever real-world complex processing is being designed, it is a great help to be able to position the different procedures at their own niche in the inheritance hierarchy, reflecting the assumptions they make, and the requirements they pose for their arguments. The discipline to use these possibilities even for the cases that look simple at first sight, distinguishes a good object oriented programmer from an ordinary one.

[20] Instead of showing musical objects here, we could even have the system play them. Although that might be great for intended results, it is not clear whether it would make error messages easier to understand.

[21] We have to remember though, that we have to adapt the copy- object methods when we add or remove slots from these objects. The (eval (show object)), that will be shown in a moment, provides an automatic alternative.

[22] However, the example shows neatly how easily Lisp code is assembled and run in Lisp itself, and delegating the main work of copying to show means that we only have to maintain a good show method when class definitions change. However, it should also be considered a trick: the use of eval in programs is discouraged because, e.g., it forces stand-alone applications, created from the program, to incorporate the complete code of the compiler. Furthermore, if the expression contains free variables, the meaning of evaluating it is difficult to formalize.

[23] Re-constructing the structuture of existing pieces of music procedurally, is an attractive method in teaching music theory classes, pioneered by Bamberger Bamberger (??)


[24] Programs that yield more exciting patterns, but still induce a meter percept, are a good area for experimentation.

[25] A low tolerance for complexity is considered an asset!

[26] You might remember our earlier remark on the use of type predicates in code as a sign of not using the object oriented style to its full extend. And indeed, the use of stringp in mirror method for pitches signals such a situation. We will come back to this in section 3.2: object oriented II using multi-methods.

[27] It has to be guaranteed that the macro expands into code that evaluates arguments only once and in the correct order.

[28] Which is the end of a small detour that had nothing to do with CLOS, but gave us a definition of the mirror function for notes that no-one can call complex anymore.

[29] Later we will see how consistency can be maintained in updating the information stored in a slot with setf.

[30] If the system can do it, the programmer must be able to do it too

[31] The use of the name "setf method" might be a bit confusing because Common Lisp has, apart from Clos, a construct called setf method for storing data in generalized variables (with associated functions defsetf and define- setf- method).

[32] This is a still a worst-case estimate, which does not take into account that during a rest a voice may be allocated elsewhere (static allocation).

[33] We wrote it here using the :lisp loop

construct: try witing it with mapc.

[34] It would be a good exercise to try to write it now.

[35] It is a nontrivial problem to define a neat consistent set of time and tempo transformations that can be combined easily. Another exercise for the interested reader.

[36] It is only possible to create a recursor like find- musical- object- onset directly, by supplying an iterator like find- element- onset with itself as functional argument, when the argument order of the predicate expected by find- element- onset (object followed by onset), is the same as the argument order of find- musical- object- onset itself.