[ < ] [ > ]   [ << ] [Plus haut] [ >> ]         [Racine] [Table des matières] [Index] [ ? ]

2.2 Fonctions Scheme

@translationof Scheme functions

Les fonctions Scheme sont des procédures Scheme chargées de créer des expressions Scheme à partir de code rédigé selon la syntaxe de LilyPond. Elles peuvent être appelées en de nombreux endroits, à l’aide d’un #, où spécifier une valeur en syntaxe Scheme est autorisé. Bien que Scheme dispose de fonctions en propre, nous nous intéresserons, au fil des paragraphes qui suivent, aux fonctions syntaxiques, autrement dit des fonctions qui reçoivent des arguments libellés dans la syntaxe de LilyPond.


[ < ] [ > ]   [ << ] [Plus haut] [ >> ]         [Racine] [Table des matières] [Index] [ ? ]

2.2.1 Définition de fonctions Scheme

@translationof Scheme function definitions

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

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

où

argNn-ième argument.
typeN?un type de prédicat Scheme pour lequel argN devra retourner #t. Il existe aussi 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 à 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 à l’emplacement courant du code.
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.

La recevabilité des arguments est déterminée par un appel effectif au prédicat après que LilyPond les a déjà convertis 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 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 par des interprétations successives du prédicat de l’argument, dans un ordre défini de sorte à minimiser les interprétations erronées et le besoin de lecture en avance.

Un prédicat qui accepte par exemple aussi bien une expression musicale qu’une hauteur considèrera c'' comme étant une hauteur plutôt qu’une expression musicale. Les durées ou postévénements qui viennent juste après viendront modifier cette interprétation. C’est la raison pour laquelle il vaut mieux éviter des prédicats par trop permissifs tel que Scheme? lorsque l’application fait plutôt appel à des types d’argument plus spécifiques.

Les différents types de prédicat propres à LilyPond sont recensés à l’annexe (notation)Types de prédicats prédéfinis section ‘Types de prédicats prédéfinis’ dans Manuel de notation.

Voir aussi

Manuel de notation : (notation)Types de prédicats prédéfinis section ‘Types de prédicats prédéfinis’ dans Manuel de notation.

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


[ < ] [ > ]   [ << ] [Plus haut] [ >> ]         [Racine] [Table des matières] [Index] [ ? ]

2.2.2 Utilisation de fonctions Scheme

@translationof Scheme function usage

Vous pouvez appeler une fonction Scheme pratiquement partout où une expression Scheme derrière un # peut prendre place. Vous appelez une fonction Scheme à partir de LilyPond en faisant précéder son nom d’un \, et en le faisant suivre de ses arguments. Lorsqu’un prédicat d’argument optionnel ne correspond pas à un argument, LilyPond l’ignore ainsi que tous les arguments optionnels qui suivent, les remplaçant par leur valeur par défaut, et « sauvegarde » en tant que prochain argument obligatoire l’argument qui ne correspondait pas. Dans la mesure où l’argument sauvegardé doit servir, les argument optionnels ne sont en fait pas considérés comme optionnels, sauf à être suivis d’un argument obligatoire.

Une exception cependant à cette règle : le fait de donner un \default en tant qu’argument optionnel aura pour résultat que cet argument et tous les autres arguments optionnels qui suivent seront ignorés et remplacés par leur valeur par défaut. Il en va de même lorsqu’aucun argument obligatoire ne suit, du fait que \default ne requiert pas de sauvegarde. C’est d’ailleurs ainsi que fonctionnent les commandes mark et key, qui retrouvent leur comportement par défaut lorsque vous les faites suivre d’un \default.

En plus de là où une expression Scheme est requise, il y a quelques endroits où des expressions # sont acceptées et évaluées uniquement pour leurs effets annexes. Il s’agit, dans la plupart des cas, d’endroits où une affectation serait tout à fait envisageable.

Dans la mesure où il n’est pas bon de renvoyer une valeur qui pourrait être mal interprétée dans certains contextes, nous vous enjoignons à utiliser des fonctions Scheme normales uniquement dans les cas où vous renvoyez toujours une valeur utile, et une fonction fantôme – voir Fonctions Scheme fantômes – dans le cas contraire.

Pour des raisons de commodité, il est possible de faire appel à des fonctions Scheme directement en Scheme, courcircuitant ainsi l’analyseur de LilyPond. Leur nom s’utilise comme n’importe quel nom de fonction. Le contrôle de typologie des arguments et l’omission des arguments optionnels seront traîtés de la même manière que lorsque l’appel est fait à partir de LilyPond, la valeur Scheme *unspecified* ayant le rôle du mot réservé \default pour omettre explicitement les arguments optionnels.


[ < ] [ > ]   [ << ] [Plus haut] [ >> ]         [Racine] [Table des matières] [Index] [ ? ]

2.2.3 Fonctions Scheme fantômes

@translationof Void scheme functions

Il arrive qu’une procédure soit exécutée pour réaliser une action, non pour renvoyer une valeur. Certains langages de programmation, tels le C et Scheme, utilisent des fonctions dans les deux cas et se débarrassent tout bonnement de la valeur renvoyée ; en règle générale, il suffit que l’expression fasse office de déclaration, et d’ignorer le résultat. C’est futé, mais pas sans risque d’erreur : la plupart des compilateurs C actuels déclenchent un avertissement si l’on se débarrasse de certaines expressions non void. Pour de nombreuses fonctions réalisant une action, les standards Scheme déclarent que la valeur de retour est indéfinie. L’interpréteur Guile qu’utilise le Scheme de LilyPond dispose d’une valeur unique *unspecified* qu’il retourne alors, en règle générale – notamment lorsqu’on utilise set! directement sur une variable – mais malheureusement pas toujours.

Une fonction LilyPond définie à l’aide de la clause define-void-function vous apporte l’assurance que c’est cette valeur spéciale – la seule valeur qui satisfasse au prédicat void? – qui sera retournée.

 
noPointAndClick =
#(define-void-function
     ()
     ()
   (ly:set-option 'point-and-click #f))
…
\noPointAndClick   % desactive le "pointer-cliquer"

L’utilisation d’un préfixe \void permet ainsi d’évaluer une expression pour ses effets annexes sans interprétation d’une quelconque valeur de retour :

 
\void #(hashq-set! une-table une-clé une-valeur)

Vous serez alors assuré que LilyPond ne tentera pas d’affecter un sens à la valeur de retour, à quelque endroit qu’elle ressorte. Ceci est aussi opérationnel dans le cadre de fonctions musicales telles que \displayMusic.


[ < ] [ > ]   [ << ] [Plus haut] [ >> ]

Ce document a été généré le le 13 juillet 2020 par gub en utilisant texi2html 1.82.

Autres langues : English, deutsch, español.
À propos de la sélection automatique de la langue.