lilypond-user
[Top][All Lists]
Advanced

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

Re: stemNeutral problem


From: Aaron Hill
Subject: Re: stemNeutral problem
Date: Thu, 13 Sep 2018 06:33:37 -0700
User-agent: Roundcube Webmail/1.3.6

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



reply via email to

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