[Top][All Lists]

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

Re: \once \revert

From: David Kastrup
Subject: Re: \once \revert
Date: Fri, 19 Aug 2011 22:57:49 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

Carl Sorensen <address@hidden> writes:

> On 8/19/11 10:15 AM, "David Kastrup" <address@hidden> wrote:
>> Up to now, \once \revert is not really documented nor used.  I have not
>> yet dug through the existing code in order to figure out what it does if
>> anything (most likely ignoring \once, but not sure).
> I would expect that \once \revert would revert an \override for the
> current time step only (meaning events whose start time is the current
> moment).  For any events whose start time is other than the current
> moment, the \override would continue to apply.
>> In order to not have the override/revert stack get into unexpected
>> interactions, I want to change \once\override to be impervious to
>> normal reverts.
> This seems to me to be a wise decision.  \once \override is a
> statement that you are creating an override for everything happening
> at the current moment; reverts would not seem to apply.

The main problem is that \once\override comes with its own implicit
revert at the end of the time step, and when this implicit revert
applies to a different \override, things get surprising.  If this
implicit revert is made special so that it will only ever apply to its
corresponding \override, then having other \reverts match the
\once\override will seem surprising.

>> That would mean that \once\revert is an obvious candidate for
>> reverting a \once\override before its time.  However, I have no idea
>> whether there is an actual sensible use for that functionality.
> I can see no sensible use for that functionality.  You would have
> conflicting statements about what should happen at this time.

Well, overrides are operating in a stack, so the last one wins.  Not too
difficult too understand.
>> \once\revert could also mean to let a current non-once override become
>> inactive just for the current time step.
> As I mentioned above, I think this is the logically consistent meaning.
>> That's likely harder to
>> implement, I think.
> You have *clearly* studied this and thought about it much more than I
> (and I'm grateful for your tackling this issue).  I would think that a
> \once command would not need a stack.  \once means "create a new
> setting from the current setting, and apply it at this moment, but
> don't carry it forward".  But again, you have much more basis for your
> observations than I have for mine.

"Don't carry it forward" naively means "reinstate the previous state",
but that would cancel any other changes happening after the
\once\whatever.  This is what happens right now with \once\override, and
it is confusing.

So a cleaner interpretation is "make things as if the \once\whatever
never occured".  However, the definition of \revert is "make things as
if the \override on top of the stack never occured".  That would mean
that \once\revert would have to disable the override, but let it keep
its position on the stack.  And temporarily disabling an override is an
operation that requires its own implementation that is different from
the other implemented operations.  Basically, we need to store the
\revert on the stack, when we only store instances of \override there
usually.  What happens if you do \once\revert \revert?  Is the \override
reverted by \once\revert now protected from the second \revert and
resurfaces after our current time step?  Is it affected by the non-\once
revert?  Is it invisible to it, so that the non-\once revert picks the
next \override in the stack to revert?

I don't think there is sufficient need for investing the effort of
defining clear and consistent semantics for all that.

> I have no idea whether there is a sensible use, either, but it is
> logically consistent, IMO.

It is also logically consistent to let the prefix \once make the
following operation work on the set of \once overrides, as opposed to
the set of not-\once overrides.  And the sets differ by having the \once
overrides be autocleared at the end of the timestep.

>> Since the parser permits \once\revert, I tend towards making it match
>> the last \once\override.  It likely does not make much sense, but then
>> it is sort of easy to understand.
> I lean to the opposite use, as I have described.

Then you should make a convincing proposal for resolving the cases I
described above.

> To me, 
> \once \override x = #y
> \once \revert x
> should be an undefined state, since there are two conflicting commands.  Why
> should the second one have preference over the first?  Just because it comes
> later in the text stream?

Yup.  Because overrides and reverts work on a stack.

> I'd be fine with having the documentation say something like
> When two \once commands conflict, the resulting state is indeterminate.
> You should never have two \once commands at the same musical moment that
> affect the same property setting.

We need a stack, anyway, so there is no point in treating \once commands
different regarding the order relations.

> In fact, I think I would be in favor of removing \once \revert from
> the parser.  The semantics of \once \revert can be confusing, and the
> same behavior could be achieved with a \once \override.  But I would
> be open to arguments from those who see good uses of \once \revert.

I'd mainly implement it (it is pretty close to no additional effort) in
order to have consistent and logical rules where people don't need to
think twice about which commands do what and why.

When we make half a dozen artificial complex regtests with combinations
of override and revert, I want people being able to actually predict
what the outcome will be.  Not because they know the code inside out,
but because the behavior obeys simple but useful rules.

If we have a "\once and non-\once overrides don't mix.  Visibility is
decided on a last-entered base, but changes are made separately.",
that's reasonably clear and predictable.

David Kastrup

reply via email to

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