]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/de/extending/scheme-tutorial.itely
resolve merge
[lilypond.git] / Documentation / de / extending / scheme-tutorial.itely
diff --git a/Documentation/de/extending/scheme-tutorial.itely b/Documentation/de/extending/scheme-tutorial.itely
new file mode 100644 (file)
index 0000000..4e1a55f
--- /dev/null
@@ -0,0 +1,1466 @@
+@c -*- coding: utf-8; mode: texinfo; documentlanguage: de -*-
+
+@ignore
+    Translation of GIT committish: 70aaf0159410169678942abd39eb13c876521437
+
+    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.14.0"
+
+@node Scheme-Übung
+@chapter Scheme-Übung
+@translationof Scheme tutorial
+
+@funindex #
+@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{http://@/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{http://www.gnu.org/software/guile/}.  Der
+@qq{R5RS}-Standard von Scheme befindet sich unter der Adresse
+@uref{http://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ürung
+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/shr/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.
+
+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.
+
+
+@node Scheme-Variablen
+@subsection Scheme-Variablen
+@translationof Scheme variables
+
+Scheme-Variablen können jedlichen 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 @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 wichtigeste 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 ausgeprochen 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 Nich-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 Boolsche 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 merhere 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::
+* Objekteigenschaften::
+* Zusammengesetzte LilyPond-Variablen::
+* Interne musikalische Repräsentation::
+@end menu
+
+@node LilyPond Scheme-Syntax
+@subsection LilyPond Scheme-Syntax
+@translationof LilyPond Scheme syntax
+
+Der Guile-Auswerter ist ein Teil von LilyPond, sodass Scheme also auch in
+normale LilyPond-Eingabedateien eingefügt werden kann.  Das Rautenzeichen
+(@code{#}) wird benutzt, um dem LilyPond-Parser mitzuteilen, dass der nächste
+Wert ein Scheme-Wert ist.
+
+Wenn der Parser eine Raute sieht, wird der Eingabe-Code an den Guile-Auswerter
+weitergereicht, der den Scheme-Ausdruck auswertet.  Der Auswerter behandelt
+die Eingabe so lange, bis er zum Ende eines Scheme-Ausdrucks kommt.
+
+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.  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 @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.
+
+
+@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 `@code{... }'})
+@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 }
+
+%% dummy action to deal with parser lookahead
+#(display "this needs to be here, sorry!")
+
+#(define newLa (map ly:music-deep-copy
+  (list traLaLa traLaLa)))
+#(define twice
+  (make-sequential-music newLa))
+
+{ \twice }
+@end lilypond
+
+In diesem Beispiel geschieht die Zuweisung, nachdem der Parser sichergestellt
+hat, dass nichts interessantes mehr nach @code{traLaLa = @{ ... @}} passiert.
+Ohne die Dummy-Aussage in dem Beispiel würde die @code{newLa}-Definition ausgeführt,
+bevor @code{traLaLa} definiert ist, was einen Syntax-Fehler hervorrufen würde.
+
+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-Werten in die Funktion @code{ly:export} einschließt, 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
+...
+@{ #(ly:export (make-sequential-music (list newLa))) @}
+@end example
+
+Scheme-Code wird sofort interpretiert, wenn der Parser darauf stößt.  Um
+Scheme-Code als Makro zu definieren (das später aufgerufen werden soll),
+muss man @ref{Leere Funktionen} benutzen oder
+
+@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
+@code{--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 @code{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 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
+@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
+          'EventChord
+          'elements
+          (list (make-music
+                  'NoteEvent
+                  'duration
+                  (ly:make-duration 2 0 1 1)
+                  'pitch
+                  (ly:make-pitch 0 0 0))
+                (make-music
+                  'AbsoluteDynamicEvent
+                  'text
+                  "f")))))
+@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 etwas Umformatierung ist die gleiche Information sehr viel
+einfacher zu lesen:
+
+@example
+(make-music 'SequentialMusic
+  'elements (list (make-music 'EventChord
+                    'elements (list (make-music 'NoteEvent
+                                      'duration (ly:make-duration 2 0 1 1)
+                                      'pitch (ly:make-pitch 0 0 0))
+                                    (make-music 'AbsoluteDynamicEvent
+                                      'text "f")))))
+@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}-Ausdruck dargestellt,
+der ein @code{NoteEvent}-Objekt (welches Dauer und
+Tonhöhe speichert) und zusätzliche Information enthält (in
+diesem Fall ein @code{AbsoluteDynamicEvent} mit einer
+@code{"f"}-Text-Eigenschaft.
+
+
+@node Eigenschaften von Musikobjekten
+@subsection Eigenschaften von Musikobjekten
+@translationof Music properties
+
+Das @code{NoteEvent}-Objekt ist das erste Objekt der
+@code{'elements}-Eigenschaft von @code{someNote}.
+
+@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
+
+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
+@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
+          'EventChord
+          'elements
+          (list (make-music
+                  'NoteEvent
+                  'duration
+                  (ly:make-duration 2 0 1 1)
+                  'pitch
+                  (ly:make-pitch 0 5 0))
+                (make-music
+                  'SlurEvent
+                  'span-direction
+                  -1)))
+        (make-music
+          'EventChord
+          'elements
+          (list (make-music
+                  'NoteEvent
+                  'duration
+                  (ly:make-duration 2 0 1 1)
+                  'pitch
+                  (ly:make-pitch 0 5 0))
+                (make-music
+                  'SlurEvent
+                  'span-direction
+                  1)))))
+@end example
+
+Eine schlechte Nachricht ist, dass die
+@code{SlurEvent}-Ausdrücke @qq{innerhalb}
+der Noten (bzw. innerhalb der
+@code{EventChord}-Ausdrücke) hinzugefügt werden müssen.
+
+Jetzt folgt eine Betrachtung der Eingabe:
+
+@example
+(make-music
+  'SequentialMusic
+  'elements
+  (list (make-music
+          'EventChord
+          'elements
+          (list (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{'elements}-Eigenschaft jeder Noten hinzugefügt
+werden, und schließlich muss eine @code{SequentialMusic}
+mit den beiden @code{EventChords} erstellt werden.
+
+@example
+doubleSlur = #(define-music-function (parser location note) (ly:music?)
+         "Return: @{ note ( note ) @}.
+         `note' is supposed to be an EventChord."
+         (let ((note2 (ly:music-deep-copy note)))
+           (set! (ly:music-property note 'elements)
+                 (cons (make-music 'SlurEvent 'span-direction -1)
+                       (ly:music-property note 'elements)))
+           (set! (ly:music-property note2 'elements)
+                 (cons (make-music 'SlurEvent 'span-direction 1)
+                       (ly:music-property note2 'elements)))
+           (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}.  Hier soll jetzt eine musikalische
+Funktion entwickelt werden, die das vornimmt.
+
+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 eine Pseudonote
+gehängt wird:
+
+@example
+@{ << \music s1*0-.-> @}
+@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
+  'EventChord
+  'elements
+  (list (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
+  'EventChord
+  'elements
+  (list (make-music
+          'NoteEvent
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch -1 0 0))
+        (make-music
+          'ArticulationEvent
+          'articulation-type
+          "marcato")))
+@end example
+
+Dabei ist zu sehen, dass eine Note (@code{c4}) als @code{EventChord}
+repräsentiert ist, mit einem @code{NoteEvent}-Ausdruck in ihrer
+Elementenliste.  Um eine Marcato-Artikulation hinzuzufügen, muss
+ein @code{ArticulationEvent}-Ausdruck zu der Elementeigenschaft
+des @code{EventChord}-Ausdrucks hinzugefügt werden.
+
+Um diese Funktion zu bauen, wird folgendermaßen begonnen:
+
+@example
+(define (add-marcato event-chord)
+  "Add a marcato ArticulationEvent to the elements of `event-chord',
+  which is supposed to be an EventChord expression."
+  (let ((result-event-chord (ly:music-deep-copy event-chord)))
+    (set! (ly:music-property result-event-chord 'elements)
+          (cons (make-music 'ArticulationEvent
+                  'articulation-type "marcato")
+                (ly:music-property result-event-chord 'elements)))
+    result-event-chord))
+@end example
+
+Die erste Zeile definiert eine Funktion in Scheme: Die Bezeichnung
+der Funktion ist @code{add-marcato} und sie hat eine Variable
+mit der Bezeichnung @code{event-chord}.  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 a marcato..."
+@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.
+
+@example
+(let ((result-event-chord (ly:music-deep-copy event-chord)))
+@end example
+
+@code{let} wird benutzt, um die lokalen Variablen zu definieren.  Hier
+wird eine lokale Variable benutzt: @code{result-event-chord}.  Sie erhält
+den Wert @code{(ly:music-deep-copy event-chord)}.  @code{ly:music-deep-copy}
+ist eine LilyPond-spezifische Funktion, die wie alle Funktionen mit dem
+Präfix @code{ly:} versehen ist.  Sie wird benutzt, um eine Kopie eines
+musikalischen Ausdrucks anzufertigen.  Hier wird @code{event-chord}
+(der Parameter der Funktion) kopiert.  Die Funktion soll ja nur ein
+Artikulationszeichen an einen @code{EventChord} gehängt werden, deshalb ist es besser,
+den @code{EventChord}, der als Argument gegeben wurde, nicht zu
+verändern, weil er woanders benutzt werden könnte.
+
+Jetzt gibt es @code{result-event-chord}, wobei es sich um einen
+@code{NoteEventChord}-Ausdruck handelt, welcher gleichzeitig eine Kopie
+von @code{event-chord} ist.  Das Makro wird seiner Eigenschaftsliste
+hinzugefügt:
+
+@example
+(set! place new-value)
+@end example
+
+Was in diesem Fall @qq{gesetzt} werden soll (@qq{place}) ist die
+@q{elements}-Eigenschaft des @code{result-event-chord}-Ausdrucks.
+
+@example
+(ly:music-property result-event-chord 'elements)
+@end example
+
+@code{ly:music-property} ist die Funktion, mit der musikalische
+Eigenschaften erreicht werden können (die @code{'elements},
+@code{'duration}, @code{'pitch} usw., die in der Ausgabe von
+@code{\displayMusic} weiter oben angezeigt werden).  Der neue
+Wert ist, was ehemals die Elementeigenschaft 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 "marcato")
+      (ly:music-property result-event-chord 'elements))
+@end example
+
+@code{cons} wird benutzt, um ein Element zu einer Liste hinzuzufügen,
+ohne dass die originale Liste verändert wird.  Das ist es, was die
+Funktion tun soll:  die gleiche Liste, aber mit dem neuen
+@code{ArticulationEvent}-Ausdruck.  Die Reihenfolge innerhalb
+der Elementeeigenschaft ist hier nicht relevant.
+
+Wenn schließlich die Marcato-Artikulation zu der entsprechenden
+@code{elements}-Eigenschaft hinzugefügt ist, kann
+@code{result-event-chord} ausgegeben werden, darum die letzte Zeile
+der Funktion.
+
+Jetzt wird die @code{add-marcato}-Funktion in eine musikalische
+Funktion umgewandelt:
+
+@example
+addMarcato = #(define-music-function (parser location event-chord)
+                                     (ly:music?)
+    "Add a marcato ArticulationEvent to the elements of `event-chord',
+    which is supposed to be an EventChord expression."
+    (let ((result-event-chord (ly:music-deep-copy event-chord)))
+      (set! (ly:music-property result-event-chord 'elements)
+            (cons (make-music 'ArticulationEvent
+                    'articulation-type "marcato")
+                  (ly:music-property result-event-chord 'elements)))
+      result-event-chord))
+@end example
+
+Eine Überprüfung, dass die Funktion richtig arbeitet, geschieht
+folgendermaßen:
+
+@example
+\displayMusic \addMarcato 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-Übung} 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 (parser location padding) (number?)
+#{
+  \once \override TextScript #'padding = #$padding
+#})
+
+\relative c''' {
+  c4^"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 (parser location padding tempotext)
+  (number? string?)
+#{
+  \once \override Score.MetronomeMark #'padding = $padding
+  \tempo \markup { \bold $tempotext }
+#})
+
+\relative c'' {
+  \tempo \markup { "Low tempo" }
+  c4 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 (parser location 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
+