1@c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*- 2 3@ignore 4 Translation of GIT committish: b3a311cd9a5a91c0243ff90835a445768e7f3e4c 5 6 When revising a translation, copy the HEAD committish of the 7 version that you are working on. For details, see the Contributors' 8 Guide, node Updating translation committishes.. 9@end ignore 10 11@c \version "2.19.22" 12 13@node Tutorial de Scheme 14@appendix Tutorial de Scheme 15@translationof Scheme tutorial 16 17@cindex Scheme 18@cindex GUILE 19@cindex Scheme, código en línea 20@cindex acceder a Scheme 21@cindex evaluar Scheme 22@cindex LISP 23 24LilyPond utiliza el lenguaje de programación Scheme, tanto como 25parte de la sintaxis del código de entrada, como para servir de 26mecanismo interno que une los módulos del programa entre sí. Esta 27sección es una panorámica muy breve sobre cómo introducir datos en 28Scheme. Si quiere saber más sobre Scheme, consulte 29@uref{http://@/www@/.schemers@/.org}. 30 31LilyPond utiliza la implementación GNU Guile de Scheme, que está 32basada en el estándar @qq{R5RS} del lenguaje. Si está aprendiendo 33Scheme para usarlo con LilyPond, no se recomienda trabajar con una 34implementación distinta (o que se refiera a un estándar 35diferente). Hay información sobre Guile en 36@uref{http://www.gnu.org/software/guile/}. El estándar de Scheme 37@qq{R5RS} se encuentra en 38@uref{http://www.schemers.org/Documents/Standards/R5RS/}. 39 40@menu 41* Introducción a Scheme:: 42* Scheme dentro de LilyPond:: 43* Construir funciones complicadas:: 44@end menu 45 46@node Introducción a Scheme 47@section Introducción a Scheme 48@translationof Introduction to Scheme 49 50Comenzaremos con una introducción a Scheme. Para esta breve 51introducción utilizaremos el intérprete GUILE para explorar la 52manera en que el lenguaje funciona. Una vez nos hayamos 53familiarizado con Scheme, mostraremos cómo se puede integrar el 54lenguaje en los archivos de LilyPond. 55 56 57@menu 58* Cajón de arena de Scheme:: 59* Variables de Scheme:: 60* Tipos de datos simples de Scheme:: 61* Tipos de datos compuestos de Scheme:: 62* Cálculos en Scheme:: 63* Procedimientos de Scheme:: 64* Condicionales de Scheme:: 65@end menu 66 67@node Cajón de arena de Scheme 68@subsection Cajón de arena de Scheme 69@translationof Scheme sandbox 70 71La instalación de LilyPond incluye también la de la implementación 72Guile de Scheme. Sobre casi todos los sistemas puede experimentar 73en una @qq{caja de arena} de Scheme abriendo una ventana del 74terminal y tecleando @q{guile}. En algunos sistemas, sobre todo 75en Windows, podría necesitar ajustar la variable de entorno 76@code{GUILE_LOAD_PATH} a la carpeta @code{../usr/share/guile/1.8} 77dentro de la instalación de LilyPond (para conocer la ruta 78completa a esta carpeta, consulte @rlearning{Otras fuentes de 79información}). Como alternativa, los usuarios de Windows pueden 80seleccionar simplemente @q{Ejecutar} del menú Inicio e introducir 81@q{guile}. 82 83Sin embargo, está disponible un cajón de arena de Scheme listo 84para funcionar con todo LilyPond cargado, con esta instrucción de 85la línea de órdenes: 86@example 87lilypond scheme-sandbox 88@end example 89 90@noindent 91Una vez está funcionando el cajón de arena, verá un indicador del 92sistema de Guile: 93 94@lisp 95guile> 96@end lisp 97 98Podemos introducir expresiones de Scheme en este indicador para 99experimentar con Scheme. Si quiere usar la biblioteca readline de 100GNU para una más cómoda edición de la línea de órdenes de Scheme, 101consulte el archivo @file{ly/scheme-sandbox.ly} para más 102información. Si ya ha activado la biblioteca readline para las 103sesiones de Guile interactivas fuera de LilyPond, debería 104funcionar también en el cajón de arena. 105 106@node Variables de Scheme 107@subsection Variables de Scheme 108@translationof Scheme variables 109 110Las variables de Scheme pueden tener cualquier valor válido de 111Scheme, incluso un procedimiento de Scheme. 112 113Las variables de Scheme se crean con @code{define}: 114 115@lisp 116guile> (define a 2) 117guile> 118@end lisp 119 120Las variables de Scheme se pueden evaluar en el indicador del 121sistema de guile, simplemente tecleando el nombre de la variable: 122 123@lisp 124guile> a 1252 126guile> 127@end lisp 128 129Las variables de Scheme se pueden imprimir en la pantalla 130utilizando la función display: 131 132@lisp 133guile> (display a) 1342guile> 135@end lisp 136 137@noindent 138Observe que el valor @code{2} y el indicador del sistema 139@code{guile} se muestran en la misma línea. Esto se puede evitar 140llamando al procedimiento de nueva línea o imprimiendo un carácter 141de nueva línea. 142 143@lisp 144guile> (display a)(newline) 1452 146guile> (display a)(display "\n") 1472 148guile> 149@end lisp 150 151Una vez que se ha creado una variable, su valor se puede modificar 152con @code{set!}: 153 154@lisp 155guile> (set! a 12345) 156guile> a 15712345 158guile> 159@end lisp 160 161@node Tipos de datos simples de Scheme 162@subsection Tipos de datos simples de Scheme 163@translationof Scheme simple data types 164 165El concepto más básico de un lenguaje son sus tipos de datos: 166números, cadenas de caracteres, listas, etc. He aquí una lista de 167los tipos de datos que son de relevancia respecto de la entrada de 168LilyPond. 169 170@table @asis 171@item Booleanos 172Los valores Booleanos son Verdadero y Falso. Verdadero en Scheme es 173@code{#t} y Falso es @code{#f}. 174@funindex ##t 175@funindex ##f 176 177@item Números 178Los números se escriben de la forma normal, @code{1} es el número 179(entero) uno, mientras que @w{@code{-1.5}} es un número en coma 180flotante (un número no entero). 181 182@item Cadenas 183Las cadenas se encierran entre comillas: 184 185@example 186"esto es una cadena" 187@end example 188 189Las cadenas pueden abarcar varias líneas: 190 191@example 192"esto 193es 194una cadena" 195@end example 196 197@noindent 198y los caracteres de nueva línea al final de cada línea se 199incluirán dentro de la cadena. 200 201Los caracteres de nueva línea también se pueden añadir mediante la 202inclusión de @code{\n} en la cadena. 203 204@example 205"esto\nes una\ncadena de varias líneas" 206@end example 207 208 209Las comillas dobles y barras invertidas se añaden a las cadenas 210precediéndolas de una barra invertida. La cadena @code{\a dijo 211"b"} se introduce como 212 213@example 214"\\a dijo \"b\"" 215@end example 216 217@end table 218 219Existen más tipos de datos de Scheme que no se estudian aquí. 220Para ver un listado completo, consulte la guía de referencia de 221Guile, 222@uref{http://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/Simple-Data-Types.html}. 223 224@node Tipos de datos compuestos de Scheme 225@subsection Tipos de datos compuestos de Scheme 226@translationof Scheme compound data types 227 228También existen tipos de datos compuestos en Scheme. Entre los 229tipos más usados en la programación de LilyPond se encuentran las 230parejas, las listas, las listas-A y las tablas de hash. 231 232@menu 233* Parejas:: 234* Listas:: 235* Listas asociativas (listas-A):: 236* Tablas de hash:: 237@end menu 238 239@node Parejas 240@unnumberedsubsubsec Parejas 241@translationof Pairs 242 243El tipo fundacional de datos compuestos de Scheme es la 244@code{pareja}. Como se espera por su nombre, una pareja son dos 245valores unidos en uno solo. El operador que se usa para formar 246una pareja se llama @code{cons}. 247 248@lisp 249guile> (cons 4 5) 250(4 . 5) 251guile> 252@end lisp 253 254Observe que la pareja se imprime como dos elementos rodeados por 255paréntesis y separados por un espacio, un punto (@code{.}) y otro 256espacio. El punto @emph{no es} un punto decimal, sino más bien un 257indicador de pareja. 258 259Las parejas también se pueden introducir como valores literales 260precediéndolos de un carácter de comilla simple o apóstrofo. 261 262@lisp 263guile> '(4 . 5) 264(4 . 5) 265guile> 266@end lisp 267 268Los dos elementos de una pareja pueden ser cualquier valor válido 269de Scheme: 270 271@lisp 272guile> (cons #t #f) 273(#t . #f) 274guile> '("bla-bla" . 3.1415926535) 275("bla-bla" . 3.1415926535) 276guile> 277@end lisp 278 279Se puede accede al primero y segundo elementos de la pareja 280mediante los procedimientos de Scheme @code{car} y @code{cdr}, 281respectivamente. 282 283@lisp 284guile> (define mipareja (cons 123 "Hola") 285@dots{} ) 286guile> (car mipareja) 287123 288guile> (cdr mipareja) 289"Hola" 290guile> 291@end lisp 292 293@noindent 294 295Nota: @code{cdr} se pronuncia "could-er", según Sussman y Abelson, 296véase 297@uref{http://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133} 298 299@node Listas 300@unnumberedsubsubsec Listas 301@translationof Lists 302 303Una estructura de datos muy común en Scheme es la 304@emph{lista}. Formalmente, una lista @q{bien hecha} se define como 305la lista vacía, representada como @code{'()} y con longitud cero, 306o bien como una pareja cuyo @code{cdr} es a su vez una lista más 307corta. 308 309Existen muchas formas de crear listas. Quizá la más común es con 310el procedimiento @code{list}: 311 312@lisp 313guile> (list 1 2 3 "abc" 17.5) 314(1 2 3 "abc" 17.5) 315@end lisp 316 317La representación de una lista como elementos individuales 318separados por espacios y encerrada entre paréntesis es realmente 319una forma compacta de las parejas con punto que constituyen la 320lista, donde el punto e inmediatamente un paréntesis de apertura 321se suprimen junto al paréntesis de cierre correspondiente. Sin 322esta compactación, la salida habría sido 323@lisp 324(1 . (2 . (3 . ("abc" . (17.5 . ()))))) 325@end lisp 326 327De igual forma que con la salida, una lista puede escribirse 328(después de haber añadido un apóstrofo para evitar su 329interpretación como una llamada de función) como una lista literal 330encerrando sus elementos entre paréntesis: 331 332@lisp 333guile> '(17 23 "fulano" "mengano" "zutano") 334(17 23 "fulano" "mengano" "zutano") 335@end lisp 336 337Las listas son una parte fundamental de Scheme. De hecho, Scheme 338se considera un dialecto de Lisp, donde @q{lisp} es una 339abreviatura de @q{List Processing} (proceso de listas). Todas las 340expresiones de Scheme son listas. 341 342 343@node Listas asociativas (listas-A) 344@unnumberedsubsubsec Listas asociativas (listas-A) 345@translationof Association lists (alists) 346 347Un tipo especial de listas son las @emph{listas asociativas} o 348@emph{listas-A}. Se puede usar una lista-A para almacenar datos 349para su fácil recuperación posterior. 350 351Las listas-A son listas cuyos elementos son parejas. El 352@code{car} de cada elemento se llama @emph{clave}, y el @code{cdr} 353de cada elemento se llama @emph{valor}. El procedimiento de 354Scheme @code{assoc} se usa para recuperar un elemento de la 355lista-A, y @code{cdr} se usa para recuperar el valor: 356 357@lisp 358guile> (define mi-lista-a '((1 . "A") (2 . "B") (3 . "C"))) 359guile> mi-lista-a 360((1 . "A") (2 . "B") (3 . "C")) 361guile> (assoc 2 mi-lista-a) 362(2 . "B") 363guile> (cdr (assoc 2 mi-lista-a)) 364"B" 365guile> 366@end lisp 367 368Las listas-A se usan mucho en LilyPond para almacenar propiedades 369y otros datos. 370 371 372@node Tablas de hash 373@unnumberedsubsubsec Tablas de hash 374@translationof Hash tables 375 376Estructuras de datos que se utilizan en LilyPond de forma 377ocasional. Una tabla de hash es similar a una matriz, pero los 378índices de la matriz pueden ser cualquier tipo de valor de Scheme, 379no sólo enteros. 380 381Las tablas de hash son más eficientes que las listas-A si hay una 382gran cantidad de datos que almacenar y los datos cambian con muy 383poca frecuencia. 384 385La sintaxis para crear tablas de hash es un poco compleja, pero 386veremos ejemplos de ello en el código fuente de LilyPond. 387 388@lisp 389guile> (define h (make-hash-table 10)) 390guile> h 391#<hash-table 0/31> 392guile> (hashq-set! h 'key1 "val1") 393"val1" 394guile> (hashq-set! h 'key2 "val2") 395"val2" 396guile> (hashq-set! h 3 "val3") 397"val3" 398@end lisp 399 400Los valores se recuperan de las tablas de hash mediante 401@code{hashq-ref}. 402 403@lisp 404guile> (hashq-ref h 3) 405"val3" 406guile> (hashq-ref h 'key2) 407"val2" 408guile> 409@end lisp 410 411Las claves y los valores se recuperan como una pareja con 412@code{hashq-get-handle}. Ésta es la forma preferida, porque 413devuelve @code{#f} si no se encuentra la clave. 414 415@lisp 416guile> (hashq-get-handle h 'key1) 417(key1 . "val1") 418guile> (hashq-get-handle h 'frob) 419#f 420guile> 421@end lisp 422 423@node Cálculos en Scheme 424@subsection Cálculos en Scheme 425@translationof Calculations in Scheme 426 427@ignore 428Todo el tiempo hemos estado usando listas. Un cálculo, como @code{(+ 4291 2)} también es una lista (que contiene el símbolo @code{+} y los 430números 1 y@tie{}2). Normalmente, las listas se interpretan como 431cálculos, y el intérprete de Scheme sustituye el resultado del 432cálculo. Para escribir una lista, detenemos la evaluación. Esto se 433hace precediendo la lista por un apóstrofo @code{'}. Así, para los 434cálculos no usamos ningún apóstrofo. 435 436Dentro de una lista o pareja precedida de apóstrofo, no hay necesidad 437de escribir ningún apóstrofo más. Lo siguiente es una pareja de 438símbolos, una lista de símbolos y una lista de listas respectivamente: 439 440@example 441#'(stem . head) 442#'(staff clef key-signature) 443#'((1) (2)) 444@end example 445@end ignore 446 447Scheme se puede usar para hacer cálculos. Utiliza sintaxis 448@emph{prefija}. Sumar 1 y@tie{}2 se escribe como @code{(+ 1 2)} y 449no como el tradicional @math{1+2}. 450 451@lisp 452guile> (+ 1 2) 4533 454@end lisp 455 456Los cálculos se pueden anidar; el resultado de una función se 457puede usar para otro cálculo. 458 459@lisp 460guile> (+ 1 (* 3 4)) 46113 462@end lisp 463 464Estos cálculos son ejemplos de evaluaciones; una expresión como 465@code{(* 3 4)} se sustituye por su valor @code{12}. 466 467Los cálculos de Scheme son sensibles a las diferencias entre 468enteros y no enteros. Los cálculos enteros son exactos, mientras 469que los no enteros se calculan con los límites de precisión 470adecuados: 471 472@lisp 473guile> (/ 7 3) 4747/3 475guile> (/ 7.0 3.0) 4762.33333333333333 477@end lisp 478 479Cuando el intérprete de Scheme encuentra una expresión que es una 480lista, el primer elemento de la lista se trata como un 481procedimiento a evaluar con los argumentos del resto de la lista. 482Por tanto, todos los operadores en Scheme son operadores prefijos. 483 484Si el primer elemento de una expresión de Scheme que es una lista 485que se pasa al intérprete @emph{no es} un operador o un 486procedimiento, se produce un error: 487 488@lisp 489guile> (1 2 3) 490 491Backtrace: 492In current input: 493 52: 0* [1 2 3] 494 495<unnamed port>:52:1: In expression (1 2 3): 496<unnamed port>:52:1: Wrong type to apply: 1 497ABORT: (misc-error) 498guile> 499@end lisp 500 501Aquí podemos ver que el intérprete estaba intentando tratar el 1 502como un operador o procedimiento, y no pudo hacerlo. De aquí que 503el error sea "Wrong type to apply: 1". 504 505Así pues, para crear una lista debemos usar el operador de lista, 506o podemos precederla de un apóstrofo para que el intérprete no 507trate de evaluarla. 508 509@lisp 510guile> (list 1 2 3) 511(1 2 3) 512guile> '(1 2 3) 513(1 2 3) 514guile> 515@end lisp 516 517Esto es un error que puede aparecer cuando trabaje con Scheme 518dentro de LilyPond. 519 520@ignore 521La misma asignación se puede hacer también completamente en Scheme, 522 523@example 524#(define veintiCuatro (* 2 doce)) 525@end example 526 527@c this next section is confusing -- need to rewrite 528 529El @emph{nombre} de una variable también es una expresión, similar a 530un número o una cadena. Se introduce como 531 532@example 533#'veintiCuatro 534@end example 535 536@funindex #'symbol 537@cindex comillas en Scheme 538 539El apóstrofo @code{'} evita que el intérprete de Scheme sustituya 540@code{veintiCuatro} por @code{24}. En vez de esto, obtenemos el 541nombre @code{veintiCuatro}. 542@end ignore 543 544 545@node Procedimientos de Scheme 546@subsection Procedimientos de Scheme 547@translationof Scheme procedures 548 549Los procedimientos de Scheme son expresiones de Scheme ejecutables 550que devuelven un valor resultante de su ejecución. También pueden 551manipular variables definidas fuera del procedimiento. 552 553@menu 554* Definir procedimientos:: 555* Predicados:: 556* Valores de retorno:: 557@end menu 558 559@node Definir procedimientos 560@unnumberedsubsubsec Definir procedimientos 561@translationof Defining procedures 562 563Los procedimientos se definen en Scheme con @code{define}: 564 565@example 566(define (nombre-de-la-función arg1 arg2 ... argn) 567 expresión-de-scheme-que-devuelve-un-valor) 568@end example 569 570Por ejemplo, podemos definir un procedimiento para calcular la 571media: 572 573@lisp 574guile> (define (media x y) (/ (+ x y) 2)) 575guile> media 576#<procedure media (x y)> 577@end lisp 578 579Una vez se ha definido un procedimiento, se llama poniendo el 580nombre del procedimiento dentro de una lista. Por ejemplo, 581podemos calcular la media de 3 y 12: 582 583@lisp 584guile> (media 3 12) 58515/2 586@end lisp 587 588 589@node Predicados 590@unnumberedsubsubsec Predicados 591@translationof Predicates 592 593Los procedimientos de Scheme que devuelven valores booleanos se 594suelen llamar @emph{predicados}. Por convenio (pero no por 595necesidad), los nombres de predicados acaban en un signo de 596interrogación: 597 598@lisp 599guile> (define (menor-que-diez? x) (< x 10)) 600guile> (menor-que-diez? 9) 601#t 602guile> (menor-que-diez? 15) 603#f 604@end lisp 605 606 607@node Valores de retorno 608@unnumberedsubsubsec Valores de retorno 609@translationof Return values 610 611Los procedimientos de Scheme siempre devuelven un valor de 612retorno, que es el valor de la última expresión ejecutada en el 613procedimiento. El valor de retorno puede ser cualquier valor de 614Scheme válido, incluso una estructura de datos compleja o un 615procedimiento. 616 617A veces, el usuario quiere tener varias expresiones de Scheme 618dentro de un procedimiento. Existen dos formas en que se pueden 619combinar distintas expresiones. La primera es el procedimiento 620@code{begin}, que permite evaluar varias expresiones, y devuelve 621el valor de la última expresión. 622 623@lisp 624guile> (begin (+ 1 2) (- 5 8) (* 2 2)) 6254 626@end lisp 627 628La segunda forma de combinar varias expresiones es dentro de un 629bloque @code{let}. Dentro de un bloque let, se crean una serie de 630ligaduras o asignaciones, y después se evalúa una secuencia de 631expresiones que pueden incluir esas ligaduras o asignaciones. El 632valor de retorno del bloque let es el valor de retorno de la 633última sentencia del bloque let: 634 635@lisp 636guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4)) 637@dots{} (+ (* x y) (/ z x))) 638508 639@end lisp 640 641 642@node Condicionales de Scheme 643@subsection Condicionales de Scheme 644@translationof Scheme conditionals 645 646@menu 647* if:: 648* cond:: 649@end menu 650 651@node if 652@unnumberedsubsubsec if 653@translationof if 654 655Scheme tiene un procedimiento @code{if}: 656 657@example 658(if expresión-de-prueba expresión-de-cierto expresión-de-falso) 659@end example 660 661@var{expresión-de-prueba} es una expresión que devuelve un valor 662booleano. Si @var{expresión-de-prueba} devuelve @code{#t}, el 663procedimiento @code{if} devuelve el valor de la 664@var{expresión-de-cierto}, en caso contrario devuelve el valor de 665la @var{expresión-de-falso}. 666 667@lisp 668guile> (define a 3) 669guile> (define b 5) 670guile> (if (> a b) "a es mayor que b" "a no es mayor que b") 671"a no es mayor que b" 672@end lisp 673 674 675@node cond 676@unnumberedsubsubsec cond 677@translationof cond 678 679Otro procedimiento condicional en Scheme es @code{cond}: 680 681@example 682(cond (expresión-de-prueba-1 secuencia-de-expresiones-resultante-1) 683 (expresión-de-prueba-2 secuencia-de-expresiones-resultante-2) 684 @dots{} 685 (expresión-de-prueba-n secuencia-de-expresiones-resultante-n)) 686@end example 687 688Por ejemplo: 689 690@lisp 691guile> (define a 6) 692guile> (define b 8) 693guile> (cond ((< a b) "a es menor que b") 694... ((= a b) "a es igual a b") 695... ((> a b) "a es mayor que b")) 696"a es menor que b" 697@end lisp 698 699@node Scheme dentro de LilyPond 700@section Scheme dentro de LilyPond 701@translationof Scheme in LilyPond 702 703@menu 704* Sintaxis del Scheme de LilyPond:: 705* Variables de LilyPond:: 706* Variables de entrada y Scheme:: 707* Importación de Scheme dentro de LilyPond:: 708* Propiedades de los objetos:: 709* Variables de LilyPond compuestas:: 710* Representación interna de la música:: 711@end menu 712 713@node Sintaxis del Scheme de LilyPond 714@subsection Sintaxis del Scheme de LilyPond 715@translationof LilyPond Scheme syntax 716@funindex $ 717@funindex # 718 719El intérprete Guile forma parte de LilyPond, lo que significa que 720se puede incluir Scheme dentro de los archivos de entrada de 721LilyPond. Existen varios métodos para incluir Scheme dentro de 722LilyPond. 723 724La manera más sencilla es utilizar el símbolo de 725almohadilla@tie{}@code{#} antes de una expresión de Scheme. 726 727Ahora bien, el código de entrada de LilyPond se estructura en 728elementos y expresiones, de forma parecida a cómo el lenguaje 729humano se estructura en palabras y frases. LilyPond tiene un 730analizador léxico que reconoce elementos indivisibles (números 731literales, cadenas de texto, elementos de Scheme, nombres de nota, 732etc.), y un analizador que entiende la sintaxis, la Gramática de 733LilyPond (@rcontrib{LilyPond grammar}). Una vez que sabe que se 734aplica una regla sintáctica concreta, ejecuta las acciones 735asociadas con ella. 736 737El método del símbolo de almohadilla@tie{}@code{#} para incrustar 738Scheme se adapta de forma natural a este sistema. Una vez que el 739analizador léxico ve un símbolo de almohadilla, llama al lector de 740Scheme para que lea una expresión de Scheme completa (que puede 741ser un identificador, una expresión encerrada entre paréntesis, o 742algunas otras cosas). Después de que se ha leído la expresión de 743Scheme, se almacena como el valor de un elemento @code{SCM_TOKEN} 744de la gramática. Después de que el analizador sintáctico ya sabe 745cómo hacer uso de este elemento, llama a Guila para que evalúe la 746expresión de Scheme. Dado que el analizador sintáctico suele 747requerir un poco de lectura por delante por parte del analizador 748léxico para tomar sus decisiones de análisis sintáctico, esta 749separación de lectura y evaluación entre los analizadores léxico y 750sintáctico es justamente lo que se necesita para mantener 751sincronizadas las ejecuciones de expresiones de LilyPond y de 752Scheme. Por este motivo se debe usar el símbolo de 753almohadilla@tie{}@code{#} para llamar a Scheme siempre que sea 754posible. 755 756Otra forma de llamar al intérprete de Scheme desde LilyPond es el 757uso del símbolo de dólar@tie{}@code{$} en lugar de la almohadilla 758para introducir las expresiondes de Scheme. En este caso, 759LilyPond evalúa el código justo después de que el analizador 760léxico lo ha leído. Comprueba el tipo resultante de la expresión 761de Scheme y después selecciona un tipo de elemento (uno de los 762varios elementos @code{xxx_IDENTIFIER} dentro de la sintaxis) para 763él. Crea una @emph{copia} del valor y la usa como valor del 764elemento. Si el valor de la expresión es vacío (El valor de Guile 765de @code{*unspecified*}), no se pasa nada en absoluto al 766analizador sintáctico. 767 768Éste es, de hecho, el mismo mecanismo exactamente que LilyPond 769emplea cuando llamamos a cualquier variable o función musical por 770su nombre, como @code{\nombre}, con la única diferencia de que el 771nombre viene determinado por el analizador léxico de LilyPond sin 772consultar al lector de Scheme, y así solamente se aceptan los 773nombres de variable consistentes con el modo actual de LilyPond. 774 775La acción inmediata de @code{$} puede llevar a alguna que otra 776sorpresa, véase @ref{Importación de Scheme dentro de LilyPond}. 777La utilización de @code{#} donde el analizador sintáctico lo 778contempla es normalmente preferible. Dentro de las expresiones 779musicales, aquellas que se crean utilizando @code{#} @emph{se 780interprentan} como música. Sin embargo, @emph{no se copian} antes 781de ser utilizadas. Si forman parte de alguna estructura que aún 782podría tener algún uso, quizá tenga que utilizar explícitamente 783@code{ly:music-deep-copy}. 784 785@funindex $@@ 786@funindex #@@ 787También existen los operadores de @q{división de listas} 788@code{$@@} y @code{#@@} que insertan todos los elementos de una 789lista dentro del contexto circundante. 790 791Ahora echemos un vistazo a algo de código de Scheme real. Los 792procedimientos de Scheme se pueden definir dentro de los archivos 793de entrada de LilyPond: 794 795@example 796#(define (media a b c) (/ (+ a b c) 3)) 797@end example 798 799Observe que los comentarios de LilyPond (@code{%} y @code{%@{ 800%@}}) no se pueden utilizar dentro del código de Scheme, ni 801siquiera dentro de un archivo de entrada de LilyPond, porque es el 802intérprete Guile, y no el analizador léxico de LilyPond, el que 803está leyendo la expresión de Scheme. Los comentarios en el Scheme 804de Guile se introducen como sigue: 805 806@example 807; esto es un comentario de una línea 808 809#! 810 Esto es un comentario de bloque (no anidable) estilo Guile 811 Pero se usan rara vez por parte de los Schemers 812 y nunca dentro del código fuente de LilyPond 813!# 814@end example 815 816Durante el resto de esta sección, supondremos que los datos se 817introducen en un archivo de música, por lo que añadiremos una 818almohadilla@tie{}@code{#} al principio de cada una de las 819expresiones de Scheme. 820 821Todas las expresiones de Scheme del nivel jerárquico superior 822dentro de un archivo de entrada de LilyPond se pueden combinar en 823una sola expresión de Scheme mediante la utilización del operador 824@code{begin}: 825 826@example 827#(begin 828 (define fulanito 0) 829 (define menganito 1)) 830@end example 831 832 833@node Variables de LilyPond 834@subsection Variables de LilyPond 835@translationof LilyPond variables 836 837Las variables de LilyPond se almacenan internamente en la forma de 838variables de Scheme. Así, 839 840@example 841doce = 12 842@end example 843 844@noindent 845equivale a 846 847@example 848#(define doce 12) 849@end example 850 851Esto significa que las variables de LilyPond están disponibles 852para su uso dentro de expresiones de Scheme. Por ejemplo, 853podríamos usar 854 855@example 856veintiCuatro = (* 2 doce) 857@end example 858 859@noindent 860lo que daría lugar a que el número @emph{24} se almacenase dentro 861de la variable @code{veintiCuatro} de LilyPond (y de Scheme). 862 863El lenguaje Scheme permite la modificación de expresiones 864complejas in situ y LilyPond hace uso de esta @q{modificación in 865situ} al usar funciones musicales. Pero cuando las expresiones 866musicales se almacenan dentro de variables en lugar de ser 867introducidas directamente, lo que habitualmente se espera cuando 868se pasan a funciones musicales sería que el valor original quedase 869intacto. Así pues, cuando se referencia una variable musical con 870la barra invertida (como @code{\veintiCuatro}), LilyPond crea una 871copia del valor musical de tal variable para utilizarla dentro de 872la expresión musical circundante, en lugar de usar el valor de la 873variable directamente. 874 875Por ello, las expresiones musicales de Scheme escritas con la 876sintasis de almohadilla @code{#} deberían utilizarse para 877cualquier material creado @q{partiendo de cero} (o que se ha 878copiado explícitamente) en lugar de utilizarse para referenciar 879música directamente. 880 881@morerefs 882Manual de extensión: 883@ref{Sintaxis del Scheme de LilyPond}. 884 885@node Variables de entrada y Scheme 886@subsection Variables de entrada y Scheme 887@translationof Input variables and Scheme 888 889El formato de entrada contempla la noción de variables: en el 890siguiente ejemplo, se asigna una expresión musical a una variable 891con el nombre @code{traLaLa}. 892 893@example 894traLaLa = @{ c'4 d'4 @} 895@end example 896 897@noindent 898 899También hay una forma de ámbito: en el ejemplo siguiente, el 900bloque @code{\layout} también contiene una variable 901@code{traLaLa}, que es independiente de la @code{\traLaLa} 902externa. 903 904@example 905traLaLa = @{ c'4 d'4 @} 906\layout @{ traLaLa = 1.0 @} 907@end example 908 909@c 910En efecto, cada archivo de entrada constituye un ámbito, y cada 911bloque @code{\header}, @code{\midi} y @code{\layout} son ámbitos 912anidados dentro del ámbito de nivel superior. 913 914Tanto las variables como los ámbitos están implementados en el 915sistema de módulos de GUILE. A cada ámbito se adjunta un módulo 916anónimo de Scheme. Una asignación de la forma: 917 918@example 919traLaLa = @{ c'4 d'4 @} 920@end example 921 922@noindent 923se convierte internamente en una definición de Scheme: 924 925@example 926(define traLaLa @var{Valor Scheme de `@code{@dots{}}'}) 927@end example 928 929Esto significa que las variables de LilyPond y las variables de 930Scheme se pueden mezclar con libertad. En el ejemplo siguiente, 931se almacena un fragmento de música en la variable @code{traLaLa}, 932y se duplica usando Scheme. El resultado se importa dentro de un 933bloque @code{\score} por medio de una segunda variable 934@code{twice}: 935 936@lilypond[verbatim] 937traLaLa = { c'4 d'4 } 938 939#(define newLa (map ly:music-deep-copy 940 (list traLaLa traLaLa))) 941#(define twice 942 (make-sequential-music newLa)) 943 944\twice 945@end lilypond 946 947@c Due to parser lookahead 948 949En realidad, éste es un ejemplo bastante interesante. La 950asignación solo tiene lugar después de que el analizador 951sintáctico se ha asegurado de que no sigue nada parecido a 952@code{\addlyrics}, de manera que necesita comprobar lo que viene a 953continuación. Lee el símbolo @code{#} y la expresión de Scheme 954siguiente @emph{sin} evaluarla, de forma que puede proceder a la 955asignación, y @emph{posteriormente} ejecutar el código de Scheme 956sin problema. 957 958@node Importación de Scheme dentro de LilyPond 959@subsection Importación de Scheme dentro de LilyPond 960@translationof Importing Scheme in LilyPond 961@funindex $ 962@funindex # 963 964El ejemplo anterior muestra cómo @q{exportar} expresiones 965musicales desde la entrada al intérprete de Scheme. Lo contrario 966también es posible. Colocándolo después de @code{$}, un valor de 967Scheme se interpreta como si hubiera sido introducido en la 968sintaxis de LilyPond. En lugar de definir @code{\twice}, el 969ejemplo anterior podría también haberse escrito como 970 971@example 972@dots{} 973$(make-sequential-music newLa) 974@end example 975 976Podemos utilizar @code{$} con una expresión de Scheme en cualquier 977lugar en el que usaríamos @code{\@var{nombre}} después de haber 978asignado la expresión de Scheme a una variable @var{nombre}. Esta 979sustitución se produce dentro del @q{analizador léxico}, de manera 980que LilyPond no llega a darse cuenta de la diferencia. 981 982Sin embargo, existe un inconveniente, el de la medida del tiempo. 983Si hubiésemos estado usando @code{$} en vez de @code{#} para 984definir @code{newLa} en el ejemplo anterior, la siguiente 985definición de Scheme habría fracasado porque @code{traLaLa} no 986habría sido definida aún. Para ver una explicación de este 987problema de momento temporal, véase @ref{Sintaxis del Scheme de 988LilyPond}. 989 990@funindex $@@ 991@funindex #@@ 992Un conveniente aspecto posterior pueden ser los operadores de 993@q{división de listas} @code{$@@} y @code{#@@} para la inserción 994de los elementos de una lista dentro del contexto circundante. 995Utilizándolos, la última parte del ejemplo se podría haber escrito 996como 997 998@example 999@dots{} 1000@{ #@@newLa @} 1001@end example 1002 1003Aquí, cada elemento de la lista que está almacenado en 1004@code{newLa} se toma en secuencia y se inserta en la lista, como 1005si hubiésemos escrito 1006 1007@example 1008@{ #(first newLa) #(second newLa) @} 1009@end example 1010 1011Ahora bien, en todas esas formas, el código de Scheme se evalúa en 1012el momento en que el código de entrada aún se está procesando, ya 1013sea en el analizador léxico o en el analizador sintáctico. Si 1014necesitamos que se ejecute en un momento posterior, debemos 1015consultar @ref{Funciones de Scheme vacías}, o almacenarlo dentro 1016de un procedimiento: 1017 1018@example 1019#(define (nopc) 1020 (ly:set-option 'point-and-click #f)) 1021 1022@dots{} 1023#(nopc) 1024@{ c'4 @} 1025@end example 1026 1027@knownissues 1028 1029No es posible mezclar variables de Scheme y de LilyPond con la 1030opción @option{--safe}. 1031 1032 1033@node Propiedades de los objetos 1034@subsection Propiedades de los objetos 1035@translationof Object properties 1036 1037Las propiedades de los objetos se almacenan en LilyPond en forma 1038de cadenas de listas-A, que son listas de listas-A. Las 1039propiedades se establecen añadiendo valores al principio de la 1040lista de propiedades. Las propiedades se leen extrayendo valores 1041de las listas-A. 1042 1043El establecimiento de un valor nuevo para una propiedad requiere 1044la asignación de un valor a la lista-A con una clave y un valor. 1045La sintaxis de LilyPond para hacer esto es la siguiente: 1046 1047@example 1048\override Stem.thickness = #2.6 1049@end example 1050 1051Esta instrucción ajusta el aspecto de las plicas. Se añade una 1052entrada de lista-A @code{'(thickness . 2.6)} a la lista de 1053propiedades de un objeto @code{Stem}. @code{thickness} se mide a 1054partir del grosor de las líneas del pentagrama, y así estas plicas 1055serán @code{2.6} veces el grosor de las líneas del pentagrama. 1056Esto hace que las plicas sean casi el doble de gruesas de lo 1057normal. Para distinguir entre las variables que se definen en los 1058archivos de entrada (como @code{veintiCuatro} en el ejemplo 1059anterior) y las variables de los objetos internos, llamaremos a 1060las últimas @q{propiedades} y a las primeras @q{variables.} Así, 1061el objeto plica tiene una propiedad @code{thickness} (grosor), 1062mientras que @code{veintiCuatro} es una variable. 1063 1064@cindex propiedades frente a variables 1065@cindex variables frente a propiedades 1066 1067@c todo -- here we're getting interesting. We're now introducing 1068@c LilyPond variable types. I think this deserves a section all 1069@c its own 1070 1071@node Variables de LilyPond compuestas 1072@subsection Variables de LilyPond compuestas 1073@translationof LilyPond compound variables 1074 1075@menu 1076* Desplazamientos:: 1077* Fracciones:: 1078* Dimensiones:: 1079* Listas-A de propiedades:: 1080* Cadenas de listas-A:: 1081@end menu 1082 1083 1084@node Desplazamientos 1085@unnumberedsubsubsec Desplazamientos 1086@translationof Offsets 1087 1088Los desplazamientos bidimensionales (coordenadas X e Y) se 1089almacenan como @emph{parejas}. El @code{car} del desplazamiento 1090es la coordenada X, y el @code{cdr} es la coordenada Y. 1091 1092@example 1093\override TextScript.extra-offset = #'(1 . 2) 1094@end example 1095 1096Esto asigna la pareja @code{(1 . 2)} a la propiedad 1097@code{extra-offset} del objeto TextScript. Estos números se miden 1098en espacios de pentagrama, y así esta instrucción mueve el objeto 1099un espacio de pentagrama a la derecha, y dos espacios hacia 1100arriba. 1101 1102Los procedimientos para trabajar con desplazamientos están en 1103@file{scm/lily-library.scm}. 1104 1105@node Fracciones 1106@unnumberedsubsubsec Fracciones 1107@subheading Fractions 1108 1109Las fracciones tal y como se utilizan por parte de LilyPond se 1110almacenan, de nuevo, como @emph{parejas}, esta vez de enteros sin 1111signo. Mientras que Scheme es capaz de representar números 1112racionaes como un tipo nativo, musicalmente @samp{2/4} y 1113@samp{1/2} no son lo mismo, y necesitamos poder distinguir entre 1114ellos. De igual forma, no existe el concepto de @q{fracciones} 1115negativas en LilyPond. Así pues, @code{2/4} en LilyPond significa 1116@code{(2 . 4)} en Scheme, y @code{#2/4} en LilyPond significa 1117@code{1/2} en Scheme. 1118 1119 1120@node Dimensiones 1121@unnumberedsubsubsec Dimensiones 1122@translationof Extents 1123 1124Las parejas se usan también para almacenar intervalos, que 1125representan un rango de números desde el mínimo (el @code{car}) 1126hasta el máximo (el @code{cdr}). Los intervalos se usan para 1127almacenar las dimensiones en X y en Y de los objetos imprimibles. 1128Para dimensiones en X, el @code{car} es la coordenada X de la 1129parte izquierda, y el @code{cdr} es la coordenada X de la parte 1130derecha. Para las dimensiones en Y, el @code{car} es la 1131coordenada inferior, y el @code{cdr} es la coordenada superior. 1132 1133Los procedimientos para trabajar con intervalos están en 1134@file{scm/lily-library.scm}. Se deben usar estos procedimientos 1135siempre que sea posible, para asegurar la consistencia del código. 1136 1137 1138@node Listas-A de propiedades 1139@unnumberedsubsubsec Listas-A de propiedades 1140@translationof Property alists 1141 1142Una lista-A de propiedades es una estructura de datos de LilyPond 1143que es una lista-A cuyas claves son propiedades y cuyos valores 1144son expresiones de Scheme que dan el valor deseado de la 1145propiedad. 1146 1147Las propiedades de LilyPond son símbolos de Scheme, como por 1148ejemplo @code{'thickness}. 1149 1150 1151@node Cadenas de listas-A 1152@unnumberedsubsubsec Cadenas de listas-A 1153@translationof Alist chains 1154 1155Una cadena de listas-A es una lista que contiene listas-A de 1156propiedades. 1157 1158El conjunto de todas las propiedades que se aplican a un grob se 1159almacena por lo general como una cadena de listas-A. Para poder 1160encontrar el valor de una propiedad determinada que debería tener 1161un grob, se busca por todas las listas-A de la cadena, una a una, 1162tratando de encontrar una entrada que contenga la clave de la 1163propiedad. Se devuelve la primera entrada de lista-A que se 1164encuentre, y el valor es el valor de la propiedad. 1165 1166El procedimiento de Scheme @code{chain-assoc-get} se usa 1167normalmente para obtener los valores de propiedades. 1168 1169@node Representación interna de la música 1170@subsection Representación interna de la música 1171@translationof Internal music representation 1172 1173Internamente, la música se representa como una lista de Scheme. 1174La lista contiene varios elementos que afectan a la salida 1175impresa. El análisis sintáctico es el proceso de convertir la 1176música de la representación de entrada de LilyPond a la 1177representación interna de Scheme. 1178 1179Cuando se analiza una expresión musical, se convierte en un 1180conjunto de objetos musicales de Scheme. La propiedad definitoria 1181de un objeto musical es que ocupa un tiempo. El tiempo que ocupa 1182se llama @emph{duración}. Las duraciones se expresan como un 1183número racional que mide la longitud del objeto musical en 1184redondas. 1185 1186Un objeto musical tiene tres clases de tipos: 1187@itemize 1188@item 1189nombre musical: Cada expresión musical tiene un nombre. Por 1190ejemplo, una nota lleva a un @rinternals{NoteEvent}, y 1191@code{\simultaneous} lleva a una @rinternals{SimultaneousMusic}. 1192Hay una lista de todas las expresiones disponibles en el manual de 1193Referencia de funcionamiento interno, bajo el epígrafe 1194@rinternals{Music expressions}. 1195 1196@item 1197@q{type} (tipo) o interface: Cada nombre musical tiene varios 1198@q{tipos} o interfaces, por ejemplo, una nota es un @code{event}, 1199pero también es un @code{note-event}, un @code{rhythmic-event}, y 1200un @code{melodic-event}. Todas las clases de música están 1201listadas en el manual de Referencia de funcionamiento interno, 1202bajo el epígrafe @rinternals{Music classes}. 1203 1204@item 1205objeto de C++: Cada objeto musical está representado por un objeto 1206de la clase @code{Music} de C++. 1207@end itemize 1208 1209La información real de una expresión musical se almacena en 1210propiedades. Por ejemplo, un @rinternals{NoteEvent} tiene 1211propiedades @code{pitch} y @code{duration} que almacenan la altura 1212y la duración de esa nota. Hay una lista de todas la propiedades 1213disponibles en el manual de Referencia de funcionamiento interno, 1214bajo el epígrafe @rinternals{Music properties}. 1215 1216Una expresión musical compuesta es un objeto musical que contiene 1217otros objetos musicales dentro de sus propiedades. Se puede 1218almacenar una lista de objetos dentro de la propiedad 1219@code{elements} de un objeto musical, o un único objeto musical 1220@q{hijo} dentro de la propiedad @code{element}. Por ejemplo, 1221@rinternals{SequentialMusic} tiene su hijo dentro de 1222@code{elements}, y @rinternals{GraceMusic} tiene su argumento 1223único dentro de @code{element}. El cuerpo de una repetición se 1224almacena dentro de la propiedad @code{element} de 1225@rinternals{RepeatedMusic}, y las alternativas dentro de 1226@code{elements}. 1227 1228@node Construir funciones complicadas 1229@section Construir funciones complicadas 1230@translationof Building complicated functions 1231 1232Esta sección explica cómo reunir la información necesaria para 1233crear funciones musicales complicadas. 1234 1235@menu 1236* Presentación de las expresiones musicales:: 1237* Propiedades musicales:: 1238* Duplicar una nota con ligaduras (ejemplo):: 1239* Añadir articulaciones a las notas (ejemplo):: 1240@end menu 1241 1242 1243@node Presentación de las expresiones musicales 1244@subsection Presentación de las expresiones musicales 1245@translationof Displaying music expressions 1246 1247@cindex almacenamiento interno 1248@cindex imprimir expresiones musicales 1249@cindex representación interna, impresión de 1250@cindex displayMusic 1251@funindex \displayMusic 1252 1253Si se está escribiendo una función musical, puede ser muy 1254instructivo examinar cómo se almacena internamente una expresión 1255musical. Esto se puede hacer con la función musical 1256@code{\displayMusic}. 1257 1258@example 1259@{ 1260 \displayMusic @{ c'4\f @} 1261@} 1262@end example 1263 1264@noindent 1265imprime lo siguiente: 1266 1267@example 1268(make-music 1269 'SequentialMusic 1270 'elements 1271 (list (make-music 1272 'NoteEvent 1273 'articulations 1274 (list (make-music 1275 'AbsoluteDynamicEvent 1276 'text 1277 "f")) 1278 'duration 1279 (ly:make-duration 2 0 1/1) 1280 'pitch 1281 (ly:make-pitch 0 0 0)))) 1282@end example 1283 1284De forma predeterminada, LilyPond imprime estos mensajes sobre la 1285consola junto al resto de los mensajes. Para separar estos 1286mensajes y guardar el resultado de @code{\display@{LOQUESEA@}}, 1287puede especificar que se use un puerto de salida opcional: 1288 1289@example 1290@{ 1291 \displayMusic #(open-output-file "display.txt") @{ c'4\f @} 1292@} 1293@end example 1294 1295Esto sobreescribe el archivo de salida anterior cada vez ques e 1296llama; si necesitamos escribir más de una expresión, debemos usar 1297una variable para el puerto y reutilizarla: 1298@example 1299@{ 1300 port = #(open-output-file "display.txt") 1301 \displayMusic \port @{ c'4\f @} 1302 \displayMusic \port @{ d'4 @} 1303 #(close-output-port port) 1304@} 1305@end example 1306 1307El manual de Guile describe los puertos detalladamente. Solo es 1308realmente necesario cerrar el puerto si necesitamos leer el 1309archivo antes de que LilyPond termine; en el primer ejemplo, no 1310nos hemos molestado en hacerlo. 1311 1312Un poco de reformateo hace a la información anterior más fácil de 1313leer: 1314 1315@example 1316(make-music 'SequentialMusic 1317 'elements (list 1318 (make-music 'NoteEvent 1319 'articulations (list 1320 (make-music 'AbsoluteDynamicEvent 1321 'text 1322 "f")) 1323 'duration (ly:make-duration 2 0 1/1) 1324 'pitch (ly:make-pitch 0 0 0)))) 1325@end example 1326 1327Una secuencia musical @code{@{ @dots{} @}} tiene el nombre 1328@code{SequentialMusic}, y sus expresiones internas se almacenan 1329coma una lista dentro de su propiedad @code{'elements}. Una nota 1330se representa como un objeto @code{NoteEvent} (que almacena las 1331propiedades de duración y altura) con información adjunta (en este 1332caso, un evento @code{AbsoluteDynamicEvent} con una propiedad 1333@code{"f"} de texto) almacenada en su propiedad 1334@code{articulations}. 1335 1336@funindex{\void} 1337 1338@code{\displayMusic} devuelve la música que imprime en la consola, 1339y por ello se interpretará al tiempo que se imprime en la consola. 1340Para evitar la interpretación, escriba @code{\void} antes de 1341@code{\displayMusic}. 1342 1343@node Propiedades musicales 1344@subsection Propiedades musicales 1345@translationof Music properties 1346 1347@ignore 1348TODO -- make sure we delineate between @emph{music} properties, 1349@emph{context} properties, and @emph{layout} properties. These 1350are potentially confusing. 1351@end ignore 1352 1353Veamos un ejemplo: 1354 1355@example 1356someNote = c' 1357\displayMusic \someNote 1358===> 1359(make-music 1360 'NoteEvent 1361 'duration 1362 (ly:make-duration 2 0 1/1) 1363 'pitch 1364 (ly:make-pitch 0 0 0)) 1365@end example 1366 1367El objeto @code{NoteEvent} es la representación de 1368@code{someNote}. Sencillo. ¿Y si ponemos el c' dentro de un 1369acorde? 1370 1371@example 1372someNote = <c'> 1373\displayMusic \someNote 1374===> 1375(make-music 1376 'EventChord 1377 'elements 1378 (list (make-music 1379 'NoteEvent 1380 'duration 1381 (ly:make-duration 2 0 1/1) 1382 'pitch 1383 (ly:make-pitch 0 0 0)))) 1384@end example 1385 1386Ahora el objeto @code{NoteEvent} es el primer objeto de la 1387propiedad @code{'elements} de @code{someNote}. 1388 1389La función @code{display-scheme-music} es la función que se usa 1390por parte de @code{\displayMusic} para imprimir la representación 1391de Scheme de una expresión musical. 1392 1393@example 1394#(display-scheme-music (first (ly:music-property someNote 'elements))) 1395===> 1396(make-music 1397 'NoteEvent 1398 'duration 1399 (ly:make-duration 2 0 1/1) 1400 'pitch 1401 (ly:make-pitch 0 0 0)) 1402@end example 1403 1404Después se accede a la altura de la nota a través de la propiedad 1405@code{'pitch} del objeto @code{NoteEvent}: 1406 1407@example 1408#(display-scheme-music 1409 (ly:music-property (first (ly:music-property someNote 'elements)) 1410 'pitch)) 1411===> 1412(ly:make-pitch 0 0 0) 1413@end example 1414 1415La altura de la nota se puede cambiar estableciendo el valor de 1416esta propiedad @code{'pitch}. 1417 1418@funindex \displayLilyMusic 1419 1420@example 1421#(set! (ly:music-property (first (ly:music-property someNote 'elements)) 1422 'pitch) 1423 (ly:make-pitch 0 1 0)) ;; establecer la altura a d'. 1424\displayLilyMusic \someNote 1425===> 1426d'4 1427@end example 1428 1429 1430@node Duplicar una nota con ligaduras (ejemplo) 1431@subsection Duplicar una nota con ligaduras (ejemplo) 1432@translationof Doubling a note with slurs (example) 1433 1434Supongamos que queremos crear una función que convierte una 1435entrada como @code{a} en @code{@{ a( a) @}}. Comenzamos 1436examinando la representación interna de la música con la que 1437queremos terminar. 1438 1439@example 1440\displayMusic@{ a'( a') @} 1441===> 1442(make-music 1443 'SequentialMusic 1444 'elements 1445 (list (make-music 1446 'NoteEvent 1447 'articulations 1448 (list (make-music 1449 'SlurEvent 1450 'span-direction 1451 -1)) 1452 'duration 1453 (ly:make-duration 2 0 1/1) 1454 'pitch 1455 (ly:make-pitch 0 5 0)) 1456 (make-music 1457 'NoteEvent 1458 'articulations 1459 (list (make-music 1460 'SlurEvent 1461 'span-direction 1462 1)) 1463 'duration 1464 (ly:make-duration 2 0 1/1) 1465 'pitch 1466 (ly:make-pitch 0 5 0)))) 1467@end example 1468 1469La mala noticia es que las expresiones @code{SlurEvent} se deben 1470añadir @q{dentro} de la nota (dentro de la propiedad 1471@code{articulations}). 1472 1473Ahora examinamos la entrada. 1474 1475@example 1476\displayMusic a' 1477===> 1478(make-music 1479 'NoteEvent 1480 'duration 1481 (ly:make-duration 2 0 1/1) 1482 'pitch 1483 (ly:make-pitch 0 5 0)))) 1484@end example 1485 1486Así pues, en nuestra función, tenemos que clonar esta expresión 1487(de forma que tengamos dos notas para construir la secuencia), 1488añadir @code{SlurEvent} a la propiedad @code{'articulations} de 1489cada una de ellas, y por último hacer una secuencia 1490@code{SequentialMusic} con los dos elementos @code{NoteEvent}. 1491Para añadir a una propiedad, es útil saber que una propiedad no 1492establecida se lee como @code{'()}, la lista vacía, así que no se 1493requiere ninguna comprobación especial antes de que pongamos otro 1494elemento delante de la propiedad @code{articulations}. 1495 1496 1497@example 1498doubleSlur = #(define-music-function (note) (ly:music?) 1499 "Return: @{ note ( note ) @}. 1500 `note' is supposed to be a single note." 1501 (let ((note2 (ly:music-deep-copy note))) 1502 (set! (ly:music-property note 'articulations) 1503 (cons (make-music 'SlurEvent 'span-direction -1) 1504 (ly:music-property note 'articulations))) 1505 (set! (ly:music-property note2 'articulations) 1506 (cons (make-music 'SlurEvent 'span-direction 1) 1507 (ly:music-property note2 'articulations))) 1508 (make-music 'SequentialMusic 'elements (list note note2)))) 1509@end example 1510 1511 1512@node Añadir articulaciones a las notas (ejemplo) 1513@subsection Añadir articulaciones a las notas (ejemplo) 1514@translationof Adding articulation to notes (example) 1515 1516La manera fácil de añadir articulación a las notas es juxtaponer dos 1517expresiones musicales. Sin embargo, 1518supongamos que queremos escribir una función musical que lo haga. 1519 1520Una @code{$variable} dentro de la notación @code{#@{@dots{}#@}} es 1521como una @code{\variable} normal en la notación clásica de 1522LilyPond. Podríamos escribir 1523 1524@example 1525@{ \music -. -> @} 1526@end example 1527 1528@noindent 1529pero a los efectos de este ejemplo, aprenderemos ahora cómo 1530hacerlo en Scheme. Empezamos examinando nuestra entrada y la 1531salida deseada. 1532 1533@example 1534% input 1535\displayMusic c4 1536===> 1537(make-music 1538 'NoteEvent 1539 'duration 1540 (ly:make-duration 2 0 1/1) 1541 'pitch 1542 (ly:make-pitch -1 0 0)))) 1543===== 1544% desired output 1545\displayMusic c4-> 1546===> 1547(make-music 1548 'NoteEvent 1549 'articulations 1550 (list (make-music 1551 'ArticulationEvent 1552 'articulation-type 1553 "accent")) 1554 'duration 1555 (ly:make-duration 2 0 1/1) 1556 'pitch 1557 (ly:make-pitch -1 0 0)) 1558@end example 1559 1560Vemos que una nota (@code{c4}) se representa como una expresión 1561@code{NoteEvent}. Para añadir una articulación de acento, se debe 1562añadir una expresión @code{ArticulationEvent} a la propiedad 1563@code{articulations} de la expresión @code{NoteEvent}. 1564 1565Para construir esta función, empezamos con 1566 1567@example 1568(define (add-accent note-event) 1569 "Add an accent ArticulationEvent to the articulations of `note-event', 1570 which is supposed to be a NoteEvent expression." 1571 (set! (ly:music-property note-event 'articulations) 1572 (cons (make-music 'ArticulationEvent 1573 'articulation-type "accent") 1574 (ly:music-property note-event 'articulations))) 1575 note-event) 1576@end example 1577 1578La primera línea es la forma de definir una función en Scheme: el 1579nombre de la función es @code{add-accent}, y tiene una variable 1580llamada @code{note-event}. En Scheme, el tipo de variable suele 1581quedar claro a partir de su nombre (¡esto también es una buena 1582práctica en otros lenguajes de programación!) 1583 1584@example 1585"Add an accent@dots{}" 1586@end example 1587 1588@noindent 1589es una descripción de lo que hace la función. No es estrictamente 1590necesaria, pero de igual forma que los nombres claros de variable, 1591es una buena práctica. 1592 1593Se preguntará por qué modificamos el evento de nota directamente 1594en lugar de trabajar sobre una copia (se puede usar 1595@code{ly:music-deep-copy} para ello). La razón es un contrato 1596silencioso: se permite que las funciones musicales modifiquen sus 1597argumentos; o bien se generan partiendo de cero (como la entrada 1598del usuario) o están ya copiadas (referenciar una variable de 1599música con @samp{\name} o la música procedente de expresiones de 1600Scheme inmediatas @samp{$(@dots{})} proporcionan una copia). Dado 1601que sería ineficiente crear copias innecesarias, el valor devuelto 1602de una función musical @emph{no} se copia. Así pues, para cumplir 1603dicho contrato, no debemos usar ningún argumento más de una vez, y 1604devolverlo cuenta como una vez. 1605 1606En un ejemplo anterior, hemos construido música mediante la 1607repetición de un argumento musical dado. En tal caso, al menos 1608una repetidión tuvo que ser una copia de sí misma. Si no lo 1609fuese, podrían ocurrir cosas muy extrañas. Por ejemplo, si usamos 1610@code{\relative} o @code{\transpose} sobre la música resultante 1611que contiene los mismos elementos varias veces, estarían sujetos 1612varias veces a la relativización o al transporte. Si los 1613asignamos a una variable de música, se rompe el curso porque hacer 1614referencia a @samp{\name} creará de nuevo una copia que no retiene 1615la identidad de los elementos repetidos. 1616 1617Ahora bien, aun cuando la función anterior no es una función 1618musical, se usará normalmente dentro de funciones musicales. Así 1619pues, tiene sentido obedecer el mismo convenio que usamos para las 1620funciones musicales: la entrada puede modificarse para producir la 1621salida, y el código que llama es responsable de crear las copias 1622si aún necesita el propio argumento sin modificar. Si observamos 1623las propias funciones de LilyPond como @code{music-map}, veremos 1624que se atienen a los mismos principios. 1625 1626¿En qué punto nos encontramos? Ahora tenemos un @code{note-event} 1627que podemos modificar, no a causa de la utilización de 1628@code{ly:music-deep-copy} sino por una explicación muy 1629desarrollada. Añadimos el acento a su propiedad de lista 1630@code{'articulations}. 1631 1632@example 1633(set! place new-value) 1634@end example 1635 1636Aquí, lo que queremos establecer (el @q{place}) es la propiedad 1637@code{'articulations} de la expresión @code{note-event}. 1638 1639@example 1640(ly:music-property note-event 'articulations) 1641@end example 1642 1643@code{ly:music-property} es la función ustilizada para acceder a las 1644propiedades musicales (las @code{'articulations}, @code{'duration}, 1645@code{'pitch}, etc, que vemos arriba en la salida de 1646@code{\displayMusic}). El nuevo valor es la antigua propiedad 1647@code{'articulations}, con un elemento adicional: la expresión 1648@code{ArticulationEvent}, que copiamos a partir de la salida de 1649@code{\displayMusic}, 1650 1651@example 1652(cons (make-music 'ArticulationEvent 1653 'articulation-type "accent") 1654 (ly:music-property result-event-chord 'articulations)) 1655@end example 1656 1657Se usa @code{cons} para añadir un elemento a la parte delantera de 1658una lista sin modificar la lista original. Esto es lo que 1659queremos: la misma lista de antes, más la nueva expresión 1660@code{ArticulationEvent}. El orden dentro de la propiedad 1661@code{'articulations} no tiene importancia aquí. 1662 1663Finalmente, una vez hemos añadido la articulación de acento a su 1664propiedad @code{articulations}, podemos devolver 1665@code{note-event}, de aquí la última línea de la función. 1666 1667Ahora transformamos la función @code{add-accent} en una función 1668musical (es cuestión de un poco de aderezo sintáctico y una 1669declaración del tipo de su argumento). 1670 1671@example 1672addAccent = #(define-music-function (note-event) 1673 (ly:music?) 1674 "Add an accent ArticulationEvent to the articulations of `note-event', 1675 which is supposed to be a NoteEvent expression." 1676 (set! (ly:music-property note-event 'articulations) 1677 (cons (make-music 'ArticulationEvent 1678 'articulation-type "accent") 1679 (ly:music-property note-event 'articulations))) 1680 note-event) 1681@end example 1682 1683A continuación verificamos que esta función musical funciona 1684correctamente: 1685 1686@example 1687\displayMusic \addAccent c4 1688@end example 1689 1690 1691@ignore 1692@menu 1693* Trucos con Scheme:: 1694@end menu 1695 1696@c @nod e Trucos con Scheme 1697@c @sectio n Trucos con Scheme 1698@c @transl ationof Tweaking with Scheme 1699 1700Hemos visto cómo la salida de LilyPond se puede modificar 1701profundamente usando instrucciones como 1702@code{\override TextScript.extra-offset = ( 1 . -1)}. 1703Pero tenemos incluso mucho más poder si 1704utilizamos Scheme. Para ver una explicación completa de esto, 1705consulte el @ref{Tutorial de Scheme}, y @ruser{Interfaces para programadores}. 1706 1707Podemos usar Scheme simplemente para sobreescribir instrucciones con 1708@code{\override}, 1709 1710TODO Find a simple example 1711@c This isn't a valid example with skylining 1712@c It works fine without padText -td 1713@end ignore 1714 1715@ignore 1716@lilypond[quote,verbatim,ragged-right] 1717padText = #(define-music-function (padding) (number?) 1718#{ 1719 \once \override TextScript.padding = #padding 1720#}) 1721 1722\relative { 1723 c'''4^"piu mosso" b a b 1724 \padText #1.8 1725 c4^"piu mosso" d e f 1726 \padText #2.6 1727 c4^"piu mosso" fis a g 1728} 1729@end lilypond 1730@end ignore 1731 1732@ignore 1733Lo podemos usar para crear instrucciones nuevas: 1734 1735@c Check this is a valid example with skylining 1736@c It is - 'padding still works 1737 1738 1739@lilypond[quote,verbatim,ragged-right] 1740tempoPadded = #(define-music-function (padding tempotext) 1741 (number? markup?) 1742#{ 1743 \once \override Score.MetronomeMark.padding = #padding 1744 \tempo \markup { \bold #tempotext } 1745#}) 1746 1747\relative { 1748 \tempo \markup { "Low tempo" } 1749 c''4 d e f g1 1750 \tempoPadded #4.0 "High tempo" 1751 g4 f e d c1 1752} 1753@end lilypond 1754 1755 1756Incluso se le pueden pasar expresiones musicales: 1757 1758@lilypond[quote,verbatim,ragged-right] 1759pattern = #(define-music-function (x y) (ly:music? ly:music?) 1760#{ 1761 #x e8 a b #y b a e 1762#}) 1763 1764\relative c''{ 1765 \pattern c8 c8\f 1766 \pattern {d16 dis} { ais16-> b\p } 1767} 1768@end lilypond 1769@end ignore 1770