lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: LilyPond to Scheme to Lilypond and variadic function


From: Aaron Hill
Subject: Re: LilyPond to Scheme to Lilypond and variadic function
Date: Tue, 24 Nov 2020 16:44:52 -0800
User-agent: Roundcube Webmail/1.4.9

On 2020-11-24 3:00 pm, Daniel Tomas wrote:
I am working on a Microtonal key for LilyPond, but I need help to construct
a function which I will try to simplify here. I have some questions :
1) In Scheme can be possible to write a function which is variadic with a
point :
( function (arg1 arg2 . m )  ( ... ))
And here  m contains not only one parameter passed. m1, m2, ...
I have not found in any place information about how to access m, is it a
list ? But in this case, we can directly use a list like
(function (arg1 arg2 ls) ( ... ))

m is a list, although there are helpers for destructuring it. This is documented in the Guile manual [1].

[1]: https://www.gnu.org/software/guile/docs/docs-1.8/guile-ref/

%%%%
\version "2.20.0"

#(define (func first second . rest)
  (let-optional rest ((third 'default) (fourth 'default))
   (format #t "\n -- func --")
   (format #t "\n     required args: first=~s, second=~s" first second)
   (format #t "\n destructured args: third=~s, fourth=~s" third fourth)
   (format #t "\n   additional args: rest=~s" rest)))

#(func 'a 'b)
#(func 'c 'd 'e)
#(func 'f 'g 'h 'i 'j)
%%%%
====
Parsing...
 -- func --
     required args: first=a, second=b
 destructured args: third=default, fourth=default
   additional args: rest=()
 -- func --
     required args: first=c, second=d
 destructured args: third=e, fourth=default
   additional args: rest=()
 -- func --
     required args: first=f, second=g
 destructured args: third=h, fourth=i
   additional args: rest=(j)
Success: compilation successfully completed
====

The advantage of (lambda args) over (lambda (args)) is that the list is implicit. Callers can invoke the procedure more naturally. Imagine if one had to say (+ (list 1 2 3)) instead of simply (+ 1 2 3).


2) Now i need to do this with music information like :
Function =  #(define-music-function
            (parser location cyclic  ls)
            (boolean? list?)
     #{
      ...
How call to another function which arguments are musical elements and 2
numbers passed n times by <ls> ?
     ...
     #}
     )

Function need to be called with unfixed number N of arguments :
\Function #t c4 2 3 d 2 5 e 4 1 f2 1 1 ... musicN nN1 nN2
Please , somebody can help me ?

The above cannot be done as LilyPond's scheme functions cannot handle such open-ended arity. The only variability is optional arguments, and even then there are some restrictions due to how the parser works.

To provide arbitrary numbers of things, you must use a list of some form.

%%%%
\version "2.20.0"

foo =
#(define-void-function (args) (list?) (format #t "\n args=~s" args))

\foo #'(this is a literal scheme list)
\foo 3,1,4,1,5,9,2,6 % ..a list of natural numbers
\foo This.Is.A.Symbol.List

baz =
#(define-void-function (prop args) (symbol? ly:music?)
  (set! args (map (lambda (m) (ly:music-property m prop))
                  (extract-typed-music args 'rhythmic-event)))
  (format #t "\n args=~s" args))

\baz pitch { c d e f }
\baz duration { 1 2. 4 }
\baz text \lyricmode { Here are some words. }
%%%%
====
Parsing...
 args=(this is a literal scheme list)
 args=(3 1 4 1 5 9 2 6)
 args=(This Is A Symbol List)
 args=(#<Pitch c > #<Pitch d > #<Pitch e > #<Pitch f >)
 args=(#<Duration 1 > #<Duration 2. > #<Duration 4 >)
 args=("Here" "are" "some" "words.")
Success: compilation successfully completed
====

With \foo, we are leveraging some of LilyPond's syntactic elements that ultimately resolve to a list. There are limitations on what types of data can appear, but it is certainly an option to consider.

\baz demonstrates working with music as a container for data. This option is ideal when inputting a variable number of musical things as it largely resembles other LilyPond syntax.


-- Aaron Hill



reply via email to

[Prev in Thread] Current Thread [Next in Thread]