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
