lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Making two functions into one


From: David Kastrup
Subject: Re: Making two functions into one
Date: Mon, 16 Jan 2023 22:58:48 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/29.0.50 (gnu/linux)

| || | | <aalderson@caramail.com> writes:

> Thank you Valentin,
>
> That was simpler than I thought. Of curse I tried first with lily code
> blocks, but have been struggling with
>
>  \time #number/8 (which doesn't work because it needs pair but gets
> int).

It gets an undefined symbol called number/8 .

What you could write here is

   \time #(cons number 8)

It turns out that fractions cannot be assembled piecemeal in LilyPond
syntax.

> There is some kind of coding convention? Both # and $ seems to work
> the same.

>From the Lilypond-Extending manual:

1.2.1 LilyPond Scheme syntax
----------------------------

The Guile interpreter is part of LilyPond, which means that Scheme can
be included in LilyPond input files.  There are several methods for
including Scheme in LilyPond.

   The simplest way is to use a hash mark ‘#’ before a Scheme
expression.

   Now LilyPond’s input is structured into tokens and expressions, much
like human language is structured into words and sentences.  LilyPond
has a lexer that recognizes tokens (literal numbers, strings, Scheme
elements, pitches and so on), and a parser that understands the syntax,
*note (lilypond-contributor)LilyPond grammar::.  Once it knows that a
particular syntax rule applies, it executes actions associated with it.

   The hash mark ‘#’ method of embedding Scheme is a natural fit for
this system.  Once the lexer sees a hash mark, it calls the Scheme
reader to read one full Scheme expression (this can be an identifier, an
expression enclosed in parentheses, or several other things).  After the
Scheme expression is read, it is stored away as the value for an
‘SCM_TOKEN’ in the grammar.  Once the parser knows how to make use of
this token, it calls Guile for evaluating the Scheme expression.  Since
the parser usually requires a bit of lookahead from the lexer to make
its parsing decisions, this separation of reading and evaluation between
lexer and parser is exactly what is needed to keep the execution of
LilyPond and Scheme expressions in sync.  For this reason, you should
use the hash mark ‘#’ for calling Scheme whenever this is feasible.

   Another way to call the Scheme interpreter from LilyPond is the use
of dollar ‘$’ instead of a hash mark for introducing Scheme expressions.
In this case, LilyPond evaluates the code right after the lexer has read
it.  It checks the resulting type of the Scheme expression and then
picks a token type (one of several ‘xxx_IDENTIFIER’ in the syntax) for
it.  It creates a _copy_ of the value and uses that for the value of the
token.  If the value of the expression is void (Guile’s value of
‘*unspecified*’), nothing at all is passed to the parser.

   This is, in fact, exactly the same mechanism that LilyPond employs
when you call any variable or music function by name, as ‘\name’, with
the only difference that the name is determined by the LilyPond lexer
without consulting the Scheme reader, and thus only variable names
consistent with the current LilyPond mode are accepted.

   The immediate action of ‘$’ can lead to surprises, see *note
Importing Scheme in LilyPond::.  Using ‘#’ where the parser supports it
is usually preferable.  Inside of music expressions, expressions created
using ‘#’ _are_ interpreted as music.  However, they are _not_ copied
before use.  If they are part of some structure that might still get
used, you may need to use ‘ly:music-deep-copy’ explicitly.

   There are also ‘list splicing’ operators ‘$@’ and ‘#@’ that insert
all elements of a list in the surrounding context.


-- 
David Kastrup



reply via email to

[Prev in Thread] Current Thread [Next in Thread]