[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2 Scheme functions

Scheme functions are Scheme procedures that can create Scheme expressions from input written in LilyPond syntax. They can be called in pretty much all places where using # for specifying a value in Scheme syntax is allowed. While Scheme has functions of its own, this chapter is concerned with syntactic functions, functions that receive arguments specified in LilyPond syntax.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2.1 Scheme function definitions

The general form for defining scheme functions is:

 
function =
#(define-scheme-function
     (arg1 arg2 …)
     (type1? type2? …)
   body)

where

argNnth argument.
typeN?A Scheme type predicate for which argN must return #t. There is also a special form (predicate? default) for specifying optional arguments. If the actual argument is missing when the function is being called, the default value is substituted instead. Default values are evaluated at definition time (including LilyPond code blocks!), so if you need a default calculated at runtime, instead write a special value you can easily recognize. If you write the predicate in parentheses but don’t follow it with a default value, #f is used as the default. Default values are not verified with predicate? at either definition or run time: it is your responsibility to deal with the values you specify. Default values that happen to be music expressions are copied while setting origin to the current input location.
bodyA sequence of Scheme forms evaluated in order, the last one being used as the return value of the scheme function. It may contain LilyPond code blocks enclosed in hashed braces ( #{…#} ), like described in LilyPond code blocks. Within LilyPond code blocks, use # to reference function arguments (eg., ‘#arg1’) or to start an inline Scheme expression containing function arguments (eg., ‘#(cons arg1 arg2)’). Where normal Scheme expressions using # don’t do the trick, you might need to revert to immediate Scheme expressions using $, for example as ‘$music’.

If your function returns a music expression, it is given a useful value of origin.

Suitability of arguments for the 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 # 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, postevents, simple strings (with or without quotes), numbers, full markups and markup lists, score, book, bookpart, context definition and output definition blocks.

Some ambiguities LilyPond sorts out by checking with predicate functions: is ‘-3’ a fingering postevent or a negative number? Is "a" 4 in lyric mode a string followed by a number, or a lyric event of duration 4? LilyPond tries the argument predicate on successive interpretations until success, with an order designed to minimize inconsistent interpretations and lookahead.

For example, a predicate accepting both music expressions and pitches will consider c'' to be a pitch rather than a music expression. Immediately following durations or postevents will change that interpretation. It’s best to avoid overly permissive predicates like scheme? when the application rather calls for more specific argument types.

For a list of available predefined type predicates, see (notation)Predefined type predicates section ‘Predefined type predicates’ in Notation Reference.

See also

Notation Reference: (notation)Predefined type predicates section ‘Predefined type predicates’ in Notation Reference.

Installed Files: ‘lily/music-scheme.cc’, ‘scm/c++.scm’, ‘scm/lily.scm’.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2.2 Scheme function usage

Scheme functions can be called pretty much anywhere where a Scheme expression starting with # can be written. You call a scheme function from LilyPond by writing its name preceded by \, followed by its arguments. Once an optional argument predicate does not match an argument, LilyPond skips this and all following optional arguments, replacing them with their specified default, and ‘backs up’ the argument that did not match to the place of the next mandatory argument. Since the backed up argument needs to go somewhere, optional arguments are not actually considered optional unless followed by a mandatory argument.

There is one exception: if you write \default in the place of an optional argument, this and all following optional arguments are skipped and replaced by their default. This works even when no mandatory argument follows since \default does not need to get backed up. The mark and key commands make use of that trick to provide their default behavior when just followed by \default.

Apart from places where a Scheme value is required, there are a few places where # 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 (see section Void scheme functions) otherwise.

For convenience, scheme functions may also be called directly from Scheme bypassing the LilyPond parser. Their name can be used like the name of an ordinary function. Typechecking of the arguments and skipping optional arguments will happen in the same manner as when called from within LilyPond, with the Scheme value *unspecified* taking the role of the \default reserved word for explicitly skipping optional arguments.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

2.2.3 Void scheme functions

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 value *unspecified* that it usually (such when using set! directly on a variable) but unfortunately not consistently returns in such cases.

Defining a LilyPond function with define-void-function makes sure that this special value (the only value satisfying the predicate void?) will be returned.

 
noPointAndClick =
#(define-void-function
     ()
     ()
   (ly:set-option 'point-and-click #f))
…
\noPointAndClick   % disable point and click

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 \void:

 
\void #(hashq-set! some-table some-key some-value)

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 \displayMusic.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]

This document was generated by gub on July 13, 2020 using texi2html 1.82.

Más nyelvek: deutsch, español, français.
Az automatikus nyelvválasztásról.