[ < ] [ > ]   [ << ] [ Subir ] [ >> ]         [Arriba] [Índice general] [Índice] [ ? ]

B.2 Funciones de Scheme

@translationof Scheme functions

Las funciones de Scheme son procedimientos de Scheme que pueden crear expresiones de Scheme a partir de código de entrada escrito en la sintaxis de LilyPond. Se pueden llamar desde prácticamente cualquier lugar en el que se permita el uso de # para la especificación de un valor en sintaxis de Scheme. Mientras que Scheme tiene funciones propias, este capítulo se ocupa de las funciones sintácticas, funciones que reciben argumentos especificados en la sintaxis de LilyPond.


[ < ] [ > ]   [ << ] [ Subir ] [ >> ]         [Arriba] [Índice general] [Índice] [ ? ]

B.2.1 Definición de funciones de Scheme

@translationof Scheme function definitions

La forma general de la definición de una función de Scheme es:

 
funcion =
#(define-scheme-function
     (arg1 arg2 …)
     (tipo1? tipo2? …)
   cuerpo)

donde

argNn-ésimo argumento.
typeN?Un predicado de tipo de Scheme para el que argN debe devolver #t. También existe una forma especial (predicate? default) para especificar argumentos opcionales. Si el argumento actual no está presente cuando se ll ama a la función, el valor predeterminado se emplea en sustitución. Los valores predeterminados se evalúan en tiempo de definición (¡incluyendo los bloques de código de LilyPond!), de manera que se necesitamos un valor por omisión calculado en tiempo de ejecución, debemos escribir en su lugar un valor especial que podamos reconocer fácilmente. Si escribimos el predicado entre paréntesis pero no lo seguimos por el valor predeterminado, se usa #f como valor por omisión. Los valores por omisión no se verifican con predicate? en tiempo de definición ni en tiempo de ejecución: es nuestra responsabilidad tratar con los valores que especifiquemos. Los valores por omisión que son expresiones musicales se copian mientras se establece origin a la ubicación actual del cursor de entrada.
cuerpouna secuencia de formas de Scheme que se evalúan ordenadamente; la última forma de la secuencia se usa como el valor de retorno de la función de Scheme. Puede contener bloques de código de LilyPond encerrados entre llaves con almohadillas ( #{…#} ), como se describe en Bloques de código de LilyPond. Dentro de los bloques de código de LilyPond, use el símbolo # para hacer referencia a argumentos de función (p.ej. ‘#arg1’) o para iniciar una expresión en línea de Scheme que contenga argumentos de función (p.ej. ‘#(cons arg1 arg2)’). Donde las expresiones de Scheme normales que usan # no funcionan, podríamos necesitar volver a expresiones de Scheme inmediatas que usan $, como por ejemplo ‘$music’.

Si nuestra función devuelve una expresión musical, recibe un valor origin útil.

La idoneidad de los argumentos para los predicados viene determinada mediante llamadas reales al predicado después de que LilyPond ya las ha convertido en una expresión de Scheme. Como consecuencia, el argumento se puede especificar en la sintaxis de Scheme si se desea (precedido de # o como resultado de haber llamado a una función de Scheme), pero LilyPond también convierte algunas construcciones de LilyPond en Scheme antes de hacer efectivamente la comprobación del predicado sobre ellas. Actualmente se encuentran entre ellas la música, los post-eventos, las cadenas simples (entrecomilladas o no), los números, los elementos de marcado y de listas de marcado, score (partitura), book (libro), bookpart (parte de libro), las definiciones de contexto y los bloques de definición de salida.

LilyPond resuelve algunas ambigüedades mediante la comprobación con funciones de predicado: ¿es ‘-3’ un post-evento de digitación o un número negativo? ¿Es "a" 4 en el modo de letra una cadena seguida por un número, o un evento de letra con la duración 4? LilyPond prueba el predicado del argumento sobre diversas interpretaciones sucesivas hasta que lo consigue, con un orden diseñado para minimizar las interpretaciones poco consistentes y la lectura por adelantado.

Por ejemplo, un predicado que acepta tanto expresiones musicales como alturas consideraría que c'' es una altura en lugar de una expresión musical. Las duraciones o post-eventos que siguen inmediatamente, cambian dicha interpretación. Es mejor evitar los predicados excesivamente permisivos como scheme? cuando la aplicación requeriría tipos de argumento más específicos.

Para ver una lista de los predicados de tipo disponibles, consulte (notation)Predicados de tipo predefinidos sección ‘Predicados de tipo predefinidos’ en Referencia de la Notación.

Véase también

Referencia de la notación: (notation)Predicados de tipo predefinidos sección ‘Predicados de tipo predefinidos’ en Referencia de la Notación.

Archivos instalados: ‘lily/music-scheme.cc’, ‘scm/c++.scm’, ‘scm/lily.scm’.


[ < ] [ > ]   [ << ] [ Subir ] [ >> ]         [Arriba] [Índice general] [Índice] [ ? ]

B.2.2 Uso de las funciones de Scheme

@translationof Scheme function usage

Las funciones de Scheme se pueden llamar casi desde cualquier lugar en que puede escribirse una expresión de Scheme que comience con la almohadilla #. Llamamos a una función de Scheme escribiendo su nombre precedido de la barra invertida \, y seguido por sus argumentos. Una vez que un argumento opcional no corresponde a ningún argumento, LilyPond se salta este argumento y todos los que le siguen, sustituyéndolos por su valor por omisión especificado, y ‘recupera’ el argumento que no correspondía al lugar del siguiente argumento obligatorio. Dado que el argumento recuperado necesita ir a algún lugar, los argumentos opcionales no se consideran realmente opcionales a no ser que vayan seguidos de un argumento obligatorio.

Existe una excepción: si escribimos \default en el lugar de un argumento opcional, este argumento y todos los argumentos opcionales que le siguen se saltan y se sustituyen por sus valores predeterminados. Esto funciona incluso si no sigue ningún argumento obligatorio porque \default no necesita recuperarse. Las instrucciones mark y key hacen uso de este truco para ofrecer su comportamiento predeterminado cuando van seguidas solamente por \default.

Aparte de los lugares en que se requiere un valor de Scheme hay ciertos sitios en que se aceptan expresiones de almohadilla # y se evalúan por sus efectos secundarios, pero por lo demás se ignoran. Son, mayormente, los lugares en que también sería aceptable colocar una asignación.

Dado que no es buena idea devolver valores que puedan malinterpretarse en algún contexto, debería usar funciones de Scheme normales solo para los casos en que siempre se devuelve un valor útil, y usar funciones de Scheme vacías (véase la sección Funciones de Scheme vacías) en caso contrario.

Por conveniencia, las funciones de Scheme también se pueden llamar directamente desde Scheme, puenteando al analizador sintáctico de LilyPond. Su nombre puede utilizarse como el nombre de una función corriente. La comprobación de tipo de los argumentos y el salto de los argumentos opcionales tiene lugar de la misma forma que cuando se llama desde dentro de LilyPond, tomando el valor de Scheme *unspecified* el papel de la palabra reservada \default para saltar explícitamente argumentos opcionales.


[ < ] [ > ]   [ << ] [ Subir ] [ >> ]         [Arriba] [Índice general] [Índice] [ ? ]

B.2.3 Funciones de Scheme vacías

@translationof Void scheme functions

En ocasiones, un procedimiento se ejecuta con el objeto de llevar a cabo alguna acción más que para devolver un valor. Algunos lenguajes de programación (como C y Scheme) usan las funciones para los dos conceptos y se limitan a descartar el valor devuelto (usualmente haciendo que cualquier expresión pueda actuar como instrucción, ignorando el resultado devuelto). Esto puede parecer inteligente pero es propenso a errores: casi todos los compiladores de C de hoy en día emiten advertencias cuando se descarta una expresión no vacía. Para muchas funciones que ejecutan una acción, los estándares de Scheme declaran que el valor de retorno sea no especificado. Guile, el intérprete de Scheme de LilyPond, tiene un valor único *unspecified* que en tales casos devuelve de forma usual (como cuando se usa directamente set! sobre una variable), pero desgraciadamente no de forma consistente.

Definir una función de LilyPond con define-void-function asegura que se devuelve este valor especial, el único valor que satisface el predicado void?.

 
noApuntarYPulsar =
#(define-void-function
     ()
     ()
   (ly:set-option 'point-and-click #f))
…
\noApuntarYPulsar   % desactivar la función de apuntar y pulsar

Si queremos evaluar una expresión sólo por su efecto colateral y no queremos que se interprete ningún valor que pueda devolver, podemos hacerlo anteponiendo el prefijo \void:

 
\void #(hashq-set! some-table some-key some-value)

De esta forma podemos asegurar que LilyPond no asignará ningún significado al valor devuelto, independientemente de dónde lo encuentre. También funciona para funciones musicales como \displayMusic.


[ < ] [ > ]   [ << ] [ Subir ] [ >> ]

Este documento ha sido generado por gub el el 13 julio 2020 utilizando texi2html 1.82.

Otros idiomas: English, deutsch, français.
Acerca de la selección automática del idioma.