Hello David, > I do have a difference in the the output of the code below, which does > not use \new Staff. > > Without \textLengthOn, it makes two staves. With \textLenthOn, it > combines the two music expressions into one stave. Why is that happening?
That is one of the many pitfalls with automatic defaultchild contexts.
Basically a score will automatically create a Staff when it encounters a music
expression without having a Staff. Now, doing an override in front does not
require Lilypond to create a second staff in that case, which is why it then
continues with a single staff.
Generally you should avoid using automatic context instantiation (at least on
the Staff level. On the Voice level you’d generally have only one voice or be
specific about it, so it is fine). You can see the same problem reduced to its
essence by doing this:
<<
{ c }
{ c }
>>
<<
{ \override TextScript.stencil = ##f c }
{ \override TextScript.stencil = ##f c }
>>
> I like your "non-music function" examples. I see that your second and
> third example use primitive-eval. What does primitive-eval do and where
> could I read about it?
Uh, please don’t like it enough to actually use it for anything that is not
extremely specific. In scheme language uses the same data structure as data. So
(function arg1 arg2 ...)
can be seen as the list
(list 'function arg1 arg2 ...)
This means we can interpret data as language and evaluate that language. This
is what the scheme procedure eval does. But eval also takes an environment (so
some sort of scoping context for this), while primitive-eval evaluates in the
current environment (in fact eval simply changes the environment, evaluates,
and changes back again).
For details checkout the guile docs for on-the-fly evaluation:
https://www.gnu.org/software/guile/manual/html_node/Fly-Evaluation.html
> The third example uses scheme code that is beyond my comprehension, at
> the moment. I do not understand how you declared the music expression
> with myCode = #'#{ ... #}. I have not seen that construction before.
In Scheme we have the concept of quoting, which essentially tells scheme to
only parse the expression, but not evaluate it. You might have already seen it
abused as a fast way to create lists like '(a b c).
Now, what is important is that #{ ... #} is implemented in the parser, and
will be replaces by a scheme call, which at evaluation time parses the
content. You can see this by doing
#(display '#{ c d e #})
which should print something like
((@@ (lily) read-lily-expression-internal) c d e /tmp/frescobaldi-kuuoq7me/
tmpp2t5xmo3/document.ly 0 (list))
(here the c d e is not the symbols c, d and e, but the string " c d e " of
what is between #{ and #}).
This is to be read as:
(@@ (lily) read-lily-expression-internal): get the binding read-lily-
expression-internal from the lily-module ([1])
([1] cdef [filename] 0 (list)): call that function with this string, (the other
arguments are the file name, the line number, and an empty list of closures).
[By the way this teaches you how to access internal scheme functions not
exported by Lilypond (if at any time you feel the need to be naughty). Use the
syntax
(@@ (lily) symbol) to resolve the binding for symbol. This comes directly from
guiles module system:
https://www.gnu.org/software/guile/manual/html_node/Using-Guile-Modules.html
Of course, using internal functions like that is not the best idea if you
strife for stability, as these internal functions might change behaviour at
any time, that is, Lilypond does not guarantee any sort of interface]
Now, the point is: Since #{ #} is converted to a scheme function call during
parsing (before the scheme expression is evaluated) we can quote the resulting
scheme expression by prefixing it with an '... or by calling (quote ...).
Essentially we see that Lilypond integrates guile so well that you can use
very specific concepts of schmeme on very specific contexts of Lilypond.
To get some more details on quoting you might want to check out the point in
Jean’s Extending-Lilypond manual:
https://extending-lilypond.gitlab.io/en/scheme/quoting.html
Cheers,
Valentin
signature.asc
Description: This is a digitally signed message part.
