<div>
            <div><p style="color: #a0a0a0;">On Saturday, 18 June 2011 at 14:11, Benjohn Barnes wrote:</p><blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;">
                    <span><div><div>I think I must not be understanding something basic about macro expansion.<br><br>I've reduced a more complex failure with macros that I am having to this simple example:<br><blockquote type="cite"><div>; Define a function.<br>(define (inc x) (+ 1 x))<br><br>;Define a macro using the function.<br>(define-macro (macro-inc x) (inc x))<br><br>; This works okay.<br>(define two (inc 1))<br><br>; This fails on load with:<br>; *** ERROR IN #<procedure #2>, "macro-test.scm"@5.30 -- Unbound variable: inc<br>(define macro-two (macro-inc 1))<br></div></blockquote></div></div></span></blockquote><div>As others have pointed out, this is works in the REPL, because each expression gets macroexpanded and evaluated before the next expression is macroexpanded. A different way to explain why this happens is to observe the fact that (load) and (include) works as if you'd have written
                </div><div><br></div><div><div>(begin</div><div>  (define (inc x) (+ 1 x))</div><div>  (define-macro (macro-inc x) (inc x))</div><div>  (define two (inc 1))</div><div>  (define macro-two (macro-inc 1)))</div></div><div><br></div><div>, which gives the "Unbound variable: inc" error even in the REPL, because the entire begin form is macro expanded before any of it is evaluated.</div><div><br></div><div>The interaction between run-time and compile time, especially in an environment with a REPL, is quite complicated. The solution Marc linked to is the preferred way to do it in vanilla Gambit.</div><div><br></div><div>The way to do this in Black Hole is to separate the code that is needed at compile time into a separate module. Here's a Black Hole version of your example:</div><div><br></div><div><div>t[master]$ cat > inc.scm </div><div>(define (inc x) (+ 1 x))</div><div><br></div><div>t[master]$ cat > example.scm </div><div>(syntax-begin (import inc))</div><div>(import inc)</div><div>(define-macro (macro-inc x) (inc x))</div><div>(define two (inc 1))</div><div>(define macro-two (macro-inc 1))</div><div><br></div><div>t[master]$ bsc</div><div>Loaded Black Hole.</div><div>Gambit v4.6.1</div><div><br></div><div>> (import example)</div><div>> two</div><div>2</div><div>> macro-two</div><div>2</div><div>> </div></div><div><br></div><div><br></div><div>The important part of this is (syntax-begin (import inc)). It imports inc into the macro namespace. Without it, macro-inc wouldn't have worked.</div><div><br></div><div>Because inc is also used at runtime, it has to be imported as usual as well.</div><div><br></div><div>A caveat: syntax-begin has turned out to be really tricky to implement right, and I might remove it in favor of a more intelligent import form that automatically infers which phases it has to import to. I don't recommend putting anything but import forms in it.</div><div><br></div><div>/Per</div><div><br></div>
            </div>
        </div>