Dynamic macros in common-lisp - when and how to use












-1














In my previous question, which @sds answered very nicely,



How to wrap and execute a lisp s-expression by another s-expression?



We came to the topic of dynamic and static macros.



The static solution of my with-open-files macro problem by @sds was:



(defmacro with-open-files ((streams file-names &rest options &key &allow-other-keys) &body body)
(if (and streams file-names)
`(with-open-file (,(pop streams) ,(pop file-names) ,@options)
(with-open-files (,streams ,file-names ,@options)
,@body))
`(progn ,@body)))


And his dynamic solution:



(defmacro with-open-files-d ((streams file-names &rest options &key &allow-other-keys) &body body)
(let ((sv (gensym "STREAMS-"))
(ab (gensym "ABORT-"))
(op (gensym "OPTIONS-")))
`(let ((,sv ,streams)
(,ab t)
(,op (list ,@options)))
(progv ,sv (mapcar (lambda (fn) (apply #'open fn op)) ,file-names)
(unwind-protect (multiple-value-prog1 (progn ,@body) (setq ,ab nil))
(dolist (s ,sv)
(when s
(close s :abort ,ab))))))))


My question is: Does using a macro in a macro automatically prohibits it to be dynamic? (I guess yes ..., since the macro call in the macro definition has to be executed before compilation, isn't it? Or not?).



And when to use a static or dynamic macro solution? - Sure, if the data are only known at runtime, one would need a dynamic macro, isn't it?
What are best practices?










share|improve this question


















  • 1




    DOLIST is a macro, you're using that in the dynamic version. So obviously it doesn't prohibit it.
    – Barmar
    Nov 12 '18 at 19:57










  • You should use whichever form produces the clearest code that solves the problem.
    – Barmar
    Nov 12 '18 at 19:58










  • @Barmar true ... but with-open-files prohibits it ... maybe because it takes an argument which is used literally? (e.g. the stream variable?) ...
    – Gwang-Jin Kim
    Nov 12 '18 at 20:01










  • Right. You can't use a macro that requires a compile-time literal when you're calculating the value at runtime.
    – Barmar
    Nov 12 '18 at 20:05
















-1














In my previous question, which @sds answered very nicely,



How to wrap and execute a lisp s-expression by another s-expression?



We came to the topic of dynamic and static macros.



The static solution of my with-open-files macro problem by @sds was:



(defmacro with-open-files ((streams file-names &rest options &key &allow-other-keys) &body body)
(if (and streams file-names)
`(with-open-file (,(pop streams) ,(pop file-names) ,@options)
(with-open-files (,streams ,file-names ,@options)
,@body))
`(progn ,@body)))


And his dynamic solution:



(defmacro with-open-files-d ((streams file-names &rest options &key &allow-other-keys) &body body)
(let ((sv (gensym "STREAMS-"))
(ab (gensym "ABORT-"))
(op (gensym "OPTIONS-")))
`(let ((,sv ,streams)
(,ab t)
(,op (list ,@options)))
(progv ,sv (mapcar (lambda (fn) (apply #'open fn op)) ,file-names)
(unwind-protect (multiple-value-prog1 (progn ,@body) (setq ,ab nil))
(dolist (s ,sv)
(when s
(close s :abort ,ab))))))))


My question is: Does using a macro in a macro automatically prohibits it to be dynamic? (I guess yes ..., since the macro call in the macro definition has to be executed before compilation, isn't it? Or not?).



And when to use a static or dynamic macro solution? - Sure, if the data are only known at runtime, one would need a dynamic macro, isn't it?
What are best practices?










share|improve this question


















  • 1




    DOLIST is a macro, you're using that in the dynamic version. So obviously it doesn't prohibit it.
    – Barmar
    Nov 12 '18 at 19:57










  • You should use whichever form produces the clearest code that solves the problem.
    – Barmar
    Nov 12 '18 at 19:58










  • @Barmar true ... but with-open-files prohibits it ... maybe because it takes an argument which is used literally? (e.g. the stream variable?) ...
    – Gwang-Jin Kim
    Nov 12 '18 at 20:01










  • Right. You can't use a macro that requires a compile-time literal when you're calculating the value at runtime.
    – Barmar
    Nov 12 '18 at 20:05














-1












-1








-1







In my previous question, which @sds answered very nicely,



How to wrap and execute a lisp s-expression by another s-expression?



We came to the topic of dynamic and static macros.



The static solution of my with-open-files macro problem by @sds was:



(defmacro with-open-files ((streams file-names &rest options &key &allow-other-keys) &body body)
(if (and streams file-names)
`(with-open-file (,(pop streams) ,(pop file-names) ,@options)
(with-open-files (,streams ,file-names ,@options)
,@body))
`(progn ,@body)))


And his dynamic solution:



(defmacro with-open-files-d ((streams file-names &rest options &key &allow-other-keys) &body body)
(let ((sv (gensym "STREAMS-"))
(ab (gensym "ABORT-"))
(op (gensym "OPTIONS-")))
`(let ((,sv ,streams)
(,ab t)
(,op (list ,@options)))
(progv ,sv (mapcar (lambda (fn) (apply #'open fn op)) ,file-names)
(unwind-protect (multiple-value-prog1 (progn ,@body) (setq ,ab nil))
(dolist (s ,sv)
(when s
(close s :abort ,ab))))))))


My question is: Does using a macro in a macro automatically prohibits it to be dynamic? (I guess yes ..., since the macro call in the macro definition has to be executed before compilation, isn't it? Or not?).



And when to use a static or dynamic macro solution? - Sure, if the data are only known at runtime, one would need a dynamic macro, isn't it?
What are best practices?










share|improve this question













In my previous question, which @sds answered very nicely,



How to wrap and execute a lisp s-expression by another s-expression?



We came to the topic of dynamic and static macros.



The static solution of my with-open-files macro problem by @sds was:



(defmacro with-open-files ((streams file-names &rest options &key &allow-other-keys) &body body)
(if (and streams file-names)
`(with-open-file (,(pop streams) ,(pop file-names) ,@options)
(with-open-files (,streams ,file-names ,@options)
,@body))
`(progn ,@body)))


And his dynamic solution:



(defmacro with-open-files-d ((streams file-names &rest options &key &allow-other-keys) &body body)
(let ((sv (gensym "STREAMS-"))
(ab (gensym "ABORT-"))
(op (gensym "OPTIONS-")))
`(let ((,sv ,streams)
(,ab t)
(,op (list ,@options)))
(progv ,sv (mapcar (lambda (fn) (apply #'open fn op)) ,file-names)
(unwind-protect (multiple-value-prog1 (progn ,@body) (setq ,ab nil))
(dolist (s ,sv)
(when s
(close s :abort ,ab))))))))


My question is: Does using a macro in a macro automatically prohibits it to be dynamic? (I guess yes ..., since the macro call in the macro definition has to be executed before compilation, isn't it? Or not?).



And when to use a static or dynamic macro solution? - Sure, if the data are only known at runtime, one would need a dynamic macro, isn't it?
What are best practices?







dynamic static macros common-lisp






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 12 '18 at 19:26









Gwang-Jin Kim

2,396116




2,396116








  • 1




    DOLIST is a macro, you're using that in the dynamic version. So obviously it doesn't prohibit it.
    – Barmar
    Nov 12 '18 at 19:57










  • You should use whichever form produces the clearest code that solves the problem.
    – Barmar
    Nov 12 '18 at 19:58










  • @Barmar true ... but with-open-files prohibits it ... maybe because it takes an argument which is used literally? (e.g. the stream variable?) ...
    – Gwang-Jin Kim
    Nov 12 '18 at 20:01










  • Right. You can't use a macro that requires a compile-time literal when you're calculating the value at runtime.
    – Barmar
    Nov 12 '18 at 20:05














  • 1




    DOLIST is a macro, you're using that in the dynamic version. So obviously it doesn't prohibit it.
    – Barmar
    Nov 12 '18 at 19:57










  • You should use whichever form produces the clearest code that solves the problem.
    – Barmar
    Nov 12 '18 at 19:58










  • @Barmar true ... but with-open-files prohibits it ... maybe because it takes an argument which is used literally? (e.g. the stream variable?) ...
    – Gwang-Jin Kim
    Nov 12 '18 at 20:01










  • Right. You can't use a macro that requires a compile-time literal when you're calculating the value at runtime.
    – Barmar
    Nov 12 '18 at 20:05








1




1




DOLIST is a macro, you're using that in the dynamic version. So obviously it doesn't prohibit it.
– Barmar
Nov 12 '18 at 19:57




DOLIST is a macro, you're using that in the dynamic version. So obviously it doesn't prohibit it.
– Barmar
Nov 12 '18 at 19:57












You should use whichever form produces the clearest code that solves the problem.
– Barmar
Nov 12 '18 at 19:58




You should use whichever form produces the clearest code that solves the problem.
– Barmar
Nov 12 '18 at 19:58












@Barmar true ... but with-open-files prohibits it ... maybe because it takes an argument which is used literally? (e.g. the stream variable?) ...
– Gwang-Jin Kim
Nov 12 '18 at 20:01




@Barmar true ... but with-open-files prohibits it ... maybe because it takes an argument which is used literally? (e.g. the stream variable?) ...
– Gwang-Jin Kim
Nov 12 '18 at 20:01












Right. You can't use a macro that requires a compile-time literal when you're calculating the value at runtime.
– Barmar
Nov 12 '18 at 20:05




Right. You can't use a macro that requires a compile-time literal when you're calculating the value at runtime.
– Barmar
Nov 12 '18 at 20:05












1 Answer
1






active

oldest

votes


















2














You misunderstood me.



When I said "static" vs "dynamic" I was talking about whether variables bound by the macro are known at compile time ("static") or only at run time ("dynamic").



Generally speaking, one should stick with "static" because it produces more readable code. The only situation when "dynamic" is needed is when creating a DSL ("domain-specific language").



Using "macro in macro" is a completely orthogonal issue.
One can always do that (when done correctly).






share|improve this answer





















  • Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
    – Gwang-Jin Kim
    Nov 12 '18 at 20:36






  • 1




    @Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
    – sds
    Nov 12 '18 at 20:37










  • thanks! And when did you feel "you got it" - did you ever had such a moment?
    – Gwang-Jin Kim
    Nov 12 '18 at 21:02











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
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268823%2fdynamic-macros-in-common-lisp-when-and-how-to-use%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









2














You misunderstood me.



When I said "static" vs "dynamic" I was talking about whether variables bound by the macro are known at compile time ("static") or only at run time ("dynamic").



Generally speaking, one should stick with "static" because it produces more readable code. The only situation when "dynamic" is needed is when creating a DSL ("domain-specific language").



Using "macro in macro" is a completely orthogonal issue.
One can always do that (when done correctly).






share|improve this answer





















  • Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
    – Gwang-Jin Kim
    Nov 12 '18 at 20:36






  • 1




    @Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
    – sds
    Nov 12 '18 at 20:37










  • thanks! And when did you feel "you got it" - did you ever had such a moment?
    – Gwang-Jin Kim
    Nov 12 '18 at 21:02
















2














You misunderstood me.



When I said "static" vs "dynamic" I was talking about whether variables bound by the macro are known at compile time ("static") or only at run time ("dynamic").



Generally speaking, one should stick with "static" because it produces more readable code. The only situation when "dynamic" is needed is when creating a DSL ("domain-specific language").



Using "macro in macro" is a completely orthogonal issue.
One can always do that (when done correctly).






share|improve this answer





















  • Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
    – Gwang-Jin Kim
    Nov 12 '18 at 20:36






  • 1




    @Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
    – sds
    Nov 12 '18 at 20:37










  • thanks! And when did you feel "you got it" - did you ever had such a moment?
    – Gwang-Jin Kim
    Nov 12 '18 at 21:02














2












2








2






You misunderstood me.



When I said "static" vs "dynamic" I was talking about whether variables bound by the macro are known at compile time ("static") or only at run time ("dynamic").



Generally speaking, one should stick with "static" because it produces more readable code. The only situation when "dynamic" is needed is when creating a DSL ("domain-specific language").



Using "macro in macro" is a completely orthogonal issue.
One can always do that (when done correctly).






share|improve this answer












You misunderstood me.



When I said "static" vs "dynamic" I was talking about whether variables bound by the macro are known at compile time ("static") or only at run time ("dynamic").



Generally speaking, one should stick with "static" because it produces more readable code. The only situation when "dynamic" is needed is when creating a DSL ("domain-specific language").



Using "macro in macro" is a completely orthogonal issue.
One can always do that (when done correctly).







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 12 '18 at 20:09









sds

38.7k1493168




38.7k1493168












  • Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
    – Gwang-Jin Kim
    Nov 12 '18 at 20:36






  • 1




    @Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
    – sds
    Nov 12 '18 at 20:37










  • thanks! And when did you feel "you got it" - did you ever had such a moment?
    – Gwang-Jin Kim
    Nov 12 '18 at 21:02


















  • Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
    – Gwang-Jin Kim
    Nov 12 '18 at 20:36






  • 1




    @Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
    – sds
    Nov 12 '18 at 20:37










  • thanks! And when did you feel "you got it" - did you ever had such a moment?
    – Gwang-Jin Kim
    Nov 12 '18 at 21:02
















Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
– Gwang-Jin Kim
Nov 12 '18 at 20:36




Which kind of mistakes do you know of "macro in macro" which are frequently done by beginners, then?
– Gwang-Jin Kim
Nov 12 '18 at 20:36




1




1




@Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
– sds
Nov 12 '18 at 20:37




@Gwang-JinKim: The main mistake is debugging using execution rather than macroexpansion.
– sds
Nov 12 '18 at 20:37












thanks! And when did you feel "you got it" - did you ever had such a moment?
– Gwang-Jin Kim
Nov 12 '18 at 21:02




thanks! And when did you feel "you got it" - did you ever had such a moment?
– Gwang-Jin Kim
Nov 12 '18 at 21:02


















draft saved

draft discarded




















































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.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • 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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53268823%2fdynamic-macros-in-common-lisp-when-and-how-to-use%23new-answer', 'question_page');
}
);

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







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()