Arc Forumnew | comments | leaders | submitlogin
2 points by waterhouse 5310 days ago | link | parent

It seems to me that a lexical binding should override a global macro binding, no matter what. I don't see a reason not to do it that way, except possibly that it would make it harder to handle macroexpansion (it adds another special case to macroexpansion, along with quoted/quasiquoted forms and parameter lists and wherever else macros shouldn't be expanded). But we already have a full code-walker in ac.scm, and aw has shown us just where to look and what to do, so this turns out not to be much of a problem.

And it turns out that both Common Lisp and Scheme agree with me, that lexical bindings should override global macro bindings. As we see here (pardon my choice of throwaway function name; it's short and the computer doesn't mind):

  > (define-macro (ass x) ;Scheme
      `(list ,x 2))
  > (let ((ass (lambda (x) (+ x 1))))
      (ass 1))
  2

  * (defmacro ass (x) `(list ,x 1)) ;CL
  ASS
  * (flet ((ass (x) (+ x 1))) (ass 2))
  3
In the above examples, if the calls to 'ass got expanded as macros, then what would be returned is some kind of list, rather than an integer. It's only in Arc that we get:

  arc> (mac ass (x) `(list ,x 1))
  #(tagged mac #<procedure: ass>)
  arc> (let ass (fn (x) (+ x 1)) (ass 2))
  (2 1)
By the way, in order to format the above code (add 2 spaces before each line), I used the following handy little 'clipboard function after copying the interactions with the REPLs. I think pbpaste works on all Unix-like systems:

  (def clipboard () (tostring:system "pbpaste"))
  
  arc> (let u (instring:clipboard) (whilet a readline.u (prn "  " a)))
    > (define (meh ass)
        (ass 1))
    > (meh (lambda (x) (+ x 1)))
    2
  nil