]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/extending/programming-interface.itely
programming-interface.itely: Explain new optional argument semantics and \default
[lilypond.git] / Documentation / extending / programming-interface.itely
index 1e8e92dbbd8f084ea6f6e9684dc1049d4a98a67c..87c6505c0f2124838571f47fc9cf938449e8d07e 100644 (file)
@@ -8,7 +8,7 @@
     Guide, node Updating translation committishes..
 @end ignore
 
-@c \version "2.14.0"
+@c \version "2.15.17"
 
 @node Interfaces for programmers
 @chapter Interfaces for programmers
@@ -146,19 +146,40 @@ given the correct @code{origin}.
 @end multitable
 
 @noindent
-Some type predicates are specially recognized by the parser and will
-make the parser look for the respective arguments in LilyPond syntax
-rather than in Scheme syntax.  Currently these are @code{ly:music?},
-@code{markup?}, @code{ly:pitch?}, and @code{ly:duration?}.
-
-If you really want to input one of the special items as a Scheme rather
-than a LilyPond expression, you may write them as a Scheme expression
-that calls @code{ly:export} at its outermost level.
-
-Other type predicates, including user-defined ones, will make the
-respective argument only be accepted as a Scheme expression, usually
-introduced with @code{#} or as the result of calling a scheme function
-itself.
+Some type predicates are specially handled by the parser since it
+can't recognize the arguments reliably otherwise.  Currently these are
+@code{ly:pitch?} and @code{ly:duration?}.
+
+Suitability of arguments for all other predicates is determined by
+actually calling the predicate after Lilypond has already converted
+them into a Scheme expression.  As a consequence, the argument can be
+specified in Scheme syntax if desired (introduced with @code{#} or as
+the result of calling a scheme function), but Lilypond will also
+convert a number of Lilypond constructs into Scheme before actually
+checking the predicate on them.  Currently, those include music,
+simple strings (with or without quotes), numbers, full markups and markup
+lists, score, book, bookpart, context definition and output definition
+blocks.
+
+For some kinds of expression (like most music not enclosed in braces)
+Lilypond needs to look further than the expression itself in order to
+determine its end.  If such an expression were considered for an
+optional argument by evaluating its predicate, Lilypond would not be
+able to ``backup'' when it decides the expression does not fit the
+parameter.  So some forms of music might need to be enclosed in braces
+to make them acceptable to Lilypond.  There are also some other
+complications that may cause a predicate function to be called several
+times on successive versions of an argument (like @code{3} and
+@code{3\cm}) or several interpretations (like @code{"a" 4} in lyric
+mode, which can either be a string followed by a number, or a lyric
+event of duration @code{4}).
+
+Music arguments preceding @code{ly:duration?} arguments must also be
+lookahead-free.  This may also hold for the last argument of a scheme
+function that is used as the last part of another expression, since
+otherwise Lilypond won't know whether following postevents or
+durations apply to the argument of the Scheme function, or to the
+containing music expression.
 
 For a list of available type predicates, see
 @ruser{Predefined type predicates}.
@@ -186,33 +207,39 @@ immediately following optional arguments are replaced with their default
 values, and the matching continues with the next non-optional argument.
 
 Apart from places where a Scheme value is required, there are a few
-places where @code{#} expressions are accepted and evaluated for their
-side effects but otherwise ignored.  Mostly those are the places where
-an assignment would be acceptable as well.
-
-There are a few special places where an argument matching
-@code{ly:music?} has to be either a music identifier or a music
-expression enclosed in @code{@{}@dots{}@code{@}} or
-@code{<<}@dots{}@code{>>} explicitly, so that possibly following
-optional durations or postevents can't be confused with additional
-arguments.  One obvious place is before a @code{ly:duration?}
-predicate.  Another is as the last argument of a scheme function when it
-is used in a place where such optional parts could be considered either
-part of the music argument or not.
-
-In those rare cases, you have to delimit your music arguments
-appropriately to spare LilyPond from getting confused.
+places where @code{#} expressions are currently accepted and evaluated
+for their side effects but otherwise ignored.  Mostly those are the
+places where an assignment would be acceptable as well.
+
+Since it is a bad idea to return values that can be misinterpreted in
+some context, you should use normal scheme functions only for those
+cases where you always return a useful value, and use void scheme
+functions (@pxref{Void scheme functions}) otherwise.
 
 @node Void scheme functions
 @subsection Void scheme functions
-
-Sometimes a function is only executed for its side effects.  In that
-case, using a scheme function means that its value will not usually be
-considered:
+@funindex define-void-function
+@funindex \void
+
+Sometimes a procedure is executed in order to perform an action rather
+than return a value.  Some programming languages (like C and Scheme)
+use functions for either concept and just discard the returned value
+(usually by allowing any expression to act as statement, ignoring the
+result).  This is clever but error-prone: most C compilers nowadays
+offer warnings for various non-``void'' expressions being discarded.
+For many functions executing an action, the Scheme standards declare
+the return value to be unspecified.  Lilypond's Scheme interpreter
+Guile has a unique ``unspecified'' value that it usually (such when
+using @code{set!} directly on a variable) but unfortunately not
+consistently returns in such cases.
+
+Defining a Lilypond function with @code{define-void-function} makes
+sure that this special value (the only value satisfying the predicate
+@code{void?}) will be returned.
 
 @example
 noPointAndClick =
-#(define-scheme-function
+#(define-void-function
      (parser location)
      ()
    (ly:set-option 'point-and-click #f))
@@ -220,6 +247,18 @@ noPointAndClick =
 \noPointAndClick   % disable point and click
 @end example
 
+If you want to evaluate an expression only for its side-effect and
+don't want any value it may return interpreted, you can do so by
+prefixing it with @code{\void}:
+
+@example
+\void #(hashq-set! some-table some-key some-value)
+@end example
+
+That way, you can be sure that Lilypond will not assign meaning to the
+returned value regardless of where it encounters it.  This will also
+work for music functions such as @code{\displayMusic}.
+
 @node Music functions
 @section Music functions
 
@@ -450,12 +489,12 @@ lilypond -d display-bar-numbers FILENAME.ly
 @node Void music functions
 @subsection Void music functions
 
-A music function must return a music expression.  If you want to execute
-a function only for its side effect, it might make more sense to use a
-scheme function instead.  But there may be cases where you sometimes
-want to produce a music expression, and sometimes not (like in the
-previous example).  Returning a @code{void} music expression via
-@code{#@{ #@}} will do that.
+A music function must return a music expression.  If you want to
+execute a function only for its side effect, you should use
+@code{define-void-function}.  But there may be cases where you
+sometimes want to produce a music expression, and sometimes not (like
+in the previous example).  Returning a @code{void} music expression
+via @code{#@{ #@}} will achieve that.
 
 @node Event functions
 @section Event functions
@@ -919,7 +958,7 @@ indented.  The indent width is taken from the @code{props} argument.
 #(define-markup-list-command (paragraph layout props args) (markup-list?)
    #:properties ((par-indent 2))
    (interpret-markup-list layout props
-     #@{\markuplines \justified-lines @{ \hspace #$par-indent $args @} #@}))
+     #@{\markuplist \justified-lines @{ \hspace #$par-indent $args @} #@}))
 @end example
 
 
@@ -948,7 +987,7 @@ interpreted using the @code{interpret-markup-list} function.
 
 This new markup list command can be used as follows:
 @example
-\markuplines @{
+\markuplist @{
   \paragraph @{
     The art of music typography is called \italic @{(plate) engraving.@}
     The term derives from the traditional process of music printing.