Han-Wen Nienhuys <hanw...@gmail.com> writes: > I've been looking at (auto)compilatoin for a bit. It fails with > > ;;; WARNING: compilation of > /home/hanwen/vc/lilypond/lily/share/lilypond/current/scm/chord-entry.scm > failed: > ;;; unhandled constant #<procedure add-session-variable (name value)> > > I'm puzzled by your macro: > > (defmacro define-session (name value) > .. > (define (add-session-variable name value) > (set! lilypond-declarations > (cons (make-session-variable name value) lilypond-declarations))) > `(,add-session-variable ',name ,value)) > > I understand why we need sessions, but I don't understand why this has > to be a macro, and why the macro has to define add-session-variable. > > Why can't this be something like > > (define lilypond-declarations '()) > (define (define-session name value) > (set! lilypond-declarations > (cons (make-session-variable name value) lilypond-declarations))) > > > When calling the macro twice, we'll define add-session-variable twice, > which seems fishy.
I think you got confused here. A macro is just an ordinary function on its inside, it only differs in its calling conventions during evaluation: instead of evaluating its arguments and calling the function body like with ordinary functions, it is called with unevaluated arguments and the result is then evaluated in its expression. add-session-variable is a local function defined inside of define-session. The effect is that it is not callable externally, and not modifiable externally. It is just putting stuff near to where it is being used (it is used as a function in the expansion of the macro). define-session is a macro since its use parallels the use of define , and the first argument of define is the symbol to be defined which must not be evaluated before define-session is being called. -- David Kastrup