"Pure" calls in the LilyPond backend produce grob properties dependent
on line break decisions.  Consequently the calls get passed "start" and
"end" arguments denoting the current line's starting and ending musical
columns (numbered sequentially from the start of the score).

To make the calls more compatible, in a first step the arguments
start/end should get removed.  They can be instead passed as a
"parameter" in the dynamic scope and queried by calling (*start*) and
(*end*) calls (which is the typical lexical convention for accessing
parameters passed implicitly).

This is a refactoring that does not change anything conceptually: it is
just somewhat tedious word.

The second iteration then becomes a lot more tricky: pure and unpure
calls are no longer distinguished explictly.

Instead, the calls of (*start*) and (*end*) itself record which
properties (most importantly stencils) queried the respective break
columns in the course of generating their value and will use the pure
caching mechanism only for those.

That allows no longer separating the two.  This is particularly useful
if a property only depends on one of the break columns, or needs to
refer to them only in isolated cases.

Being able to forego pure treatments when not necessary has a potential
for saving quite some runtime.  Of course, for imprudently written
callbacks, it also has the potential to blow up runtime in return for
treating the dependencies correctly.

One consequence of figuring out the pure/unpure stuff automagically
would be that programming callbacks would become more straightforward
and look less like an arcane art.  Which is a good thing.

Throwing this out in the open as a project because right now I am in a
tricky personal situation where I'll not likely be able to work on it
myself for a while.

In addition, part 1 is mostly grunge work touching a lot of stuff in
pretty mechanical ways, the stuff I am comparatively bad at completing
in a sensible time frame.  The most involved part here is getting
backward compatibility and convert-ly sorted out.

It would probably make sense to retain ly:make-unpure-pure-container
with the same semantics and calling conventions but stop using it in our
code base, instead using ly:make-unpure-pure-container-1 (for the
1-argument version of the call).

Part 2 is where the magic lies.  Having completed part 1, part 2 would
become more accessible for analyzing and tackling.

With (*start*)/(*end*) only being accessed when really necessary, the
amount of code needing touching would not be distributed all over the
place.  So changing the semantics would not involve code lines all over
the place and could possibly done in several phases.

How do we enter such a multi-phase project in the issue tracker?

-- 
David Kastrup


Reply via email to