stemNeutral problem

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

stemNeutral problem

Edward Neeman
Hello,

I’ve come across some weird behaviour from the \stemNeutral command. This doesn’t work:

%%%%

\version "2.19.82"

\relative {  \stemUp <g' bes d>8) r8
     \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
    \stemNeutral c,16 es ges bes }

%%%

Adding a second \stemNeutral command is necessary to reset the stems to normal. Why might this be?

Thanks,
Edward

---
Dr. Edward Neeman
www.neemanpianoduo.com




_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

Federico Bruni-2


Il giorno gio 13 set 2018 alle 5:08, Edward Neeman
<[hidden email]> ha scritto:

> Hello,
>
> I’ve come across some weird behaviour from the \stemNeutral
> command. This doesn’t work:
>
> %%%%
>
> \version "2.19.82"
>
> \relative {  \stemUp <g' bes d>8) r8
>      \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
>     \stemNeutral c,16 es ges bes }
>
> %%%
>
> Adding a second \stemNeutral command is necessary to reset the stems
> to normal. Why might this be?
>
> Thanks,
> Edward
>

It works as expected, because the default direction in this case is
\stemUp.
Try this snippet:

\version "2.19.82"

\relative {
  g' % default is \stemUp
  \stemUp <g bes d>8 r8
  \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
  % \stemNeutral resets to default, that is \stemUp
  \stemNeutral c,16
  es ges bes
}





_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

Edward Neeman
Thanks for the reply.

I still don’t understand why two \stemNeutral commands work differently to just one. Take out one of them in this example and it looks different:

%%%

\version "2.19.82"

\relative {
g' % default is \stemUp
\stemUp <g bes d>8 r8
\acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
% \stemNeutral resets to default, that is \stemUp
\stemNeutral
\stemNeutral % this duplicate command is necessary
c,16
es ges bes
}

%%%

Thanks,
Edward

---
Dr. Edward Neeman
www.neemanpianoduo.com



> On 13 Sep 2018, at 2:52 pm, Federico Bruni <[hidden email]> wrote:
>
>
>
> Il giorno gio 13 set 2018 alle 5:08, Edward Neeman <[hidden email]> ha scritto:
>> Hello,
>> I´ve come across some weird behaviour from the \stemNeutral command. This doesn´t work:
>> %%%%
>> \version "2.19.82"
>> \relative {  \stemUp <g' bes d>8) r8
>>     \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
>>    \stemNeutral c,16 es ges bes }
>> %%%
>> Adding a second \stemNeutral command is necessary to reset the stems to normal. Why might this be?
>> Thanks,
>> Edward
>
> It works as expected, because the default direction in this case is \stemUp.
> Try this snippet:
>
> \version "2.19.82"
>
> \relative {
> g' % default is \stemUp
> \stemUp <g bes d>8 r8
> \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
> % \stemNeutral resets to default, that is \stemUp
> \stemNeutral c,16
> es ges bes
> }
>
>
>
>


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

Federico Bruni-2
You are right, it seems weird.
If you check your property-init.ly file you'll find these definitions:

stemUp = \override Stem.direction = #UP
stemDown = \override Stem.direction = #DOWN
stemNeutral = \revert Stem.direction

But I don't know what's happening here.

Il giorno gio 13 set 2018 alle 7:13, Edward Neeman
<[hidden email]> ha scritto:

> Thanks for the reply.
>
> I still don’t understand why two \stemNeutral commands work
> differently to just one. Take out one of them in this example and it
> looks different:
>
> %%%
>
> \version "2.19.82"
>
> \relative {
> g' % default is \stemUp
> \stemUp <g bes d>8 r8
> \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
> % \stemNeutral resets to default, that is \stemUp
> \stemNeutral
> \stemNeutral % this duplicate command is necessary
> c,16
> es ges bes
> }
>
> %%%
>
> Thanks,
> Edward
>
> ---
> Dr. Edward Neeman
> www.neemanpianoduo.com
>
>
>
>>  On 13 Sep 2018, at 2:52 pm, Federico Bruni <[hidden email]>
>> wrote:
>>
>>
>>
>>  Il giorno gio 13 set 2018 alle 5:08, Edward Neeman
>> <[hidden email]> ha scritto:
>>>  Hello,
>>>  I´ve come across some weird behaviour from the \stemNeutral
>>> command. This doesn´t work:
>>>  %%%%
>>>  \version "2.19.82"
>>>  \relative {  \stemUp <g' bes d>8) r8
>>>      \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
>>>     \stemNeutral c,16 es ges bes }
>>>  %%%
>>>  Adding a second \stemNeutral command is necessary to reset the
>>> stems to normal. Why might this be?
>>>  Thanks,
>>>  Edward
>>
>>  It works as expected, because the default direction in this case is
>> \stemUp.
>>  Try this snippet:
>>
>>  \version "2.19.82"
>>
>>  \relative {
>>  g' % default is \stemUp
>>  \stemUp <g bes d>8 r8
>>  \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
>>  % \stemNeutral resets to default, that is \stemUp
>>  \stemNeutral c,16
>>  es ges bes
>>  }
>>
>>
>>
>>
>


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

Aaron Hill
On 2018-09-12 10:30 pm, Federico Bruni wrote:
> You are right, it seems weird.
> If you check your property-init.ly file you'll find these definitions:
>
> stemUp = \override Stem.direction = #UP
> stemDown = \override Stem.direction = #DOWN
> stemNeutral = \revert Stem.direction
>
> But I don't know what's happening here.

Something fishy with grace notes, I think.  Consider the following:

%%%%
\version "2.19.82"
<< { b'4 \stemUp b'4 \grace { \stemDown b'8 }
      \stemNeutral b'4 \stemNeutral b'4 } >>
%%%%

The occurrence of b'4 after the grace should be stem-down as that is its
neutral direction.

What is odd is that this behavior is unique to Stem.direction as far as
my testing has shown.  If you redefine \stemUp, \stemDown, and
\stemNeutral to, say, change the Stem.color, then the fault does not
occur.  Grace (or acciaccatura) notes must be special-cased in how they
work with Stem.direction.  (I believe that grace notes are neutrally
stem-up regardless of position on the staff.)  And something is not
playing nice with normal \override/\revert logic.

-- Aaron Hill
_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user

stemdir.cropped.png (5K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

David Kastrup
In reply to this post by Edward Neeman
Edward Neeman <[hidden email]> writes:

> Hello,
>
> I’ve come across some weird behaviour from the \stemNeutral command. This doesn’t work:
>
> %%%%
>
> \version "2.19.82"
>
> \relative {  \stemUp <g' bes d>8) r8
>      \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
>     \stemNeutral c,16 es ges bes }
>
> %%%
>
> Adding a second \stemNeutral command is necessary to reset the stems to normal. Why might this be?

Here is the deal.  \acciaccatura does an implicit \temporary \stemUp (as
that's a default for grace notes) which it cancels at the end of
\acciacatura, provided that it is still active.

\stemDown will cancel this preexisting \temporary \stemUp.
Consequently, \acciacatura does not see the preexisting \temporary
\stemUp at its end any more and will do nothing, in effect leaving a
\temporary \stemDown on the stack.  Your next \stemUp will replace it
with a \temporary \stemUp which will get canceled by \stemNeutral,
making the original \stemUp surface.

Ugh.  The solution is to cancel your \stemDown yourself, using
\stemNeutral .

Now let's assume that \acciaccatura would not do that kind of "matched
pop" at its end and would remove the \stemDown.  Now if you write
\acciaccatura { \stemNeutral ... } this would pop the _preceding_
\stemUp which would be even worse.  And was the reason the current
behavior was implemented.

So maybe the "matched pop" should be done in a different manner: if the
previous state of the stack can be restored, do so, without actually
looking at what you are going to pop in order to get there.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

David Kastrup
David Kastrup <[hidden email]> writes:

> Edward Neeman <[hidden email]> writes:
>
>> Hello,
>>
>> I’ve come across some weird behaviour from the \stemNeutral command. This doesn’t work:
>>
>> %%%%
>>
>> \version "2.19.82"
>>
>> \relative {  \stemUp <g' bes d>8) r8
>>      \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
>>     \stemNeutral c,16 es ges bes }
>>
>> %%%
>>
>> Adding a second \stemNeutral command is necessary to reset the stems to normal. Why might this be?
>
> Here is the deal.  \acciaccatura does an implicit \temporary \stemUp (as
> that's a default for grace notes) which it cancels at the end of
> \acciacatura, provided that it is still active.
>
> \stemDown will cancel this preexisting \temporary \stemUp.
> Consequently, \acciacatura does not see the preexisting \temporary
> \stemUp at its end any more and will do nothing, in effect leaving a
> \temporary \stemDown on the stack.  Your next \stemUp will replace it
> with a \temporary \stemUp which will get canceled by \stemNeutral,
> making the original \stemUp surface.
>
> Ugh.  The solution is to cancel your \stemDown yourself, using
> \stemNeutral .
>
> Now let's assume that \acciaccatura would not do that kind of "matched
> pop" at its end and would remove the \stemDown.  Now if you write
> \acciaccatura { \stemNeutral ... } this would pop the _preceding_
> \stemUp which would be even worse.  And was the reason the current
> behavior was implemented.
>
> So maybe the "matched pop" should be done in a different manner: if the
> previous state of the stack can be restored, do so, without actually
> looking at what you are going to pop in order to get there.

The "matched pop" is also used for \once \override .  If you write
something like

\stemDown \once \stemUp \stemNeutral

what's the expectation for the current timestep, and what's the
expectation for afterwards?

In short, this is sort-of a messy area.  It's not necessarily the best
way \acciaccatura works but the premise is that the behavior for its
private overrides is similar to \once \override and either try not to
tamper with stuff they don't understand because then the effects are
"non-local".

Maybe the understanding could be extended beyond where it is now but it
would require some refactoring: the current implementation delivers a
"pop token" at negligible cost, and so there are no separate
implementations for when it is actually needed and not.  For a slightly
better "pop token" like sketched above, there would be non-trivial
cost.  I am not sure it would work all that much better.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

Edward Neeman
Thanks David, that makes a lot of sense!

With your explanation in mind I’m thinking the current implementation in best.

Edward

---
Dr. Edward Neeman
www.neemanpianoduo.com



On 13 Sep 2018, at 9:42 pm, David Kastrup <[hidden email]> wrote:

David Kastrup <[hidden email]> writes:

Edward Neeman <[hidden email]> writes:

Hello,

I’ve come across some weird behaviour from the \stemNeutral command. This doesn’t work:

%%%%

\version "2.19.82"

\relative {  \stemUp <g' bes d>8) r8
    \acciaccatura { \stemDown <ges' bes>8 } \stemUp <c e g!> r
   \stemNeutral c,16 es ges bes }

%%%

Adding a second \stemNeutral command is necessary to reset the stems to normal. Why might this be?

Here is the deal.  \acciaccatura does an implicit \temporary \stemUp (as
that's a default for grace notes) which it cancels at the end of
\acciacatura, provided that it is still active.

\stemDown will cancel this preexisting \temporary \stemUp.
Consequently, \acciacatura does not see the preexisting \temporary
\stemUp at its end any more and will do nothing, in effect leaving a
\temporary \stemDown on the stack.  Your next \stemUp will replace it
with a \temporary \stemUp which will get canceled by \stemNeutral,
making the original \stemUp surface.

Ugh.  The solution is to cancel your \stemDown yourself, using
\stemNeutral .

Now let's assume that \acciaccatura would not do that kind of "matched
pop" at its end and would remove the \stemDown.  Now if you write
\acciaccatura { \stemNeutral ... } this would pop the _preceding_
\stemUp which would be even worse.  And was the reason the current
behavior was implemented.

So maybe the "matched pop" should be done in a different manner: if the
previous state of the stack can be restored, do so, without actually
looking at what you are going to pop in order to get there.

The "matched pop" is also used for \once \override .  If you write
something like

\stemDown \once \stemUp \stemNeutral

what's the expectation for the current timestep, and what's the
expectation for afterwards?

In short, this is sort-of a messy area.  It's not necessarily the best
way \acciaccatura works but the premise is that the behavior for its
private overrides is similar to \once \override and either try not to
tamper with stuff they don't understand because then the effects are
"non-local".

Maybe the understanding could be extended beyond where it is now but it
would require some refactoring: the current implementation delivers a
"pop token" at negligible cost, and so there are no separate
implementations for when it is actually needed and not.  For a slightly
better "pop token" like sketched above, there would be non-trivial
cost.  I am not sure it would work all that much better.

-- 
David Kastrup


_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

David Kastrup
Edward Neeman <[hidden email]> writes:

> Thanks David, that makes a lot of sense!
>
> With your explanation in mind I’m thinking the current implementation in best.

Well, the problem really is finding an implementation that does not
cause surprises.  One could rather brutally restore all settings made
inside of a \grace group that are subject to \grace settings.  Those
would be (currently)

(define general-grace-settings
  `((Voice Stem font-size -3)
    (Voice Flag font-size -3)
    (Voice NoteHead font-size -3)
    (Voice TabNoteHead font-size -4)
    (Voice Dots font-size -3)
    (Voice Stem length-fraction 0.8)
    (Voice Stem no-stem-extend #t)
    (Voice Beam beam-thickness 0.384)
    (Voice Beam length-fraction 0.8)
    (Voice Accidental font-size -4)
    (Voice AccidentalCautionary font-size -4)
    (Voice Script font-size -3)
    (Voice Fingering font-size -8)
    (Voice StringNumber font-size -8)))

(define-public score-grace-settings
  (append
    `((Voice Stem direction ,UP)
      (Voice Slur direction ,DOWN))
    general-grace-settings))

So basically at the end of the \grace group, rewind to what was there
before.  However, the property lists are per-Grob, not per-property, so
either one would have to restore the complete state of all the listed
Grobs, or one would have to filter the lists into components relating to
the desired properties and unrelated components, and reassemble the
respective lists afterwards.

Probably easier to just restore the complete Grob definitions.  Would
people be surprised if a color override of a Beam was reverted at the
end of a \grace group?

I don't know.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

Aaron Hill
In reply to this post by David Kastrup
On 2018-09-13 4:42 am, David Kastrup wrote:
> [...] If you write something like
>
> \stemDown \once \stemUp \stemNeutral
>
> what's the expectation for the current timestep, and what's the
> expectation for afterwards?

If \stem(Up|Down|Neutral) were as simple as "Stem.direction :=
(Up|Down|Neutral)" and \once pushes a new value onto a stack that will
be popped at some later time to restore the original value, then the
property could have a well-defined* value during evaluation:

"\stemDown \once \stemUp <{> \stemNeutral <...> <}>"

Token(s)            Stem.direction (Stack)
------------------------------------------------
\stemDown           Down           ()
\once \stemUp <{>   Up             (Down)
\stemNeutral <...>  Neutral        (Down)
<}>                 Down           ()

Note that I have indicated <{> and <}> which are invisible, though
implied, tokens that define the scope of \once.  In LilyPond, this scope
seems to be based on timestep.  So we must presume that <...> includes
something that has stepped time forward once as to trigger the cleanup
behavior of \once.

(* I say "well-defined" above but I should clarify that this behavior
might not match expectations.  An explicit \stemNeutral might seem to
folks to have the final say, but since it is within the scope of \once
implicitly, its value is also temporary.)

Of course, \stemNeutral in particular does not set the property but
rather "unsets" it by \reverting whatever value the property may have
been \overridden with.  This means that \override might be preserving a
value on a stack for later restoration.

"\stemDown \once \stemUp <{> \stemNeutral <...> <}>"

Token(s)            Stem.direction (Stack)
------------------------------------------------
\stemDown           Down           (<undefined>)
\once \stemUp <{>   Up             (Down, <undefined>)
\stemNeutral <...>  Down           (<undefined>)
<}>                 <undefined>    ()

The problem here is that \stemNeutral \reverted the value of the \stemUp
but was left with the value that \once placed on the stack--*not* the
neutral state we expect.  So the result is even less clear.

Of course, \override does not need to make use of a stack if \revert
were to instead always set the property to an undefined (unset) value.

"\stemDown \once \stemUp <{> \stemNeutral <...> <}>"

Token(s)            Stem.direction (Stack)
------------------------------------------------
\stemDown           Down           ()
\once \stemUp <{>   Up             (Down)
\stemNeutral <...>  <undefined>    (Down)
<}>                 Down           ()

This behavior is identical the first version, where now neutrality is
indicated by a lack of value.  It is still slightly counter-intuitive
because the effect of \stemNeutral does not persist beyond the scope of
the \once.

- - - -

This discussion is particularly interesting as I have found myself
working through "Principles of Compiler Design" (Aho/Ullman) again after
having perused it far too quickly when I was much younger and much less
equipped to fully appreciate it.  One relevant realization I have is
that it seems there is no worthwhile amount of effort one can expend to
design a language with precision and unambiguity such that it can fully
prevent someone writing nonsense as input.  I think it was Chomsky who
came up with something like: "Colorless green ideas sleep furiously."

-- Aaron Hill

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

David Kastrup
Aaron Hill <[hidden email]> writes:

> Token(s)            Stem.direction (Stack)
> ------------------------------------------------
> \stemDown           Down           ()
> \once \stemUp <{>   Up             (Down)
> \stemNeutral <...>  <undefined>    (Down)
> <}>                 Down           ()
>
> This behavior is identical the first version, where now neutrality is
> indicated by a lack of value.  It is still slightly counter-intuitive
> because the effect of \stemNeutral does not persist beyond the scope
> of the \once.

The current behavior tries to keep surprising behavior close to the
cause of the surprise.  Basically it prefers "huh?" over "WHAT?!?!?!?!".
It's not trivial to do significantly better.

> This discussion is particularly interesting as I have found myself
> working through "Principles of Compiler Design" (Aho/Ullman) again
> after having perused it far too quickly when I was much younger and
> much less equipped to fully appreciate it.  One relevant realization I
> have is that it seems there is no worthwhile amount of effort one can
> expend to design a language with precision and unambiguity such that
> it can fully prevent someone writing nonsense as input.  I think it
> was Chomsky who came up with something like: "Colorless green ideas
> sleep furiously."

Chomsky was more about differences in being well-formed and
well-meaning.  I mean, between syntactic correctness and semantic sense.

I'd not attribute "nonsense" to the input written: such combinations
easily come about when combining various settings into semantic blocks
and such blocks into meaningful actions, and that is actually exactly
what happens when the equivalents of \graceOn and \graceOff influence a
block of properties that are useful to change for other reasons as well.

For some things, the stack model works well.  For some other, less well.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user
Reply | Threaded
Open this post in threaded view
|

Re: stemNeutral problem

David Kastrup
In reply to this post by Aaron Hill
Aaron Hill <[hidden email]> writes:

> On 2018-09-13 4:42 am, David Kastrup wrote:
>> [...] If you write something like
>>
>> \stemDown \once \stemUp \stemNeutral
>>
>> what's the expectation for the current timestep, and what's the
>> expectation for afterwards?
>
> If \stem(Up|Down|Neutral) were as simple as "Stem.direction :=
> (Up|Down|Neutral)" and \once pushes a new value onto a stack that will
> be popped at some later time to restore the original value, then the
> property could have a well-defined* value during evaluation:

Huh.  I forgot issue 4609.  \once stemUp is independent of \stemNeutral
nowadays.  \stemNeutral cancels \stemDown but you'll only get to see it
at the next timestep.

This is not the behavior we want for

\grace { \stemNeutral ... }

(namely \stemNeutral only becoming effective after the \grace is ended)
so one has to design that behavior differently.

--
David Kastrup

_______________________________________________
lilypond-user mailing list
[hidden email]
https://lists.gnu.org/mailman/listinfo/lilypond-user