A.2.1 Sintaxis del Scheme de LilyPond (Extender LilyPond)

#### A.2.1 Sintaxis del Scheme de LilyPond

El intérprete Guile forma parte de LilyPond, lo que significa que se puede incluir Scheme dentro de los archivos de entrada de LilyPond. Existen varios métodos para incluir Scheme dentro de LilyPond.

La manera más sencilla es utilizar el símbolo de almohadilla `#` antes de una expresión de Scheme.

Ahora bien, el código de entrada de LilyPond se estructura en elementos y expresiones, de forma parecida a cómo el lenguaje humano se estructura en palabras y frases. LilyPond tiene un analizador léxico que reconoce elementos indivisibles (números literales, cadenas de texto, elementos de Scheme, nombres de nota, etc.), y un analizador que entiende la sintaxis, la Gramática de LilyPond. Una vez que sabe que se aplica una regla sintáctica concreta, ejecuta las acciones asociadas con ella.

El método del símbolo de almohadilla `#` para incrustar Scheme se adapta de forma natural a este sistema. Una vez que el analizador léxico ve un símbolo de almohadilla, llama al lector de Scheme para que lea una expresión de Scheme completa (que puede ser un identificador, una expresión encerrada entre paréntesis, o algunas otras cosas). Después de que se ha leído la expresión de Scheme, se almacena como el valor de un elemento `SCM_TOKEN` de la gramática. Después de que el analizador sintáctico ya sabe cómo hacer uso de este elemento, llama a Guila para que evalúe la expresión de Scheme. Dado que el analizador sintáctico suele requerir un poco de lectura por delante por parte del analizador léxico para tomar sus decisiones de análisis sintáctico, esta separación de lectura y evaluación entre los analizadores léxico y sintáctico es justamente lo que se necesita para mantener sincronizadas las ejecuciones de expresiones de LilyPond y de Scheme. Por este motivo se debe usar el símbolo de almohadilla `#` para llamar a Scheme siempre que sea posible.

Otra forma de llamar al intérprete de Scheme desde LilyPond es el uso del símbolo de dólar `$` en lugar de la almohadilla para introducir las expresiondes de Scheme. En este caso, LilyPond evalúa el código justo después de que el analizador léxico lo ha leído. Comprueba el tipo resultante de la expresión de Scheme y después selecciona un tipo de elemento (uno de los varios elementos `xxx_IDENTIFIER` dentro de la sintaxis) para él. Crea una copia del valor y la usa como valor del elemento. Si el valor de la expresión es vacío (El valor de Guile de `*unspecified*`), no se pasa nada en absoluto al analizador sintáctico.

Éste es, de hecho, el mismo mecanismo exactamente que LilyPond emplea cuando llamamos a cualquier variable o función musical por su nombre, como `\nombre`, con la única diferencia de que el nombre viene determinado por el analizador léxico de LilyPond sin consultar al lector de Scheme, y así solamente se aceptan los nombres de variable consistentes con el modo actual de LilyPond.

La acción inmediata de `$` puede llevar a alguna que otra sorpresa, véase Importación de Scheme dentro de LilyPond. La utilización de `#` donde el analizador sintáctico lo contempla es normalmente preferible. Dentro de las expresiones musicales, aquellas que se crean utilizando `#` se interprentan como música. Sin embargo, no se copian antes de ser utilizadas. Si forman parte de alguna estructura que aún podría tener algún uso, quizá tenga que utilizar explícitamente `ly:music-deep-copy`.

También existen los operadores de ‘división de listas’ `$@` y `#@` que insertan todos los elementos de una lista dentro del contexto circundante.

Ahora echemos un vistazo a algo de código de Scheme real. Los procedimientos de Scheme se pueden definir dentro de los archivos de entrada de LilyPond:

    #(define (media a b c) (/ (+ a b c) 3))

Observe que los comentarios de LilyPond (`%` y `%{ %}`) no se pueden utilizar dentro del código de Scheme, ni siquiera dentro de un archivo de entrada de LilyPond, porque es el intérprete Guile, y no el analizador léxico de LilyPond, el que está leyendo la expresión de Scheme. Los comentarios en el Scheme de Guile se introducen como sigue:

    ; esto es un comentario de una línea

    #!
      Esto es un comentario de bloque (no anidable) estilo Guile
      Pero se usan rara vez por parte de los Schemers
      y nunca dentro del código fuente de LilyPond
    !#

Durante el resto de esta sección, supondremos que los datos se introducen en un archivo de música, por lo que añadiremos una almohadilla `#` al principio de cada una de las expresiones de Scheme.

Todas las expresiones de Scheme del nivel jerárquico superior dentro de un archivo de entrada de LilyPond se pueden combinar en una sola expresión de Scheme mediante la utilización del operador `begin`:

    #(begin
      (define fulanito 0)
      (define menganito 1))

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

- Appendix A Tutorial de Scheme
  - A.1 Introducción a Scheme
    - A.1.1 Cajón de arena de Scheme
    - A.1.2 Variables de Scheme
    - A.1.3 Tipos de datos simples de Scheme
    - A.1.4 Tipos de datos compuestos de Scheme
      - Parejas
      - Listas
      - Listas asociativas (listas-A)
      - Tablas de hash
    - A.1.5 Cálculos en Scheme
    - A.1.6 Procedimientos de Scheme
      - Definir procedimientos
      - Predicados
      - Valores de retorno
    - A.1.7 Condicionales de Scheme
      - if
      - cond
  - A.2 Scheme dentro de LilyPond
    - A.2.1 Sintaxis del Scheme de LilyPond
    - A.2.2 Variables de LilyPond
    - A.2.3 Depuración del código de Scheme
    - A.2.4 Variables de entrada y Scheme
    - A.2.5 Importación de Scheme dentro de LilyPond
    - A.2.6 Propiedades de los objetos
    - A.2.7 Variables de LilyPond compuestas
      - Desplazamientos
      - Fracciones
      - Dimensiones
      - Listas-A de propiedades
      - Cadenas de listas-A
    - A.2.8 El modelo de caja de LilyPond
    - A.2.9 Representación interna de la música
  - A.3 Construir funciones complicadas
    - A.3.1 Una primera aproximación (ejemplo)
    - A.3.2 Presentación de las expresiones musicales
    - A.3.3 Propiedades musicales
    - A.3.4 Duplicar una nota con ligaduras (ejemplo)
    - A.3.5 Añadir articulaciones a las notas (ejemplo)
- B Interfaces para programadores
  - B.1 Bloques de código de LilyPond
  - B.2 Funciones de Scheme
    - B.2.1 Definición de funciones de Scheme
    - B.2.2 Uso de las funciones de Scheme
    - B.2.3 Funciones de Scheme vacías
  - B.3 Funciones musicales
    - B.3.1 Definiciones de funciones musicales
    - B.3.2 Uso de las funciones musicales
    - B.3.3 Funciones de sustitución sencillas
    - B.3.4 Funciones de sustitución intermedias
    - B.3.5 Matemáticas dentro de las funciones
    - B.3.6 Funciones sin argumentos
    - B.3.7 Funciones musicales vacías
  - B.4 Funciones de eventos
  - B.5 Funciones de marcado
    - B.5.1 Construcción de elementos de marcado en Scheme
    - B.5.2 Cómo funcionan internamente los elementos de marcado
    - B.5.3 Definición de una instrucción de marcado nueva
      - Sintaxis de la definición de instrucciones de marcado
      - Acerca de las propiedades
      - Un ejemplo completo
      - Adaptación de instrucciones incorporadas
      - Convertir elementos de marcado en cadenas
    - B.5.4 Definición de nuevas instrucciones de lista de marcado
  - B.6 Contextos para programadores
    - B.6.1 Evaluación de contextos
    - B.6.2 Ejecutar una función sobre todos los objetos de la presentación
  - B.7 Funciones de callback
  - B.8 Contenedores Unpure-pure
  - B.9 Trucos difíciles
- C Interfaces de Scheme de LilyPond
- Appendix D GNU Free Documentation License
- Appendix E Índice