+(define-public (partial-music-function fun-list arg-list)
+ (let* ((good (every list? arg-list))
+ (sig (ly:music-function-signature (car fun-list))))
+ (and good
+ (ly:make-music-function
+ (cons (car sig) (list-tail (cdr sig) (length (car arg-list))))
+ (lambda rest
+ ;; Every time we use music-function, it destructively
+ ;; reverses its list of arguments. Changing the calling
+ ;; convention would be non-trivial since we do error
+ ;; propagation to the reversed argument list by making it
+ ;; a non-proper list. So we just create a fresh copy of
+ ;; all argument lists for each call. We also want to
+ ;; avoid reusing any music expressions without copying and
+ ;; want to let them point to the location of the music
+ ;; function call rather than its definition.
+ (let ((arg-list (ly:music-deep-copy arg-list (*location*))))
+ (fold music-function-chain
+ (music-function (car fun-list)
+ (reverse! rest (car arg-list)))
+ (cdr fun-list) (cdr arg-list))))))))