guicho271828 / recursive-macroexpansion

Provides another `macroexpand`
8 stars 0 forks source link

macrolet forms not handled correctly #1

Closed DalekBaldwin closed 9 years ago

DalekBaldwin commented 9 years ago

The handler appears to be storing the code for expansion functions instead of actual function objects.

On SBCL:

(recursive-macroexpansion:rmacroexpand
 '(macrolet ((stuff ()
              `(+ 2 2)))
   (stuff)))

The value
  (LAMBDA (#1=#:WHOLE1390 #2=#:ENVIRONMENT1391)
    (DECLARE (IGNORE #2#))
    (LET* #3=()
      (DECLARE (MUFFLE-CONDITIONS CODE-DELETION-NOTE))
      (LET ((#4=#:ARGS1393 (CDR #1#)))
        (UNLESS (SB-INT:PROPER-LIST-OF-LENGTH-P #4# 0 0)
          (SB-KERNEL::ARG-COUNT-ERROR 'SB-CLTL2:PARSE-MACRO
                                      'STUFF #4# 'NIL 0 0)))
      (LET* #3#
        (BLOCK STUFF `(+ 2 2)))))
is not of type
  (OR FUNCTION NULL).
   [Condition of type TYPE-ERROR]
DalekBaldwin commented 9 years ago

I've played around with modifying the handler for macrolet to wrap the result of (parse-macro name args body env) in an eval, but that doesn't take into account the lexical environment. SBCL has an internal function called eval-in-lexenv. I don't know whether there's an approach that's portable across all the implementations CL21 supports.

guicho271828 commented 9 years ago

thank you for pointing it out, ill look into it soon.

I wish there were more libraries aimed to work in compilation time. Bike/compiler-macro would also intetrst you.

DalekBaldwin commented 9 years ago

By the way, here's what the Hyperspec says:

"The macro-expansion functions defined by macrolet are defined in the lexical environment in which the macrolet form appears. Declarations and macrolet and symbol-macrolet definitions affect the local macro definitions in a macrolet, but the consequences are undefined if the local macro definitions reference any local variable or function bindings that are visible in that lexical environment."

This seems to say that the only part of the lexical environment that should matter to macrolet macros is declarations, but I'm not sure what kind of declarations from expanded code would have an effect on expander code. So it might not be an issue, or it might be something that only matters when the Lisp implementation is in interpreter mode, but it would take some careful investigation to make sure.