Hi, The "delayed evaluation" thread is a bit long and confusing, so I would like to try to summarize it.
Lilypond has a way to embed Lilypond code in Scheme, and Scheme code in Lilypond code. The former uses a reader macro, #{#}. The latter uses specially-marked variables and expressions, specifically, those preceded by $ or #. For example, the following Scheme expression is an embedded lilypond code fragment: #{ \displayLilyMusic $p #} which expands out at read-time to: (#<procedure embedded-lilypond (parser lily-string filename line closures)> parser " \\displayLilyMusic $p " #f 0 (list (cons 20 (lambda () p)))) Here the procedure is embedded in the output of the reader macro. We can see that the $p is translated to (cons 20 (lambda () p)). Whenever $p is evaluated, that lambda is run. Embedded Scheme (via $ or #) has access to Scheme's environment. Variables in lilypond are in a separate environment (implemented using modules), so we don't have to be concerned about lilypond accessing or defining Scheme lexicals. David hacks on Lilypond. He notes that the above expression used to expand out to: (#<procedure embedded-lilypond (parser lily-string filename line closures)> parser " \\displayLilyMusic $p " #f 0 (the-environment)) in 1.8. Then, whenever lilypond needed to evaluate an embedded Scheme value, it would use `local-eval' with the captured environment. It is clearly much more convenient for lilypond hackers than having to scan for embedded Scheme beforehand and build up closures for each embedded Scheme expression. David noted that while "the closure solution" works for him, he wondered if there was something better to use. It took some time for everyone to understand the problem. In the end, there were four workable possibilities. 1) Keep using closures. 2) Incorporate local-eval and the-environment into Guile 2.0. 3) Have lilypond use its own evaluator or compiler. 4) Have lilypond make the embedded lilypond code expand out to actual Scheme. (It was unclear whether the lilypond grammar allowed this.) Mark and Noah looked at implementing local-eval, and I recommended staying with the closure solution. Ludovic noted success with method (3) in the Skribilo context. I would like to start a new thread around local-eval, but besides that, we should probably agree on the summary first. So please do send any corrections to this summary to the list. Thanks :) Andy -- http://wingolog.org/