2.2.1 Definition von Scheme-Funktionen (LilyPond erweitern)

#### 2.2.1 Definition von Scheme-Funktionen

Die übliche Form zur Definition von Scheme-Funktionen ist:

    function =
    #(define-scheme-function
         (Arg1 Arg2 …)
         (Typ1? Typ2? …)
       body)

wobei

`parser` | ganz genau das Wort `parser` sein muss, damit LilyPond eine Umgebung (`#{`…`#}`) mit Zugriff auf den Parser bekommt.
`ArgN` | nte Argument
`TypN?` | eine Scheme-Typenprädikat, für welches `argN` `#t` ausgeben muss. Manche dieser Prädikate werden vom Parser besonders erkannt, siehe unten. Es gibt auch eine Spezialform `(predicate? default)`, um optionale Argumente anzugeben. Wenn das eigentlich Argument fehlt, während die Funktion aufgerufen wird, wird der Standardwert anstelle eingesetzt. Standardwerte werden bei ihrer Definition evaluiert (gilt auch für LilyPond-Codeabschnitte), so dass man besser einen speziellen Wert schreibt, den man einfach erkennen kann, wenn der Wert während der Ausführung der Position evaluiert weren soll. Wenn man das Prädikat in Klammern setzt, aber kein Standardwert folt, wird `#f` als Standard eingesetzt. Standardwerte werden weder bei der Definition noch bei der Ausführung mit predicate? verifiziert, sodass man selber verantworlich für funktionsfähige Werte ist. Standardwerte, die musikalische Ausdrücke darstellen, werden kopiert und `origin` auf den Parameter `location` gesetzt.
`body` | Eine Folge von Scheme-Formeln, die der Reihe nach ausgewertet werden, wobei die letzte als Ausgabewert der Scheme-Funktion eingesetzt wird. Sie kann LilyPond-Codeabschnitte enthalten, eingeschlossen mit Raute-Klammern ( `#{…#}` ), wie beschrieben in LilyPond-Codeabschnitte. Innerhalb von LilyPond-Codeabschnitten wird mit `#` auf Funktionsargumente (etwa ‘`#Arg1`’) verwiesen oder ein neuer Scheme-Ausdruck mit Funktionsargumenten begonnen (etwa ‘`#(cons Arg1 Arg2)`’). Wo normale Scheme-Ausdrücke mit `#` nicht funktionieren, kann man auf direkte Scheme-Ausdrücke zurückgreifen, die mit `$` begonnen werden (etwa ‘`$music`’). Wenn die Funktion eine musikalische Funktion ausgibt, bekommt sie einen Wert von `origin`. zugewiesen.

Einige Typenprädikate werden vom Parser besonders behandelt, weil er sonst die Argumente nicht zuverlässig erkennen könnte. Im Moment handelt es sich um `ly:pitch?` und `ly:duration?`.

Die Eignung der Argumente für alle anderen Prädikate wird festgestellt, indem das Prädikat aufgerufen wird, nachdem LilyPond es schon in einen Scheme-Ausdruck umgewandelt hat. Demzufolge kann das Argument in Scheme-Syntax angegeben werden, wenn nötig (beginnend mit `#` oder als Result des Aufrufes einer Scheme-Funktion), aber LilyPond konvertiert auch eine Reihe von LilyPond-Strukturen nach Scheme, bevor dann tatsächlich die Prädikate überprüft werden. Bei den letzteren handelt es sich im Moment um music (Noten), postevents, simple strings (einfache Zeichenketten mit oder ohne Anführungszeichen) numbers (Zahlen), markup (Beschriftung) und markup lists (Beschriftungslisten), score (Partitur), book (Buch), bookpart (Buchteil), Kontextdefinitions- und Ausgabedefinitionsumgebungen.

Für einige Arten von Ausdrücken (wie die meisten Noten, die nicht in Klammern geschrieben werden) muss LilyPond weiter nach vorne schauen als der Ausdruck selber reicht, um das Ende des Ausdrucks zu bestimmen. Wenn solche Ausdrücke für optionale Argumente mit einbezogen würden, indem ihre Prädikate ausgewählt würden, könnte LilyPond nicht mehr zurückgehen, wenn es feststellt, dass der Ausdruck nicht zu dem Parameter passt. Darum müssen manche Formen von Noten möglicherweise in Klammern eingeschlossen werden, damit LilyPond sie akzeptiert. Es gibt auch einige andere Mehrdeutigkeiten, die LilyPond durch Testen von Prädikatfunktionen eingrenzt: ist etwa ‘`-3`’ die Anmerkung für einen Fingersatz oder eine negative Zahl? Ist `"a" 4` im Gesangskontext eine Zeichenkette gefolgt von einer Zahl oder ein Gesangstextereignis mit der Dauer `4`? LilyPond entscheidet, indem es Prädaikate befragt. Das heißt, dass man zu durchlässige Prädikate wie `scheme?` vermeiden sollte, wenn man eine bestimmmte Verwendung beabsichtigt und nicht nur eine Funktion für die allgemeine Verwendung schreibt.

Eine Liste der möglichen vordefinierten Typenprädikte findet sich in Vordefinierte Typprädikate.

#### Siehe auch

Notationsreferenz Vordefinierte Typprädikate.

Installierte Dateien: `lily/music-scheme.cc`, `scm/c++.scm`, `scm/lily.scm`.

#### LilyPond erweitern v2.26.0 (stable-branch).

- 1 Scheme-Tutorium
  - 1.1 Einleitung in Scheme
    - 1.1.1 Scheme-Sandkasten
    - 1.1.2 Scheme-Variablen
    - 1.1.3 Einfache Scheme-Datentypen
    - 1.1.4 Zusammengesetzte Scheme-Datentypen
    - 1.1.5 Berechnungen in Scheme
    - 1.1.6 Scheme-Prozeduren
    - 1.1.7 Scheme-Konditionale
  - 1.2 Scheme in LilyPond
    - 1.2.1 LilyPond Scheme-Syntax
    - 1.2.2 LilyPond-Variablen
    - 1.2.3 Eingabe-Variablen und Scheme
    - 1.2.4 Scheme in LilyPond importieren
    - 1.2.5 Objekteigenschaften
    - 1.2.6 Zusammengesetzte LilyPond-Variablen
    - 1.2.7 Interne musikalische Repräsentation
  - 1.3 Komplizierte Funktionen erstellen
    - 1.3.1 Musikalische Funktionen darstellen
    - 1.3.2 Eigenschaften von Musikobjekten
    - 1.3.3 Verdoppelung einer Note mit Bindebögen (Beispiel)
    - 1.3.4 Artikulationszeichen zu Noten hinzufügen (Beispiel)
- 2 Schnittstellen für Programmierer
  - 2.1 LilyPond-Codeabschnitte
  - 2.2 Scheme-Funktionen
    - 2.2.1 Definition von Scheme-Funktionen
    - 2.2.2 Benutzung von Scheme-Funktionen
    - 2.2.3 Leere Scheme-Funktionen
  - 2.3 Musikalische Funktionen
    - 2.3.1 Definition der musikalischen Funktionen
    - 2.3.2 Benutzung von musikalischen Funktionen
    - 2.3.3 Einfache Ersetzungsfunktionen
    - 2.3.4 Mittlere Ersetzungsfunktionen
    - 2.3.5 Mathematik in Funktionen
    - 2.3.6 Funktionen ohne Argumente
    - 2.3.7 Leere musikalische Funktionen
  - 2.4 Ereignisfunktionen
  - 2.5 Textbeschriftungsfunktionen
    - 2.5.1 Beschriftungskonstruktionen in Scheme
    - 2.5.2 Wie Beschriftungen intern funktionieren
    - 2.5.3 Neue Definitionen von Beschriftungsbefehlen
      - Syntax der Definition von Textbeschriftungsbefehlen
      - Über Eigenschaften
      - Ein vollständiges Bespiel
      - Eingebaute Befehle anpassen
    - 2.5.4 Neue Definitionen von Beschriftungslistenbefehlen
  - 2.6 Kontexte für Programmierer
    - 2.6.1 Kontextauswertung
    - 2.6.2 Eine Funktion auf alle Layout-Objekte anwenden
  - 2.7 Callback-Funktionen
  - 2.8 Scheme-Code innerhalb LilyPonds
  - 2.9 Schwierige Korrekturen
- 3 LilyPond Scheme-Schnittstellen
- Appendix A GNU Free Documentation License
- Appendix B Register