lilypond-devel
[Top][All Lists]
Advanced

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

Re: pure/impure?!?!


From: David Kastrup
Subject: Re: pure/impure?!?!
Date: Sun, 24 May 2015 10:55:30 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

Keith OHara <address@hidden> writes:

> David Kastrup <dak <at> gnu.org> writes:
>
>> Ignored or not: those are values indicating breakpoints of the
>> current system.  They should not even be available for functions
>> evaluated before any line-breaking.  Or maybe they are called for one
>> of a set of tentative not-final line breaks, but in that case it
>> would make little sense to call the post-linebreak (impure?)
>> functions without the actual linebreak information.
>
> Yes.

This "Yes" is rather safe from getting sued for discrimination.

> The parameters 'start' and 'end' let the page-breaking code estimate
> how tall each system will be by calling the pure-height function on
> each VerticalAxisGroup, which might call pure-height on its contained
> spanners like Slurs, whose height could depend on where the
> line-breaks are.  The results are cached in a hash table indexed by
> the start/end pair.

If start/end are tentative for the pure functions, they are fixed for
the impure functions.  Since the impure ones need to be able to crank
out perfect values, they would appear to have more of an absolute need
for accessing start/end values.  So where do the impure functions get
their start/end values from when they need them?

The reason I am asking is that I am working on not passing start/end to
pure functions at all, instead providing a different way to access them
when needed (fluids basically).  However, it would appear that impure
functions would already need to have some way of accessing the final
start/end values anyway.  So I better make sure that both end up using
the same mechanism.

> The idea was to consider line-breaks and page breaks simultaneously,
> to find the best overall page layout.  In practice, this does not work
> very well because 1) there is no time to do a trial horizontal spacing
> for each line-break set, so the page fit is evaluated with
> conservatively estimated heights of systems only, not skyline

"trial horizontal spacing" and "skyline" sound like two different
things.  "there is no time" is always a dangerous statement since some
scores are small, reasonable algorithms are O(n) or O(n lg n), computer
performance goes up every year, and a final manual typesetting pass
takes weeks to months in comparison.  So pinning an architecture down to
the degree where the initial "there is no time" statement is
supplemented by "there is no way" is imprudent.

> 2) in frenched scores, where well-chosen line-breaks let us remove
> more empty staves, the page-fit score often favors generating
> mostly-empty staves to fill pages more uniformly.

For one thing, it means that we should likely have our page scoring more
open to tweaks.  For another, frenching should likely not be an absolute
operation but a scored option.  If the room is there anyway, a
transitory staff may appear a line early, making it easier to come in.
There is no point in frenching a short passage when it does not lead to
any ultimate space savings.  And so on.

> We can't simply remove the simultaneous consideration of line- and
> page-breaks, because page-turn-breaking needs to put the final line-
> break on each odd page at a feasible point.  We might be able to shift
> to two strategies: 1) line-breaking then best-fit onto pages using the
> skylines of the lines, 2) page-turn-breaking at feasible places, then
> line breaking within each page.

I prefer lazy calculation that dynamically keeps track of dependencies,
and a graph traversal minimization scoring.

Yes, lots of buzzwords.  The first step to that means is _not_ passing
break-dependent information like start/end around like complimentary
servings but have anyone that wants it _ask_ for it.  Then start keeping
track who is asking for what under which circumstances.

A function that does not ask for start/end or other break-dependent
information can get its results calculated only once, ever, and cached
from that point of time.

> The usual (not 'pure') functions to determine Y-offsets are free to
> look up properties of other objects, that can call functions to look
> up the line-breaking results or induce line-breaking if it hasn't been
> done yet.

And that's where I want to get: everyone is allowed to do that, but then
the conditions used for arriving at that result are recorded and the
result, while cached, is only used for cases meeting the same
preconditions (in case line breaks are too expensive to do tentatively
for each break position, one precondition can be "line breaking did not
happen yet", and a page/line break model equivalent to the current one
will have that condition).

> The 'pure' functions are supposed to avoid calling functions with the
> side effect of inducing line-breaking, and that has caused a
> proliferation of 'pure' versions of functions where we would not
> expect a distinction between pre-/post line-breaking

Well, the current setup is too contorted to be maintainable and safely
extensible.  Whenever somebody tries to improve spacing or cross-staff
or whatever somewhere, we get a series of exploding things until stuff
settles down again.  Basically, the inherent complexity of the task is
spread too thin across the code.  It needs to get consolidated into one
place if we want to get to a point where people specializing in
typography rather than low-level code tweakery and debugging can hope to
improve LilyPond's aesthetics.

Anyway: how do impure functions reference (and trigger?) line breaks?

-- 
David Kastrup



reply via email to

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