Expanding nested macro calls during code compilation/evaluation
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have a next piece of code:
(in-package :cl-user)
(defmacro test0 (form)
(format t "test0: Expander phase: ~s" form)
`(format t "test0: Expansion phase: ~s" ,form))
(defmacro test1 (form)
(format t "test1: Expander phase: ~s" form)
(test0 form)
`(format t "test1: Expansion phase: ~s" ,form))
Common Lisp implementation: "SBCL 1.3.16"
.
Results of
(compile-file "source.lisp")
:
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFMACRO TEST0 ...)
; compiling (DEFMACRO TEST1 ...)test0: Expander phase: FORMtest0: Expander phase: FORM
Results of
(load "source.lisp")
:
; #<PACKAGE "COMMON-LISP-USER">
; TEST0
test0: Expander phase: FORM
; TEST1
And I just can't understand next things:
Why is nested subform
(test0 form)
expanded and processed in the definition oftest1
macro? Why isn't it processed in the macro call instead?Where is Common Lisp standard specify such a behavior?
eval-when
? Files compilation? Forms evaluation?Finally, why is
"test0: Expander phase: FORM"
printed twice during compilation(compile-file
) and only once during evaluation(load
)?
I think the answers are pretty obvious but I can't find them out.
common-lisp
add a comment |
I have a next piece of code:
(in-package :cl-user)
(defmacro test0 (form)
(format t "test0: Expander phase: ~s" form)
`(format t "test0: Expansion phase: ~s" ,form))
(defmacro test1 (form)
(format t "test1: Expander phase: ~s" form)
(test0 form)
`(format t "test1: Expansion phase: ~s" ,form))
Common Lisp implementation: "SBCL 1.3.16"
.
Results of
(compile-file "source.lisp")
:
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFMACRO TEST0 ...)
; compiling (DEFMACRO TEST1 ...)test0: Expander phase: FORMtest0: Expander phase: FORM
Results of
(load "source.lisp")
:
; #<PACKAGE "COMMON-LISP-USER">
; TEST0
test0: Expander phase: FORM
; TEST1
And I just can't understand next things:
Why is nested subform
(test0 form)
expanded and processed in the definition oftest1
macro? Why isn't it processed in the macro call instead?Where is Common Lisp standard specify such a behavior?
eval-when
? Files compilation? Forms evaluation?Finally, why is
"test0: Expander phase: FORM"
printed twice during compilation(compile-file
) and only once during evaluation(load
)?
I think the answers are pretty obvious but I can't find them out.
common-lisp
add a comment |
I have a next piece of code:
(in-package :cl-user)
(defmacro test0 (form)
(format t "test0: Expander phase: ~s" form)
`(format t "test0: Expansion phase: ~s" ,form))
(defmacro test1 (form)
(format t "test1: Expander phase: ~s" form)
(test0 form)
`(format t "test1: Expansion phase: ~s" ,form))
Common Lisp implementation: "SBCL 1.3.16"
.
Results of
(compile-file "source.lisp")
:
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFMACRO TEST0 ...)
; compiling (DEFMACRO TEST1 ...)test0: Expander phase: FORMtest0: Expander phase: FORM
Results of
(load "source.lisp")
:
; #<PACKAGE "COMMON-LISP-USER">
; TEST0
test0: Expander phase: FORM
; TEST1
And I just can't understand next things:
Why is nested subform
(test0 form)
expanded and processed in the definition oftest1
macro? Why isn't it processed in the macro call instead?Where is Common Lisp standard specify such a behavior?
eval-when
? Files compilation? Forms evaluation?Finally, why is
"test0: Expander phase: FORM"
printed twice during compilation(compile-file
) and only once during evaluation(load
)?
I think the answers are pretty obvious but I can't find them out.
common-lisp
I have a next piece of code:
(in-package :cl-user)
(defmacro test0 (form)
(format t "test0: Expander phase: ~s" form)
`(format t "test0: Expansion phase: ~s" ,form))
(defmacro test1 (form)
(format t "test1: Expander phase: ~s" form)
(test0 form)
`(format t "test1: Expansion phase: ~s" ,form))
Common Lisp implementation: "SBCL 1.3.16"
.
Results of
(compile-file "source.lisp")
:
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFMACRO TEST0 ...)
; compiling (DEFMACRO TEST1 ...)test0: Expander phase: FORMtest0: Expander phase: FORM
Results of
(load "source.lisp")
:
; #<PACKAGE "COMMON-LISP-USER">
; TEST0
test0: Expander phase: FORM
; TEST1
And I just can't understand next things:
Why is nested subform
(test0 form)
expanded and processed in the definition oftest1
macro? Why isn't it processed in the macro call instead?Where is Common Lisp standard specify such a behavior?
eval-when
? Files compilation? Forms evaluation?Finally, why is
"test0: Expander phase: FORM"
printed twice during compilation(compile-file
) and only once during evaluation(load
)?
I think the answers are pretty obvious but I can't find them out.
common-lisp
common-lisp
edited Nov 16 '18 at 14:32
sds
40.4k1498177
40.4k1498177
asked Nov 16 '18 at 13:13
Андрій ТимчукАндрій Тимчук
33
33
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
A macro is a function which operates on code.
Since in Lisp code is just a
list
,
macro functions look like ordinary functions.
Your defmacro test1
is treated as a definition of a function, so all the code is processed appropriately and (test0 form)
is macroexpanded when the SBCL compiles defmacro test1
. This answers q1.
load
"sequentially executes
each form it encounters", so to answer your q2, you need to read 3.1
Evaluation, specifically,
3.1.2.1.2.2 Macro Forms.
As for how many times a macro is expanded, this is not specified by the
standard (an implementation can expand it on every call of the user
function!), and this is a reason why it is not a good idea for a macro
to have side effects (e.g., to do output).
In your case, loading requires expansion when test1
is defined.
Compilation expands when it defines test1
and then again when it
compiles it.
Remember, defmacro
arranges that the macro can be used in the
following code (including in itself recursively), so is has to be defined immediately.
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done duringload
orcompile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?
– Андрій Тимчук
Nov 19 '18 at 13:19
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53338637%2fexpanding-nested-macro-calls-during-code-compilation-evaluation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
A macro is a function which operates on code.
Since in Lisp code is just a
list
,
macro functions look like ordinary functions.
Your defmacro test1
is treated as a definition of a function, so all the code is processed appropriately and (test0 form)
is macroexpanded when the SBCL compiles defmacro test1
. This answers q1.
load
"sequentially executes
each form it encounters", so to answer your q2, you need to read 3.1
Evaluation, specifically,
3.1.2.1.2.2 Macro Forms.
As for how many times a macro is expanded, this is not specified by the
standard (an implementation can expand it on every call of the user
function!), and this is a reason why it is not a good idea for a macro
to have side effects (e.g., to do output).
In your case, loading requires expansion when test1
is defined.
Compilation expands when it defines test1
and then again when it
compiles it.
Remember, defmacro
arranges that the macro can be used in the
following code (including in itself recursively), so is has to be defined immediately.
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done duringload
orcompile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?
– Андрій Тимчук
Nov 19 '18 at 13:19
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
add a comment |
A macro is a function which operates on code.
Since in Lisp code is just a
list
,
macro functions look like ordinary functions.
Your defmacro test1
is treated as a definition of a function, so all the code is processed appropriately and (test0 form)
is macroexpanded when the SBCL compiles defmacro test1
. This answers q1.
load
"sequentially executes
each form it encounters", so to answer your q2, you need to read 3.1
Evaluation, specifically,
3.1.2.1.2.2 Macro Forms.
As for how many times a macro is expanded, this is not specified by the
standard (an implementation can expand it on every call of the user
function!), and this is a reason why it is not a good idea for a macro
to have side effects (e.g., to do output).
In your case, loading requires expansion when test1
is defined.
Compilation expands when it defines test1
and then again when it
compiles it.
Remember, defmacro
arranges that the macro can be used in the
following code (including in itself recursively), so is has to be defined immediately.
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done duringload
orcompile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?
– Андрій Тимчук
Nov 19 '18 at 13:19
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
add a comment |
A macro is a function which operates on code.
Since in Lisp code is just a
list
,
macro functions look like ordinary functions.
Your defmacro test1
is treated as a definition of a function, so all the code is processed appropriately and (test0 form)
is macroexpanded when the SBCL compiles defmacro test1
. This answers q1.
load
"sequentially executes
each form it encounters", so to answer your q2, you need to read 3.1
Evaluation, specifically,
3.1.2.1.2.2 Macro Forms.
As for how many times a macro is expanded, this is not specified by the
standard (an implementation can expand it on every call of the user
function!), and this is a reason why it is not a good idea for a macro
to have side effects (e.g., to do output).
In your case, loading requires expansion when test1
is defined.
Compilation expands when it defines test1
and then again when it
compiles it.
Remember, defmacro
arranges that the macro can be used in the
following code (including in itself recursively), so is has to be defined immediately.
A macro is a function which operates on code.
Since in Lisp code is just a
list
,
macro functions look like ordinary functions.
Your defmacro test1
is treated as a definition of a function, so all the code is processed appropriately and (test0 form)
is macroexpanded when the SBCL compiles defmacro test1
. This answers q1.
load
"sequentially executes
each form it encounters", so to answer your q2, you need to read 3.1
Evaluation, specifically,
3.1.2.1.2.2 Macro Forms.
As for how many times a macro is expanded, this is not specified by the
standard (an implementation can expand it on every call of the user
function!), and this is a reason why it is not a good idea for a macro
to have side effects (e.g., to do output).
In your case, loading requires expansion when test1
is defined.
Compilation expands when it defines test1
and then again when it
compiles it.
Remember, defmacro
arranges that the macro can be used in the
following code (including in itself recursively), so is has to be defined immediately.
answered Nov 16 '18 at 14:31
sdssds
40.4k1498177
40.4k1498177
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done duringload
orcompile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?
– Андрій Тимчук
Nov 19 '18 at 13:19
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
add a comment |
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done duringload
orcompile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?
– Андрій Тимчук
Nov 19 '18 at 13:19
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done during
load
or compile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?– Андрій Тимчук
Nov 19 '18 at 13:19
Thank you for your response, it helps me a lot. But some points are still unclear to me. "sequentially executes each form it encounters" - for macro form it means "expand and evaluate result". But how is function forms executed? I mean, the function evaluate subforms(body) when it's called. But what is done during
load
or compile-file
? As I understand, compiler can optimize calls somehow, for example, inline function. But where is specified in the standard how function forms is executed?– Андрій Тимчук
Nov 19 '18 at 13:19
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
3.1.2.1.2.3 Function Forms
– sds
Nov 19 '18 at 13:26
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
I suggest that you ask a separate question about "top level forms". Comments is not the right place for new questions.
– sds
Nov 19 '18 at 13:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53338637%2fexpanding-nested-macro-calls-during-code-compilation-evaluation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown