LilyPond Contributor's Guide: 10.16.3 Music functions and GUILE debugging

### 10.16.3 Music functions and GUILE debugging

Ian Hulin was trying to do some debugging in music functions, and came up with the following question (edited and adapted to current versions):

HI all, I’m working on the Guile Debugger Stuff, and would like to try debugging a music function definition such as:

>     conditionalMark =
>     #(define-music-function () ()
>       #{ \tag instrumental-part {\mark \default} #} )

It appears `conditionalMark` does not get set up as an equivalent of a Scheme

>     (define conditionalMark = define-music-function () () ...

although something gets defined because Scheme apparently recognizes

>     #(set-break! conditionalMark)

later on in the file without signalling any Guile errors.

However the breakpoint trap is never encountered as `define-music-function` passed things on to `ly:make-music-function`, which is really C++ code `ly_make_music_function`, so Guile never finds out about the breakpoint.

The answer in the mailing list archive at that time was less than helpful. The question already misidentifies the purpose of `ly:make-music-function` which is only called once at the time of defining `conditionalMark` but is not involved in its later execution.

Here is the real deal:

A music function is not the same as a GUILE function. It boxes both a proper Scheme function (with argument list and body from the `define-music-function` definition) along with a call signature representing the types of both function and arguments.

Those components can be reextracted using `ly:music-function-extract` and `ly:music-function-signature`, respectively.

When LilyPond’s parser encounters a music function call in its input, it reads, interprets, and verifies the arguments individually according to the call signature and then calls the proper Scheme function.

While it is actually possible these days to call a music function as if it were a Scheme function itself, this pseudo-call uses its own wrapping code matching the argument list as a whole to the call signature, substituting omitted optional arguments with defaults and verifying the result type.

So putting a breakpoint on the music function itself will still not help with debugging uses of the function using LilyPond syntax.

However, either calling mechanism ultimately calls the proper Scheme function stored as part of the music function, and that is where the breakpoint belongs:

>     #(set-break! (ly:music-function-extract conditionalMark))

will work for either calling mechanism.

#### LilyPond — Contributor’s Guide v2.22.2 (stable-branch).