2.3.8. Patterns
Patterns sind Objekte, die Daten nach bestimmten Ordnungsregeln sequentiell generieren. Pattern können aus jeder Art von Lisp Daten bestehen und -wie Prozesse- verschachtelt werden. Es existieren verschiedene Patternklassen, die im Common Music Directory unter Patterns aufgelistet sind.
Wie andere Objekte in Common Music werden Pattern mit der Funktion new
instantiiert.
2.3.8.1. Cycle
Die folgende Funktion definiert ein cycle
Pattern mit den Elementen '(2 1 3 4) und bindet dieses Pattern an das Symbol *testpattern*
.
(defparameter *testpattern* (new cycle :of '(2 1 3 4)))
Daten werden mit der Funktion next
generiert. Wenn die Funktion kein Argument hat, wird pro Funktionsaufruf genau ein Wert gemäß den Regeln des Patterns generiert. Ein cycle
Pattern hat die Eigenschaft, dass die einzelnen Elemente zyklisch ausgelesen werden.
(next *testpattern*) ;; -> 2 (next *testpattern*) ;; -> 1 (next *testpattern*) ;; -> 3 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 2 (next *testpattern*) ;; -> 1 (next *testpattern*) ;; -> 3 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 2
Wird der Funktion next
als 2. Argument der Wahrheitswert T
übergeben, wird eine komplette Periode bis zum Ende der aktuellen Periode als Liste zurückgegeben.
(next *testpattern* t) ;; -> (2 1 3 4) (next *testpattern* t) ;; -> (2 1 3 4) (next *testpattern* t) ;; -> (2 1 3 4)
Eine Zahl als 2. Argument von next
gibt die Anzahl der zu generierenden Daten an:
(next *testpattern* 100) ;; -> (2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 ;; 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 ;; 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4 2 1 3 4)
Pattern sind grundsätzlich unendlich, d.h. die Funktion next
gibt immer einen Wert aus.
2.3.8.2. Line
Das 'line' Pattern gibt die definierten Elemente der Reihe nach aus. Nach der Ausgabe des letzten Elementes der Reihe, springt das Pattern aber nicht an den Anfang zurück, wie bei einem 'cycle', sondern das letzte Element wird (beliebig oft) wiederholt:
(defparameter *testpattern* (new line :of '(2 1 3 4))) (next *testpattern*) ;; -> 2 (next *testpattern*) ;; -> 1 (next *testpattern*) ;; -> 3 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 4 (next *testpattern*) ;; -> 4
2.3.8.3. Weighting
Für das Generieren von Zufallszahlen existiert die Patternklasse 'weighting'. Wenn in dem Pattern lediglich Elemente aufgeführt werden, so werden Zufallsfolgen mit gleicher Gewichtung der Elemente erzeugt.
(next (new weighting :of '(1 2 3 4)) 20) (3 2 2 4 4 4 2 2 2 3 2 3 1 3 3 3 1 2 1 4)
Um die Elemente zu gewichten, verwendet man an Stelle der Elemente Listen, deren ersten Position das Element und im Rest der Liste das Keywort :weight
und das relative Gewicht dieses Elementes aufgeführt wird. Der Defaultwert für :weight
ist 1. Im folgenden Ausdruck erscheint also die 1 im Durchschnitt doppelt so häufig, wie die anderen Elemente des Pattern.
(next (new weighting :of '((1 :weight 2) 2 3 4)) 20) ;; -> (4 1 1 1 1 2 1 2 2 3 3 4 2 3 3 2 2 1 4 2)
Das Keyworte :max
und :min
beziehen sich auf die Anzahl direkter Wiederholung eines Elementes aus einer Zufallsfolge:
(next (new weighting :of '((1 :max 1) (2 :min 2) 3 4)) 20) ;; -> (3 4 2 2 3 3 4 1 3 4 4 3 1 3 3 1 2 2 4 2) ;;; Zufallsfolge mit gleicher Gewichtung aller Elemente ohne direkte ;;; Wiederholung eines Elements: (next (new weighting :of '((1 :max 1) (2 :max 1) (3 :max 1) (4 :max 1))) 20) ;; -> (3 2 3 4 3 1 4 2 1 4 1 3 1 3 4 2 1 4 1 2)
2.3.8.4. Heap
Ein Heap ist ein Pattern, bei dem in jeder Periode sämtliche Elemente des Patterns in einer Zufallsreihenfolge erscheinen. Auf diese Weise ist gewährleistet, dass innerhalb einer Periode jedes Element genau einmal erscheint.
(next (new heap :of '(1 2 3 4)) 40) ;; -> (2 4 3 1 ;; 1 2 3 4 ;; 1 3 4 2 ;; 3 2 4 1 ;; 1 3 4 2 ;; 3 4 1 2 ;; 1 2 3 4 ;; 4 1 3 2 ;; 1 2 4 3 ;; 4 2 3 1)
2.3.8.5. Verschachtelte Pattern
Patterns lassen sich wie Prozesse verschachteln und ermöglichen dadurch die Realisation sehr komplexer Datenströme.
;;; Verschachteltes Pattern (next (new cycle :of (list (new cycle :of '(a b c d e) :for (new cycle :of '(1 2 3 4 3 2))) (new cycle :of '(1 2 3 4) :for (new cycle of '(4 3 2 1))))) 40) ;; -> (a ;; 1 2 3 4 ;; b c ;; 1 2 3 ;; d e a ;; 4 1 ;; b c d e ;; 2 ;; a b c ;; 3 4 1 2 ;; d e ;; 3 4 1 ;; a ;; 2 3 ;; b c ;; 4 ;; d e)
2.3.8.6. Thunk
Die Patternklasse 'thunk' verwendet eine Funktion ohne Argumente, die bei einem Aufruf eine komplette Periode von Daten als Liste zurückgeben muss. Auf diese Weise ist es möglich, in einem verschachtelten Pattern bei jeder neuen Periode wieder mit dem Phrasenbeginn zu starten.
(next (let ((phrase '(dies ist ein test)) (phrasenlaengen (new cycle :of '(1 2 3 4 3 2)))) (new thunk :of (lambda () (next (new cycle of phrase :for (next phrasenlaengen)) t)))) 40) ;; -> (dies ;; dies ist ;; dies ist ein ;; dies ist ein test ;; dies ist ein ;; dies ist ;; dies ;; dies ist ;; dies ist ein ;; dies ist ein test ;; dies ist ein ;; dies ist ;; dies ;; dies ist ;; dies ist ein ;; dies ist ein test)