[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Questions about using Scheme with Lilypond
From: |
Aaron Hill |
Subject: |
Re: Questions about using Scheme with Lilypond |
Date: |
Sun, 15 Nov 2020 15:07:08 -0800 |
User-agent: |
Roundcube Webmail/1.4.9 |
On 2020-11-15 12:03 pm, Tom Brennan wrote:
I'd like to create a function that would allow me to create a
`bookpart`
from a list of arguments. E.g.,
[...]
Is this kind of thing possible?
Yes-ish, see my post [1] last month about "returning" books and book
parts.
[1]:
https://lists.gnu.org/archive/html/lilypond-user/2020-10/msg00406.html
2. Applying variadic arguments (i.e., "splat"). E.g., in Clojure, you
can
do something like this:
[...]
but you can't just throw a list in right there, right? It would need to
be
expanded, in the `apply` sense. I assume Guile has macros, like
Clojure,
but I don't know how to use them yet. Would that path lead me to
success
here, though?
Guile does support macros, although these are not needed for procedures
of variable arity. Consider:
%%%%
\version "2.20.0"
#(define (foo . args) (format #t "\nargs=~s" args))
#(foo 1 2)
#(foo 'a 'b 'c)
#((lambda args (format #t "\nargs=~s" args)) 3 'd)
%%%%
====
Parsing...
args=(1 2)
args=(a b c)
args=(3 d)
====
The problem you are hitting is that music functions must have fixed
arity. There is limited support for optional arguments, but the parser
ultimately needs to know how much input will be consumed by a function.
Otherwise, you could invoke a music function and potentially read to the
end of the file.
To work around this limitation, you can leverage existing constructs
that contain variable numbers of things. Consider a function that needs
to accept one or more pitches. You could instead accept ly:music? so
multiple pitches are specified within curly braces (i.e. sequential
music). The music-pitches procedure will handle extracting the pitches
from the provided music:
%%%%
\version "2.20.0"
baz = #(define-void-function (pitches) (ly:music?)
(format #t "\npitches=~s" (music-pitches pitches)))
\baz a
\baz { b d f }
%%%%
====
Parsing...
pitches=(#<Pitch a >)
pitches=(#<Pitch b > #<Pitch d > #<Pitch f >)
====
-- Aaron Hill