Re: for-each?

2023-07-03 Thread David Kastrup
Jean Abou Samra  writes:

> Le lundi 03 juillet 2023 à 22:08 +0200, David Kastrup a écrit :
>> Ugh, that's a can of worms.  #xxx will only accept a context-dependent
>> set of values and reject values not fitting the context.  But the
>> context includes whether or not, for example, we are in lyrics mode.
>> For that reason \new ... accepts only a rather limited set of
>> expressions, mostly delimited expressions where the mode-switching
>> happens at the delimiters.
>> 
>> So it's more the $... that is problematic, but $... always comes with a
>> warning tag with possibly untimely mode switching because of how parser
>> lookahead works.
>> 
>> So all in all, I'm queasy about touching anything here.  It's not like
>> you cannot just use one level of { } to get a context where #... will be
>> well-defined.
>
>
> On a related note, \new XXX is the only syntactic context I know
> where XXX = \xxx is accepted if xxx was defined with define-music-function,
> but not if it was defined with define-scheme-function, even if
> the function returns music.

Pretty sure there are more.

> I dunno whether that's expected, or improvable. At any rate, it is the
> only case where I am aware of an advantage of define-music-function
> over define-scheme-function.
>
> (And yes, I should really look into the parser code myself, but I
> don't have the time right now.)

If you want to work on consistency and reducing quirks like syntactic
define-xxx-function differentiation, "having the time" sort of requires
a sabbatical.  Certainly beyond GSoC level.

-- 
David Kastrup



Re: for-each?

2023-07-03 Thread Jean Abou Samra
Le lundi 03 juillet 2023 à 22:08 +0200, David Kastrup a écrit :
> Ugh, that's a can of worms.  #xxx will only accept a context-dependent
> set of values and reject values not fitting the context.  But the
> context includes whether or not, for example, we are in lyrics mode.
> For that reason \new ... accepts only a rather limited set of
> expressions, mostly delimited expressions where the mode-switching
> happens at the delimiters.
> 
> So it's more the $... that is problematic, but $... always comes with a
> warning tag with possibly untimely mode switching because of how parser
> lookahead works.
> 
> So all in all, I'm queasy about touching anything here.  It's not like
> you cannot just use one level of { } to get a context where #... will be
> well-defined.


On a related note, \new XXX is the only syntactic context I know
where XXX = \xxx is accepted if xxx was defined with define-music-function,
but not if it was defined with define-scheme-function, even if
the function returns music.

I dunno whether that's expected, or improvable. At any rate, it is
the only case where I am aware of an advantage of define-music-function
over define-scheme-function.

(And yes, I should really look into the parser code myself, but
I don't have the time right now.)


signature.asc
Description: This is a digitally signed message part


Re: for-each?

2023-07-03 Thread David Kastrup
David Kastrup  writes:

> Lukas-Fabian Moser  writes:
>
>> Or maybe even:
>>
>> \version "2.25.6"
>>
>> parts = {
>>   { c' }
>>   { d' }
>>   { e' }
>>   { f' }
>> }
>>
>> group = #
>> (define-music-function (parts) (ly:music?)
>>   #{
>> \new StaffGroup
>> $(make-music 'SimultaneousMusic parts)
>>   #})
>>
>> \group \parts
>>
>> ? But I'm surprised (a bit) that I need $ here - the \new commands
>> still puzzle me sometimes.
>
> Huh.  I would not have thought so either.  Maybe worth looking at.

Ugh, that's a can of worms.  #xxx will only accept a context-dependent
set of values and reject values not fitting the context.  But the
context includes whether or not, for example, we are in lyrics mode.
For that reason \new ... accepts only a rather limited set of
expressions, mostly delimited expressions where the mode-switching
happens at the delimiters.

So it's more the $... that is problematic, but $... always comes with a
warning tag with possibly untimely mode switching because of how parser
lookahead works.

So all in all, I'm queasy about touching anything here.  It's not like
you cannot just use one level of { } to get a context where #... will be
well-defined.

-- 
David Kastrup



Re: for-each?

2023-07-03 Thread David Kastrup
Lukas-Fabian Moser  writes:

> Or maybe even:
>
> \version "2.25.6"
>
> parts = {
>   { c' }
>   { d' }
>   { e' }
>   { f' }
> }
>
> group = #
> (define-music-function (parts) (ly:music?)
>   #{
> \new StaffGroup
> $(make-music 'SimultaneousMusic parts)
>   #})
>
> \group \parts
>
> ? But I'm surprised (a bit) that I need $ here - the \new commands
> still puzzle me sometimes.

Huh.  I would not have thought so either.  Maybe worth looking at.
I had been considering this approach, but it requires knowing the
magical word "SimultaneousMusic".  Admittedly, my approach required
knowing the magical word "elements".

-- 
David Kastrup



Re: for-each?

2023-07-03 Thread Lukas-Fabian Moser

That has an awkward look.  I'd rather use

```
\version "2.25.6"

parts = {
   {c'}
   {d'}
   {e'}
   {f'}
 }

group =
#(define-music-function
   (parts) (ly:music?)
   #{\new StaffGroup << #@(ly:music-property parts 'elements) >>#})

\group \parts
```


Or maybe even:

\version "2.25.6"

parts = {
  { c' }
  { d' }
  { e' }
  { f' }
}

group = #
(define-music-function (parts) (ly:music?)
  #{
    \new StaffGroup
    $(make-music 'SimultaneousMusic parts)
  #})

\group \parts

? But I'm surprised (a bit) that I need $ here - the \new commands still 
puzzle me sometimes.


Lukas




Re: for-each?

2023-07-03 Thread Pierre-Luc Gauthier
Le dim. 2 juill. 2023, à 15 h 28, Valentin Petzel  a écrit :

> you should not use for-each in such a case. for-each is essentially a version
> of map that does not return anything.
> …the @ token to tell the parser to insert not the scheme
> object in question, but all the elements of it:

(studiously taking notes in this scheme 101 course)

> The other way would be to construct the SimultaneousMusic << ... >> directly
> in scheme:
> $(make-music 'SimultaneousMusic 'elements parts)

Thanks for the explanation Valentin. I really appreciate it.


Jean Abou Samra  writes:
> You can't — for-each is not the right tool for this. What you actually want 
> is called list splicing: #@

Thanks a lot Jean. This is exactly what I needed.


David Kastrup  a écrit :
> That has an awkward look.  I'd rather use

Yes, sorry for that, I tried to MWEise my very awkward and barely
functioning part system.

>  #@(ly:music-property parts 'elements)

^ Thanks, I'll keep this one in my tool box.



-- 
Pierre-Luc Gauthier



Re: Music function to manage a moment and beat for the Staff and the Voice

2023-07-03 Thread Volodymyr Prokopyuk
Hi Jean,

It worked! I managed to move from a Nunjucks macro to a LilyPond music
function for creating custom shaped slurs. Thank you very much for your
substantial support! It would be much more difficult if ever possible for
me without your help!

Thank you,
Vlad

On Sun, Jul 2, 2023 at 9:44 PM Jean Abou Samra  wrote:

> Le dimanche 02 juillet 2023 à 18:47 +0200, Volodymyr Prokopyuk a écrit :
>
> 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)?
>
>
>
>
> The control-points property has the form
>
> ((ax . ay) (bx . by) (cx . cy) (dx . dy))
>
> as you can see when you use plain \shape #'((ax . ay) (bx . by) (cx . cy)
> (dx . dy)) . That expression is a list of pairs (lists are in parentheses
> and pairs are in parentheses with a dot in the middle). So you can create
> it with either
>
> (list (cons ax ay) (cons bx by) (cons cx cy) (cons dx dy))
>
> where list is the function to build a list and cons is the function to
> build a pair, or
>
> `((,ax . ,ay) (,bx . ,by) (,cx . ,cy) (,dx . ,dy))
>
> which uses quasiquoting to achieve the same result.
>
> If you are not yet familiar with quoting, I really recommend reading about
> it (e.g., https://extending-lilypond.gitlab.io/en/scheme/quoting.html ).
> It's a concept that causes a lot of confusion for Scheme newcomers, yet is
> essential to understand for writing Scheme effectively.
>
>
>
>
>- How would I call this function? I guess c'4 \shapedSlur fu #'((bs .
>3.0) (ht . 2.0)) ( d)
>
>
>
> Yes, that's it.
>
> Best,
> Jean
>
>


Re: How to submit a feature request (issue)

2023-07-03 Thread Jean Abou Samra
Le dimanche 02 juillet 2023 à 23:25 -0700, Curt McDowell a écrit :
>  
> I don't think it's tenable to expect anyone to keep a separate version of
> LilyPond for each unique \version called for by all the scores in their
> library. In the current system, that would be the only way to guarantee
> correct and consistent output.


The recommended approach is not to keep zillions of versions, but to upgrade all
your scores once a stable release is out (2.24 being the latest), using convert-
ly. Stable releases are relatively infrequent (the two latest ones took a year
and a half each).

> I'd hesitate to call the LilyPond version system "lazy", as backward
> compatibility can be complex especially with subjective fuzzy output
> correctness, but pretty much every other programming language or application
> file format manages to deal with it. When they reach a breaking point after a
> decade (maybe something like going from Guile 1.8 to 2.2), they increment the
> major version number and only then do users have to maintain multiple versions
> or modernize a lot of code (e.g. Python 2.7 to 3).

Python is not a bad point of comparison, since it's a very dynamic language,
similar to LilyPond. And you will find that backwards compatibility is a major
common complaint against the language, and not just because of Python 3. I think
it has been getting better lately, but at the price of a lot of effort put into
backwards compatibility.

All the best,
Jean



signature.asc
Description: This is a digitally signed message part


Re: How to submit a feature request (issue)

2023-07-03 Thread Curt McDowell
I don't think it's tenable to expect anyone to keep a separate version 
of LilyPond for each unique \version called for by all the scores in 
their library. In the current system, that would be the only way to 
guarantee correct and consistent output.


I'd hesitate to call the LilyPond version system "lazy", as backward 
compatibility can be complex especially with subjective fuzzy output 
correctness, but pretty much every other programming language or 
application file format manages to deal with it. When they reach a 
breaking point after a decade (maybe something like going from Guile 1.8 
to 2.2), they increment the major version number and only then do users 
have to maintain multiple versions or modernize a lot of code (e.g. 
Python 2.7 to 3).


It's just fortunate that LilyPond is sufficiently backward compatible 
for basic code that version problems don't often crop up. convert-ly 
will be there if something actually goes wrong, but this remains an 
annoyance for people concerned with precision.


On 7/1/2023 12:09 PM, Jean Abou Samra wrote:

Le samedi 01 juillet 2023 à 11:30 -0700, Curt McDowell a écrit :

I tend not to use convert-ly because I feel upgrading a file version
would unfairly force anyone who wants to compile my music to upgrade
their LilyPond installation. Upgrading might not be straightforward when
using a standard distro, and I'd hate for someone to risk destabilizing
their working environment on my account.


lilypond.org distributes static self-contained binaries of LilyPond 
that can just be unpacked in whatever directory and run from there 
without being installed in some way, so the risk of destabilizing the 
environment is exactly zero.