lilypond-user
[Top][All Lists]
Advanced

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

Two optional arguments


From: Urs Liska
Subject: Two optional arguments
Date: Tue, 14 Jul 2020 14:30:10 +0200
User-agent: Evolution 3.36.3-1

Hi all,

is it correct that you can't write a music function with two optional
arguments in a row? If so:

* is that on purpose?
* is that inevitable?
* is there a workaround for my use case (below)?

Consider this function

twoOpts =
#(define-void-function (one two three)((symbol? 'foo) (number? 5)
string?)
   (ly:message "one: ~a
two: ~a
three: ~a" one two three))

and this call

\twoOpts
hey 
4
"bar"

This works correctly, and when I comment out the 4 it properly picks
the default value 5.
However, when I comment out both or only the first value it fails with

    error: wrong type for argument 3.  Expecting string, found 4


This behavious is consistent with the extending manual 
http://lilypond.org/doc/v2.21/Documentation/extending/index_7#Scheme-functions

"Once an optional argument predicate does not match an argument,
LilyPond skips this and all following optional arguments, replacing
them with their specified default, and ‘backs up’ the argument that did
not match to the place of the next mandatory argument. Since the backed
up argument needs to go somewhere, optional arguments are not actually
considered optional unless followed by a mandatory argument."

So in 

\twoOpts
%hey 
4
"bar"

The 4 doesn't match the first symbol? predicate, so all optional
arguments receive their defaults and the 4 is "backed-up" to the next
mandatory argument which happens to be a string? that now fails.

It does work (also consistent with the docs) when each optional
argument is followed by its "own" backup mandatory argument.

So far, so bad. What I don't understand is why in case of a missing
optional argument (detected by a failed type check) LilyPond has to
skip "this and all following optional arguments". Couldn't LilyPond
just skip "this" and back up the failed argument to the next (mandatory
*or* optional) argument to cascade through all available arguments.

In the call

\twoOpts 4 "bar"

 * 4 wouldn't match symbol?
 * so one would get the default value 'foo
 * then the 4 is checked against the next predicate, which works
 * so two gets the 4
 * finally three gets "bar"

In the call

\twoOpts "bar"

 * "bar" wouldn't match symbol?
 * so one gets the default 'foo
 * "bar" is then checked against the next predicate, which fails too
 * so two gets the default 5
 * finally "bar" matches the mandatory argument's predicate

I totally understand that it is absolutely necessary to have an
unambiguous order of predicates when optional arguments are involved,
but couldn't it be possible to have multiple optional ones following
after another.

I would really like to write a function with a symbol? and a
ly:context-mod? argument and have both of them optional.

Is there any possible workaround currently?
Would this be a legitimate feature request?
Is there anything I've overlooked that makes this impossible?

ThanksUrs




reply via email to

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