Arc Forumnew | comments | leaders | submitlogin
Lexically shadowing a macro?
3 points by twilightsentry 2902 days ago | 5 comments
I was fooling around when I came across an unexpected (to me) bug/feature. I wrote something like the following:

(def trivial-example (obj key) (obj key))

I expected that the global binding of obj would be shadowed, and so I'd end up looking up the value of key in obj. However, ac.scm always looks at global bindings when considering whether a symbol is a macro. Of course, changing 'obj' to 'ob' solves the problem, but it still seems to me that in a lisp-1, a lexical binding should always shadow a global binding, regardless of what's being bound.

I made a few hacks to ac.scm to assume that any lexically bound symbol isn't a macro:

Or maybe there's a perfectly good reason for macros to act as they do now and I just don't see it.

1 point by conanite 2902 days ago | link

The lexical binding shadows the global binding if it isn't in functional position:

  (def trivial-example (obj with) (foo obj with))
does what you would expect it to do. But I don't know whether or why it's better that global macro definitions override lexical bindings in functional position.


1 point by pg 2902 days ago | link

Macros are something that happens at compile time, not runtime. A macro call looks like a function call, but it's really something completely different.


2 points by rntz 2901 days ago | link

This... isn't really an explanation. Lexical bindings of things are also determined at compile time - just not the values they'll be bound to. So you can't have a locally-bound macro, but you can let locally-bound symbols shadow macros, and there's no real reason not to.

(If that first sentence doesn't seem to make any sense to other readers: What variable or relative stack position a variable will be stored in in C is determined at compile time, but the value is not. Obviously the backend isn't the same here, but the same concept holds, at least the way arc is currently implemented; in particular, there is a parameter to 'ac that indicates what symbols are lexically and locally bound. In Python, on the other hand, the local environment is accessible at runtime, so lexical bindings are not always determinable at byte-compilation-time.)


1 point by almkglor 2868 days ago | link

  (mac helper (foo)
    `(do ,foo))
  (mac real-macro (bar)
    `(helper ,bar))

  (let helper
       (fn (x) (+ x 1))
    (real-macro (helper 1)))


2 points by rntz 2842 days ago | link

This could be a poster child for hygienic macros.