[ << Scheme tutorial ] | [Top][Contents][Index][ ? ] | [ Interfaces for programmers >> ] | ||
[ < LilyPond variables ] | [ Up : Scheme in LilyPond ] | [ Object properties > ] |
1.2.3 Input variables and Scheme
The input format supports the notion of variables: in the following
example, a music expression is assigned to a variable with the name
traLaLa
.
traLaLa = { c'4 d'4 }
There is also a form of scoping: in the following example, the
\layout
block also contains a traLaLa
variable, which is
independent of the outer \traLaLa
.
traLaLa = { c'4 d'4 } \layout { traLaLa = 1.0 }
In effect, each input file is a scope, and all \header
,
\midi
, and \layout
blocks are scopes nested inside that
toplevel scope.
Both variables and scoping are implemented in the GUILE module system. An anonymous Scheme module is attached to each scope. An assignment of the form:
traLaLa = { c'4 d'4 }
is internally converted to a Scheme definition:
(define traLaLa Scheme value of `...
')
This means that LilyPond variables and Scheme variables may be freely
mixed. In the following example, a music fragment is stored in the
variable traLaLa
, and duplicated using Scheme. The result is
imported in a \score
block by means of a second variable
twice
:
traLaLa = { c'4 d'4 } #(define newLa (map ly:music-deep-copy (list traLaLa traLaLa))) #(define twice (make-sequential-music newLa)) { \twice }
This is actually a rather interesting example. The assignment will only
take place after the parser has ascertained that nothing akin to
\addlyrics
follows, so it needs to check what comes next. It
reads #
and the following Scheme expression without
evaluating it, so it can go ahead with the assignment, and
afterwards execute the Scheme code without problem.
The above example shows how to ‘export’ music expressions from the
input to the Scheme interpreter. The opposite is also possible. By
placing it after $
, a Scheme
value is interpreted as if it were entered in LilyPond syntax.
Instead of defining \twice
, the example above could also have
been written as
... { $(make-sequential-music (list newLa)) }
You can use $
with a Scheme expression anywhere you could use
\name
after having assigned the Scheme expression to a
variable name. This replacement happens in the ‘lexer’, so
Lilypond is not even aware of the difference.
One drawback, however, is that of timing. If we had been using $
instead of #
for defining newLa
in the above example, the
following Scheme definition would have failed because traLaLa
would not yet have been defined. For an explanation of this timing
problem, LilyPond Scheme syntax.
In any case, evaluation of Scheme code happens in the parser at latest. If you need it to be executed at a later point of time, Void scheme functions, or store it in a macro:
#(define (nopc) (ly:set-option 'point-and-click #f)) ... #(nopc) { c'4 }
Known issues and warnings
Mixing Scheme and LilyPond variables is not possible with the ‘--safe’ option.
[ << Scheme tutorial ] | [Top][Contents][Index][ ? ] | [ Interfaces for programmers >> ] | ||
[ < LilyPond variables ] | [ Up : Scheme in LilyPond ] | [ Object properties > ] |
他の言語: deutsch, español, français
About automatic language selection.