Hi Jean,

Thank you very much for multiple options! I've decided to try the first
one. I still have two difficulties

   - How to create alist from the components ax, ay, ... (see comment in
   the code below)?
   - How would I call this function? I guess c'4 \shapedSlur fu #'((bs .
   3.0) (ht . 2.0)) ( d)

I managed to created the below music function following your advice for the
option 1

shapedSlur = #(define-music-function (dir prs mus) (symbol? alist?
ly:music?)
  (let* ((bs (assoc-get 'bs pars 2.0))
         (sh (assoc-get 'sh prs 0.5))
         (wd (assoc-get 'wd prs 1.0))
         (ht (assoc-get 'ht prs 1.0))
         (dt (assoc-get 'dt prs 0.0))
         (pts (cond
               ((equal? dir 'fu)
                (let ((ax (+ sh (* 0.0 wd)))
                      (bx (+ sh (* 1.0 wd)))
                      (cx (+ sh (* 2.0 wd)))
                      (dx (+ sh (* 3.0 wd)))
                      (ay bs)
                      (by (+ bs ht))
                      (cy (+ bs ht))
                      (dy (+ bs dt)))
                  ;; Do not know how to create alist suitable for
                  ;; \tweak control-points
                  (list ax ay bx by cx cy dx dy)))
               ((equal? dir 'fd)
                (let ((ax (+ sh (* 0.0 wd)))
                      (bx (+ sh (* 1.0 wd)))
                      (cx (+ sh (* 2.0 wd)))
                      (dx (+ sh (* 3.0 wd)))
                      (ay (* -1 bs))
                      (by (* -1 (+ bs ht)))
                      (cy (* -1 (+ bs ht)))
                      (dy (* -1 (+ bs dt))))
                  (list ax ay bx by cx cy dx dy)))
               ((equal? dir 'bu)
                (let ((ax (- (+ sh (* 0.0 wd)) (* 3.0 wd)))
                      (bx (- (+ sh (* 1.0 wd)) (* 3.0 wd)))
                      (cx (- (+ sh (* 2.0 wd)) (* 3.0 wd)))
                      (dx (- (+ sh (* 3.0 wd)) (* 3.0 wd)))
                      (ay (+ bs dt))
                      (by (+ bs ht))
                      (cy (+ bs ht))
                      (dy bs))
                  (list ax ay bx by cx cy dx dy)))
               ((equal? dir 'bd)
                (let ((ax (- (+ sh (* 0.0 wd)) (* 3.0 wd)))
                      (bx (- (+ sh (* 1.0 wd)) (* 3.0 wd)))
                      (cx (- (+ sh (* 2.0 wd)) (* 3.0 wd)))
                      (dx (- (+ sh (* 3.0 wd)) (* 3.0 wd)))
                      (ay (* -1 (+ bs dt)))
                      (by (* -1 (+ bs ht)))
                      (cy (* -1 (+ bs ht)))
                      (dy (* -1 bs)))
                  (list ax ay bx by cx cy dx dy)))
               )))
    (tweak 'control-points pts mus)))

Thank you,
Vlad

On Sun, Jul 2, 2023 at 3:05 PM Jean Abou Samra <[email protected]> wrote:

> Le dimanche 02 juillet 2023 à 14:28 +0200, Volodymyr Prokopyuk a écrit :
>
> I wonder if there is a *way to define a music function with default
> parameters* and be able to selectively specify some parameters using the 
> *parameters
> names* leaving all other parameters with their default values? Probably
> it is asking too much :)
>
> It is indeed asking too much from music functions (as in many languages
> where functions are called without parentheses or some other delimiter).
> There are a couple of ways around this restriction, though. One would be to
> just specify your arguments in a Scheme alist, like
>
> shapedSlur =
> #(define-music-function (params item) (alist? ly:music?)
>    (let* ((dir (assoc-get 'dir params))
>           (bs (assoc-get 'bs params 2.0))
>           ...)
>      (tweak 'control-points `(...) item)))
>
> Another one is to define a Scheme function. If you use define instead of
> define*, it will recognize special objects in its argument list (called
> "keywords", written with "#:") which define named parameters.
>
> #(define* (shaped-slur dir #:key (bs 2.0)
>                                  (sh 0.5)
>                                  (wd 1.0)
>                                  (ht 1.0)
>                                  (dt 0.0))
>    (let ((control-points ...))
>      #{ \tweak control-points #control-points \etc #}))
>
> {
>   c'$(shaped-slur 'your-dir #:bs 3.0 #:sh 0.1)( c')
> }
>
> Finally, you could abuse context mods a bit ("context mods" is the
> technical name for \with blocks), like this:
>
> shapedSlur =
> #(define-music-function (params item) (ly:context-mod? ly:music?)
>    (let* ((properties (filter-map (match-lambda (('assign prop val) (cons 
> prop val))
>                                                 (else #f))
>                                   (ly:get-context-mods params)))
>           (dir (assoc-get 'dir properties))
>           (bs (assoc-get 'bs properties 2.0))
>           ...
>           (control-points `(...)))
>      (tweak 'control-points control-points item)))
>
> {
>   c'\shapedSlur \with { dir=#'foo bs=5.0 } ( c')
> }
>
> Best,
>
> Jean
>

Reply via email to