Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 11:25 AM, Trevor Bača trevorb...@gmail.com wrote: 6. Lily reads the terminal close } brace. Even here, I'm willing to bet, Lily sees no reason to kill off the explicit named foo context. I bet Lily reads the terminal close } brace and instead simply closes off the original music *expression*. My guess would be that not until EOF does Lily finally kill off the original named foo context. EOF does not play any role in this. The parsing into trees of music expressions is done beforehand, and the iteration is not connected directly with the input file. Each iterator contains a pointer to the context it delivers events to. This pointer is actually reference counted, and a context is ended when its reference count drops to zero. == naked { } expressions DO NOT cause contexts to be instantiated at the open { brace and destroyed at the close } brace. Look for descend_to_bottom(). Generally, event chords (rests, notes, lyrics) cause a bottom context (lyrics, voice, chordnames) to be instantiated as child of the current context. The iterator for { } (sequential) will change its context to the one of its child if that child has a deeper level than the current one. so, \new Staff { c d } the iterator for 'c' will create a Voice, the enclosing iterator will change from Staff to Voice, since Voice is deeper nested in the context tree. This is a super long-winded way of me coming around to Carl's mental model: Try not to form mental models. Use the source instead. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On 12/15/08 7:18 AM, Han-Wen Nienhuys hanw...@gmail.com wrote: Try not to form mental models. Use the source instead. Unfortunately, not very many of us understand the source completely, and so we need mental models to work in LilyPond. Of course, our mental models will be incorrect in some detail, and we'll need to revise them from time to time. But even if we use the source, we'll have to make mental models of the source, and those may be incorrect as well. Maybe I'm the only person who doesn't understand the full source code, but I doubt it. Certainly developers should understand the source code when they modify it, and understanding the source code is preferable to an incorrect mental model, but the idea of documentation is to allow users to form correct mental models about program operation WITHOUT reading the source code. So I believe that we SHOULD form mental models, based on the docs and our experiences, and whenever there's a weakness in the mental model, it points to a place to improve the docs. Thanks, Carl ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 5:25 PM, Carl D. Sorensen c_soren...@byu.edu wrote: On 12/15/08 7:18 AM, Han-Wen Nienhuys hanw...@gmail.com wrote: Try not to form mental models. Use the source instead. Unfortunately, not very many of us understand the source completely, and so we need mental models to work in LilyPond. Of course, our mental models will be incorrect in some detail, and we'll need to revise them from time to time. sure, but if you spend a lot of time and effort on theorizing (like Trevor did), you might as well invest that time effort into looking at the source code itself. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
2008/12/15 Carl D. Sorensen c_soren...@byu.edu: On 12/15/08 7:18 AM, Han-Wen Nienhuys hanw...@gmail.com wrote: Try not to form mental models. Use the source instead. Unfortunately, not very many of us understand the source completely, and so we need mental models to work in LilyPond. Of course, our mental models will be incorrect in some detail, and we'll need to revise them from time to time. I have a question for the few developers that in some degree do understand the source code and are able to hack it, fix bugs, implement new features, etc. Is the code properly commented, so that (thinking on the future) new people can learn from it without having to figure out all the time what does each function, file etc. do? Sure, I can look at it and say, but I want the opinion of skilled programmers. If not, is there any chance of this to improve? -- Francisco Vila. Badajoz (Spain) http://www.paconet.org ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 09:26:15PM +0100, Francisco Vila wrote: Is the code properly commented, so that (thinking on the future) new people can learn from it without having to figure out all the time what does each function, file etc. do? Sure, I can look at it and say, but I want the opinion of skilled programmers. If not, is there any chance of this to improve? In my (somewhat limited) experience, no matter how good the documentation for source code, getting involved in a large project is always easier if you have a mentor. There's always little details or tricks that a person can pass along that never make it into the source docs... and besides, a mentor can tailor his answers directly to your questions, rather than the general info that you'd find in documentation. That's why I was hoping that somebody would offer to be the Frogmeister (you can have a non-silly name if you want!). People willing to spend time fixing bugs would gain a mentor to guide them towards a better understanding of the source code, and the mentor would gain more people fixing bugs in lilypond (which in turn leads to a better program which presumably the mentor is using :). Sure, we could ask a skilled developer to spend 50 hours writing better source docs... but I don't think that's a good trade-off. Their time is so limited, and the number of potential developers is so small, that I think that personal mentorship is the best way to go. Now, if one of those new developers wants to spend 5 hours a week carefully documenting what he's learned about the internals while fixing bugs, I certainly wouldn't object. But of course, that developer needs to consider the trade-offs involved: more bug fixes? Writing translations? Documenting the source code? Cheers, - Graham ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On 12/15/08 6:25 AM, Trevor Bača trevorb...@gmail.com wrote: On Sun, Dec 14, 2008 at 9:10 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: On Mon, Dec 15, 2008 at 12:18 AM, Trevor Bača trevorb...@gmail.com wrote: ... even though contexts do not literally nest! (Even though their iterators inherit from one another.) So, to resume, this leads to the following situation: EXPRESSIONS: * exhibit syntactic nesting * do not exhibit 'visual nesting' (or, maybe, 'properties nesting') CONTEXTS: * do not exhibit syntactic nesting * do exhibit 'visual nesting' / 'properties nesting' Or maybe a better way of saying it: EXPRESSIONS: * exhibit syntactic nesting * do not store grob properties CONTEXTS: * do not exhibit syntactic nesting * do store grob properties Hm. I think I get it now. Much thanks to everyone. If anyone sees more details missing from my working-out process, please correct. Trevor. I'd say it differently: EXPRESSIONS: Establish the timing of music-events relative to one another So there is no difference between { {c4 d} {e f} {g a}} and {c4 d e f g a } Similarly, there is no difference between { {\override myObject #'prop = #value c4 d} {\override myObject #'prop = #new-value e f} {g a} } and { \override myObject #'prop = #value c4 d \override myObject #'prop = #new-value e f g a } Both expressions cause the first override to apply to the current context starting and the moment of the note c4 and the second override to apply starting at the moment of the note e. Note that those overrides will apply to ALL OBJECTS OF TYPE myObject IN THE CURRENT CONTEXT, starting at those times. So { c4 d \override myObject #'prop = #value e f} { g4 a b c} will have the overrides applied to the e, f, b, and c, but not g4 and a. This is because it's the music moment, not the source file relative location, that defines the applicability of the overrides. CONTEXTS: Provide the evaluation environment (my words, not Han-Wen's) in which all music events will be evaluated when it's time to put them in the output stream (midi file or printed page). All properties that matter but are not tied to a particular grob reside in a context that contains the grob. They may be tied to the immediate context containing the grob (e.g. Voice, for NoteHead) or may come from a context above the current context in the heierarchy (e.g. the Staff that contains the Voice that contains the notehead). The confusion comes in because, if there is no appropriate context available, when LilyPond sees a music expression it will automatically create a context. And there is nothing in the input syntax that tells you when the context will be created. So I continue to get surprised from time to time if I don't explicitly instantiate all contexts. I think your discussion about naked music expressions is illuminating, but also potentially confusing. It's not naked expressions that cause the challenge, but expressions that occur at a point in the music stream (not the input stream) where no appropriate context exists, therefore requiring LilyPond to create one. So if we look at your example 2: %%% VOICE-RESOLUTION EXAMPLE 2 %%% \version 2.11.57 { \new Voice = foo { \override Voice.NoteHead #'color = #red g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EX 2 %%% Looking in music stream (not input stream) order: 1a instantiate Voice foo (this takes no musical time). Oops, we don't have a Staff context to hold foo, so we'll need to create one. 1b Make an override to the notehead color (this also takes no musical time) 1c engrave g'8 (this is the first thing that takes musical time) 2 engrave a'8 3 engrave b'8 4 engrave c''8 Now we're done with the music expression explicitly created in voice foo 5 engrave d''8 -- and since we have a voice foo, just keep on with it. 6 engrave e''8 7 engrave f''8 8 engrave g''8 In contrast, we have Example 2+1 Note: %%% EX 2 + 1 NOTE %%% { c'8 \new Voice = foo { \override Voice.NoteHead #'color = #red g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EX 2 MOD %%% Looking at this in music stream order we have 1. engrave c'8. Oops, we don't have a Voice context to engrave c'8. Therefore we need to create a Voice context for c'8. And since we don't have a Staff to hold the Voice, we'll need to create a Staff context as well. 2a. create a new Voice context called foo, and assign the next expression to voice foo. (no musical time) 2b. engrave g'8 in foo context 3. engrave a'8 in foo context 4. engrave b'8 in foo context 5. engrave c''8 in foo context Now I'm done with the music expression that was assigned to Voice foo. 6. engrave d''8. It goes in the Voice context that we were using before we
Re: Scheme function to print out active Voice context during interpretation?
2008/12/15 Carl D. Sorensen c_soren...@byu.edu: I'd say it differently: EXPRESSIONS: Establish the timing of music-events relative to one another CONTEXTS: Provide the evaluation environment (my words, not Han-Wen's) in which all music events will be evaluated when it's time to put them in the output stream (midi file or printed page). very well said. The confusion comes in because, if there is no appropriate context available, when LilyPond sees a music expression it will automatically In this case, the order of instantation depends on the order in the music expression, which helps people confuse context and music expressions too. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On 12/15/08 2:26 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: 2008/12/15 Carl D. Sorensen c_soren...@byu.edu: I'd say it differently: EXPRESSIONS: Establish the timing of music-events relative to one another CONTEXTS: Provide the evaluation environment (my words, not Han-Wen's) in which all music events will be evaluated when it's time to put them in the output stream (midi file or printed page). very well said. The confusion comes in because, if there is no appropriate context available, when LilyPond sees a music expression it will automatically In this case, the order of instantation depends on the order in the music expression, which helps people confuse context and music expressions too. But it's the order in the music stream, not the input stream, isn't it? Otherwise, why does { \new Voice=foo { c } d } result in only a single voice being instantiated, but { d \new Voice=foo { c } } result in two voices being instantiated? Thanks, Carl ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
code comments (was Re: Scheme function to print out active Voice context during interpretation?)
On Mon, Dec 15, 2008, Francisco Vila paconet@gmail.com said: I have a question for the few developers that in some degree do understand the source code and are able to hack it, fix bugs, implement new features, etc. Is the code properly commented, so that (thinking on the future) new people can learn from it without having to figure out all the time what does each function, file etc. do? Newbie to the project, but one who has been programming since 1968, this is something I have discussed at length with other experience programmers. I speak in general, have yet to delve into Lp code at all, so please forgive if this is already covered by a project policy or perhaps a gnu policy. Good code commenting is a challenging skill, at its best the comments on archived code should Be accurate, uptodate, not telling lies. Explain why someone would want to invoke the code Describe context for use - arguments in, side effects, value(s) returned. Cite sources for non-trivial algorythms used, if original, publish a white paper to the project which can be cited. In many cases comments will exceed the code itself. Line-by-line comments are sometimes useful but should give information beyond the obvious. In a language like postscript the expected state of the stack is ofen a useful comment. Some projects embed text for documentation and help files with the code itself to encourage parallel maintenance. -- Dana Emery ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 2:09 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: On Mon, Dec 15, 2008 at 5:25 PM, Carl D. Sorensen c_soren...@byu.edu wrote: On 12/15/08 7:18 AM, Han-Wen Nienhuys hanw...@gmail.com wrote: Try not to form mental models. Use the source instead. Unfortunately, not very many of us understand the source completely, and so we need mental models to work in LilyPond. Of course, our mental models will be incorrect in some detail, and we'll need to revise them from time to time. sure, but if you spend a lot of time and effort on theorizing (like Trevor did), you might as well invest that time effort into looking at the source code itself. I think both are good: wanton speculation taken together with digging through source. :-) I've been digging through source this morning ... and I'm understanding much better ... but still unable to resolve at least one example, which I've included at the end of this message. What I've found so far: * There are 22 -iterator.cc files with Music_iterator being the base class from which the others all directly (or, more usually, indirectly) inherit. (Simple_music_iterator, Music_wrapper_iterator and Sequential_iterator are all popular choices to derive from, too, but all three inherit from Music_iterator at base.) Concrete iterators exist to iterate over regular stuff like EventChord and and 'simple music' (which parser.yy makes me think means basically notes and rests). Iterators also exist to iterate over more complex music expressions like grace music, time-scaled music, voltas, and music expressions passed to the \unfold command. My understanding of this flock of iterators available in the C++ source is as a type of realization of the visitor pattern that separates traversal from other activities like calculation and modification. * Additionally, both the comments at the head of music-iterator.hh and Erik's thesis make it clear that the object over which the different iterators iterate is a (conceptual) queue of music events *that all happen at the same moment*. That is, when it comes time to iterate, the first thing that happens is that the entire context tree (starting from the Global context and proceeding all the way to bottom-level voice contexts) are *prepared* for Moment 0; then iterators iterate over all events that happen at Moment 0 *no matter at which level of the context tree those different events occur*. This helps because I was assuming (wrongly) earlier that iteration would be a depth-first search starting from the root of the expression tree; if that were the case then each context would be visited before any of its children. But, in fact, section 9.4 of Erik's thesis says One of the consequences of a OneTimeStep stream event, is that all contexts are visited in a post-order tree walk; i.e., each context is visited after all its children have been visited. I haven't been able to verify this in the code, however. * I've also found that a pronouncement like \new Voice { c'4 } is actually THREE expressions. The \new Voice is actually a music expression all by itself (of type ContextSpeccedMusic). There is a Context_specced_music_iterator defined in an eponymous .cc file and inheriting from Music_wrapper_iterator. The purpose of the Context_specced_music_iterator is to descend to the one (and only one) child that each ContextSpeccedMusic like \new Voice music have: something like Sequential is the usual option. So the parser (which I only understand vaguely) decomposes \new Voice { c'4 } into three expressions with \new Voice parsed as ContextSpeccedMusic, with { } parsed as Sequential, with c'4 parsed as EventChord (I think). Further, the parser builds the resulting music expression such that ContextSpeccedMusic is the parent of Sequential which is, in turn, the parent of EventChord. * Also, all parsing is done before any iteration is done. * OK, so based on this understanding, can somebody please correct my understanding of the parsing (not the iteration, just the parsing) of the following expression (which is the same as my original example #2): { \new Voice { c'8 c'8 c'8 c'8 } d'8 d'8 d'8 d'8 } If I'm understanding how the parser works, then what should result here is a music expression that looks like this: Global V \new Score V \new Staff V \new Voice V Sequential V \new Voice, d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 If I'm counting correctly, that's 15 total nodes in the expression tree. Eight atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and the first \new Voice are all created implicitly. I know that the next part in the process is iteration. But I want to stop and check my understanding here: am I understanding the output
Re: Scheme function to print out active Voice context during interpretation?
On 12/15/08 3:12 PM, Trevor Bača trevorb...@gmail.com wrote: On Mon, Dec 15, 2008 at 2:09 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: On Mon, Dec 15, 2008 at 5:25 PM, Carl D. Sorensen c_soren...@byu.edu wrote: On 12/15/08 7:18 AM, Han-Wen Nienhuys hanw...@gmail.com wrote: Try not to form mental models. Use the source instead. Unfortunately, not very many of us understand the source completely, and so we need mental models to work in LilyPond. Of course, our mental models will be incorrect in some detail, and we'll need to revise them from time to time. sure, but if you spend a lot of time and effort on theorizing (like Trevor did), you might as well invest that time effort into looking at the source code itself. I think both are good: wanton speculation taken together with digging through source. :-) I've been digging through source this morning ... and I'm understanding much better ... but still unable to resolve at least one example, which I've included at the end of this message. What I've found so far: * There are 22 -iterator.cc files with Music_iterator being the base class from which the others all directly (or, more usually, indirectly) inherit. (Simple_music_iterator, Music_wrapper_iterator and Sequential_iterator are all popular choices to derive from, too, but all three inherit from Music_iterator at base.) Concrete iterators exist to iterate over regular stuff like EventChord and and 'simple music' (which parser.yy makes me think means basically notes and rests). Iterators also exist to iterate over more complex music expressions like grace music, time-scaled music, voltas, and music expressions passed to the \unfold command. My understanding of this flock of iterators available in the C++ source is as a type of realization of the visitor pattern that separates traversal from other activities like calculation and modification. * Additionally, both the comments at the head of music-iterator.hh and Erik's thesis make it clear that the object over which the different iterators iterate is a (conceptual) queue of music events *that all happen at the same moment*. That is, when it comes time to iterate, the first thing that happens is that the entire context tree (starting from the Global context and proceeding all the way to bottom-level voice contexts) are *prepared* for Moment 0; then iterators iterate over all events that happen at Moment 0 *no matter at which level of the context tree those different events occur*. This helps because I was assuming (wrongly) earlier that iteration would be a depth-first search starting from the root of the expression tree; if that were the case then each context would be visited before any of its children. But, in fact, section 9.4 of Erik's thesis says One of the consequences of a OneTimeStep stream event, is that all contexts are visited in a post-order tree walk; i.e., each context is visited after all its children have been visited. I haven't been able to verify this in the code, however. * I've also found that a pronouncement like \new Voice { c'4 } is actually THREE expressions. The \new Voice is actually a music expression all by itself (of type ContextSpeccedMusic). There is a Context_specced_music_iterator defined in an eponymous .cc file and inheriting from Music_wrapper_iterator. The purpose of the Context_specced_music_iterator is to descend to the one (and only one) child that each ContextSpeccedMusic like \new Voice music have: something like Sequential is the usual option. So the parser (which I only understand vaguely) decomposes \new Voice { c'4 } into three expressions with \new Voice parsed as ContextSpeccedMusic, with { } parsed as Sequential, with c'4 parsed as EventChord (I think). Further, the parser builds the resulting music expression such that ContextSpeccedMusic is the parent of Sequential which is, in turn, the parent of EventChord. * Also, all parsing is done before any iteration is done. * OK, so based on this understanding, can somebody please correct my understanding of the parsing (not the iteration, just the parsing) of the following expression (which is the same as my original example #2): { \new Voice { c'8 c'8 c'8 c'8 } d'8 d'8 d'8 d'8 } If I'm understanding how the parser works, then what should result here is a music expression that looks like this: Global V \new Score V \new Staff V \new Voice V Sequential V \new Voice, d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 If I'm counting correctly, that's 15 total nodes in the expression tree. Eight atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and the first \new Voice are all created
Re: Scheme function to print out active Voice context during interpretation?
Hi Trevor, On Mon, Dec 15, 2008 at 2:12 PM, Trevor Bača trevorb...@gmail.com wrote: * OK, so based on this understanding, can somebody please correct my understanding of the parsing (not the iteration, just the parsing) of the following expression (which is the same as my original example #2): { \new Voice { c'8 c'8 c'8 c'8 } d'8 d'8 d'8 d'8 } If I'm understanding how the parser works, then what should result here is a music expression that looks like this: Global V \new Score V \new Staff V \new Voice V Sequential V \new Voice, d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 If I'm counting correctly, that's 15 total nodes in the expression tree. Eight atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and the first \new Voice are all created implicitly. I know that the next part in the process is iteration. But I want to stop and check my understanding here: am I understanding the output of the parser correctly at this point? I'm pretty sure this would be the result *after* iteration. The parser output can be visualized with \displayMusic. So your example would look like this, using your convention above: Sequential VV \new Voice d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 After this, the iteration process starts, proceeding moment by moment and making sure everything is placed in the correct context. Then you would end up with a tree that looks like the one you posted. I believe the implicit creation of contexts happens during iteration. (I could be completely wrong, but it makes sense to me). -Patrick ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 8:12 PM, Trevor Bača trevorb...@gmail.com wrote: * OK, so based on this understanding, can somebody please correct my understanding of the parsing (not the iteration, just the parsing) of the following expression (which is the same as my original example #2): { \new Voice { c'8 c'8 c'8 c'8 } d'8 d'8 d'8 d'8 } If I'm understanding how the parser works, then what should result here is a music expression that looks like this: Global V \new Score V \new Staff V \new Voice V Sequential V \new Voice, d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 If I'm counting correctly, that's 15 total nodes in the expression tree. Eight atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and the first \new Voice are all created implicitly. I know that the next part in the process is iteration. But I want to stop and check my understanding here: am I understanding the output of the parser correctly at this point? No. the \new Staff and \new Score are created at iteration time. Look for path_to_acceptable_context(). Also, you can use the \displayMusic music function to get to the parse tree. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 10:20 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: I know that the next part in the process is iteration. But I want to stop and check my understanding here: am I understanding the output of the parser correctly at this point? No. the \new Staff and \new Score are created at iteration time. Look for path_to_acceptable_context(). and to be extra clear, it's the Staff and Score contexts that get created. The expression is not modified during iteration. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 6:21 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: On Mon, Dec 15, 2008 at 10:20 PM, Han-Wen Nienhuys hanw...@gmail.com wrote: I know that the next part in the process is iteration. But I want to stop and check my understanding here: am I understanding the output of the parser correctly at this point? No. the \new Staff and \new Score are created at iteration time. Look for path_to_acceptable_context(). and to be extra clear, it's the Staff and Score contexts that get created. The expression is not modified during iteration. OK, got it. Will check path_to_acceptable_context( ). -- Trevor Bača trevorb...@gmail.com ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 6:09 PM, Patrick McCarty pnor...@gmail.com wrote: Hi Trevor, On Mon, Dec 15, 2008 at 2:12 PM, Trevor Bača trevorb...@gmail.com wrote: * OK, so based on this understanding, can somebody please correct my understanding of the parsing (not the iteration, just the parsing) of the following expression (which is the same as my original example #2): { \new Voice { c'8 c'8 c'8 c'8 } d'8 d'8 d'8 d'8 } If I'm understanding how the parser works, then what should result here is a music expression that looks like this: Global V \new Score V \new Staff V \new Voice V Sequential V \new Voice, d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 If I'm counting correctly, that's 15 total nodes in the expression tree. Eight atomic nodes and seven internal nodes. The Global, \new Score, \new Staff and the first \new Voice are all created implicitly. I know that the next part in the process is iteration. But I want to stop and check my understanding here: am I understanding the output of the parser correctly at this point? I'm pretty sure this would be the result *after* iteration. The parser output can be visualized with \displayMusic. So your example would look like this, using your convention above: Sequential VV \new Voice d'8, d'8, d'8, d'8 V Sequential V c'8, c'8, c'8, c'8 After this, the iteration process starts, proceeding moment by moment and making sure everything is placed in the correct context. Then you would end up with a tree that looks like the one you posted. I believe the implicit creation of contexts happens during iteration. (I could be completely wrong, but it makes sense to me). OK, and Han-Wen confirms what you're saying, too. Much appreciated. Going back to look at more code now ... -- Trevor Bača trevorb...@gmail.com ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On 12/15/08 1:26 PM, Francisco Vila paconet@gmail.com wrote: 2008/12/15 Carl D. Sorensen c_soren...@byu.edu: On 12/15/08 7:18 AM, Han-Wen Nienhuys hanw...@gmail.com wrote: Try not to form mental models. Use the source instead. Unfortunately, not very many of us understand the source completely, and so we need mental models to work in LilyPond. Of course, our mental models will be incorrect in some detail, and we'll need to revise them from time to time. I have a question for the few developers that in some degree do understand the source code and are able to hack it, fix bugs, implement new features, etc. Is the code properly commented, so that (thinking on the future) new people can learn from it without having to figure out all the time what does each function, file etc. do? Sure, I can look at it and say, but I want the opinion of skilled programmers. If not, is there any chance of this to improve? In my opinion, the code is written sufficiently well that if you're willing to spend the time you can eventually get up to speed. There are very few comments, but there are good function names, good variable names, and good consistency. For me, the biggest thing missing is an overall sense of the architecture. It's alluded to in Erik Sandberg's thesis, and you can kind of get it figured out with the source code and the ongoing discussions. But it's still a bit challenging to get into starting from scratch. As far as the prospects for improving the situation, I'd say they're not great. It seems to me that remedying the situation would require a major time investment, and provide no new functionality, just improved accessibility for an unnamed future round of developers. If we had somebody who was interested in getting into the internals and also interested in documenting things, then I think the situation might change. But I have no idea who that person might be. Carl ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
Hi Trevor! Le dimanche 14 décembre 2008 à 12:42 -0600, Trevor Bača a écrit : Is there a way to print out the name (or other identity) of the currently active voice just before any given note or rest in an input file? Does something like this exist? I haven't found such a function in Lily sources and docs, try these two music functions (freely inspired from barNumberCheck definition): whichContext = #(define-music-function (parser location) () (make-music 'ApplyContext 'origin location 'procedure ( lambda (c) (display (string-append \nCurrent voice is (ly:context-id c) \n) locationWhichContext = #(define-music-function (parser location) () (make-music 'ApplyContext 'origin location 'procedure ( lambda (c) (display (ly:input-message location current voice is ~a (ly:context-id c)) It's also possible to make Scheme avatars of these functions, but then they would need to take the location as an argument. This should be added to the docs IMHO; should this be added in LSR, the manual or the (yet to be written) docstring of applyContext? [The motivation is that I'm researching the way that LilyPond determines which voice music events are assigned to ... from a user's perspective based solely on looking at input files. Voice-resolution in the example above is of course quite clear; voice-resolution when there are multiple anonymous voices, possibly in parallel, has become extremely tricky as I've written more and more test files, all of which I'll be happy to post if anyone else is interested in that sort of thing.] Please do :-) I guess some of these tests may be added to LSR. Hope this helps, John ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Sun, Dec 14, 2008 at 4:42 PM, Trevor Bača trevorb...@gmail.com wrote: [The motivation is that I'm researching the way that LilyPond determines which voice music events are assigned to ... from a user's perspective based solely on looking at input files. Voice-resolution in the example above is of course quite clear; voice-resolution when there are multiple anonymous voices, possibly in parallel, has become extremely tricky as I've written more and more test files, all of which I'll be happy to post if anyone else is interested in that sort of thing.] That sounds like a very circumspect way to find this out. Check out lily/*-iterator.cc; in particular, look for calls to void Music_iterator::descend_to_child (Context *child_report) void Music_iterator::set_context (..) which explain some of the things you are seeing. Note that contexts do not 'nest' as you claim in a message below. Voice contexts cannot contain any other context. -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
2008/12/15 Trevor Bača trevorb...@gmail.com: (Stop and think what you'd expect here before looking at the output.) You're right, one expects something different at first, but then I remembered the Temporary polyphonic passages section under http://lilypond.org/doc/v2.11/Documentation/user/lilypond/Multiple-voices#Single_002dstaff-polyphony here says something interesting: Here, the first expression within a temporary polyphonic passage is placed into the Voice context which was in use immediately before the polyphonic passage, and that same Voice context continues after the temporary section. Other expressions within the angle brackets are assigned to distinct temporary voices. This allows lyrics to be assigned to one continuing voice before, during and after a polyphonic section I think this applies well to your examples, not a polyphonic situation, but still one in which a new voice context is created and given an internal name, in order of availability. The new Voice without any preceding notes is the same before, during and after; the new Voice with a preceding note is a truly new context, different from the one which that note was in. Does it have any sense? -- Francisco Vila. Badajoz (Spain) http://www.paconet.org ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On 12/14/08 4:34 PM, Trevor Bača trevorb...@gmail.com wrote: I have a pretty big stockpile of tests and sometime in the next couple of days I'll find a way to organize them and send them over. But I'd like to start with the pair of examples that just seems absolutely pathological to me. Here it is: %%% VOICE-RESOLUTION EXAMPLE 1 %%% \version 2.11.57 { \override Voice.NoteHead #'color = #red c'8 d'8 e'8 f'8 \new Voice = foo { g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EXAMPLE 1 %%% So far, so good. In example 1, LilyPond creates two voices with one nested inside the other. We see this because the outer eight notes are red while the inner four notes are black. But now look at this: %%% VOICE-RESOLUTION EXAMPLE 2 %%% \version 2.11.57 { \new Voice = foo { \override Voice.NoteHead #'color = #red g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EX 2 %%% (Stop and think what you'd expect here before looking at the output.) Here LilyPond renders a single voice! We see this because all eight notes are red. Sprinkling the new \whichContext function before the first, fourth (and eighth) notes in each example (where possible) makes it clear that the foo context governs only the middle four notes in the first example while governing *all* eight notes in the second example. What on earth is going on here? What's so odd is that if you look at example 2 and think OK, this is all just a single voice because the explicitly instantiated voice 'leaks' over into the following four notes ... then you're in for a big surprise when you add just a single note to the beginning of the example: %%% EX 2 + 1 NOTE %%% { c'8 \new Voice = foo { \override Voice.NoteHead #'color = #red g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EX 2 MOD %%% That single note at the beginning now breaks the example into two voices just like example 1! Can anyone explain what's going on here? In examples 1 and 2+1 note, the first music occurs without a voice being defined. Therefore, LilyPond creates (instantiates) a voice. Voice foo is then created, and limited to the notes contained in the brackets. In example 2, Voice foo is created before any voice is instantiated. Then, the music that comes after the voice foo definition is just applied to the existing voice foo, since there is no explicit instantiation. This kind of inconsistency shows up lots of times when you use automatic instantiation of contexts. In order to avoid these things, I've take to explicitly instantiating all contexts. (And if I used multiple books in a score, I'd explicitly instantiate all of them as well). Implicit instantiation is beginner-friendly but expert-unfriendly, IMO. It makes less for the user to type in building a simple song, but it hides the structure of LilyPond, and makes it unnecessarily difficult to set complex music. A while ago there was a post suggesting that we do away with all implicit instantiation and require users to explicitly instantiate contexts. That went nowhere. But I think there ought to be a statement somewhere that says for complex scores, it is best to explicitly instantiate all voices. In my experience, that avoids lots of confusion. Just my 0.02. Carl ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
Le dimanche 14 décembre 2008 à 17:41 -0700, Carl D. Sorensen a écrit : A while ago there was a post suggesting that we do away with all implicit instantiation and require users to explicitly instantiate contexts. That went nowhere. I really think this feature is worth keeping it, if you recall that ly source are often typed by hand. But I think there ought to be a statement somewhere that says for complex scores, it is best to explicitly instantiate all voices. In my experience, that avoids lots of confusion. IIRC it's already mentioned in Chapter 3 Fundamental concepts in the Learning Manual. However it might be good to include examples like that one from Trevor, to show how evil implicit context instantiation is in complex situations. What about creating a new LSR tag horror? :-D Cheers, John ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
2008/12/14 Carl D. Sorensen c_soren...@byu.edu On 12/14/08 4:34 PM, Trevor Bača trevorb...@gmail.com wrote: I have a pretty big stockpile of tests and sometime in the next couple of days I'll find a way to organize them and send them over. But I'd like to start with the pair of examples that just seems absolutely pathological to me. Here it is: %%% VOICE-RESOLUTION EXAMPLE 1 %%% \version 2.11.57 { \override Voice.NoteHead #'color = #red c'8 d'8 e'8 f'8 \new Voice = foo { g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EXAMPLE 1 %%% So far, so good. In example 1, LilyPond creates two voices with one nested inside the other. We see this because the outer eight notes are red while the inner four notes are black. But now look at this: %%% VOICE-RESOLUTION EXAMPLE 2 %%% \version 2.11.57 { \new Voice = foo { \override Voice.NoteHead #'color = #red g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EX 2 %%% (Stop and think what you'd expect here before looking at the output.) Here LilyPond renders a single voice! We see this because all eight notes are red. Sprinkling the new \whichContext function before the first, fourth (and eighth) notes in each example (where possible) makes it clear that the foo context governs only the middle four notes in the first example while governing *all* eight notes in the second example. What on earth is going on here? What's so odd is that if you look at example 2 and think OK, this is all just a single voice because the explicitly instantiated voice 'leaks' over into the following four notes ... then you're in for a big surprise when you add just a single note to the beginning of the example: %%% EX 2 + 1 NOTE %%% { c'8 \new Voice = foo { \override Voice.NoteHead #'color = #red g'8 a'8 b'8 c''8 } d''8 e''8 f''8 g''8 } %%% END EX 2 MOD %%% That single note at the beginning now breaks the example into two voices just like example 1! Can anyone explain what's going on here? In examples 1 and 2+1 note, the first music occurs without a voice being defined. Therefore, LilyPond creates (instantiates) a voice. Voice foo is then created, and limited to the notes contained in the brackets. In example 2, Voice foo is created before any voice is instantiated. Then, the music that comes after the voice foo definition is just applied to the existing voice foo, since there is no explicit instantiation. OK, this explanation is extremely helpful. But there's still something deeply wrong. Han-Wen from a bit earlier: Note that contexts do not 'nest' as you claim in a message below. Voice contexts cannot contain any other context. But check this out: %%% VOICE-RESOLUTION EX 3 %%% \version 2.11.65 \include english.ly \new Voice = foo { \override Voice.NoteHead #'color = #red \whichContext c'8 cs'8 \new Voice = bar { \override Voice.NoteHead #'color = #blue \whichContext d'8 ef'8 \new Voice = blah { \override Voice.NoteHead #'color = #green \whichContext e'8 f'8 fs'8 g'8 } \whichContext af'8 a'8 } \whichContext bf'8 b'8 } %%% END %%% It appears as though the voice contexts are indeed nesting ... perfectly, in fact! And, in fact, John's new \whichContext function emits the following during interpretation: GNU LilyPond 2.11.65 Processing `0303.ly' Parsing... Interpreting music... Current voice is foo Current voice is bar Current voice is blah Current voice is bar Current voice is foo Preprocessing graphical objects... Finding the ideal number of pages... Fitting music on 1 page... Drawing systems... Layout output to `0303.ps'... Converting to `./0303.pdf'... This is nesting, isn't it? (How else to explain the stickiness of the grob overrides?) Or have I completely lost my mind? (Han-Wen's suggestion about looking over the iterator code makes sense and I'll take a look right after I get in a quick jog ... because I think I might go mildly insane otherwise ...) This kind of inconsistency shows up lots of times when you use automatic instantiation of contexts. In order to avoid these things, I've take to explicitly instantiating all contexts. (And if I used multiple books in a score, I'd explicitly instantiate all of them as well). Implicit instantiation is beginner-friendly but expert-unfriendly, IMO. It makes less for the user to type in building a simple song, but it hides the structure of LilyPond, and makes it unnecessarily difficult to
Re: Scheme function to print out active Voice context during interpretation?
On 12/14/08 7:18 PM, Trevor Bača trevorb...@gmail.com wrote: In examples 1 and 2+1 note, the first music occurs without a voice being defined. Therefore, LilyPond creates (instantiates) a voice. Voice foo is then created, and limited to the notes contained in the brackets. In example 2, Voice foo is created before any voice is instantiated. Then, the music that comes after the voice foo definition is just applied to the existing voice foo, since there is no explicit instantiation. OK, this explanation is extremely helpful. But there's still something deeply wrong. Han-Wen from a bit earlier: Note that contexts do not 'nest' as you claim in a message below. Voice contexts cannot contain any other context. But check this out: %%% VOICE-RESOLUTION EX 3 %%% \version 2.11.65 \include english.ly http://english.ly \new Voice = foo { \override Voice.NoteHead #'color = #red \whichContext c'8 cs'8 \new Voice = bar { \override Voice.NoteHead #'color = #blue \whichContext d'8 ef'8 \new Voice = blah { \override Voice.NoteHead #'color = #green \whichContext e'8 f'8 fs'8 g'8 } \whichContext af'8 a'8 } \whichContext bf'8 b'8 } %%% END %%% It appears as though the voice contexts are indeed nesting ... perfectly, in fact! I would not say the the contexts nest (i.e., Voice blah is not part of Voice bar). But music expressions can be nested, and notes are assigned to voices by your various music expressions. It seems to make sense to me, once I understand that there is some monkey business that goes on when contexts (including, but not limited to Voices) are implicitly instantiated. My mental model (which is based on function, not on reviewing code) is that \new Voice = Foo { ... } says Create a new context called foo, and put all the notes in this music expression in Voice Foo unless something comes along to change it. When something comes along to change it, the notes are put in a different Voice context. But the new Voice context is not part of the old Voice context. Voice is a lowest-level context. Carl And, in fact, John's new \whichContext function emits the following during interpretation: GNU LilyPond 2.11.65 Processing `0303.ly http://0303.ly ' Parsing... Interpreting music... Current voice is foo Current voice is bar Current voice is blah Current voice is bar Current voice is foo Preprocessing graphical objects... Finding the ideal number of pages... Fitting music on 1 page... Drawing systems... Layout output to `0303.ps http://0303.ps '... Converting to `./0303.pdf'... This is nesting, isn't it? (How else to explain the stickiness of the grob overrides?) Or have I completely lost my mind? (Han-Wen's suggestion about looking over the iterator code makes sense and I'll take a look right after I get in a quick jog ... because I think I might go mildly insane otherwise ...) ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel
Re: Scheme function to print out active Voice context during interpretation?
On Mon, Dec 15, 2008 at 12:18 AM, Trevor Bača trevorb...@gmail.com wrote: OK, this explanation is extremely helpful. But there's still something deeply wrong. Han-Wen from a bit earlier: Note that contexts do not 'nest' as you claim in a message below. Voice contexts cannot contain any other context. But check this out: %%% VOICE-RESOLUTION EX 3 %%% \version 2.11.65 \include english.ly \new Voice = foo { \override Voice.NoteHead #'color = #red \whichContext c'8 cs'8 \new Voice = bar { \override Voice.NoteHead #'color = #blue \whichContext d'8 ef'8 \new Voice = blah { \override Voice.NoteHead #'color = #green \whichContext e'8 f'8 fs'8 g'8 } \whichContext af'8 a'8 } \whichContext bf'8 b'8 } %%% END %%% It appears as though the voice contexts are indeed nesting ... perfectly, in fact! The music expressions are nested, as you can easily see from the syntax. However, the contexts themselves (that the music expressions are shipping their events to) are actually running in parallel, and are siblings in the context tree. When you do \new Voice = foo { c4 // * \new Voice = bar { d4 } e4 } at the location marked by * there is an iterator for the outer expression (delivering events to Voice=foo); the moment \new Voice = bar expression is opened, this creates an iterator pointing to Voice=bar. The outer iterator still points to foo, but it has no events to deliver, because the inner iterator already sends them to bar. The moment the final note (e4) is processed, the relevant iterator (Event_chord_iterator, if memory serves me) inherits the destination from its parent, so the e4 goes to foo. The foo and bar voice contexts themselves are not nested, they are contained in their respective Staff objects and are independent. And, in fact, John's new \whichContext function emits the following during interpretation: -- Han-Wen Nienhuys - han...@xs4all.nl - http://www.xs4all.nl/~hanwen ___ lilypond-devel mailing list lilypond-devel@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-devel