Le samedi 01 juillet 2023 à 16:42 +0200, Volodymyr Prokopyuk a écrit : > I'm trying to define a music function as below, however I've faced > difficulties with parameter predicates, visibility of the Staff object, and > flexibility of the solution ideally without code duplication > > **Desired music function** (the code is not working) > > ``` > momentBeat = #(define-music-function (moment beat scope) > (fraction? list? (what? Staff)) > #{ > \set #scope.beamExceptions = #'() > \set #scope.baseMoment = #(ly:make-moment moment) > \set #scope.beatStructure = #beat > #}) > ``` > > **Usage** > > ``` > \momentBeat 1/2 #'(1) > \momentBeat 1/4 1,1,1,1 Voice > ``` > > **Questions** > > > - It seems that Staff is not available to Guile at that moment. I tried to > use "Staff" string and 'Staff symbol for the scope parameter with a cond > expression and code replication for Staff and Voice, but I did not manage to > get it to work due to incorrect predicates errors > > - How would it look like an idiomatic and working implementation of the above > music function?
There are a couple problems here. - The `#` character introduces a Scheme expression. In Scheme, dots are allowed in identifiers. As such, `\set #scope.beamExceptions` is trying to look up a variable literally called "scope.beamExceptions". You need a space after `#scope` to terminate the Scheme expression. - A `fraction?` is not a rational number but a (numerator . denominator) pair. The reason is that `fraction?` is the predicate for music functions like `\time`, and `\time 4/4` needs to be distinguished from `\time 2/2` (for example). The `ly:make-moment` function, on the other hand, expects a rational number. - If you want an optional argument to actually be optional, it must not be the last argument. Otherwise, you can't actually omit it, you can only replace it with `\default`. See [here](https://extending-lilypond.gitlab.io/en/extending/music.html#optional-arguments) for more details. Here is a working version of your function: ``` \version "2.24.1" momentBeat = #(define-music-function (scope moment beat) ((symbol? 'Staff) fraction? list?) #{ \set #scope .beamExceptions = #'() \set #scope .baseMoment = #(ly:make-moment (/ (car moment) (cdr moment))) \set #scope .beatStructure = #beat #}) { \momentBeat Voice 1/8 3,3,2 c'8 8 8 8 8 8 8 8 } ``` Best, Jean
signature.asc
Description: This is a digitally signed message part