Arc Forumnew | comments | leaders | submitlogin
3 points by akkartik 1068 days ago | link | parent

I don't think this has come up before. An f-expr based Lisp would automatically have this property (at much performance cost). But we haven't discussed lexical macros as a separate construct.

I feel like something kinda related has come up a couple of times before: allowing local variables to override macros. I think there was even a one-line patch to ac.scm at some point. But it must have had some issue since it's not in Anarki :)

Maybe this thread brings up some ideas?

2 points by aw 1068 days ago | link

> allowing local variables to override macros

Yes, that's easy to do. At the top of ac-call in ac.scm where it checks ac-macro?, also check to see that "fn" isn't a symbol and in env.


3 points by waterhouse 1068 days ago | link

Yup, I have that change.

(define (ac-call fn args env) (let ((macfn (ac-macro? fn))) - (cond (macfn + (cond ((and macfn (not (lex? fn env))) (ac-mac-call macfn args env))

Now, if you wanted to define the macro locally, like this...

  (let-macro my-def (name args . body) `(= ,name (fn ,args ,@body))
    ... (my-def ...))
Then, well, you could conceivably change the semantics of "env" as it's passed around in ac.scm. Currently it's just a list of variables that are bound, and things test for whether a variable is present in that list. You could change it to a list of (variable-name macro-it's-bound-to-if-any), and have the special form (let-macro name arglist bodexpr . body) insert `(,name (fn ,arglist ,bodexpr) into env, while everything else puts in (variable nil), and change all the existing tests on "env" to search for "a list whose car is x" rather than "x", and lastly make ac-call call the macro-function on the expression if it finds one in the lexenv.

In theory, one could put arbitrarily complicated information, such as about deduced types of variables, into this "env" mapping, and implement some amount of compiler optimization that way.

First-class macros, of course, are the semantically nicest approach, but more difficult to compile.


3 points by waterhouse 1068 days ago | link

Gack, formatting got messed up on the first snippet. Too late to edit. Should be:

   (define (ac-call fn args env)
     (let ((macfn (ac-macro? fn)))
  -    (cond (macfn
  +    (cond ((and macfn (not (lex? fn env)))
              (ac-mac-call macfn args env))