]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/es/extending/scheme-tutorial.itely
Rerun scripts/auxiliar/update-with-convert-ly.sh
[lilypond.git] / Documentation / es / extending / scheme-tutorial.itely
index 3afef4b85f5e89d53492b8b78cbb10eec01ae2bf..1081c7560df9182b1672ef28354261bc824d494b 100644 (file)
@@ -1,20 +1,19 @@
 @c -*- coding: utf-8; mode: texinfo; documentlanguage: es -*-
 
 @ignore
-    Translation of GIT committish: fe2cae0fa47ec4ec0184e6b3d15572fbcba881cf
+    Translation of GIT committish: 26a079ca2393d053315ef8dbef626c897dc9645a
 
     When revising a translation, copy the HEAD committish of the
     version that you are working on.  For details, see the Contributors'
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.13.29"
+@c \version "2.17.6"
 
 @node Tutorial de Scheme
 @appendix Tutorial de Scheme
 @translationof Scheme tutorial
 
-@funindex #
 @cindex Scheme
 @cindex GUILE
 @cindex Scheme, código en línea
@@ -74,13 +73,21 @@ Guile de Scheme.  Sobre casi todos los sistemas puede experimentar en
 una @qq{caja de arena} de Scheme abriendo una ventana del terminal y
 tecleando @q{guile}.  En algunos sistemas, sobre todo en Windows,
 podría necesitar ajustar la variable de entorno @code{GUILE_LOAD_PATH}
-a la carpeta @code{../usr/shr/guile/1.8} dentro de la instalación de
+a la carpeta @code{../usr/share/guile/1.8} dentro de la instalación de
 LilyPond (para conocer la ruta completa a esta carpeta, consulte
 @rlearning{Otras fuentes de información}).  Como alternativa, los
 usuarios de Windows pueden seleccionar simplemente @q{Ejecutar} del
 menú Inicio e introducir @q{guile}.
 
-Una vez está funcionando el cajón de arena de Guile, verá un indicador
+Sin embargo, está disponible un cajón de arena de Scheme listo para
+funcionar con todo LilyPond cargado, con esta instrucción de la línea
+de órdenes:
+@example
+lilypond scheme-sandbox
+@end example
+
+@noindent
+Una vez está funcionando el cajón de arena, verá un indicador
 del sistema de Guile:
 
 @lisp
@@ -88,7 +95,12 @@ guile>
 @end lisp
 
 Podemos introducir expresiones de Scheme en este indicador para
-experimentar con Scheme.
+experimentar con Scheme.  Si quiere usar la biblioteca readline de GNU
+para una más cómoda edición de la línea de órdenes de Scheme, consulte
+el archivo @file{ly/scheme-sandbox.ly} para más información.  Si ya ha
+activado la biblioteca readline para las sesiones de Guile
+interactivas fuera de LilyPond, debería funcionar también en el cajón
+de arena.
 
 @node Variables de Scheme
 @subsection Variables de Scheme
@@ -161,7 +173,7 @@ Los valores Booleanos son Verdadero y Falso.  Verdadero en Scheme es
 
 @item Números
 Los números se escriben de la forma normal, @code{1} es el número
-(entero) uno, mientras que @code{-1.5} es un número en coma flotante
+(entero) uno, mientras que @w{@code{-1.5}} es un número en coma flotante
 (un número no entero).
 
 @item Cadenas
@@ -631,6 +643,7 @@ guile> (cond ((< a b) "a es menor que b")
 * Sintaxis del Scheme de LilyPond::
 * Variables de LilyPond::
 * Variables de entrada y Scheme::
+* Importación de Scheme dentro de LilyPond::
 * Propiedades de los objetos::
 * Variables de LilyPond compuestas::
 * Representación interna de la música::
@@ -639,30 +652,90 @@ guile> (cond ((< a b) "a es menor que b")
 @node Sintaxis del Scheme de LilyPond
 @subsection Sintaxis del Scheme de LilyPond
 @translationof LilyPond Scheme syntax
+@funindex $
+@funindex #
 
 El intérprete Guile forma parte de LilyPond, lo que significa que se
 puede incluir Scheme dentro de los archivos de entrada de LilyPond.
-La marca de almohadilla @code{#} se utiliza para indicar al analizador
-sintáctico de LilyPond que lo siguiente es un valor de Scheme.
-
-Una vez el analizador sintáctico se encuentra con un símbolo de
-almohadilla, la entrada se le pasa al intérprete Guile para evaluar la
-expresión de Scheme.  El intérprete continúa procesando la entrada
-hasta que se encuentra con el final de una expresión de Scheme.
-
-Los procedimientos de Scheme se pueden definir 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@tie{}@code{#} 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
+sintáctico que entiende la sintaxis, la @ruser{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@tie{}@code{#} 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 @code{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@tie{}@code{#} 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@tie{}@code{$} 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
+@code{xxx_IDENTIFIER} dentro de la sintaxis) para él.  Crea una
+@emph{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 @code{*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 @code{\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 @code{$} puede llevar a alguna que otra
+sorpresa, véase @ref{Variables de entrada y Scheme}.  La utilización
+de @code{#} donde el analizador sintáctico lo contempla es normalmente
+preferible.  Dentro de las expresiones musicales, aquellas que se
+crean utilizando @code{#} @emph{se interprentan} como música.  Sin
+embargo, @emph{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 @code{ly:music-deep-copy}.
+
+@funindex $@@
+@funindex #@@
+También existen los operadores de @q{división de listas} @code{$@@} y
+@code{#@@} 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:
 
 @example
-#(define (average a b c) (/ (+ a b c) 3))
+#(define (media a b c) (/ (+ a b c) 3))
 @end example
 
 Observe que los comentarios de LilyPond (@code{%} y @code{%@{ %@}}) no
 se pueden utilizar dentro del código de Scheme, ni siquiera dentro de
-un archivo de entrada de LilyPond input file, porque es el intérprete
-Guile, y no el analizador sintáctico de LilyPond, el que está
-interpretando la expresión de Scheme.  Los comentarios en el Scheme de
-Guile se introducen como sigue:
+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:
 
 @example
 ; esto es un comentario de una línea
@@ -675,8 +748,8 @@ Guile se introducen como sigue:
 @end example
 
 Durante el resto de esta sección, supondremos que los datos se
-introducen en un archivo de música, por lo que añadiremos almohadillas
-@code{#} al principio de todas las expresiones de Scheme.
+introducen en un archivo de música, por lo que añadiremos
+almohadillas@tie{}@code{#} al principio de todas 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
@@ -718,6 +791,18 @@ veintiCuatro = (* 2 doce)
 lo que daría lugar a que el número 24 se almacenase dentro de la
 variable @code{veintiCuatro} de LilyPond (y de Scheme).
 
+La forma usual de referirse a las variables de LilyPond,
+@ref{Sintaxis del Scheme de LilyPond},
+
+es llamarlas usando una barra invertida, es decir
+@code{\veintiCuatro}.  Dado que esto crea una copia para la mayor
+parte de los tipos internos de LilyPond, concretamente las expresiones
+musicales, las funciones musicales no sueln crear copias del material
+que ellas mismas modifican.  Por este motivo, las expresiones
+musicales dadas con @code{#} no deberían, por lo general, contener
+material que no se haya creado partiendo de cero o copiado
+explícitamente en lugar de estar referenciado directamente.
+
 @node Variables de entrada y Scheme
 @subsection Variables de entrada y Scheme
 @translationof Input variables and Scheme
@@ -770,40 +855,81 @@ usando Scheme.  El resultado se importa dentro de un bloque
 @lilypond[verbatim]
 traLaLa = { c'4 d'4 }
 
-%% dummy action to deal with parser lookahead
-#(display "this needs to be here, sorry!")
-
 #(define newLa (map ly:music-deep-copy
   (list traLaLa traLaLa)))
 #(define twice
   (make-sequential-music newLa))
 
-{ \twice }
+\twice
 @end lilypond
 
 @c Due to parser lookahead
 
-En este ejemplo, la asignación se produce después de que el analizador
-sintáctico ha verificado que no ocurre nada interesante después de
-@code{traLaLa = @{ ... @}}.  Sin la sentencia muda del ejemplo
-anterior, la definición de @code{newLa} se ejecuta antes de que se
-defina @code{traLaLa}, produciendo un error de sintaxis.
+En realidad, éste es un ejemplo bastante interesante.  La asignación
+solo tiene lugar después de que el analizador sintáctico se ha
+asegurado de que no sigue nada parecido a @code{\addlyrics}, de manera
+que necesita comprobar lo que viene a continuación.  Lee el símbolo
+@code{#} y la expresión de Scheme siguiente @emph{sin} evaluarla, de
+forma que puede proceder a la asignación, y @emph{posteriormente}
+ejecutar el código de Scheme sin problema.
+
+@node Importación de Scheme dentro de LilyPond
+@subsection Importación de Scheme dentro de LilyPond
+@translationof Importing Scheme in LilyPond
+@funindex $
+@funindex #
 
 El ejemplo anterior muestra cómo @q{exportar} expresiones musicales
 desde la entrada al intérprete de Scheme.  Lo contrario también es
-posible.  Envolviendo un valor de Scheme en la función
-@code{ly:export}, se interpreta un valor de Scheme como si hubiera
-sido introducido en la sintaxis de LilyPond.  En lugar de definir
-@code{\twice}, el ejemplo anterior podría también haberse escrito como
+posible.  Colocándolo después de @code{$}, un valor de Scheme se
+interpreta como si hubiera sido introducido en la sintaxis de
+LilyPond.  En lugar de definir @code{\twice}, el ejemplo anterior
+podría también haberse escrito como
 
 @example
 ...
-@{ #(ly:export (make-sequential-music (list newLa))) @}
+$(make-sequential-music newLa)
 @end example
 
-El código de Scheme se evalúa tan pronto como el analizador sintáctico
-lo encuentra.  Para definir código de Scheme dentro de un macro (para
-llamarse más tarde), utilice @ref{Funciones vacías}, o bien
+Podemos utilizar @code{$} con una expresión de Scheme en cualquier
+lugar en el que usaríamos @code{\@var{nombre}} después de haber
+asignado la expresión de Scheme a una variable @var{nombre}.  Esta
+sustitución se produce dentro del @q{analizador léxico}, de manera que
+LilyPond no llega a darse cuenta de la diferencia.
+
+Sin embargo, existe un inconveniente, el de la medida del tiempo.  Si
+hubiésemos estado usando @code{$} en vez de @code{#} para definir
+@code{newLa} en el ejemplo anterior, la siguiente definición de Scheme
+habría fracasado porque @code{traLaLa} no habría sido definida aún.
+Para ver una explicación de este problema de momento temporal, véase
+@ref{Sintaxis del Scheme de LilyPond}.
+
+@funindex $@@
+@funindex #@@
+Un conveniente aspecto posterior pueden ser los operadores de
+@q{división de listas} @code{$@@} y @code{#@@} para la inserción de
+los elementos de una lista dentro del contexto circundante.
+Utilizándolos, la última parte del ejemplo se podría haber escrito
+como
+
+@example
+...
+@{ #@@newLa @}
+@end example
+
+Aquí, cada elemento de la lista que está almacenado en @code{newLa} se
+toma en secuencia y se inserta en la lista, como si hubiésemos escrito
+
+@example
+@{ #(first newLa) #(second newLa) @}
+@end example
+
+Ahora bien, en todas esas formas, el código de Scheme se evalúa en el
+momento en que el código de entrada aún se está procesando, ya sea en
+el analizador léxico o en el analizador sintáctico.  Si necesitamos
+que se ejecute en un momento posterior, debemos consultar
+@ref{Funciones de Scheme vacías}, o almacenarlo dentro de un
+procedimiento:
 
 @example
 #(define (nopc)
@@ -817,7 +943,7 @@ llamarse más tarde), utilice @ref{Funciones vacías}, o bien
 @knownissues
 
 No es posible mezclar variables de Scheme y de LilyPond con la opción
-@code{--safe}.
+@option{--safe}.
 
 
 @node Propiedades de los objetos
@@ -834,7 +960,7 @@ asignación de un valor a la lista-A con una clave y un valor.  La
 sintaxis de LilyPond para hacer esto es la siguiente:
 
 @example
-\override Stem #'thickness = #2.6
+\override Stem.thickness = #2.6
 @end example
 
 Esta instrucción ajusta el aspecto de las plicas.  Se añade una
@@ -864,11 +990,11 @@ tiene una propiedad @code{thickness} (grosor), mientras que
 @subheading Desplazamientos
 
 Los desplazamientos bidimensionales (coordenadas X e Y) se almacenan
-como @code{parejas}.  El @code{car} del desplazamiento es la
+como @emph{parejas}.  El @code{car} del desplazamiento es la
 coordenada X, y el @code{cdr} es la coordenada Y.
 
 @example
-\override TextScript #'extra-offset = #'(1 . 2)
+\override TextScript.extra-offset = #'(1 . 2)
 @end example
 
 Esto asigna la pareja @code{(1 . 2)} a la propiedad
@@ -879,6 +1005,16 @@ espacio de pentagrama a la derecha, y dos espacios hacia arriba.
 Los procedimientos para trabajar con desplazamientos están en
 @file{scm/lily-library.scm}.
 
+@subheading Fractions
+
+Fractions as used by LilyPond are again stored as @emph{pairs}, this
+time of unsigned integers.  While Scheme can represent rational numbers
+as a native type, musically @samp{2/4} and @samp{1/2} are not the same,
+and we need to be able to distinguish between them.  Similarly there are
+no negative @q{fractions} in LilyPond's mind.  So @code{2/4} in LilyPond
+means @code{(2 . 4)} in Scheme, and @code{#2/4} in LilyPond means
+@code{1/2} in Scheme.
+
 @subheading Dimensiones
 
 Las parejas se usan también para almacenar intervalos, que representan
@@ -1019,18 +1155,16 @@ imprime lo siguiente:
   'SequentialMusic
   'elements
   (list (make-music
-          'EventChord
-          'elements
+          'NoteEvent
+          'articulations
           (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 0 0))
-                (make-music
                   'AbsoluteDynamicEvent
                   'text
-                  "f")))))
+                  "f"))
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch 0 0 0))))
 @end example
 
 De forma predeterminada, LilyPond imprime estos mensajes sobre la
@@ -1042,27 +1176,45 @@ salida a un archivo.
 lilypond archivo.ly >salida.txt
 @end example
 
-Con la aplicación de un poco de formateo, la información anterior es
-fácil de leer,
+Con un poco de magia combinada de LilyPond y Scheme, podemos realmente
+hacer que LilyPond dirija solamente esta salida a su propio archivo:
+
+@example
+@{
+  #(with-output-to-file "display.txt"
+      (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
+@}
+@end example
+
+
+Un poco de reformateo hace a la información anterior más fácil de
+leer:
 
 @example
 (make-music 'SequentialMusic
-  'elements (list (make-music 'EventChord
-                    'elements (list (make-music 'NoteEvent
-                                      'duration (ly:make-duration 2 0 1 1)
-                                      'pitch (ly:make-pitch 0 0 0))
-                                    (make-music 'AbsoluteDynamicEvent
-                                      'text "f")))))
+  'elements (list
+            (make-music 'NoteEvent
+               'articulations (list
+                              (make-music 'AbsoluteDynamicEvent
+                                'text
+                                "f"))
+              'duration (ly:make-duration 2 0 1 1)
+              'pitch    (ly:make-pitch 0 0 0))))
 @end example
 
 Una secuencia musical @code{@{ ... @}} tiene el nombre
 @code{SequentialMusic}, y sus expresiones internas se almacenan coma
 una lista dentro de su propiedad @code{'elements}.  Una nota se
-representa como una expresión @code{EventChord} que contiene un objeto
-@code{NoteEvent} (que almacena las propiedades de duración y altura) y
-cualquier información adicional (en este caso, un evento
-@code{AbsoluteDynamicEvent} con una propiedad @code{"f"} de texto.
+representa como un objeto @code{NoteEvent} (que almacena las
+propiedades de duración y altura) con información adjunta (en este
+caso, un evento @code{AbsoluteDynamicEvent} con una propiedad
+@code{"f"} de texto) almacenada en su propiedad @code{articulations}.
 
+@funindex{\void}
+@code{\displayMusic} devuelve la música que imprime en la consola, y
+por ello se interpretará al tiempo que se imprime en la consola.  Para
+evitar la interpretación, escriba @code{\void} antes de
+@code{\displayMusic}.
 
 @node Propiedades musicales
 @subsection Propiedades musicales
@@ -1072,13 +1224,27 @@ cualquier información adicional (en este caso, un evento
 @c @emph{context} properties, and @emph{layout} properties.  These
 @c are potentially confusing.
 
-El objeto @code{NoteEvent} es el primer objeto de la propiedad
-@code{'elements} de @code{someNote}.
+Veamos un ejemplo:
 
 @example
 someNote = c'
 \displayMusic \someNote
 ===>
+(make-music
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch 0 0 0))
+@end example
+
+The @code{NoteEvent} object is the representation of @code{someNote}.
+Straightforward.  How about putting c' in a chord?
+
+@example
+someNote = <c'>
+\displayMusic \someNote
+===>
 (make-music
   'EventChord
   'elements
@@ -1090,6 +1256,9 @@ someNote = c'
           (ly:make-pitch 0 0 0))))
 @end example
 
+Ahora el objeto @code{NoteEvent} es el primer objeto
+de la propiedad @code{'elements} de @code{someNote}.
+
 La función @code{display-scheme-music} es la función que se usa por
 parte de @code{\displayMusic} para imprimir la representación de
 Scheme de una expresión musical.
@@ -1136,7 +1305,7 @@ d'
 @translationof Doubling a note with slurs (example)
 
 Supongamos que queremos crear una función que convierte una entrada
-como @code{a} en @code{a( a)}.  Comenzamos examinando la
+como @code{a} en @code{@{ a( a) @}}.  Comenzamos examinando la
 representación interna de la música con la que queremos terminar.
 
 @example
@@ -1146,71 +1315,68 @@ representación interna de la música con la que queremos terminar.
   'SequentialMusic
   'elements
   (list (make-music
-          'EventChord
-          'elements
+          'NoteEvent
+          'articulations
           (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))
-                (make-music
                   'SlurEvent
                   'span-direction
-                  -1)))
+                  -1))
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch 0 5 0))
         (make-music
-          'EventChord
-          'elements
+          'NoteEvent
+          'articulations
           (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))
-                (make-music
                   'SlurEvent
                   'span-direction
-                  1)))))
+                  1))
+          'duration
+          (ly:make-duration 2 0 1 1)
+          'pitch
+          (ly:make-pitch 0 5 0))))
 @end example
 
-Las malas noticias son que las expresiones @code{SlurEvent} se deben
-añadir @q{dentro} de la nota (o para ser más exactos, dentro de la
-expresión @code{EventChord}).
+La mala noticia es que las expresiones @code{SlurEvent} se deben
+añadir @q{dentro} de la nota (dentro de la
+propiedad @code{articulations}).
 
 Ahora examinamos la entrada,
 
 @example
+\displayMusic a'
+===>
 (make-music
-  'SequentialMusic
-  'elements
-  (list (make-music
-          'EventChord
-          'elements
-          (list (make-music
-                  'NoteEvent
-                  'duration
-                  (ly:make-duration 2 0 1 1)
-                  'pitch
-                  (ly:make-pitch 0 5 0))))))
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch 0 5 0))))
 @end example
 
 Así pues, en nuestra función, tenemos que clonar esta expresión (de
 forma que tengamos dos notas para construir la secuencia), añadir
-@code{SlurEvent} a la propiedad @code{'elements} de cada una de
+@code{SlurEvent} a la propiedad @code{'articulations} de cada una de
 ellas, y por último hacer una secuencia @code{SequentialMusic} con los
-dos @code{EventChords}.
+dos @code{EventChords}.  Para añadir a una propiedad, es útil saber
+que una propiedad no establecida se lee como @code{'()}, la lista
+vacía, así que no se requiere ninguna comprobación especial antes de
+que pongamos otro elemento delante de la propiedad
+@code{articulations}.
+
 
 @example
 doubleSlur = #(define-music-function (parser location note) (ly:music?)
          "Return: @{ note ( note ) @}.
-         `note' is supposed to be an EventChord."
+         `note' is supposed to be a single note."
          (let ((note2 (ly:music-deep-copy note)))
-           (set! (ly:music-property note 'elements)
+           (set! (ly:music-property note 'articulations)
                  (cons (make-music 'SlurEvent 'span-direction -1)
-                       (ly:music-property note 'elements)))
-           (set! (ly:music-property note2 'elements)
+                       (ly:music-property note 'articulations)))
+           (set! (ly:music-property note2 'articulations)
                  (cons (make-music 'SlurEvent 'span-direction 1)
-                       (ly:music-property note2 'elements)))
+                       (ly:music-property note2 'articulations)))
            (make-music 'SequentialMusic 'elements (list note note2))))
 @end example
 
@@ -1222,7 +1388,11 @@ doubleSlur = #(define-music-function (parser location note) (ly:music?)
 La manera fácil de añadir articulación a las notas es mezclar dos
 expresiones musicales en un solo contexto, como se explica en
 @ruser{Crear contextos}.  Sin embargo, supongamos que queremos
-escribir una función musical que lo haga.
+escribir una función musical que lo haga.  Esto tiene la ventaja
+adicional de que podemos usar esa función musical para añadir una
+articulación (como una instrucción de digitación) a una nota única
+dentro de un acorde, lo cual no es posible si nos limitamos a mezclar
+fragmentos de música independientes.
 
 Una @code{$variable} dentro de la notación @code{#@{...#@}} es como
 una @code{\variable} normal en la notación clásica de LilyPond.
@@ -1234,10 +1404,10 @@ Sabemos que
 
 @noindent
 no funciona en LilyPond.  Podríamos evitar este problema adjuntando la
-articulación a una nota falsa,
+articulación a un acorde vacío,
 
 @example
-@{ << \music s1*0-.-> @}
+@{ << \music <> -. -> >> @}
 @end example
 
 @noindent
@@ -1249,61 +1419,54 @@ Scheme.  Empezamos examinando nuestra entrada y la salida deseada,
 \displayMusic c4
 ===>
 (make-music
-  'EventChord
-  'elements
-  (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch -1 0 0))))
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch -1 0 0))))
 =====
 %  desired output
 \displayMusic c4->
 ===>
 (make-music
-  'EventChord
-  'elements
+  'NoteEvent
+  'articulations
   (list (make-music
-          'NoteEvent
-          'duration
-          (ly:make-duration 2 0 1 1)
-          'pitch
-          (ly:make-pitch -1 0 0))
-        (make-music
           'ArticulationEvent
           'articulation-type
-          "marcato")))
+          "accent"))
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch -1 0 0))
 @end example
 
 Vemos que una nota (@code{c4}) se representa como una expresión
-@code{EventChord}, con una expresión @code{NoteEvent} en su lista de
-elementos.  Para añadir una articulación de marcato, se debe añadir
-una expresión @code{ArticulationEvent} a la propiedad elements de la
-expresión @code{EventChord}.
+@code{NoteEvent}.  Para añadir una articulación de acento, se debe
+añadir una expresión @code{ArticulationEvent} a la propiedad
+@code{articulations} de la expresión @code{NoteEvent}.
 
 Para construir esta función, empezamos con
 
 @example
-(define (add-marcato event-chord)
-  "Add a marcato ArticulationEvent to the elements of `event-chord',
-  which is supposed to be an EventChord expression."
-  (let ((result-event-chord (ly:music-deep-copy event-chord)))
-    (set! (ly:music-property result-event-chord 'elements)
-          (cons (make-music 'ArticulationEvent
-                  'articulation-type "marcato")
-                (ly:music-property result-event-chord 'elements)))
-    result-event-chord))
+(define (add-accent note-event)
+  "Add an accent ArticulationEvent to the articulations of `note-event',
+  which is supposed to be a NoteEvent expression."
+  (set! (ly:music-property note-event 'articulations)
+        (cons (make-music 'ArticulationEvent
+                'articulation-type "accent")
+              (ly:music-property note-event 'articulations)))
+  note-event)
 @end example
 
 La primera línea es la forma de definir una función en Scheme: el
-nombre de la función es @code{add-marcato}, y tiene una variable
-llamada @code{event-chord}.  En Scheme, el tipo de variable suele
+nombre de la función es @code{add-accent}, y tiene una variable
+llamada @code{note-event}.  En Scheme, el tipo de variable suele
 quedar claro a partir de su nombre (¡esto también es una buena
 práctica en otros lenguajes de programación!)
 
 @example
-"Add a marcato..."
+"Add an accent..."
 @end example
 
 @noindent
@@ -1311,85 +1474,102 @@ es una descripción de lo que hace la función.  No es estrictamente
 necesaria, pero de igual forma que los nombres claros de variable, es
 una buena práctica.
 
-@example
-(let ((result-event-chord (ly:music-deep-copy event-chord)))
-@end example
-
-Se usa @code{let} para declarar las variables locales.  Aquí usamos
-una variable local, llamada @code{result-event-chord}, a la que le
-damos el valor @code{(ly:music-deep-copy event-chord)}.
-@code{ly:music-deep-copy} es una función específica de LilyPond, como
-todas las funciones que comienzan por @code{ly:}.  Se usa para hacer
-una copia de una expresión musical.  Aquí, copiamos @code{event-chord}
-(el parámetro de la función).  Recuerde que nuestro propósito es
-añadir un marcato a una expresión @code{EventChord}.  Es mejor no
-modificar el @code{EventChord} que se ha dado como argumento, porque
-podría utilizarse en algún otro lugar.
-
-Ahora tenemos un @code{result-event-chord}, que es una expresión
-@code{NoteEventChord} y es una copia de @code{event-chord}.  Añadimos
-el marcato a su propiedad de la lista de @code{'elements}.
+Se preguntará porqué modificamos el evento de nota directamente en
+lugar de trabajar sobre una copia (se puede usar
+@code{ly:music-deep-copy} para ello).  La razón es un contrato
+silencioso: se permite que las funciones musicales modifiquen sus
+argumentos; o bien se generan partiendo de cero (como la entrada del
+usuario) o están ya copiadas (referenciar una variable de música con
+@samp{\name} o la música procedente de expresiones de Scheme
+inmediatas @samp{$(@dots{})} proporcionan una copia).  Dado que sería
+ineficiente crear copias innecesarias, el valor devuelto de una
+función musical @emph{no} se copia.  Así pues, para cumplir dicho
+contrato, no debemos usar ningún argumento más de una vez, y
+devolverlo cuenta como una vez.
+
+En un ejemplo anterior, hemos construido música mediante la repetición
+de un argumento musical dado.  En tal caso, al menos una repetidión
+tuvo que ser una copia de sí misma.  Si no lo fuese, podrían ocurrir
+cosas muy extrañas.  Por ejemplo, si usamos @code{\relative} o
+@code{\transpose} sobre la música resultante que contiene los mismos
+elementos varias veces, estarían sujetos varias veces a la
+relativización o al transporte.  Si los asignamos a una variable de
+música, se rompe el curso porque hacer referencia a @samp{\name}
+creará de nuevo una copia que no retiene la identidad de los elementos
+repetidos.
+
+Ahora bien, aun cuando la función anterior no es una función musical,
+se usará normalmente dentro de funciones musicales.  Así pues, tiene
+sentido obedecer el mismo convenio que usamos para las funciones
+musicales: la entrada puede modificarse para producir la salida, y el
+código que llama es responsable de crear las copias si aún necesita el
+propio argumento sin modificar.  Si observamos las propias funciones
+de LilyPond como @code{music-map}, veremos que se atienen a los mismos
+principios.
+
+¿En qué punto nos encontramos?  Ahora tenemos un @code{note-event} que
+podemos modificar, no a causa de la utilización de
+@code{ly:music-deep-copy} sino por una explicación muy desarrollada.
+Añadimos el acento a su propiedad de lista @code{'articulations}.
 
 @example
-(set! lugar valor-nuevo)
+(set! place new-value)
 @end example
 
-Aquí, lo que queremos establecer (el @q{lugar}) es la propiedad
-@code{'elements} de la expresión @code{result-event-chord}.
+Aquí, lo que queremos establecer (el @q{place}) es la propiedad
+@code{'articulations} de la expresión @code{note-event}.
 
 @example
-(ly:music-property result-event-chord 'elements)
+(ly:music-property note-event 'articulations)
 @end example
 
-@code{ly:music-property} es la función que se usa para acceder a las
-propiedades musicales (los @code{'elements}, @code{'duration},
-@code{'pitch}, etc, que vimos en la salida de @code{\displayMusic}
-anterior).  El nuevo valor es la antigua propiedad @code{'elements},
-con un elemento adicional: la expresión @code{ArticulationEvent}, que
-copiamos a partir de la salida de @code{\displayMusic},
+@code{ly:music-property} es la función ustilizada para acceder a las
+propiedades musicales (las @code{'articulations}, @code{'duration},
+@code{'pitch}, etc, que vemos arriba en la salida de
+@code{\displayMusic}).  El nuevo valor es la antigua propiedad
+@code{'articulations}, con un elemento adicional: la expresión
+@code{ArticulationEvent}, que copiamos a partir de la salida de
+@code{\displayMusic},
 
 @example
 (cons (make-music 'ArticulationEvent
-        'articulation-type "marcato")
-      (ly:music-property result-event-chord 'elements))
+        'articulation-type "accent")
+      (ly:music-property result-event-chord 'articulations))
 @end example
 
-@code{cons} se usa para añadir un elemento a una lista sin modificar
-la lista original.  Esto es lo que queremos: la misma lista que antes,
-más la expresión @code{ArticulationEvent} nueva.  El orden dentro de
-la propiedad @code{'elements} no es importante aquí.
+Se usa @code{cons} para añadir un elemento a la parte delantera de una
+lista sin modificar la lista original.  Esto es lo que queremos: la
+misma lista de antes, más la nueva expresión @code{ArticulationEvent}.
+El orden dentro de la propiedad @code{'articulations} no tiene
+importancia aquí.
 
-Finalmente, una vez hemos añadido la articulación marcato a su
-propiedad @code{elements}, podemos devolver @code{result-event-chord},
-de ahí la última línea de la función.
+Finalmente, una vez hemos añadido la articulación de acento a su
+propiedad @code{articulations}, podemos devolver @code{note-event}, de
+aquí la última línea de la función.
 
-Ahora transformamos la función @code{add-marcato} en una función
-musical:
+Ahora transformamos la función @code{add-accent} en una función
+musical (es cuestión de un poco de aderezo sintáctico y una
+declaración del tipo de su único argumento @q{real}).
 
 @example
-addMarcato = #(define-music-function (parser location event-chord)
+addAccent = #(define-music-function (parser location note-event)
                                      (ly:music?)
-    "Add a marcato ArticulationEvent to the elements of `event-chord',
-    which is supposed to be an EventChord expression."
-    (let ((result-event-chord (ly:music-deep-copy event-chord)))
-      (set! (ly:music-property result-event-chord 'elements)
-            (cons (make-music 'ArticulationEvent
-                    'articulation-type "marcato")
-                  (ly:music-property result-event-chord 'elements)))
-      result-event-chord))
+  "Add an accent ArticulationEvent to the articulations of `note-event',
+  which is supposed to be a NoteEvent expression."
+  (set! (ly:music-property note-event 'articulations)
+        (cons (make-music 'ArticulationEvent
+                'articulation-type "accent")
+              (ly:music-property note-event 'articulations)))
+  note-event)
 @end example
 
 Podemos verificar que esta función musical funciona correctamente:
 
 @example
-\displayMusic \addMarcato c4
+\displayMusic \addAccent c4
 @end example
 
 
-
-
-
-
 @ignore
 @menu
 * Trucos con Scheme::
@@ -1397,11 +1577,10 @@ Podemos verificar que esta función musical funciona correctamente:
 
 @c @nod e Trucos con Scheme
 @c @sectio n Trucos con Scheme
-@translationof Tweaking with Scheme
+@c @transl ationof Tweaking with Scheme
 
 Hemos visto cómo la salida de LilyPond se puede modificar
-profundamente usando instrucciones como @code{\override TextScript
-#'extra-offset = ( 1 . -1)}.  Pero tenemos incluso mucho más poder si
+profundamente usando instrucciones como @code{\override TextScript.extra-offset = ( 1 . -1)}.  Pero tenemos incluso mucho más poder si
 utilizamos Scheme.  Para ver una explicación completa de esto,
 consulte el @ref{Tutorial de Scheme}, y @ruser{Interfaces para programadores}.
 
@@ -1417,7 +1596,7 @@ TODO Find a simple example
 @lilypond[quote,verbatim,ragged-right]
 padText = #(define-music-function (parser location padding) (number?)
 #{
-  \once \override TextScript #'padding = #$padding
+  \once \override TextScript.padding = #padding
 #})
 
 \relative c''' {
@@ -1439,16 +1618,16 @@ Lo podemos usar para crear instrucciones nuevas:
 
 @lilypond[quote,verbatim,ragged-right]
 tempoPadded = #(define-music-function (parser location padding tempotext)
-  (number? string?)
+  (number? markup?)
 #{
-  \once \override Score.MetronomeMark #'padding = $padding
-  \tempo \markup { \bold $tempotext }
+  \once \override Score.MetronomeMark.padding = #padding
+  \tempo \markup { \bold #tempotext }
 #})
 
 \relative c'' {
   \tempo \markup { "Low tempo" }
   c4 d e f g1
-  \tempoPadded #4.0 #"High tempo"
+  \tempoPadded #4.0 "High tempo"
   g4 f e d c1
 }
 @end lilypond
@@ -1459,7 +1638,7 @@ Incluso se le pueden pasar expresiones musicales:
 @lilypond[quote,verbatim,ragged-right]
 pattern = #(define-music-function (parser location x y) (ly:music? ly:music?)
 #{
-  $x e8 a b $y b a e
+  #x e8 a b #y b a e
 #})
 
 \relative c''{