The rewrite combines both of the approaches above: it uses 'round-filled-box for the stencil, and allows you to specify the length of the dashes and the spaces in between the dashes. The trade-off is that you may need to play around with the values to get the stem to end with a dash, or to end with a dash which isn't cut off too much.
I incorporated the alterations that Harm made because I think they make the code clearer.
I imagine the function build-pos-list could be done more elegantly, but at least it works. Any suggestions for doing this more artfully are welcome!
\version "2.15.38"
%#(set-global-staff-size 30)
#(define (make-round-filled-box x1 x2 y1 y2 blot-diameter)
(ly:make-stencil (list 'round-filled-box (- x1) x2 (- y1) y2 blot-diameter)
(cons x1 x2)
(cons y1 y2)))
#(define (build-pos-list len on off)
(let ((lst '(0)))
(define (helper)
(let ((bottom (+ (car lst) on)))
(if (< bottom len)
(begin
(set! lst (cons bottom lst))
(let ((top (+ (car lst) off)))
(if (< top len)
(begin
(set! lst (cons top lst))
(helper))
(set! lst (cons len lst)))))
(set! lst (cons len lst)))))
(helper)
(reverse lst)))
#(define (dashed-stem on off)
(lambda (grob)
(let* ((blot (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter))
(stencil (ly:stem::print grob))
(X-ext (ly:stencil-extent stencil X))
(thickness (interval-length X-ext))
(Y-ext (ly:stencil-extent stencil Y))
(len (interval-length Y-ext))
(new-stencil empty-stencil)
(factors (build-pos-list len on off)))
(define (helper args)
(if (<= 2 (length args))
(begin
(set! new-stencil
(ly:stencil-add
new-stencil
(ly:stencil-translate-axis
(make-round-filled-box (/ thickness -2) (/ thickness 2)
(car args) (cadr args)
blot)
(interval-start Y-ext)
Y)))
(helper (cddr args)))
new-stencil))
(if (or (zero? on) (zero? off))
stencil
(helper factors)))))
dashedStems =
#(define-music-function (parser location on off) (number? number?)
#{
\override Stem #'stencil = #(dashed-stem on off)
#})
\relative c'' {
\dashedStems #0.5 #0.4
c d e f,,
a'8 g' f' g,
}