While reading through precompiler.lisp, I noticed we have 3 concepts for transformation of lisp sources
* normal macros, * compiler-macros, * source-transforms
The difference between macros and compiler-macros is well documented in the CLHS; however, the difference between compiler-macros and source-transforms is unclear to me. I found that the former is expanded in compiler-pass1 while the latter is expanded in precompiler.lisp. However, when we're compiling for interpretation (not compilation), *in-jvm-compile* is NIL, meaning that source-transforms don't get expanded.
The net effect would be that both source-transforms and compiler-macros only get expanded when we're compiling. I'm wondering what the benefit of source transforms is if this is really true.
Bye,
Erik.
On Sun, Jul 12, 2009 at 12:15 PM, Erik Huelsmannehuels@gmail.com wrote:
While reading through precompiler.lisp, I noticed we have 3 concepts for transformation of lisp sources
- normal macros,
- compiler-macros,
- source-transforms
The difference between macros and compiler-macros is well documented in the CLHS; however, the difference between compiler-macros and source-transforms is unclear to me. I found that the former is expanded in compiler-pass1 while the latter is expanded in precompiler.lisp. However, when we're compiling for interpretation (not compilation), *in-jvm-compile* is NIL, meaning that source-transforms don't get expanded.
The net effect would be that both source-transforms and compiler-macros only get expanded when we're compiling. I'm wondering what the benefit of source transforms is if this is really true.
I had the opportunity to talk to Peter Graves on IRC yesterday. He explained how this works and especially, how he designed it to work in XCL (his post-ABCL Lisp compiler off-the-ground rewrite in C++).
So, this is his take on it in XCL:
* as the CLHS documents: there can only be 1 compiler-macro per symbol * the user is free to define his own compiler macros
The two statements above mean that the (correct) operation of the compiler should not depend on any compiler macros.
XCL uses source-transforms to make sure the user can define compiler macros for any symbol he or she likes. XCL expands compiler macros in the compiler (not in the preprocessor/macro-expander) XCL expands source transforms after compiler macros.
I think this is the sane thing to do: it removes the dependency of ABCL on certain compiler macros to be available.
I fully intend to implement this strategy in ABCL too. This means the following steps:
* making source transforms out of the compiler macros currently defined in precompiler.lisp * moving all source transforms (and thus compiler macros) from precompiler.lisp to compiler-pass1.lisp * remove all expansion of compiler macros from precompiler.lisp (moving it to compiler-pass1.lisp) - as they are not expanded when not compiling anyway.
I hope to execute these changes in the coming week.
Bye,
Erik.
On Jul 13, 2009, at 17:04, Erik Huelsmann wrote:
So, this is his take on it in XCL:
- as the CLHS documents: there can only be 1 compiler-macro per symbol
- the user is free to define his own compiler macros
The two statements above mean that the (correct) operation of the compiler should not depend on any compiler macros.
XCL uses source-transforms to make sure the user can define compiler macros for any symbol he or she likes.
Er, this would be true except for CLHS 11.1.2.1.2:
"Except where explicitly allowed, the consequences are undefined if any of the following actions are performed on an external symbol of the COMMON-LISP package: ... 3. Defining, undefining, or binding it as a macro or compiler macro. (Some exceptions are noted below.)"
That is, the implementation may rely on compiler macro definitions for CL: symbols.
There may be reasons to use a different mechanism than compiler- macros, but user redefinition is not one of them.
On Tue, Jul 14, 2009 at 2:22 AM, Kevin Reidkpreid@mac.com wrote:
On Jul 13, 2009, at 17:04, Erik Huelsmann wrote:
So, this is his take on it in XCL:
- as the CLHS documents: there can only be 1 compiler-macro per symbol
- the user is free to define his own compiler macros
The two statements above mean that the (correct) operation of the compiler should not depend on any compiler macros.
XCL uses source-transforms to make sure the user can define compiler macros for any symbol he or she likes.
Er, this would be true except for CLHS 11.1.2.1.2:
"Except where explicitly allowed, the consequences are undefined if any of the following actions are performed on an external symbol of the COMMON-LISP package: ... 3. Defining, undefining, or binding it as a macro or compiler macro. (Some exceptions are noted below.)"
That is, the implementation may rely on compiler macro definitions for CL: symbols.
There may be reasons to use a different mechanism than compiler- macros, but user redefinition is not one of them.
Thanks for the reaction! That's food for thought. I'll consider what other reasons there are (probably: non-cl-symbols...)
If there really aren't any, then we still need to reorganize the code: in that case we will have to leave the entire concept of source transforms behind.
Bye,
Erik.
If there really aren't any, then we still need to reorganize the code: in that case we will have to leave the entire concept of source transforms behind.
Btw. the precompiler seems to expand source-transforms, but not compiler-macros at the moment.
MACROEXPAND-ALL should expand neither source-transforms nor compiler-macros.
So you probably want to rename *IN-JVM-COMPILE* to *PRECOMPILER-CONTEXT* which can be one of three possible values: :INTERPRETER, :JVM, or :MACROEXPAND-ALL.
-T.
armedbear-devel@common-lisp.net