On the hopefully correct assumption that this was intended to go to the list and just mistakenly sent in private (I don't think there is content that would benefit from a private discussion):
Jan Warchoł <lemniskata.bernoulli...@gmail.com> writes: > 2011/8/5 David Kastrup <d...@gnu.org>: >> >> If I take the following code: >> >> \relative c' { >> c4 >> \once\override Stem #'color = #red >> \override Stem #'color = #blue >> c4 c >> \revert Stem #'color >> c4 >> } >> >> the result is that the second stem is blue, and the third is already >> black again. That surprised me. If I take >> >> \relative c' { >> c4 >> \override Stem #'color = #blue >> \once\override Stem #'color = #red >> c4 c >> \revert Stem #'color >> c4 >> } >> >> then the second stem is red and the third is blue which looks like less >> of a surprise. If we take the following: >> >> \relative c' { >> c4 >> \override Stem #'color = #blue >> \once\override Stem #'color = #red >> \revert Stem #'color >> c4 c >> c4 >> } >> >> then just the second stem is blue. > > Very interesting! I'd expect something slightly different. I think that originally \override was a push, \revert was a pop, and \once\override was a push/pop pair (that's more or less what is in the user docs as well). Then somebody probably thought that \override\override\revert should be a nop since \override has to be used instead of \set anyway (which would not push), and turned \override into a pop-push pair (pop never goes beyond the current context, so "little harm done"). That explains why the first example pairs the pop from the \once\override with the push from \override. In the first example, the \override should, when cancelling the push from \once\override, not leave the corresponding pop lying around to be executed later. Now take that incoherent mess, and add nested properties into it. Apparently the current code has no qualms to start an \override with a pop that will cancel an entirely unrelated operation. Now if we do something like (never mind the value and the syntax) \override a.b.c \override a should the second \override be able to cancel the first one with its implied \revert at its front? How about if we do \override a \override a.b.c instead? Should the second override be able to cancel the first one? Only partially? What if we now do \override a \override a.b.c \override a How many \revert a should we need to have the stack empty again? If we do \override a \override a.b.c \revert a.b.c what should the state of a.whatever be? Changed against before or not? What should the state of a.b.c be? Changed against before (to the value set by \override a) or not? The effects of override/revert on a straightforward simple property are currently an unholy mess you can't figure out from the documentation. And now I am trying to implement sane semantics for nested properties. How should I try matching mixed-level nested overrides/reverts when the current implementation does not even sensibly match straightforward overrides/reverts? Maybe reverts (in particular from \once\override) should try keeping some sort of lexical information about what override they are supposed to cancel, and only apply to that override (in case it is still in effect) instead of just reverting whatever happens to be at the top of the override stack when they get their action. Anyway, I've boiled the additional info for correctly dealing with nested overrides (once we figured out how to deal with non-nested overrides sanely) to one value per nested override: the alist entry of the nested override itself. Everything behind that is not synchronized to parenting context changes. Everything else in the override is a copy from parenting contexts (or an override lower in this stack, something that will need consideration if stacks are not reverted strictly in order) and needs updating when things underneath change. -- David Kastrup _______________________________________________ lilypond-devel mailing list lilypond-devel@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-devel