I added (if (ly:stencil? (ly:stem::print grob)) ... to the function (and some construction-helpers, maybe deleted). Now it works with \change Staff, too. "2.15.13" or higher is still needed.
All you need here is a call to ly:stem::print first; there's no need to integrate it into the logic of the function.
This is enough:
#(define ((stem-length y) grob)
(ly:stem::print grob) ; this line must be present
(ly:grob-set-property! grob 'length y)
(ly:stem::print grob))
This doesn't work, though:
#(define ((stem-length y) grob)
(let ((stencil (ly:stem::print grob)))
(ly:grob-set-property! grob 'length y)
stencil))
Why is this? If you or anyone reading this can explain, I'd love to hear the answer.
Any idea how to change to make it work with "2.14.2"?
I wasn't able to figure out how to use 'length on a single beamed stem with 2.14.2. However, you can use the 'stem-end-position property here. (It seems that this property is no longer available in 2.15.13.) So, in 2.14.2, this line will get you what you want:
\once \override Stem #'stem-end-position = #-8
-David