@c -*- coding: utf-8; mode: texinfo; documentlanguage: de -*-

@ignore
    Translation of GIT committish: e5a609e373eae846857f9a6d70a402a3d42b7d94

    When revising a translation, copy the HEAD committish of the
    version that you are working on.  For details, see the Contributors'
    Guide, node Updating translation committishes..
@end ignore

@c \version "2.19.22"

@node Scheme-Tutorium
@chapter Scheme-Tutorium
@translationof Scheme tutorial


@cindex Scheme
@cindex GUILE
@cindex Scheme, in einer LilyPond-Datei
@cindex LISP
@cindex Auswertung von Scheme-Code

LilyPond verwendet die Scheme-Programmiersprache sowohl als Teil
der Eingabesyntax als auch als internen Mechanismus, um Programmmodule
zusammenzufügen.  Dieser Abschnitt ist ein sehr kurzer Überblick über
die Dateneingabe mit Scheme.  Wenn Sie mehr über Scheme wissen wollen,
gehen Sie zu @uref{https://@/www@/.schemers@/.org}.

LilyPond benutzt die GNU Guile-Implementation von Scheme, die auf dem
@qq{R5RS}-Standard von Scheme basiert.  Wenn Sie Scheme lernen wollen,
um es innerhalb von LilyPond zu benutzen, wird es nicht empfohlen,
mit einer anderen Implementation (die sich auf einen anderen
Standard bezieht) zu arbeiten.  Information zu Guile findet sich
unter @uref{https://www.gnu.org/software/guile/}.  Der
@qq{R5RS}-Standard von Scheme befindet sich unter der Adresse
@uref{https://www.schemers.org/Documents/Standards/R5RS/}.


@menu
* Einleitung in Scheme::
* Scheme in LilyPond::
* Komplizierte Funktionen erstellen::
@end menu

@node Einleitung in Scheme
@section Einleitung in Scheme
@translationof Introduction to Scheme

Wir wollen mit einer Einführung in Scheme beginnen.  Für diese kurze Einführung
soll der GUILE-Interpreter genommen werden, um zu erforschen, wie die Sprache
funktioniert.  Nach besserer Bekanntschaft mit Scheme soll gezeigt werden, wie
die Sprache in LilyPond-Dateien eingefügt werden kann.

@menu
* Scheme-Sandkasten::
* Scheme-Variablen::
* Einfache Scheme-Datentypen::
* Zusammengesetzte Scheme-Datentypen::
* Berechnungen in Scheme::
* Scheme-Prozeduren::
* Scheme-Konditionale::
@end menu

@node Scheme-Sandkasten
@subsection Scheme-Sandkasten
@translationof Scheme sandbox

Die LilyPond-Installation enthält gleichzeitig auch die
Guile-Implementation von Scheme.  Auf den meisten Systemen kann
man in einer Scheme-sandbox experimentieren, indem man ein
Kommandozeilen-Fenster öffnet und @code{guile} aufruft.  Unter
einigen Systemen, insbesondere unter Windows, muss man evtl.
die Umgebungsvariable @code{GUILE_LOAD_PATH} auf das Verzeichnis
@code{../usr/share/guile/1.8} innerhalb des LilyPond-Installationsverzeichnisses
setzen (der vollständige Pfad ist erklärt in @rlearning{Mehr Information}).
Alternativ können Windows-Benutzer auch einfach @qq{Ausführen} im
Startmenü wählen und @code{guile} schreiben.

Es gibt auch eine direkte Scheme-Umgebung mit allen LilyPond-Voreinstellungen,
die man auf der Kommandozeile mit folgendem Befehl aufrufen kann:

@example
lilypond scheme-sandbox
@end example

@noindent
Wenn guile einmal läuft, erhält man die Eingabeaufforderung von guile:

@lisp
guile>
@end lisp

Man kann Scheme-Ausdrucke hier eingeben und mit Scheme experimentieren.
Siehe die Datei @file{ly/scheme-sandbox.ly} zu Information, wie man
die GNU readline-Bibliothek benutzen kann, um bessere Scheme-Formatierung
der Kommandozeile zu erhalten.  Wenn die readline-Bibliothek für interaktive
Guile-Sitzungen außerhalb von LilyPond schon aktiviert ist, sollte es auch
in der Sandbox funktionieren.


@node Scheme-Variablen
@subsection Scheme-Variablen
@translationof Scheme variables

Scheme-Variablen können jeglichen gültigen Scheme-Wert erhalten, auch
Scheme-Prozeduren.

Scheme-Variablen werden mit @code{define} definiert:

@lisp
guile> (define a 2)
guile>
@end lisp

Scheme-Variablen können an der Guile-Eingabeaufforderung ausgewertet werden,
indem man einfach die Variable eintippt.

@lisp
guile> a
2
guile>
@end lisp

Scheme-Variablen können auf dem Bildschirm ausgegeben werden, indem man
@code{display} zum Anzeigen benutzt:

@lisp
guile> (display a)
2guile>
@end lisp

Sowohl der Wert @code{2} als auch die Eingabeaufforderung @code{guile}
werden auf der gleichen Zeile ausgegeben.  Das kann man vermeiden, indem
man eine @code{newline}-Prozedur für eine Leerzeile aufruft oder das
Zeichen für eine neue Zeile anzeigen lässt:

@lisp
guile> (display a)(newline)
2
guile> (display a)(display "\n")
2
guile>
@end lisp

Wenn eine Variable einmal erstellt wurde, kann ihr Wert durch @code{set!}
verändert werden:

@lisp
guile> (set! a 12345)
guile> a
12345
guile>
@end lisp

@node Einfache Scheme-Datentypen
@subsection Einfache Scheme-Datentypen
@translationof Scheme simple data types

Das Grundlegendste an einer Sprache sind Daten: Zahlen, Zeichen,
Zeichenketten, Listen usw.  Hier ist eine Liste der Datentypen, die für
LilyPond-Eingabedateien relevant sind.

@table @asis
@item Boolesche Variablen
Werte einer Booleschen Variable sind Wahr oder Falsch. Die Scheme-Entsprechung
für Wahr ist @code{#t} und für Falsch @code{#f}.
@funindex ##t
@funindex ##f

@item Zahlen
Zahlen werden wie üblich eingegeben, @code{1} ist die (ganze)
Zahl Eins, während @w{@code{-1.5}} eine Gleitkommazahl (also
eine nicht-ganze) ist.

@item Zeichenketten
Zeichenketten werden in doppelte Anführungszeichen gesetzt:

@example
"Das ist eine Zeichenkette"
@end example

Zeichenketten können über mehrere Zeilen reichen:

@example
"Das
ist
eine Zeichenkette"
@end example

@noindent
und die Zeichen für eine neue Zeile am Ende jeder Zeile werden auch
in die Zeichenkette aufgenommen.

Zeichen für eine neue Zeile können auch hinzugefügt werden, indem man
@code{\n} in die Zeichenkette aufnimmt.

@example
"das\nist eine\nmehrzeilige Zeichenkette"
@end example

Anführungszeichen und neue Zeilen können auch mit sogenannten
Fluchtsequenzen eingefügt werden. Die Zeichenkette
@code{a sagt "b"} wird wie folgt eingegeben:

@example
"a sagt \"b\""
@end example

@end table

Weitere zusätzliche Scheme-Datentypen, die hier nicht besprochen wurden,
finden sich in einer vollständigen Liste der Scheme-Datentypen in der
Guile-Referenzanleitung:
@uref{http://www.gnu.org/software/guile/manual/html_node/Simple-Data-Types.html}.


@node Zusammengesetzte Scheme-Datentypen
@subsection Zusammengesetzte Scheme-Datentypen
@translationof Scheme compound data types

Es gibt auch zusammengesetzte Datentypen in Scheme.  Die Datentypen, die in
LilyPond häufig benutzt werden, beinhalten Paare, Listen, assoziative Listen
und Hash-Tabellen.

@subheading Paare (pair)

Der wichtigste zusammengesetzte Datentyp in Scheme ist ein Paar (@code{pair}).
Wie aus dem Namen schon hervorgeht, besteht ein Paar aus zwei zusammengeschweißten
Werten.  Die Prozedur um ein Paar zu erstellen ist @code{cons}.

@lisp
guile> (cons 4 5)
(4 . 5)
guile>
@end lisp

Das Paar wird dargestellt als zwei Elemente, von Klammern umgeben
und durch Leerzeichen und einen Punkt (@code{.}) getrennt.  Der Punkt ist
@emph{kein} Dezimalpunkt, sondern markiert die Gruppe als Paar.

Paare können auch wörtlich eingegeben werden, indem man ihnen voraus ein
einfaches Anführungszeichen (@code{'} setzt.

@lisp
guile> '(4 . 5)
(4 . 5)
guile>
@end lisp

Beide Elemente eines Paares können beliebige gültige Scheme-Werte sein:

@lisp
guile> (cons #t #f)
(#t . #f)
guile> '("blah-blah" . 3.1415926535)
("blah-blah" . 3.1415926535)
guile>
@end lisp

Das erste Element eines Paares kann mit der Prozedur @code{car},
das zweite mit der Prozedur @code{cdr} angesprochen werden.

@lisp
guile> (define mypair (cons 123 "hello there")
... )
guile> (car mypair)
123
guile> (cdr mypair)
"hello there"
guile>
@end lisp

@noindent

Achtung:  @code{cdr} wird ausgesprochen wie "kudd-err", nach Sussman und
Abelson, siehe
@uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}

@subheading Listen (list)

Ein sehr häufiger Datentyp in Scheme ist die Liste (@emph{list}).  Formal
gesehen wird eine Liste entweder als leere Liste definiert
(repräsentiert als @code{'()}), oder als ein Paar, dessen @code{cdr}
eine Liste ist.

Es gibt viele Arten, Listen zu erstellen.  Die vielleicht häufigste Methode
ist die @code{list}-Prozedur:

@lisp
guile> (list 1 2 3 "abc" 17.5)
(1 2 3 "abc" 17.5)
@end lisp

Wie man sehen kann, wird eine Liste dargestellt in Form der einzelnen
Elemente, getrennt durch ein Leerzeichen und als Gruppe in Klammern eingeschlossen.
Anders als bei einem Paar, befindet sich kein Punkt zwischen den Elementen.

Eine Liste kann auch als wörtliche Liste notiert werden, indem man die
enthaltenen Elemente in Klammern einschließt und ein einfaches Anführungszeichen
voranschreibt:

@lisp
guile> '(17 23 "foo" "bar" "bazzle")
(17 23 "foo" "bar" "bazzle")
@end lisp

Listen haben eine zentrale Stellung in Scheme.  Scheme wird als Dialekt
von Lisp angesehen, und das Wort @qq{lisp} steht für @qq{List Processing}.
Scheme-Ausdrücke sind immer Listen.

@subheading Assoziative Listen (alist)

Eine besonderer Listentyp ist die @emph{assoziative Liste} oder @emph{alist}.
Eine Alist wird benutzt, um Daten zum einfachen Abrufen zu speichern.

Alisten sind Listen, deren Elemente als Paare kommen.  Der @code{car}-Teil
jedes Elements wird als @emph{Schlüssel} (key) bezeichnet, der
@code{cdr}-Teil jedes Elements wird @emph{Wert} (value) genannt.
Die Scheme-Prozedur @code{assoc} wird benutzt, um einen Eintrag aus einer
Aliste aufzurufen, und mit @code{cdr} wird sein Wert abgefragt:

@lisp
guile> (define my-alist '((1  . "A") (2 . "B") (3 . "C")))
guile> my-alist
((1 . "A") (2 . "B") (3 . "C"))
guile> (assoc 2 my-alist)
(2 . "B")
guile> (cdr (assoc 2 my-alist))
"B"
guile>
@end lisp

Alisten werden sehr viel in LilyPond genutzt, um Eigenschaften und
andere Daten zu speichern.

@subheading Hash-Tabellen (hash table)

Eine Datenstruktur, die ab und zu in LilyPond eingesetzt wird.
Eine Hash-Tabelle ähnelt einem Array, aber die Indexe des Arrays
können beliebige Scheme-Werte sein, nicht nur Integre.

Hash-Tabellen sind effizienter als Alisten, wenn man viele Daten
speichern will und die Daten sich oft ändern.

Die Syntax, mit der Hash-Tabellen erstellt werden, ist etwas komplex,
aber man kann Beispiele hierzu im LilyPond-Quellcode finden.

@lisp
guile> (define h (make-hash-table 10))
guile> h
#<hash-table 0/31>
guile> (hashq-set! h 'key1 "val1")
"val1"
guile> (hashq-set! h 'key2 "val2")
"val2"
guile> (hashq-set! h 3 "val3")
"val3"
@end lisp

Werte werden aus den Hash-Tabellen mit @code{hashq-ref} ausgelesen.

@lisp
guile> (hashq-ref h 3)
"val3"
guile> (hashq-ref h 'key2)
"val2"
guile>
@end lisp

Schlüssel und Werte werden als Paar mit @code{hashq-get-handle} ausgelesen.
Das ist die beste Art, weil hier @code{#f} ausgegeben wird, wenn ein
Schlüssel nicht gefunden werden kann.

@lisp
guile> (hashq-get-handle h 'key1)
(key1 . "val1")
guile> (hashq-get-handle h 'frob)
#f
guile>
@end lisp


@node Berechnungen in Scheme
@subsection Berechnungen in Scheme
@translationof Calculations in Scheme

@ignore
We have been using lists all along.  A calculation, like @code{(+ 1 2)}
is also a list (containing the symbol @code{+} and the numbers 1
and@tie{}2).  Normally lists are interpreted as calculations, and the
Scheme interpreter substitutes the outcome of the calculation.  To enter a
list, we stop the evaluation.  This is done by quoting the list with a
quote @code{'} symbol.  So, for calculations do not use a quote.

Inside a quoted list or pair, there is no need to quote anymore.  The
following is a pair of symbols, a list of symbols and a list of lists
respectively,

@example
#'(stem . head)
#'(staff clef key-signature)
#'((1) (2))
@end example
@end ignore

Scheme kann verwendet werden, um Berechnungen durchzuführen. Es
verwendet eine @emph{Präfix}-Syntax. Um 1 und@tie{}2 zu addieren, muss
man @code{(+ 1 2)} schreiben, und nicht @math{1+2}, wie in traditioneller
Mathematik.

@lisp
guile> (+ 1 2)
3
@end lisp

Berechnungen können geschachtelt werden und das Ergebnis einer Berechnung
kann für eine neue Berechnung eingesetzt werden.

@lisp
guile> (+ 1 (* 3 4))
13
@end lisp

Diese Berechnungen sind Beispiele von Auswertungen. Ein Ausdruck
wie @code{(* 3 4)} wird durch seinen Wert @code{12} ersetzt.

Scheme-Berechnungen können zwischen Integren und Nicht-Integren
unterscheiden.  Integre Berechnungen sind exakt, während Nicht-Integre
nach den passenden Genauigkeitseinschränkungen berechnet werden:

@lisp
guile> (/ 7 3)
7/3
guile> (/ 7.0 3.0)
2.33333333333333
@end lisp

Wenn der Scheme-Berechner einen Ausdruck antrifft, der eine Liste darstellt,
wird das erste Element der Liste als Prozedur behandelt, die mit
Argumenten des Restes der Liste ausgewertet werden.  Darum sind alle
Operatoren in Scheme vorangestellt.

Wenn das erste Element eines Scheme-Ausdrucks, der eine Liste darstellt,
@emph{kein} Operator oder keine Prozedur ist, gibt es einen Fehler:

@lisp
guile> (1 2 3)

Backtrace:
In current input:
  52: 0* [1 2 3]

<unnamed port>:52:1: In expression (1 2 3):
<unnamed port>:52:1: Wrong type to apply: 1
ABORT: (misc-error)
guile>
@end lisp

Hier kann man sehen, dass Scheme versucht hat, 1 als einen Operator oder
eine Prozedur zu behandeln, was aber nicht möglich war.  Darum der Fehler
"Wrong type to apply: 1".

Wenn man also eine Liste erstellen will, braucht man also einen Listen-Operator
oder man muss die Liste als wörtliches Zitat schreiben, sodass Scheme sie
nicht auszuwerten versucht.

@lisp
guile> (list 1 2 3)
(1 2 3)
guile> '(1 2 3)
(1 2 3)
guile>
@end lisp

Dieser Fehler kann durchaus vorkommen, wenn man Scheme unter LilyPond
einsetzt.

@ignore
The same assignment can be done in completely in Scheme as well,

@example
#(define twentyFour (* 2 twelve))
@end example

@c this next section is confusing -- need to rewrite

The @emph{name} of a variable is also an expression, similar to a
number or a string.  It is entered as

@example
#'twentyFour
@end example

@funindex #'symbol
@cindex quoting in Scheme

The quote mark @code{'} prevents the Scheme interpreter from substituting
@code{24} for the @code{twentyFour}.  Instead, we get the name
@code{twentyFour}.
@end ignore


@node Scheme-Prozeduren
@subsection Scheme-Prozeduren
@translationof Scheme procedures

Scheme-Prozeduren sind ausführbare Scheme-Ausdrücke, die einen
Wert ausgeben, der das Resultat ihrer Ausführung darstellt.  Sie können
auch Variablen verändern, die außerhalb dieser Prozedur definiert wurden.

@subheading Prozeduren definieren

Prozeduren werden in Scheme mit @code{define} definiert:

@example
(define (function-name arg1 arg2 ... argn)
 scheme-expression-that-gives-a-return-value)
@end example

Beispielsweise könnte man eine Prozedur definieren, die den Durchschnitt
berechnet:

@lisp
guile> (define (average x y) (/ (+ x y) 2))
guile> average
#<procedure average (x y)>
@end lisp

Wenn die Prozedur einmal definiert ist, wird sie aufgerufen indem man
die Prozedur und die Argumente in eine Liste schreibt.  Man könnte also den
Durchschnitt von 3 und 12 berechnen:

@lisp
guile> (average 3 12)
15/2
@end lisp

@subheading Prädikate

Scheme-Prozeduren, die Boolesche Werte ausgeben, werden oft als Prädikate
(predicate) bezeichnet.  Es herrscht die Übereinkunft, Prädikat-Bezeichnungen
mit einem Fragezeichen abzuschließen:

@lisp
guile> (define (less-than-ten? x) (< x 10))
guile> (less-than-ten? 9)
#t
guile> (less-than-ten? 15)
#f
@end lisp

@subheading Wiedergabe-Werte

Scheme-Prozeduren geben immer einen Wiedergabe-Wert (return value) aus, welcher
der Wert des letzten Ausdrucks ist, der in der Prozedur ausgeführt wurde.  Der
Wiedergabewert kann ein beliebiger gültiger Scheme-Wert sein, auch eine
komplexe Datenstruktur oder eine Prozedur.

Manchmal würden Benutzer gerne mehrere Scheme-Ausdrucke in einer Prozedur haben.
Es gibt zwei Arten, wie mehrere Ausdrücke kombiniert werden können.  Die erste
Art ist die @code{begin}-Prozedur, der es ermöglicht, dass mehrere Ausdrücke
ausgewertet werden und den Wert des letzten Ausdrucks wiedergibt.

@lisp
guile> (begin (+ 1 2) (- 5 8) (* 2 2))
4
@end lisp

Die andere Art, mehrere Ausdrücke zu kombinieren, ist eine @code{let}-Umgebung.
In dieser Umgebung wird eine Serie von Verbindungen erstellt, und dann wird eine
Sequenz von Ausdrücken ausgewertet, die diese Bindungen einschließen können.
Der Wiedergabewert der let-Umgebung ist der Wiedergabewert der letzten Aussage
in der let-Umgebung:

@lisp
guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
... (+ (* x y) (/ z x)))
508
@end lisp


@node Scheme-Konditionale
@subsection Scheme-Konditionale
@translationof Scheme conditionals

@subheading if

Scheme hat eine @code{if}-Prozedur:

@example
(if test-expression true-expression false-expression)
@end example

@var{test-expression} ist ein Ausdruck, der einen Booleschen
Wert zurück gibt.  Wenn @var{test-expression} den Wert @code{#t}
ausgibt, gibt die if-Prozedur den Wert von @var{true-expression} aus,
in allen anderen Fällen den Wert von @var{false-expression}.

@lisp
guile> (define a 3)
guile> (define b 5)
guile> (if (> a b) "a is greater than b" "a is not greater than b")
"a is not greater than b"
@end lisp

@subheading cond

Eine andere konditionale Prozedur in Scheme ist
@code{cond}:

@example
(cond (test-expression-1 result-expression-sequence-1)
      (test-expression-2 result-expression-sequence-2)
      ...
      (test-expression-n result-expression-sequence-n))
@end example

Beispielsweise:

@lisp
guile> (define a 6)
guile> (define b 8)
guile> (cond ((< a b) "a is less than b")
...          ((= a b) "a equals b")
...          ((> a b) "a is greater than b"))
"a is less than b"
@end lisp



@node Scheme in LilyPond
@section Scheme in LilyPond
@translationof Scheme in LilyPond

@menu
* LilyPond Scheme-Syntax::
* LilyPond-Variablen::
* Eingabe-Variablen und Scheme::
* Scheme in LilyPond importieren::
* Objekteigenschaften::
* Zusammengesetzte LilyPond-Variablen::
* Interne musikalische Repräsentation::
@end menu

@node LilyPond Scheme-Syntax
@subsection LilyPond Scheme-Syntax
@translationof LilyPond Scheme syntax

@funindex $
@funindex #

Der Guile-Auswerter ist ein Teil von LilyPond, sodass Scheme also auch in
normale LilyPond-Eingabedateien eingefügt werden kann.  Es gibt mehrere
Methoden, um Scheme in LilyPond zu integrieren.

Die einfachste Weise ist es, ein Rautenzeichen@tie{}@code{#} vor einem
Scheme-Ausdruck zu benutzen.

Die Eingabe von LilyPond ist in Zeichen und Ausdrücke gegliedert, so etwa
wie die menschliche Sprache sich in Wörter und Sätze gliedert.  LilyPond
hat einen Lexer, der Zeichen erkennt (Zahlen, Zeichenketten, Scheme-Elemente,
Tonhöhen usw.) und einen Parser, der die Syntax versteht,
@rcontribnamed{LilyPond grammar, LilyPond-Grammatik}.
Wenn dann eine bestimmte Syntaxregel als zuständig erkannt wurde, werden die
damit verknüpften Aktionen ausgeführt.

Die Rautenzeichenmethode (@code{#}), mit der Scheme eingebettet werden kann,
passt sehr gut in dieses System.  Wenn der Lexer ein Rautenzeichen sieht, ruft
er den Scheme-reader auf, um den ganzen Scheme-Ausdruck zu lesen (das kann eine
Variable, ein Ausdruck in Klammern oder verschiedene andere Sachen sein).  Nachdem
der Scheme-Ausdruck gelesen wurde, wird er als Wert eines @code{SCM_TOKEN} in der
Grammatik gespeichert.  Wenn der Parser weiß, wie er diesen Wert benutzen kann,
ruft er Guile auf, um den Scheme-Ausdruck auszuwerten.  Weil der Parser normalerweise
dem Lexer etwas voraus sein muss, ist die Trennung von Lesen und Auswerten zwischen
Lexer und Parser genau das richtige, um die Auswertung von LilyPond- und
Scheme-Ausdrücken synchron zu halten.  Aus diesem Grund sollte das Rautenzeichen
zum Einbinden von Scheme immer benutzt werden, wenn es möglich ist.

Eine andere Möglichkeit, Scheme aufzurufen, ist die Benutzung des Dollarzeichens
(@code{$}) anstelle der Raute.  In diesem Fall wertet LilyPond den Code sofort
aus, nachdem der Lexer ihn gelesen hat.  Dabei wird der resultierende
Scheme-Ausdruckstyp geprüft und eine Tokentyp dafür ausgesucht (einer von mehreren
@code{xxx_IDENTIFIER} in der Syntax).  Wenn der Wert des Ausdrucks gültig ist
(der Guilde-Wert für @code{*unspecified*}), dann wird nichts an den Parser
übergeben.

Das ist auch der gleiche Mechanismus, nach dem LilyPond funktioniert, wenn man eine Variable oder musikalische Funktion mit ihrer Bezeichnung ausruft, wie
in @code{\Bezeichnung}, mit dem einzigen Unterschied, dass ihre Bezeichnung durch den
LilyPond-Lexer bestimmt wird, ohne den Scheme-reader einzubeziehen, und also
nur Variablen akzeptiert werden, die im aktuellen LilyPond-Modus gültig sind.

Die direkte Auswirkung von @code{$} kann zu Überraschungen führen, siehe
@ref{Eingabe-Variablen und Scheme}.  Es bietet sich daher an, @code{#} immer
zu benützen, wenn der Parser es unterstützt.  Innerhalb von musikalischen
Ausdrücken werden Ausdrücke, die mit @code{#} erstellt werden, @emph{tatsächlich}
als Noten interpretiert.  Sie werden jedoch @emph{nicht} vor der Benutzung
kopiert.  Wenn Sie Teil einer Struktur sind, die noch einmal benutzt werden
soll, muss man eventuell @code{ly:music-deep-copy} explizit einsetzen.

@funindex $@@
@funindex #@@

Es gibt auch die Operatoren @code{$@@} und @code{#@@}, die eine @qq{listentrennende}
Funktion aufweisen, indem sie alle Elemente einer Liste in den umgebenden
Kontext einfügen.

Jetzt wollen wir uns tatsächlichen Scheme-Code anschauen.  Scheme-Prozeduren
können in LilyPond-Eingabedateien definiert werden:

@example
#(define (average a b c) (/ (+ a b c) 3))
@end example

LilyPond-Kommentare (@code{%} oder @code{%@{ %@}}) können innerhalb
von Scheme-Code nicht benutzt werden, nicht einmal in einer LilyPond-Eingabedatei,
weil der Guile-Interpreter und nicht der LilyPond-Parser den Scheme-Ausdruck
liest.  Kommentare in Guile Scheme werden wie folgt notiert:

@example
; Einzeiliges Kommentar

#!
  Guile-Stil Blockkommentar (nicht schachtelbar)
  Diese Kommentare werden von Scheme-Programmierern
  selten benutzt und nie im Quellcode
  von LilyPond
!#
@end example

Für den Rest dieses Abschnitts soll angenommen werden, dass die Daten in
einer LilyPond-Eingabedatei notiert werden sollen, sodass immer@tie{}@code{#}
vor die Scheme-Ausdrücke gestellt wird.

Alle Scheme-Ausdrücke auf oberster Ebene in einer LilyPond-Eingabedatei
können in einen einzigen Scheme-Ausdruck zusammengefasst werden mit
@code{begin}:

@example
#(begin
  (define foo 0)
  (define bar 1))
@end example


@node LilyPond-Variablen
@subsection LilyPond-Variablen
@translationof LilyPond variables

LilyPond-Variablen werden intern als Scheme-Variablen gespeichert. Darum
ist

@example
Zwoelf = 12
@end example

@noindent
das Gleiche wie

@example
#(define Zwoelf 12)
@end example

Das bedeutet, dass Scheme-Ausdrücke auf LilyPond-Variablen zugreifen können.
Man könnte also schreiben:

@example
Vierundzwanzig = #(* 2 Zwoelf)
@end example

@noindent
was zur Folge hätte, dass die Zahl 24 in der LilyPond (und Scheme-)Variablen
@code{Vierundzwanzig} gespeichert wird.

Üblicherweise greift man auf LilyPond-Variablen zu, indem man ihnen einen
Backslash voranstellt. Siehe auch @ref{LilyPond Scheme-Syntax}, also etwa
@code{\Vierundzwanzig}.  Weil dadurch eine Kopie des Wertes für die meisten
von LilyPonds internen Typen erstellt wird (insbesondere musikalische Funktionen),
erstellen musikalische Funktionen normalerweise Kopien von Material, das sie
verändern.  Aus diesem Grund sollten musikalische Funktionen, die mit @code{#}
aufgerufen werden, kein Material enthalten, dass entweder von Grund auf neu
erstellt wird oder explizit kopiert wird, sondern besser direkt auf das relevante
Material verweisen.


@node Eingabe-Variablen und Scheme
@subsection Eingabe-Variablen und Scheme
@translationof Input variables and Scheme

Das Eingabeformat unterstützt die Notation von Variablen: Im folgenden
Beispiel wird ein musikalischer Ausdruck einer Variablen mit der
Bezeichnung @code{traLaLa} zugewiesen:

@example
traLaLa = @{ c'4 d'4 @}
@end example

Variablen haben beschränkte Geltungsbereiche: im unten stehenden Beispiel
enthält auch die @code{\layout}-Umgebung eine @code{traLaLa}-Variable,
die sich aber von der @code{traLaLa}-Variable auf oberster Ebene unterscheidet:

@example
traLaLa = @{ c'4 d'4 @}
\layout @{ traLaLa = 1.0 @}
@end example

Jede Eingabedatei ist solch ein Gültigkeitsbereich, und alle
@code{\header}-, @code{\midi}- und @code{\layout}-Umgebungen
sind Gültigkeitsbereiche, die in diesen obersten Gültigkeitsbereich
eingebettet sind.

Sowohl Variablen als auch Gültigkeitsbereiche sind im Guile Modulsystem
eingebaut.  Ein anonymes Scheme-Modul wird jedem Gültigkeitsbereich
angehängt.  Eine Zuweisen in der Form von

@example
traLaLa = @{ c'4 d'4 @}
@end example

@noindent
wird intern in die Scheme-Definition

@example
(define traLaLa @var{Scheme-Wert von `... '})
@end example

@noindent
konvertiert.

Das bedeutet, dass LilyPond-Variablen und Scheme-Variablen frei gemischt
werden können.  Im folgenden Beispiel wird ein Notenfragment in der
Variable @code{traLaLa} gespeichert und mit Scheme dupliziert.  Das
Resultat wird in eine @code{\score}-Umgebung mit einer weiteren
Variable @code{twice} importiert:

@lilypond[verbatim]
traLaLa = { c'4 d'4 }

#(define newLa (map ly:music-deep-copy
  (list traLaLa traLaLa)))
#(define twice
  (make-sequential-music newLa))

\twice
@end lilypond

Das ist ein interessantes Beispiel.  Die Zuweisung findet erst statt,
nachdem der Parser sichergestellt hat, dass nichts folgt, das Ähnlichkeit
mit @code{\addlyrics} hat, sodass er prüfen muss, was als nächstes kommt.
Er liest @code{#} und den darauf folgenden Scheme-Ausdruck, @emph{ohne} ihn
auszuwerten, so dass er weiterlesen und erst @emph{danach}
wird der Scheme-Code ohne Probleme ausführen kann.


@node Scheme in LilyPond importieren
@subsection Scheme in LilyPond importieren
@translationof Importing Scheme in LilyPond

@funindex $
@funindex #

Das Beispiel zeigt, wie man musikalische Ausdrücke aus der Eingabe in den
Scheme-Auswerter @qq{exportieren} kann.  Es geht auch andersherum.  Indem
man Scheme-Werte nach @code{$} schreibt, wird ein
Scheme-Wert interpretiert, als ob er in LilyPond-Syntax eingeben wäre.
Anstatt @code{\twice} zu definieren, könne man also auch schreiben:

@example
...
$(make-sequential-music newLa)
@end example

Mann kann @code{$} zusammen mit einem Scheme-Ausdruck überall benutzen,
wo auch @code{\@var{Bezeichnung}} gültig wäre, nachdem der Scheme-Ausdruck
einmal einer Variable @var{Bezeichnung} zugewiesen worden ist.  Der Austausch
geschieht im Lexer, sodass LilyPond den Unterschied gar nicht merkt.

Ein negativer Effekt ist aber das Timing.  Wenn man @code{$} anstelle von
@code{#} für die Definition von @code{newLa} im obigen Beispiel eingesetzt
hätte, würde der folgende Scheme-Ausdruck fehlschlagen, weil @code{traLaLa}
noch nicht definiert worden wäre.  Zu einer Erklärung dieses Timingproblems
siehe @ref{LilyPond Scheme-Syntax}.

@funindex $@@
@funindex #@@

Eine weitere Bequemlichkeit können die @qq{listentrennenden} Operatoren
@code{$@@} und @code{#@@} bieten, indem sie die Elemente einer Liste
in den umgebenden Kontext einfügen.  Wenn man sie einsetzt, hätte der
letzte Teil des Beispiels auch so geschrieben werden können:

@example
...
@{ #@@newLa @}
@end example

Hier wird jedes Element der Liste, welche in @code{newLa} gespeichert ist,
der Reihenfolge nach genommen und in die Liste eingefügt, als ob man
geschrieben hätte:

@example
@{ #(first newLa) #(second newLa) @}
@end example

In allen diesen Formen findet die Auswertung des Scheme-Codes statt,
während die Eingabe noch gelesen wird, entweder im Lexer oder im Parser.
Wenn man es später ausgeführt haben möchte, muss man
@ref{Leere Scheme-Funktionen} benutzen oder es in einem Makro speichern:

@example
#(define (nopc)
  (ly:set-option 'point-and-click #f))

...
#(nopc)
@{ c'4 @}
@end example

@knownissues

Scheme- und LilyPond-Variablen können nicht gemischt werden, wenn man die
@option{--safe}-Option benutzt.


@node Objekteigenschaften
@subsection Objekteigenschaften
@translationof Object properties

Objekteigenschaften werden in LilyPond in Form von Alisten-Ketten
gespeichert, also als Listen von Alisten.  Eigenschaften werden
geändert, indem man Werte an den Anfang der Eigenschaftsliste
hinzufügt.  Eigenschaften werden gelesen, indem Werte aus der
Aliste gelesen werden.

Ein neuer Wert für eine Eigenschaft kann gesetzt werden, indem man
der Alist einen Wert mit Schlüssel und dem Wert zuweist.  Die
LilyPond-Syntax hierfür ist:

@example
\override Stem.thickness = #2.6
@end example

Diese Anweisung verändert die Erscheinung der Notenhälse. Der Alist-Eintrag
@code{'(thickness . 2.6)} wird zu der Eigenschaftsliste eines
@code{Stem}-(Hals-)Objektes hinzugefügt.
@code{thickness} wird relativ zu den Notenlinien errechnet, in diesem
Fall sind die Hälse also 2,6 mal so dick wie die Notenlinien.  Dadurch
werden Hälse fast zweimal so dick dargestellt, wie sie normalerweise sind.
Um zwischen Variablen zu unterscheiden, die in den Quelldateien direkt
definiert werden (wie @code{Vierundzwanzig} weiter oben), und zwischen denen,
die für interne Objekte zuständig sind, werden hier die ersteren
@qq{Variablen} genannt, die letzteren dagegen @qq{Eigenschaften}.
Das Hals-Objekt hat also eine @code{thickness}-Eigenschaft, während
@code{Vierundzwanzig} eine Variable ist.

@cindex Eigenschaften versus Bezeichner
@cindex Bezeichner versus Eigenschaften


@node Zusammengesetzte LilyPond-Variablen
@subsection Zusammengesetzte LilyPond-Variablen
@translationof LilyPond compound variables

@subheading Abstände (offset)

Zweidimensionale Abstände (X- und Y-Koordinaten) werden
als @emph{pairs} (Paare) gespeichert. Der @code{car}-Wert des
Abstands ist die X-Koordinate und der @code{cdr}-Wert die
Y-Koordinate.

@example
\override TextScript.extra-offset = #'(1 . 2)
@end example

Hierdurch wird das Paar @code{(1 . 2)} mit der Eigenschaft @code{extra-offset}
des TextScript-Objektes verknüpft. Diese Zahlen werden in
Systembreiten  gemessen, so dass der Befehl das Objekt eine Systembreite
nach rechts verschiebt und zwei Breiten nach oben.

Prozeduren, um mit Abständen zu arbeiten, finden sich in @file{scm/lily-library.scm}.

@subheading Brüche (fractions)

Brüche, wie sie LilyPond benutzt, werden wiederum als Paare gespeichert,
dieses Mal als unbezeichnete ganze Zahlen.  Während Scheme rationale Zahlen
als einen negativen Typ darstellen kann, sind musikalische gesehen
@samp{2/4} und @samp{1/2} nicht das selbe, sodass man zwischen beiden unterscheiden
können muss.  Ähnlich gibt es auch keine negativen Brüche in LilyPonds Sinn.
Somit bedeutet @code{2/4} in LilyPond  @code{(2 . 4)} in Scheme, und @code{#2/4} in
LilyPond bedeutet @code{1/2} in Scheme.

@subheading Bereiche (extend)

Paare werden auch benutzt, um Intervalle zu speichern, die einen Zahlenbereich
vom Minimum (dem @code{car}) bis zum Maximum (dem @code{cdr}) darstellen.
Intervalle werden benutzt, um die X- und Y-Ausdehnung von druckbaren
Objekten zu speichern.  Bei X-Ausdehnungen ist @code{car} die linke
X-Koordinate und @code{cdr} die rechte X-Koordinate.  Für Y-Ausdehnungen
ist @code{car} die untere Koordinate und @code{cdr} die obere Koordinate.

Prozeduren, um mit Intervallen zu arbeiten, finden sich in
@file{scm/lily-library.scm}.  Diese Prozeduren sollten benutzt, wenn es möglich
ist, um den Code konsistent zu halten.

@subheading Eigenschafts-Alisten (property alist)

Eine Eigenschafts-Aliste ist eine LilyPond-Datenstruktur, die eine Aliste
darstellt, deren Schlüssel Eigenschaften sind und deren Werte
Scheme-Ausdrücke sind, die den erwünschen Wert der Eigenschaft ausgeben.

LilyPond-Eigenschaften sind Scheme-Symbole, wie etwa @code{'thickness}
(Dicke).

@subheading Alisten-Ketten (alist chains)

Eine Alisten-Kette ist eine Liste, die Eigenschafts-Alisten enthält.

Die Menge aller Eigenschaften, die sich auf einen Grob auswirken, wird
typischerweise in einer Alisten-Kette gespeichert.  Um den Wert einer
bestimmten Eigenschaft zu finden, die ein Grob haben soll, wird jede
Liste in der Kette nach einander durchsucht, wobei nach einem Eintrag
geschaut wird, der den Eigenschaftsschlüssel enthält.  Der erste
gefundene Alisten-Eintrag wird benutzt und dessen Wert ist der
Wert der Eigenschaft.

Die Scheme-Prozedur @code{chain-assoc-get} wird normalerweise benutzt,
um Grob-Eigenschaftenwerte zu erhalten.


@node Interne musikalische Repräsentation
@subsection Interne musikalische Repräsentation
@translationof Internal music representation

Intern werden Noten als Scheme-Liste dargestellt.  Die Liste enthält
verschiedene Elemente, die die Druckausgabe beeinflussen.  Parsen
nennt man den Prozess, der die Noten aus der LilyPond-Repräsentation
in die interne Scheme-Repräsentation überführt.

Wenn ein musikalischer Ausdruck geparst wird, wird er in eine Gruppe
von Scheme-Musikobjekten konvertiert.  Die definierende Eigenschaft
eines Musikobjektes ist, dass es Zeit einnimmt.  Die Zeit, die
ein Objekt braucht, wird Dauer (engl. @emph{duration}) genannt.
Dauern werden in rationalen Zahlen ausgedrückt, die die Länge des
Musikobjekts in Ganzen Noten angeben.

Ein Musikobjekt hat drei Typen:

@itemize
@item
Musikbezeichnung (music name): Jeder Musikausdruck hat eine Bezeichnung.  Eine
Note beispielsweise erzeugt ein @rinternals{NoteEvent} und @code{\simultaneous}
produziert @rinternals{SimultaneousMusic}.  Eine Liste aller möglichen
Ausdrücke findet sich in der Referenz der Interna, unter
@rinternals{Music expressions}.

@item
Typ (type) oder Schnittstelle (interface): Jede Musikbezeichnung hat mehrere
Typen oder Schnittstellen, beispielsweise eine Note ist ein Ereignis (@code{event}),
aber auch ein Notenereignis (@code{note-event}), ein rhythmisches Ereignis
(@code{rhythmic-event}) und ein Melodieereignis (@code{melodic-event}).
Alle Musikklassen sind in der Referenz der Interna aufgelistet, unter
@rinternals{Music classes}.

@item
C++-Objekt: Jedes Musikobjekt ist durch ein Objekt der C++-Klasse @code{Music}
repräsentiert.
@end itemize

Die eigentliche Information eines musikalischen Ausdrucks wird in Eigenschaften
gespeichert.  Ein @rinternals{NoteEvent} beispielsweise hat die Eigenschaften
Tonhöhe (@code{pitch}) und Dauer (@code{duration}), die die Dauer und die
Tonhöhe der Note speichern.  Eine Liste aller möglichen Eigenschaften findet
sich in der Referenz der Interna, unter
@rinternals{Music properties}.

Ein zusammengesetzter musikalischer Ausdruck ist ein Musikobjekt, das andere
Musikobjekte als Eigenschaften enthält.  Eine Liste an Objekten kann in der
@code{elements}-Eigenschaft eines Musikobjekts bzw. ein einziges
Ableger-Musikelement in der @code{element}-Eigenschaft gespeichert werden.
@rinternals{SequentialMusic} beispielsweise hat sein einziges Argument in
@code{element}.  Der Körper einer Wiederholung wird in der @code{element}-Eigenschaft
von @rinternals{RepeatedMusic} gespeichert, und die alternativen Endungen
in @code{elements}.


@node Komplizierte Funktionen erstellen
@section Komplizierte Funktionen erstellen
@translationof Building complicated functions

Dieser Abschnitt zeigt, wie man Information zusammensucht,
um komplizierte musikalische Funktionen  zu erstellen.

@menu
* Musikalische Funktionen darstellen::
* Eigenschaften von Musikobjekten::
* Verdoppelung einer Note mit Bindebögen (Beispiel)::
* Artikulationszeichen zu Noten hinzufügen (Beispiel)::
@end menu


@node Musikalische Funktionen darstellen
@subsection Musikalische Funktionen darstellen
@translationof Displaying music expressions

@cindex interne Speicherung
@cindex Musikausdrücke anzeigen
@cindex Anzeigen von Musikausdrücken

@funindex \displayMusic

Wenn man eine musikalische Funktion erstellt, ist es oft
hilfreich sich anzuschauen, wie musikalische Funktionen
intern gespeichert werden.  Das kann mit der Funktion
@code{\displayMusic} erreicht werden:

@example
@{
  \displayMusic @{ c'4\f @}
@}
@end example

@noindent
zeigt:

@example
(make-music
  'SequentialMusic
  'elements
  (list (make-music
          'NoteEvent
          'articulations
          (list (make-music
                  'AbsoluteDynamicEvent
                  'text
                  "f"))
          'duration
          (ly:make-duration 2 0 1/1)
          'pitch
          (ly:make-pitch 0 0 0))))
@end example

Normalerweise gibt LilyPond diese Ausgabe auf der Konsole mit
allen anderen Nachrichten aus.  Um die wichtigen Nachrichten
in einer Datei zu speichern, kann die Ausgabe in eine Datei
umgeleitet werden:

@example
lilypond file.ly >display.txt
@end example

Mit LilyPond- und Scheme-Magie kann man LilyPond anweisen, genau
diese Ausgabe an eine eigene Datei zu senden:

@example
@{
  #(with-output-to-file "display.txt"
      (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
@}
@end example

Mit etwas Umformatierung ist die gleiche Information sehr viel
einfacher zu lesen:

@example
(make-music 'SequentialMusic
  'elements (list
	     (make-music 'NoteEvent
               'articulations (list
			       (make-music 'AbsoluteDynamicEvent
				 'text
				 "f"))
	       'duration (ly:make-duration 2 0 1/1)
	       'pitch    (ly:make-pitch 0 0 0))))
@end example

Eine musikalische @code{@{ ... @}}-Sequenz hat die Bezeichnung
@code{SequentialMusic} und ihre inneren Ausdrücke werden als
Liste in seiner @code{'elements}-Eigenschaft gespeichert.  Eine
Note ist als als ein @code{EventChord}-Objekt dargestellt (welches Dauer und
Tonhöhe speichert) und zusätzliche Information enthält (in
diesem Fall ein @code{AbsoluteDynamicEvent} mit einer
@code{"f"}-Text-Eigenschaft).

@funindex \void

@code{\displayMusic} gibt die Noten aus, die dargestellt werden, sodass
sie sowohl angezeigt als auch ausgewertet werden.  Um die Auswertung zu
vermeiden, kann @code{\void} vor @code{\displayMusic} geschrieben werden.


@node Eigenschaften von Musikobjekten
@subsection Eigenschaften von Musikobjekten
@translationof Music properties

TODO -- make sure we delineate between @emph{music} properties,
@emph{context} properties, and @emph{layout} properties.  These
are potentially confusing.

Schauen wir uns ein Beispiel an:

@example
someNote = c'
\displayMusic \someNote
===>
(make-music
  'NoteEvent
  'duration
  (ly:make-duration 2 0 1/1)
  'pitch
  (ly:make-pitch 0 0 0))
@end example

Das @code{NoteEvent}-Objekt ist die Repräsentation von @code{someNote}.
Einfach.  Wie fügt man denn ein c' in einen Akkorde ein?

@example
someNote = <c'>
\displayMusic \someNote
===>
(make-music
  'EventChord
  'elements
  (list (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2 0 1/1)
          'pitch
          (ly:make-pitch 0 0 0))))
@end example

Jetzt ist das @code{NoteEvent}-Objekt das erste Objekt der
@code{'elements}-Eigenschaft von @code{someNote}.

Die @code{display-scheme-music}-Funktion ist die Funktion, die von
@code{\displayMusic} eingesetzt wird, um die Scheme-Repräsentation
eines musikalischen Ausdrucks anzuzeigen.

@example
#(display-scheme-music (first (ly:music-property someNote 'elements)))
===>
(make-music
  'NoteEvent
  'duration
  (ly:make-duration 2 0 1/1)
  'pitch
  (ly:make-pitch 0 0 0))
@end example

Danach wird die Tonhöhe der Note von der @code{'pitch}-Eigenschaft
des @code{NoteEvent}-Objektes gelesen:

@example
#(display-scheme-music
   (ly:music-property (first (ly:music-property someNote 'elements))
                      'pitch))
===>
(ly:make-pitch 0 0 0)
@end example

Die Tonhöhe einer Note kann geändert werden, indem man diese
@code{'pitch}-Eigenschaft umdefiniert:

@funindex \displayLilyMusic

@example
#(set! (ly:music-property (first (ly:music-property someNote 'elements))
                          'pitch)
       (ly:make-pitch 0 1 0)) ;; Die Tonhöhen auf d' verändern.
\displayLilyMusic \someNote
===>
d'
@end example


@node Verdoppelung einer Note mit Bindebögen (Beispiel)
@subsection Verdoppelung einer Note mit Bindebögen (Beispiel)
@translationof Doubling a note with slurs (example)

In diesem Abschnitt soll gezeigt, werden, wie man eine
Funktion erstellt, die eine Eingabe wie @code{a}
nach @code{@{ a( a) @}} umdefiniert.  Dazu wird zuerst die
interne Repräsentation der Musik betrachtet, die
das Endergebnis darstellt:

@example
\displayMusic@{ a'( a') @}
===>
(make-music
  'SequentialMusic
  'elements
  (list (make-music
          'NoteEvent
          'articulations
          (list (make-music
                  'SlurEvent
                  'span-direction
                  -1))
          'duration
          (ly:make-duration 2 0 1/1)
          'pitch
          (ly:make-pitch 0 5 0))
        (make-music
          'NoteEvent
          'articulations
          (list (make-music
                  'SlurEvent
                  'span-direction
                  1))
          'duration
          (ly:make-duration 2 0 1/1)
          'pitch
          (ly:make-pitch 0 5 0))))
@end example

Eine schlechte Nachricht ist, dass die
@code{SlurEvent}-Ausdrücke @qq{innerhalb}
der Noten (in ihrer @code{articulations}-Eigenschaft) hinzugefügt werden müssen.

Jetzt folgt eine Betrachtung der Eingabe:

@example
\displayMusic a'
===>
(make-music
  'NoteEvent
  'duration
  (ly:make-duration 2 0 1/1)
  'pitch
  (ly:make-pitch 0 5 0))))
@end example

In der gewünschten Funktion muss also dieser Ausdruck
kopiert werden (sodass zwei Noten vorhanden sind, die
eine Sequenz bilden), dann müssen @code{SlurEvent}
zu der @code{'articulations}-Eigenschaft jeder Noten hinzugefügt
werden, und schließlich muss eine @code{SequentialMusic}
mit den beiden @code{EventChords} erstellt werden.  Um zu
einer Eigenschaft etwas hinzuzufügen, ist es nützlich zu wissen, dass
eine nicht gesetzte Eigenschaft als @code{'()} gelesen wird, sodass
keine speziellen Überprüfungen nötig sind, bevor ein anderes
Element vor die @code{articulations}-Eigenschaft gesetzt wird.

@example
doubleSlur = #(define-music-function (note) (ly:music?)
         "Return: @{ note ( note ) @}.
         `note' is supposed to be a single note."
         (let ((note2 (ly:music-deep-copy note)))
           (set! (ly:music-property note 'articulations)
                 (cons (make-music 'SlurEvent 'span-direction -1)
                       (ly:music-property note 'articulations)))
           (set! (ly:music-property note2 'articulations)
                 (cons (make-music 'SlurEvent 'span-direction 1)
                       (ly:music-property note2 'articulations)))
           (make-music 'SequentialMusic 'elements (list note note2))))
@end example


@node Artikulationszeichen zu Noten hinzufügen (Beispiel)
@subsection Artikulationszeichen zu Noten hinzufügen (Beispiel)
@translationof Adding articulation to notes (example)

Am einfachsten können Artikulationszeichen zu Noten
hinzugefügt werden, indem man zwei musikalische Funktionen
in einen Kontext einfügt, wie erklärt in
@ruser{Kontexte erstellen und referenzieren}.  Hier soll jetzt eine musikalische
Funktion entwickelt werden, die das vornimmt.  Daraus ergibt sich
der zusätzliche Vorteil, dass diese musikalische Funktion eingesetzt
werden kann, um eine Artikulation (wie etwa eine Fingersatzanweisung)
einer einzigen Note innerhalb eines Akkordes hinzugefügt werden
kann, was nicht möglich ist, wenn einfach unabhängige Noten ein einem
Kontext miteinander verschmolzen werden.

Eine @code{$variable} innerhalb von @code{#@{...#@}} ist das
gleiche wie die normale Befehlsform @code{\variable} in
üblicher LilyPond-Notation.  Es ist bekannt dass

@example
@{ \music -. -> @}
@end example

@noindent
in LilyPond nicht funktioniert.  Das Problem könnte vermieden
werden, indem das Artikulationszeichen an einen leeren Akkord
gehängt wird:

@example
@{ << \music <> -. -> >> @}
@end example

@noindent
aber in diesem Beispiel soll gezeigt werden, wie man das in
Scheme vornimmt.  Zunächst wird die Eingabe und die gewünschte
Ausgabe examiniert:

@example
%  Eingabe
\displayMusic c4
===>
(make-music
  'NoteEvent
  'duration
  (ly:make-duration 2 0 1/1)
  'pitch
  (ly:make-pitch -1 0 0))))
=====
%  gewünschte Ausgabe
\displayMusic c4->
===>
(make-music
  'NoteEvent
  'articulations
  (list (make-music
          'ArticulationEvent
          'articulation-type 'accent))
  'duration
  (ly:make-duration 2 0 1/1)
  'pitch
  (ly:make-pitch -1 0 0))
\displayMusic c4
===>
(make-music
  'EventChord
  'elements
  (list (make-music
          'NoteEvent
          'duration
          (ly:make-duration 2 0 1/1)
          'pitch
          (ly:make-pitch -1 0 0))))
@end example

Dabei ist zu sehen, dass eine Note (@code{c4}) als @code{NoteEvent}-Ausdruck
repräsentiert ist.  Um eine Akzent-Artikulation hinzuzufügen, muss
ein @code{ArticulationEvent}-Ausdruck zu der Elementeigenschaft @code{articulations}
des @code{NoteEvent}-Ausdrucks hinzugefügt werden.

Um diese Funktion zu bauen, wird folgendermaßen begonnen:

@example
(define (add-accent note-event)
  "Add an accent ArticulationEvent to the articulations of `note-event',
  which is supposed to be a NoteEvent expression."
  (set! (ly:music-property note-event 'articulations)
        (cons (make-music 'ArticulationEvent
                'articulation-type 'accent)
              (ly:music-property note-event 'articulations)))
  note-event)
@end example

Die erste Zeile definiert eine Funktion in Scheme: Die Bezeichnung
der Funktion ist @code{add-accent} und sie hat eine Variable
mit der Bezeichnung @code{note-event}.  In Scheme geht der Typ
einer Variable oft direkt aus der Bezeichnung hervor (das ist auch
eine gute Methode für andere Programmiersprachen).

@example
"Add an accent..."
@end example

@noindent
ist eine (englische) Beschreibung, was diese Funktion tut.  Sie ist
nicht unbedingt notwendig, aber genauso wie klare Variablen-Bezeichnungen
ist auch das eine gute Methode.

Es kann seltsam scheinen, warum das Notenereignis direkt verändert wird,
anstatt mit einer Kopie zu arbeiten (@code{ly:music-deep-copy} kann dafür
benützt werden).  Der Grund ist eine stille Übereinkunft: musikalische
Funktionen dürfen ihre Argumente verändern: sie werden entweder von
Grund auf erstellt (wie Eingabe des Benutzers) oder sind schon kopiert
(etwa Verweis auf eine Variable mit  @samp{\Bezeichnung} oder Noten aus
einem Scheme-Ausdruck @samp{$(@dots{})} sind Kopien).  Weil es uneffizient
wäre, unnötige Kopien zu erstellen, wird der Wiedergabewert einer musikalischen
Funktion @emph{nicht} kopiert.  Um sich also an die Übereinkunft zu halten,
dürfen Argumente nicht mehr als einmal benützt werden, und sie wiederzugeben
zählt als eine Benutzung.

In einem früheren Beispiel wurden Noten konstruiert, indem ein musikalisches
Argument wiederholt wurde.  In diesem Fall muss wenigstens eine Wiederholung
eine Kopie ihres Arguments sein.  Wenn es keine Kopie ist, können seltsame
Dinge passieren.  Wenn man beispielsweise @code{\relative} oder @code{\transpose}
auf die resultierenden Noten anwendet, die die gleichen Elemente mehrmals
enthalten, werden die Elemente mehrmals der @code{\relative}-Veränderung
oder Transposition unterworfen.  Wenn man sie einer musikalischen Variable
zuweist, wird dieser Fluch aufgehoben, denn der Verweis auf @samp{\Bezeichnung}
erstellt wiederum eine Kopie, die nicht die Identität der wiederholten
Elemente überträgt.

Während die Funktion oben keine musikalische Funktion ist, wird sie
normalerweise inmitten musikalischer Funktionen eingesetzt.  Darum
ist es sinnvoll, der gleichen Übereinkunft zu folgen, die für musikalische
Funktionen gelten:  Die Eingabe kann verändert worden sein, um die
Ausgabe zu produzieren, und der den Aufruf erstellt, ist verantwortlich
für die Erstellung von Kopien, wenn er immernoch die unveränderten
Argumente benötigt.  Wenn man sich LilyPonds eigene Funktionen wie etwa
@code{music-map} anschaut, sieht man, dass sie denselben Prinzipien folgen.

Aber wo waren wir?  Jetzt gibt es ein @code{note-event}, das verändert
werden kann, nicht unter Einsatz von @code{ly:music-deep-copy} sondern
aufgrund einer langen Erklärung.  Der Akzent wird zu seiner
@code{'articulations}-Liste hinzugefügt:

@example
(set! place neuer-Wert)
@end example

Was in diesem Fall @qq{gesetzt} werden soll (@qq{place}) ist die
@q{'articulations}-Eigenschaft des @code{note-event}-Ausdrucks.

@example
(ly:music-property note-event 'articulations)
@end example

@code{ly:music-property} ist die Funktion, mit der musikalische
Eigenschaften erreicht werden können (die @code{'articulations},
@code{'duration}, @code{'pitch} usw., die in der Ausgabe von
@code{\displayMusic} weiter oben angezeigt werden).  Der neue
Wert ist, was ehemals die @code{'articulations}-Eigenschaft war, mit einem
zusätzlichen Element: dem @code{ArticulationEvent}-Ausdruck,
der aus der Ausgabe von @code{\displayMusic} kopiert werden kann:

@example
(cons (make-music 'ArticulationEvent
        'articulation-type 'accent)
      (ly:music-property result-event-chord 'articulations))
@end example

@code{cons} wird benutzt, um ein Element vorne an eine Liste hinzuzufügen,
ohne dass die originale Liste verändert wird.  Das ist es, was die
Funktion tun soll:  die gleiche Liste wie vorher, aber mit dem neuen
@code{ArticulationEvent}-Ausdruck.  Die Reihenfolge innerhalb
der Elementeeigenschaft ist hier nicht relevant.

Wenn schließlich die Akzent-Artikulation zu der entsprechenden
@code{elements}-Eigenschaft hinzugefügt ist, kann
@code{note-event} ausgegeben werden, darum die letzte Zeile
der Funktion.

Jetzt wird die @code{add-accent}-Funktion in eine musikalische
Funktion umgewandelt (hierzu gehört etwas syntaktischer Zuckerguß und
eine Deklaration des Typs ihres einzigen @qq{wirklichen} Arguments:

@example
addAccent = #(define-music-function (note-event)
                                     (ly:music?)
  "Add an accent ArticulationEvent to the articulations of `note-event',
  which is supposed to be a NoteEvent expression."
  (set! (ly:music-property note-event 'articulations)
        (cons (make-music 'ArticulationEvent
                'articulation-type 'accent)
              (ly:music-property note-event 'articulations)))
  note-event)
@end example

Eine Überprüfung, dass die Funktion richtig arbeitet, geschieht
folgendermaßen:

@example
\displayMusic \addAccent c4
@end example


@ignore

@menu
* Optimierungen mit Scheme::
@end menu

@c node Optimierungen mit Scheme
@c appendixsec Optimierungen mit Scheme
@c translationof Tweaking with Scheme

Wir haben gesehen wie LilyPond-Eingabe massiv beeinflusst
werden kann, indem Befehle wie etwa
@code{\override TextScript.extra-offset = ( 1 . -1)}
benutzt werden.  Aber es wurde gezeigt, dass Scheme noch
mächtiger ist.  Eine bessere Erklärung findet sich in der@ref{Scheme-Tutorium} und in
@ruser{Schnittstellen für Programmierer}.

Scheme kann auch in einfachen @code{\override}-Befehlen
benutzt werden:

TODO Find a simple example
@c This isn't a valid example with skylining
@c It works fine without padText  -td


@lilypond[quote,verbatim,ragged-right]
padText = #(define-music-function (padding) (number?)
#{
  \once \override TextScript.padding = #padding
#})

\relative {
  c'''4^"piu mosso" b a b
  \padText #1.8
  c4^"piu mosso" d e f
  \padText #2.6
  c4^"piu mosso" fis a g
}
@end lilypond


Es kann auch benutzt werden, um Befehle zu erstellen:

@c Check this is a valid example with skylining
@c It is - 'padding still works

@lilypond[quote,verbatim,ragged-right]
tempoPadded = #(define-music-function (padding tempotext)
  (number? markup?)
#{
  \once \override Score.MetronomeMark.padding = #padding
  \tempo \markup { \bold #tempotext }
#})

\relative {
  \tempo \markup { "Low tempo" }
  c''4 d e f g1
  \tempoPadded #4.0 "High tempo"
  g4 f e d c1
}
@end lilypond

Sogar ganze Musikausdrücke können eingefügt werden:

@lilypond[quote,verbatim,ragged-right]
pattern = #(define-music-function (x y) (ly:music? ly:music?)
#{
  #x e8 a b $y b a e
#})

\relative c''{
  \pattern c8 c8\f
  \pattern {d16 dis} { ais16-> b\p }
}
@end lilypond
@end ignore

