]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/extending/scheme-tutorial.itely
Issue 4296: Let \displayLilyMusic print even repeated durations
[lilypond.git] / Documentation / extending / scheme-tutorial.itely
index 9b055dcba6475654ce457bc1fcaaf3860d04de01..a399570dec32412e13b77457a294999e9af1ee94 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.15.20"
+@c \version "2.17.11"
 
 @node Scheme tutorial
 @chapter Scheme tutorial
@@ -209,7 +209,15 @@ For a complete listing see the Guile reference guide,
 There are also compound data types in Scheme.  The  types commonly used in
 LilyPond programming include pairs, lists, alists, and hash tables.
 
-@subheading Pairs
+@menu
+* Pairs::
+* Lists::
+* Association lists (alists)::
+* Hash tables::
+@end menu
+
+@node Pairs
+@unnumberedsubsubsec Pairs
 
 The foundational compound data type of Scheme is the @code{pair}.  As
 might be expected from its name, a pair is two values glued together.
@@ -250,7 +258,7 @@ Scheme procedures @code{car} and @code{cdr}, respectively.
 
 @lisp
 guile> (define mypair (cons 123 "hello there")
-... )
+@dots{} )
 guile> (car mypair)
 123
 guile> (cdr mypair)
@@ -264,11 +272,13 @@ Note:  @code{cdr} is pronounced "could-er", according Sussman and
 Abelson, see
 @uref{http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#footnote_Temp_133}
 
-@subheading Lists
+@node Lists
+@unnumberedsubsubsec Lists
 
-A very common Scheme data structure is the @emph{list}.  Formally, a
-list is defined as either the empty list (represented as @code{'()},
-or a pair whose @code{cdr} is a list.
+A very common Scheme data structure is the @emph{list}.  Formally,
+a @q{proper} list is defined to be either the empty list with its
+input form @code{'()} and length@tie{}0, or a pair whose
+@code{cdr} in turn is a shorter list.
 
 There are many ways of creating lists.  Perhaps the most common is
 with the @code{list} procedure:
@@ -294,7 +304,8 @@ Lists are a central part of Scheme.  In, fact, Scheme is considered
 a dialect of lisp, where @q{lisp} is an abbreviation for
 @q{List Processing}.  Scheme expressions are all lists.
 
-@subheading Association lists (alists)
+@node Association lists (alists)
+@unnumberedsubsubsec Association lists (alists)
 
 A special type of list is an @emph{association list} or @emph{alist}.
 An alist is used to store data for easy retrieval.
@@ -318,7 +329,8 @@ guile>
 
 Alists are widely used in LilyPond to store properties and other data.
 
-@subheading Hash tables
+@node Hash tables
+@unnumberedsubsubsec Hash tables
 
 A data structure that is used occasionally in LilyPond.  A hash table
 is similar to an array, but the indexes to the array can be any type
@@ -488,7 +500,14 @@ Scheme procedures are executable scheme expressions that return a
 value resulting from their execution.  They can also manipulate
 variables defined outside of the procedure.
 
-@subheading Defining procedures
+@menu
+* Defining procedures::
+* Predicates::
+* Return values::
+@end menu
+
+@node Defining procedures
+@unnumberedsubsubsec Defining procedures
 
 Procedures are defined in Scheme with define
 
@@ -514,7 +533,8 @@ guile> (average 3 12)
 15/2
 @end lisp
 
-@subheading Predicates
+@node Predicates
+@unnumberedsubsubsec Predicates
 
 Scheme procedures that return boolean values are often called
 @emph{predicates}.  By convention (but not necessity), predicate names
@@ -528,7 +548,8 @@ guile> (less-than-ten? 15)
 #f
 @end lisp
 
-@subheading Return values
+@node Return values
+@unnumberedsubsubsec Return values
 
 Scheme procedures always return a return value, which is the value
 of the last expression executed in the procedure.  The return
@@ -554,14 +575,20 @@ statement in the let block:
 
 @lisp
 guile> (let ((x 2) (y 3) (z 4)) (display (+ x y)) (display (- z 4))
-... (+ (* x y) (/ z x)))
+@dots{} (+ (* x y) (/ z x)))
 508
 @end lisp
 
 @node Scheme conditionals
 @subsection Scheme conditionals
 
-@subheading if
+@menu
+* if::
+* cond::
+@end menu
+
+@node if
+@unnumberedsubsubsec if
 
 Scheme has an @code{if} procedure:
 
@@ -581,14 +608,15 @@ guile> (if (> a b) "a is greater than b" "a is not greater than b")
 "a is not greater than b"
 @end lisp
 
-@subheading cond
+@node cond
+@unnumberedsubsubsec cond
 
 Another conditional procedure in scheme is @code{cond}:
 
 @example
 (cond (test-expression-1 result-expression-sequence-1)
       (test-expression-2 result-expression-sequence-2)
-      ...
+      @dots{}
       (test-expression-n result-expression-sequence-n))
 @end example
 
@@ -633,7 +661,7 @@ Now LilyPond's input is structured into tokens and expressions, much
 like human language is structured into words and sentences.  LilyPond
 has a lexer that recognizes tokens (literal numbers, strings, Scheme
 elements, pitches and so on), and a parser that understands the syntax,
-@ruser{LilyPond grammar}.  Once it knows that a particular syntax rule
+@rcontrib{LilyPond grammar}.  Once it knows that a particular syntax rule
 applies, it executes actions associated with it.
 
 The hash mark@tie{}@code{#} method of embedding Scheme is a natural fit
@@ -667,8 +695,12 @@ without consulting the Scheme reader, and thus only variable names
 consistent with the current Lilypond mode are accepted.
 
 The immediate action of @code{$} can lead to surprises, @ref{Input
-variables and Scheme}.  Using @code{#} where the parser supports it is
-usually preferable.
+variables and Scheme}.  Using @code{#} where the parser supports it
+is usually preferable.  Inside of music expressions, expressions
+created using @code{#} @emph{are} interpreted as music.  However,
+they are @emph{not} copied before use.  If they are part of some
+structure that might still get used, you may need to use
+@code{ly:music-deep-copy} explicitly.
 
 @funindex $@@
 @funindex #@@
@@ -789,7 +821,7 @@ traLaLa = @{ c'4 d'4 @}
 is internally converted to a Scheme definition:
 
 @example
-(define traLaLa @var{Scheme value of `@code{... }'})
+(define traLaLa @var{Scheme value of `@code{@dots{}}'})
 @end example
 
 This means that LilyPond variables and Scheme variables may be freely
@@ -831,7 +863,7 @@ Instead of defining @code{\twice}, the example above could also have
 been written as
 
 @example
-...
+@dots{}
 $(make-sequential-music newLa)
 @end example
 
@@ -854,15 +886,15 @@ context.  Using those, the last part of the example could have been
 written as
 
 @example
-...
-@{ $@@newLa @}
+@dots{}
+@{ #@@newLa @}
 @end example
 
 Here, every element of the list stored in @code{newLa} is taken in
 sequence and inserted into the list, as if we had written
 
 @example
-@{ $(first newLa) $(second newLa) @}
+@{ #(first newLa) #(second newLa) @}
 @end example
 
 Now in all of these forms, the Scheme code is evaluated while the
@@ -874,7 +906,7 @@ If you need it to be executed at a later point of time, check out
 #(define (nopc)
   (ly:set-option 'point-and-click #f))
 
-...
+@dots{}
 #(nopc)
 @{ c'4 @}
 @end example
@@ -898,7 +930,7 @@ the alist with both a key and a value.  The LilyPond syntax for doing
 this is:
 
 @example
-\override Stem #'thickness = #2.6
+\override Stem.thickness = #2.6
 @end example
 
 This instruction adjusts the appearance of stems.  An alist entry
@@ -923,14 +955,23 @@ while @code{twentyFour} is a variable.
 @node LilyPond compound variables
 @subsection LilyPond compound variables
 
-@subheading Offsets
+@menu
+* Offsets::
+* Fractions::
+* Extents::
+* Property alists::
+* Alist chains::
+@end menu
+
+@node Offsets
+@unnumberedsubsubsec Offsets
 
 Two-dimensional offsets (X and Y coordinates) are stored as @emph{pairs}.
 The @code{car} of the offset is the X coordinate, and the @code{cdr} is
 the Y coordinate.
 
 @example
-\override TextScript #'extra-offset = #'(1 . 2)
+\override TextScript.extra-offset = #'(1 . 2)
 @end example
 
 This assigns the pair @code{(1 . 2)} to the @code{extra-offset}
@@ -940,7 +981,8 @@ this command moves the object 1 staff space to the right, and 2 spaces up.
 
 Procedures for working with offsets are found in @file{scm/lily-library.scm}.
 
-@subheading Fractions
+@node Fractions
+@unnumberedsubsubsec Fractions
 
 Fractions as used by LilyPond are again stored as @emph{pairs}, this
 time of unsigned integers.  While Scheme can represent rational numbers
@@ -950,7 +992,8 @@ 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 Extents
+@node Extents
+@unnumberedsubsubsec Extents
 
 Pairs are also used to store intervals, which represent a range of numbers
 from the minimum (the @code{car}) to the maximum (the @code{cdr}).
@@ -963,7 +1006,8 @@ Procedures for working with intervals are found in
 @file{scm/lily-library.scm}.  These procedures should be used when possible
 to ensure consistency of code.
 
-@subheading Property alists
+@node Property alists
+@unnumberedsubsubsec Property alists
 
 A property alist is a LilyPond data structure that is an alist whose
 keys are properties and whose values are Scheme expressions that give
@@ -971,7 +1015,8 @@ the desired value for the property.
 
 LilyPond properties are Scheme symbols, such as @code{'thickness}.
 
-@subheading Alist chains
+@node Alist chains
+@unnumberedsubsubsec Alist chains
 
 An alist chain is a list containing property alists.
 
@@ -1083,30 +1128,37 @@ will display
                   'text
                   "f"))
           'duration
-          (ly:make-duration 2 0 1 1)
+          (ly:make-duration 2 0 1/1)
           'pitch
           (ly:make-pitch 0 0 0))))
 @end example
 
 By default, LilyPond will print these messages to the console along
 with all the other messages.  To split up these messages and save
-the results of @code{\display@{STUFF@}}, redirect the output to
-a file.
+the results of @code{\display@{STUFF@}}, you can specify an optional
+output port to use:
 
 @example
-lilypond file.ly >display.txt
+@{
+  \displayMusic #(open-output-file "display.txt") @{ c'4\f @}
+@}
 @end example
 
-With a combined bit of Lilypond and Scheme magic, you can actually
-let Lilypond direct just this output to a file of its own:
-
+This will overwrite a previous output file whenever it is called; if you
+need to write more than one expression, you would use a variable for
+your port and reuse it:
 @example
 @{
-  $(with-output-to-file "display.txt"
-      (lambda () #@{ \displayMusic @{ c'4\f @} #@}))
+  port = #(open-output-file "display.txt")
+  \displayMusic \port @{ c'4\f @}
+  \displayMusic \port @{ d'4 @}
+  #(close-output-port port)
 @}
 @end example
 
+Guile's manual describes ports in detail.  Closing the port is actually
+only necessary if you need to read the file before Lilypond finishes; in
+the first example, we did not bother to do so.
 
 A bit of reformatting makes the above information easier to read:
 
@@ -1118,16 +1170,16 @@ A bit of reformatting makes the above information easier to read:
                               (make-music 'AbsoluteDynamicEvent
                                 'text
                                 "f"))
-              'duration (ly:make-duration 2 0 1 1)
+              'duration (ly:make-duration 2 0 1/1)
               'pitch    (ly:make-pitch 0 0 0))))
 @end example
 
-A @code{@{ ... @}} music sequence has the name @code{SequentialMusic},
-and its inner expressions are stored as a list in its @code{'elements}
-property.  A note is represented as a @code{NoteEvent} object (storing
-the duration and pitch properties) with attached information (in this
-case, an @code{AbsoluteDynamicEvent} with a @code{"f"} text property)
-stored in its @code{articulations} property.
+A @code{@{ @dots{} @}} music sequence has the name
+@code{SequentialMusic}, and its inner expressions are stored as a list
+in its @code{'elements} property.  A note is represented as a
+@code{NoteEvent} object (storing the duration and pitch properties) with
+attached information (in this case, an @code{AbsoluteDynamicEvent} with
+a @code{"f"} text property) stored in its @code{articulations} property.
 
 @funindex{\void}
 @code{\displayMusic} returns the music it displays, so it will get
@@ -1150,7 +1202,7 @@ someNote = c'
 (make-music
   'NoteEvent
   'duration
-  (ly:make-duration 2 0 1 1)
+  (ly:make-duration 2 0 1/1)
   'pitch
   (ly:make-pitch 0 0 0))
 @end example
@@ -1168,7 +1220,7 @@ someNote = <c'>
   (list (make-music
           'NoteEvent
           'duration
-          (ly:make-duration 2 0 1 1)
+          (ly:make-duration 2 0 1/1)
           'pitch
           (ly:make-pitch 0 0 0))))
 @end example
@@ -1186,7 +1238,7 @@ expression.
 (make-music
   'NoteEvent
   'duration
-  (ly:make-duration 2 0 1 1)
+  (ly:make-duration 2 0 1/1)
   'pitch
   (ly:make-pitch 0 0 0))
 @end example
@@ -1212,7 +1264,7 @@ The note pitch can be changed by setting this @code{'pitch} property,
        (ly:make-pitch 0 1 0)) ;; set the pitch to d'.
 \displayLilyMusic \someNote
 ===>
-d'
+d'4
 @end example
 
 
@@ -1237,7 +1289,7 @@ representation of the desired result.
                   'span-direction
                   -1))
           'duration
-          (ly:make-duration 2 0 1 1)
+          (ly:make-duration 2 0 1/1)
           'pitch
           (ly:make-pitch 0 5 0))
         (make-music
@@ -1248,7 +1300,7 @@ representation of the desired result.
                   'span-direction
                   1))
           'duration
-          (ly:make-duration 2 0 1 1)
+          (ly:make-duration 2 0 1/1)
           'pitch
           (ly:make-pitch 0 5 0))))
 @end example
@@ -1265,7 +1317,7 @@ Now we examine the input,
 (make-music
   'NoteEvent
   'duration
-  (ly:make-duration 2 0 1 1)
+  (ly:make-duration 2 0 1/1)
   'pitch
   (ly:make-pitch 0 5 0))))
 @end example
@@ -1273,7 +1325,7 @@ Now we examine the input,
 So in our function, we need to clone this expression (so that we have
 two notes to build the sequence), add a @code{SlurEvent} to the
 @code{'articulations} property of each one, and finally make a
-@code{SequentialMusic} with the two @code{EventChords}.  For adding to a
+@code{SequentialMusic} with the two @code{NoteEvent} elements.  For adding to a
 property, it is useful to know that an unset property is read out as
 @code{'()}, the empty list, so no special checks are required before we
 put another element at the front of the @code{articulations} property.
@@ -1297,14 +1349,14 @@ doubleSlur = #(define-music-function (parser location note) (ly:music?)
 @subsection Adding articulation to notes (example)
 
 The easy way to add articulation to notes is to merge two music
-expressions into one context, as explained in @ruser{Creating contexts}.
+expressions into one context.
 However, suppose that we want to write a music function that does this.
 This will have the additional advantage that we can use that music
 function to add an articulation (like a fingering instruction) to a
 single note inside of a chord which is not possible if we just merge
 independent music.
 
-A @code{$variable} inside the @code{#@{...#@}} notation is like
+A @code{$variable} inside the @code{#@{@dots{}#@}} notation is like
 a regular @code{\variable} in classical LilyPond notation.  We
 know that
 
@@ -1331,7 +1383,7 @@ Scheme.  We begin by examining our input and desired output,
 (make-music
   'NoteEvent
   'duration
-  (ly:make-duration 2 0 1 1)
+  (ly:make-duration 2 0 1/1)
   'pitch
   (ly:make-pitch -1 0 0))))
 =====
@@ -1346,7 +1398,7 @@ Scheme.  We begin by examining our input and desired output,
           'articulation-type
           "accent"))
   'duration
-  (ly:make-duration 2 0 1 1)
+  (ly:make-duration 2 0 1/1)
   'pitch
   (ly:make-pitch -1 0 0))
 @end example
@@ -1376,7 +1428,7 @@ from its name.  (this is good practice in other programming languages,
 too!)
 
 @example
-"Add an accent..."
+"Add an accent@dots{}"
 @end example
 
 @noindent
@@ -1486,7 +1538,7 @@ We may verify that this music function works correctly,
 
 We have seen how LilyPond output can be heavily modified using
 commands like
-@code{\override TextScript #'extra-offset = ( 1 . -1)}.  But
+@code{\override TextScript.extra-offset = ( 1 . -1)}.  But
 we have even more power if we use Scheme.  For a full explanation
 of this, see the @ref{Scheme tutorial}, and
 @ref{Interfaces for programmers}.
@@ -1502,7 +1554,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''' {
@@ -1524,16 +1576,16 @@ We can use it to create new commands:
 
 @lilypond[quote,verbatim,ragged-right]
 tempoPadded = #(define-music-function (parser location padding tempotext)
-  (number? string?)
+  (number? markup?)
 #{
-  \once \override Score.MetronomeMark #'padding = $padding
+  \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
@@ -1544,7 +1596,7 @@ Even music expressions can be passed in:
 @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''{