<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.kram.nz/index.php?action=history&amp;feed=atom&amp;title=SE701%3AApril_7</id>
	<title>SE701:April 7 - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.kram.nz/index.php?action=history&amp;feed=atom&amp;title=SE701%3AApril_7"/>
	<link rel="alternate" type="text/html" href="https://wiki.kram.nz/index.php?title=SE701:April_7&amp;action=history"/>
	<updated>2026-04-30T00:19:51Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://wiki.kram.nz/index.php?title=SE701:April_7&amp;diff=12299&amp;oldid=prev</id>
		<title>Mark: 1 revision(s)</title>
		<link rel="alternate" type="text/html" href="https://wiki.kram.nz/index.php?title=SE701:April_7&amp;diff=12299&amp;oldid=prev"/>
		<updated>2008-11-03T05:27:41Z</updated>

		<summary type="html">&lt;p&gt;1 revision(s)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt; ;;; File:    music.lisp&lt;br /&gt;
 ;;; Author:  John Hamer&lt;br /&gt;
 ;;; Date:    7 April 2008&lt;br /&gt;
 ;;; Purpose: illustrate Common Lisp generic functions and classes&lt;br /&gt;
 &lt;br /&gt;
 (defclass music () ())&lt;br /&gt;
 &lt;br /&gt;
 (defgeneric duration (music))&lt;br /&gt;
 &lt;br /&gt;
 ;; A single note&lt;br /&gt;
 (defclass note (music)&lt;br /&gt;
   ((key      :initarg :key&lt;br /&gt;
 	     :initform (error &amp;quot;Must specify the note key&amp;quot;)&lt;br /&gt;
 	     :accessor note-key) ; should be :reader&lt;br /&gt;
    (duration :initarg :duration&lt;br /&gt;
 	     :initform (error &amp;quot;Must specify the note duration&amp;quot;)&lt;br /&gt;
 	     :reader duration)))&lt;br /&gt;
 &lt;br /&gt;
 (defmethod print-object ((n note) stream)&lt;br /&gt;
   (with-slots (key duration) n&lt;br /&gt;
     (setf (note-key n) 120) ; illustrating that with-slots is not a simple (let ...)&lt;br /&gt;
     (print-unreadable-object (n stream :type t)&lt;br /&gt;
       (format stream &amp;quot;~a, ~a&amp;quot; key duration))))&lt;br /&gt;
 &lt;br /&gt;
 ;; Silence&lt;br /&gt;
 (defclass musical-rest (music)&lt;br /&gt;
   ((duration :initarg :duration :initform 0 :reader duration)))&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ;; Sequential and parallel composition   &lt;br /&gt;
 (defclass music-composite (music)&lt;br /&gt;
   ((terms :initarg :terms :reader terms)))&lt;br /&gt;
 &lt;br /&gt;
 (defclass par (music-composite) ())&lt;br /&gt;
 (defclass seq (music-composite) ())&lt;br /&gt;
 &lt;br /&gt;
 (defun seq (&amp;amp;rest terms)&lt;br /&gt;
   (make-instance &amp;#039;seq :terms terms))&lt;br /&gt;
 (defun par (&amp;amp;rest terms)&lt;br /&gt;
   (make-instance &amp;#039;par :terms terms))&lt;br /&gt;
 &lt;br /&gt;
 (defmethod initialize-instance :after ((mc music-composite) &amp;amp;key)&lt;br /&gt;
   (with-slots (terms) mc&lt;br /&gt;
     (assert (every #&amp;#039;(lambda (m) (subtypep m &amp;#039;music)) terms)&lt;br /&gt;
 	    (terms)&lt;br /&gt;
 	    &amp;quot;Music-composites require a list of music: ~a&amp;quot; terms)))&lt;br /&gt;
 &lt;br /&gt;
 (defmethod print-object ((mc music-composite) stream)&lt;br /&gt;
   (print-unreadable-object (mc stream :type t)&lt;br /&gt;
     (format stream &amp;quot;~{~a~}&amp;quot; (terms mc))))&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ;; Decorators&lt;br /&gt;
 &lt;br /&gt;
 (defclass music-decorator (music)&lt;br /&gt;
   ((term :initarg :term&lt;br /&gt;
 	 :initform (error &amp;quot;Must specify the music term&amp;quot;)&lt;br /&gt;
 	 :reader term)))&lt;br /&gt;
 &lt;br /&gt;
 ;; Tempo&lt;br /&gt;
 (defclass tempo (music-decorator)&lt;br /&gt;
   ((tempo-ratio :initarg :ratio :reader tempo-ratio)))&lt;br /&gt;
 &lt;br /&gt;
 (defun tempo (m r)&lt;br /&gt;
   (make-instance &amp;#039;tempo :term m :ratio r))&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ;; Transpose&lt;br /&gt;
 (defclass trans (music-decorator)&lt;br /&gt;
   ((offset :initarg :offset :reader offset)))&lt;br /&gt;
 &lt;br /&gt;
 (defun trans (m d)&lt;br /&gt;
   (make-instance &amp;#039;trans :term m :offset d))&lt;br /&gt;
 &lt;br /&gt;
 ;; Instrument&lt;br /&gt;
 (defclass instr (music-decorator)&lt;br /&gt;
   ((instrument :initarg :instrument :reader instrument)))&lt;br /&gt;
 &lt;br /&gt;
 (defun instr (m i)&lt;br /&gt;
   (make-instance &amp;#039;instr :term m :instrument i))&lt;br /&gt;
 &lt;br /&gt;
 ;; Phrase&lt;br /&gt;
 (defclass phrase (music-decorator)&lt;br /&gt;
   ((phrasing :initarg :phrasing :reader phrasing)))&lt;br /&gt;
 &lt;br /&gt;
 (defun phrase (m p)&lt;br /&gt;
   (make-instance &amp;#039;phrase :term m :phrasing p))&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 ;; Duration of complex music pieces&lt;br /&gt;
 (defmethod duration ((m seq))&lt;br /&gt;
   (reduce #&amp;#039;+ (terms m) :key #&amp;#039;duration))&lt;br /&gt;
 (defmethod duration ((m par))&lt;br /&gt;
   (reduce #&amp;#039;max (terms m) :key #&amp;#039;duration))&lt;br /&gt;
 (defmethod duration ((m tempo))&lt;br /&gt;
   (/ (duration (term m)) (tempo-ratio m)))&lt;br /&gt;
 (defmethod duration ((m music-decorator))&lt;br /&gt;
   (duration (term m)))&lt;br /&gt;
 &lt;br /&gt;
 ;;;- Retro&lt;br /&gt;
 (defgeneric retro (music)&lt;br /&gt;
   (:documentation &amp;quot;MUSIC played backwards&amp;quot;))&lt;br /&gt;
 &lt;br /&gt;
 (defmethod retro ((m music))&lt;br /&gt;
   m)&lt;br /&gt;
 (defmethod retro ((p par))&lt;br /&gt;
   (par (mapcar #&amp;#039;retro (terms p))))&lt;br /&gt;
 (defmethod retro ((s seq))&lt;br /&gt;
   (seq (nreverse (mapcar #&amp;#039;retro (terms s)))))&lt;br /&gt;
 (defmethod retro ((m tempo))&lt;br /&gt;
   (tempo (retro (term m)) (tempo-ratio m)))&lt;br /&gt;
 (defmethod retro ((m trans))&lt;br /&gt;
   (trans (retro (term m)) (offset m)))&lt;br /&gt;
 (defmethod retro ((m instr))&lt;br /&gt;
   (instr (retro (term m)) (instrument m)))&lt;br /&gt;
 (defmethod retro ((m phrase))&lt;br /&gt;
   (phrase (retro (term m)) (phrasing m)))&lt;/div&gt;</summary>
		<author><name>Mark</name></author>
	</entry>
</feed>