2.2.1 Définition de fonctions Scheme

D’une manière générale, une fonction Scheme se définit ainsi :

fonction =
#(define-scheme-function
     (parser location arg1 arg2 …)
     (type1? type2? …)
   corps)

parserdoit être littéralement parser, de telle sorte que l’analyseur grammatical puisse accéder aux blocs de code LilyPond (#{#}).
argNnième argument
typeN?un type de prédicat Scheme pour lequel argN devra retourner #t. Certains de ces prédicats, comme nous le verrons plus loin, bénéficient d’un traitement particulier de la part du parser. De même existe une forme spécifique – (prédicat? default) – qui permet de fournir des argument optionnels. En l’absence d’argument réel au moment de l’appel de la fonction, c’est la valeur par défaut qui lui sera substituée. Les valeurs par défaut sont évaluées dès l’apparition de la définition, y compris dans le cas de blocs de code LilyPond ; vous devrez donc, si ces valeurs par défaut ne peuvent être déterminées que plus tard, mentionner une valeur spéciale que vous reconnaîtrez facilement. Lorsque vous mentionnez un prédicat entre parenthèses sans toutefois fournir sa valeur par défaut, celle-ci sera considérée comme étant #f. Les valeurs par défaut d’un prédicat? ne sont vérifiées ni au moment de la définition, ni à l’exécution ; il est de votre ressort de gérer les valeurs que vous spécifiez. Une valeur par défaut constituée d’une expression musicale est recopiée dès la définition de origin vers le paramètre location.
corpsune séquence de formules Scheme évaluées dans l’ordre, la dernière servant de valeur de retour de la fonction. Il peut contenir des blocs de code LilyPond, enchâssés dans des accolades et hashes#{…#}  – comme indiqué à la rubrique Blocs de code LilyPond. Au sein d’un bloc de code LilyPond, un # permet de référencer des arguments de la fonction – tel ‘#arg1’ – ou d’ouvrir une expression Scheme contenant les arguments de la fonction – par exemple ‘#(cons arg1 arg2)’. Dans le cas où une expression Scheme introduite par # ne vous permet pas de parvenir à vos fins, vous pourriez devoir revenir à une expression Scheme « immédiate » à l’aide d’un $, comme ‘$music’. Lorsque votre fonction retourne une expression musicale, lui est attribuée la valeur origin.

Certains types de prédicat font l’objet d’un traitement spécial de la part de l’analyseur grammatical, dans la mesure où il n’a aucun autre moyen de reconnaître efficacement les arguments. Il s’agit, à l’heure actuelle, de ly:pitch? et ly:duration?.

Pour tous les autres prédicats, la recevabilité des arguments est déterminée par un appel effectif au prédicat après que LilyPond les a déjà converti en expression Scheme. Par voie de conséquence, l’argument peut tout à fait se libeller en syntaxe Scheme – introduite par un # ou en tant que résultat d’un appel à une fonction Scheme. Par ailleurs, LilyPond convertira en Scheme un certain nombre de constructions purement LilyPond avant même d’en avoir vérifié le prédicat. C’est notamment le cas de la musique, des postévénements, des chaînes simples (avec ou sans guillemets), des nombres, des markups et listes de markups, ainsi que des blocs score, book, bookpart, ou qui définissent un contexte ou un format de sortie.

Il existe certaines formes d’expression, comme la plupart du temps où la musique n’est pas bornée par des accolades, où LilyPond doit lire au-delà de cette même expression afin d’en déterminer la fin. Si une telle expression devait, après évaluation du prédicat, faire l’objet d’un argument optionnel, LilyPond n’aurait aucun moyen, à partir du moment où il aura décidé que l’expression ne correspond pas au paramètre, de « revenir en arrière ». C’est la raison pour laquelle certaines formes musicales devraient être bornées par des accolades pour que LilyPond puisse les reconnaître efficacement. Il existe d’autres situations pour lesquelles LilyPond lèvera toute ambiguïté grâce aux fonctions de prédicat : un ‘-3’ est-il un postévénement de type doigté ou un nombre négatif ? Un "a" 4 en mode paroles est-il une chaîne suivie d’un nombre ou bien un événement syllabe de durée 4 ? LilyPond répondra à ces questions après consultation du prédicat. Pour toutes ces raisons, nous vous enjoignons à éviter d’utiliser des prédicats permissifs tel que scheme?, dès que vous voulez les utiliser dans un but particulier plutôt que dans une fonction de portée générale.

Les différents types des prédicat propres à LilyPond sont recensés à l’annexe Types de prédicats prédéfinis.

Voir aussi

Manuel de notation : Types de prédicats prédéfinis.

Fichiers d’initialisation : ‘lily/music-scheme.cc’, ‘scm/c++.scm’, ‘scm/lily.scm’.


Autres langues : English, deutsch, español.
About automatic language selection.

LilyPond — Extension des fonctionnalités