| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
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.
| 2.2.1 Scheme function definitions | ||
| 2.2.2 Scheme function usage | ||
| 2.2.3 Void scheme functions |
| [ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
The general form for defining scheme functions is:
function =
#(define-scheme-function
(arg1 arg2 …)
(type1? type2? …)
body)
|
where
argN | nth 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. |
body | A 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 |
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.
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] | [ ? ] |
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] | [ ? ] |
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.
Andere talen: deutsch, español, français.
Gebruik van automatische taalkeuze.