10.13.3 How purity is defined and stored

Purity can currently be defined two different ways in LilyPond that correspond to two types of scenarios. In one scenario, we know that a callback is pure, but we are not necessarily certain what properties will use this callback. In another, we want a property to be pure, but we don’t want to guarantee that its callback function will be pure in all circumstances.

In the first scenario, we register the callback in define-grobs.scm in one of four places depending on what the function does.

At all stages of the compilation process, when LilyPond wants the pure version of a property, it will consult these lists and see if it can get this property for a given Grob. Note that you do not need to register the pure property in the grob itself. For example, there is no property ‘pure-Y-extent’. Rather, by registering these functions as defined above, every time LilyPond needs a pure property, it will check to see if a Grob contains one of these functions and, if so, will use its value. If LilyPond cannot get a pure function, it will return a value of ##f for the property.

LilyPond is smart enough to know if a series of chained functions are pure. For example, if a Y-offset property has four chained functions and all of them have pure equivalents, LilyPond will read the four pure equivalents when calculating the pure property. However, if even one is impure, LilyPond will not return a pure property for the offset (instead returning something like #f or '()) and will likely wreak havoc on your score.

In the second scenario, we create an unpure-pure-container (unpure is not a word, but hey, neither was Lilypond until the 90s). For example:

#(define (foo grob)
  '(-1 . 1))

#(define (bar grob start end)
  '(-2 . 2))

\override Stem #'length = #(ly:make-unpure-pure-container foo bar)

This is useful if we want to:

Items can only ever have two pure heights: their actual pure height if they are between ‘start’ and ‘end’, or an empty interval if they are not. Thus, their pure property is cached to speed LilyPond up. Pure heights for spanners are generally not cached as they change depending on the start and end values. They are only cached in certain particular cases. Before writing a lot of caching code, make sure that it is a value that will be reused a lot.

LilyPond — Contributor’s Guide v2.17.97 (development-branch).