* macros and macroexpand @ 2023-08-07 11:03 Heime 2023-08-07 11:46 ` Yuri Khan ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Heime @ 2023-08-07 11:03 UTC (permalink / raw) To: Heime via Users list for the GNU Emacs text editor I have made a macro and know that they are supposed to return expanded code for use. Still I cannot understand the need to call "macroexpand". Should't the macro already perform the expansion ? ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 11:03 macros and macroexpand Heime @ 2023-08-07 11:46 ` Yuri Khan 2023-08-07 12:43 ` Heime 2023-08-07 14:28 ` [External] : " Drew Adams 2023-08-07 18:59 ` Emanuel Berg 2 siblings, 1 reply; 14+ messages in thread From: Yuri Khan @ 2023-08-07 11:46 UTC (permalink / raw) To: Heime; +Cc: Heime via Users list for the GNU Emacs text editor On Mon, 7 Aug 2023 at 18:04, Heime <heimeborgia@protonmail.com> wrote: > I have made a macro and know that they are supposed to return > expanded code for use. Still I cannot understand the need to > call "macroexpand". Should't the macro already perform the > expansion ? You should be posting small examples of code that you’re trying, otherwise, there is high chance people will either misunderstand you or just disregard your questions as ill-posed. ---- When you define a macro, you indeed write the definition similarly to a function that returns expanded code. (defmacro foo (&rest body) `(bar ,@body)) When you evaluate a form that references a macro, Elisp will (1) expand the macro, and (2) evaluate the result of the expansion: (foo 'quux) ⇒ Debugger entered--Lisp error: (void-function bar) On the other hand, calling ‘macroexpand’ on a data representation of that form will just return the expansion result: (macroexpand '(foo 'quux)) ⇒ (bar 'quux) In this example, I did not bother to define ‘bar’, so Elisp assumes it would be a function and complains at evaluation time. But I could further define ‘bar’ as a macro: (defmacro bar (&rest body) `(baz ,@body)) In this case, evaluating the original form shows that Elisp expanded both macros ‘foo’ and ‘bar’, and then tried to call the undefined function ‘baz’: (foo 'quux) ⇒ Debugger entered--Lisp error: (void-function baz) Meanwhile, ‘macroexpand’ still just expands a single level of macros: (macroexpand '(foo 'quux)) ⇒ (bar 'quux) and you can invoke it repeatedly until you get to the fixed point: (macroexpand (macroexpand '(foo 'quux))) ⇒ (baz 'quux) (macroexpand (macroexpand (macroexpand '(foo 'quux)))) ⇒ (baz 'quux) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 11:46 ` Yuri Khan @ 2023-08-07 12:43 ` Heime 2023-08-07 14:22 ` Philip Kaludercic 0 siblings, 1 reply; 14+ messages in thread From: Heime @ 2023-08-07 12:43 UTC (permalink / raw) To: Yuri Khan; +Cc: Heime via Users list for the GNU Emacs text editor Sent with Proton Mail secure email. ------- Original Message ------- On Monday, August 7th, 2023 at 11:46 PM, Yuri Khan <yuri.v.khan@gmail.com> wrote: > On Mon, 7 Aug 2023 at 18:04, Heime heimeborgia@protonmail.com wrote: > > > I have made a macro and know that they are supposed to return > > expanded code for use. Still I cannot understand the need to > > call "macroexpand". Should't the macro already perform the > > expansion ? > > > You should be posting small examples of code that you’re trying, > otherwise, there is high chance people will either misunderstand you > or just disregard your questions as ill-posed. > > ---- > > When you define a macro, you indeed write the definition similarly to > a function that returns expanded code. > > (defmacro foo (&rest body) > `(bar ,@body)) When you evaluate a form that references a macro, Elisp will (1) expand the macro, and (2) evaluate the result of the expansion: (foo 'quux) ⇒ Debugger entered--Lisp error: (void-function bar) On the other hand, calling ‘macroexpand’ on a data representation of that form will just return the expansion result: (macroexpand '(foo 'quux)) ⇒ (bar 'quux) In this example, I did not bother to define ‘bar’, so Elisp assumes it would be a function and complains at evaluation time. But I could further define ‘bar’ as a macro: (defmacro bar (&rest body)` (baz ,@body)) > > In this case, evaluating the original form shows that Elisp expanded > both macros ‘foo’ and ‘bar’, and then tried to call the undefined > function ‘baz’: > > (foo 'quux) > ⇒ Debugger entered--Lisp error: (void-function baz) > > Meanwhile, ‘macroexpand’ still just expands a single level of macros: > > (macroexpand '(foo 'quux)) > ⇒ (bar 'quux) > > and you can invoke it repeatedly until you get to the fixed point: > > (macroexpand (macroexpand '(foo 'quux))) > ⇒ (baz 'quux) > > (macroexpand (macroexpand (macroexpand '(foo 'quux)))) > ⇒ (baz 'quux) Then macroexpand is useful for diagnostics to expand at one level only at a time. Thusly, if I just want to get the expanded code produced by a macro, I can just do pp-to-string upon the object made by a macro. (defmacro adder (mopi mopj) `(+ ,(cl-second mopi) ,(cl-third mopj))) (princ (pp-to-string '(adder (* 3 5) (* 5 7)) )) I would not do (princ (pp-to-string (macroexpand '(adder (* 3 5) (* 5 7))) )) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 12:43 ` Heime @ 2023-08-07 14:22 ` Philip Kaludercic 2023-08-07 18:06 ` Heime 0 siblings, 1 reply; 14+ messages in thread From: Philip Kaludercic @ 2023-08-07 14:22 UTC (permalink / raw) To: Heime; +Cc: Yuri Khan, Heime via Users list for the GNU Emacs text editor Heime <heimeborgia@protonmail.com> writes: > Sent with Proton Mail secure email. > > ------- Original Message ------- > On Monday, August 7th, 2023 at 11:46 PM, Yuri Khan <yuri.v.khan@gmail.com> wrote: > > >> On Mon, 7 Aug 2023 at 18:04, Heime heimeborgia@protonmail.com wrote: >> >> > I have made a macro and know that they are supposed to return >> > expanded code for use. Still I cannot understand the need to >> > call "macroexpand". Should't the macro already perform the >> > expansion ? >> >> >> You should be posting small examples of code that you’re trying, >> otherwise, there is high chance people will either misunderstand you >> or just disregard your questions as ill-posed. >> >> ---- >> >> When you define a macro, you indeed write the definition similarly to >> a function that returns expanded code. >> >> (defmacro foo (&rest body) >> `(bar ,@body)) When you evaluate a form that references a macro, >> Elisp will (1) expand the macro, and (2) evaluate the result of the >> expansion: (foo 'quux) ⇒ Debugger entered--Lisp error: >> (void-function bar) On the other hand, calling ‘macroexpand’ on a >> data representation of that form will just return the expansion >> result: (macroexpand '(foo 'quux)) ⇒ (bar 'quux) In this example, I >> did not bother to define ‘bar’, so Elisp assumes it would be a >> function and complains at evaluation time. But I could further >> define ‘bar’ as a macro: (defmacro bar (&rest body)` (baz ,@body)) >> >> In this case, evaluating the original form shows that Elisp expanded >> both macros ‘foo’ and ‘bar’, and then tried to call the undefined >> function ‘baz’: >> >> (foo 'quux) >> ⇒ Debugger entered--Lisp error: (void-function baz) >> >> Meanwhile, ‘macroexpand’ still just expands a single level of macros: >> >> (macroexpand '(foo 'quux)) >> ⇒ (bar 'quux) >> >> and you can invoke it repeatedly until you get to the fixed point: >> >> (macroexpand (macroexpand '(foo 'quux))) >> ⇒ (baz 'quux) >> >> (macroexpand (macroexpand (macroexpand '(foo 'quux)))) >> ⇒ (baz 'quux) > > Then macroexpand is useful for diagnostics to expand at one level only > at a time. Thusly, if I just want to get the expanded code produced by > a macro, I can just do pp-to-string upon the object made by a macro. > > (defmacro adder (mopi mopj) > `(+ ,(cl-second mopi) ,(cl-third mopj))) > > (princ (pp-to-string '(adder (* 3 5) (* 5 7)) )) ^ don't do this If you quote an expression, it won't be evaluated or macro-expanded any further. You can sort-of think of a macro like a kind of inline function call. The evaluation would go along these lines: (princ (pp-to-string (adder (* 3 5) (* 5 7)))) will be transformed into this at macro-expansion time, and evaluation would do this: (princ (pp-to-string (+ (cl-second '(* 3 5)) (cl-third '(* 5 7))))) (princ (pp-to-string (+ 3 7))) (princ (pp-to-string 10)) (princ "10\n") "10\n" > I would not do > > (princ (pp-to-string (macroexpand '(adder (* 3 5) (* 5 7))) )) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 14:22 ` Philip Kaludercic @ 2023-08-07 18:06 ` Heime 2023-08-07 20:08 ` Philip Kaludercic 0 siblings, 1 reply; 14+ messages in thread From: Heime @ 2023-08-07 18:06 UTC (permalink / raw) To: Philip Kaludercic Cc: Yuri Khan, Heime via Users list for the GNU Emacs text editor Sent with Proton Mail secure email. ------- Original Message ------- On Tuesday, August 8th, 2023 at 2:22 AM, Philip Kaludercic <philipk@posteo.net> wrote: > Heime heimeborgia@protonmail.com writes: > > > Sent with Proton Mail secure email. > > > > ------- Original Message ------- > > On Monday, August 7th, 2023 at 11:46 PM, Yuri Khan yuri.v.khan@gmail.com wrote: > > > > > On Mon, 7 Aug 2023 at 18:04, Heime heimeborgia@protonmail.com wrote: > > > > > > > I have made a macro and know that they are supposed to return > > > > expanded code for use. Still I cannot understand the need to > > > > call "macroexpand". Should't the macro already perform the > > > > expansion ? > > > > > > You should be posting small examples of code that you’re trying, > > > otherwise, there is high chance people will either misunderstand you > > > or just disregard your questions as ill-posed. > > > > > > ---- > > > > > > When you define a macro, you indeed write the definition similarly to > > > a function that returns expanded code. > > > > > > (defmacro foo (&rest body) > > > `(bar ,@body)) When you evaluate a form that references a macro, Elisp will (1) expand the macro, and (2) evaluate the result of the expansion: (foo 'quux) ⇒ Debugger entered--Lisp error: (void-function bar) On the other hand, calling ‘macroexpand’ on a data representation of that form will just return the expansion result: (macroexpand '(foo 'quux)) ⇒ (bar 'quux) In this example, I did not bother to define ‘bar’, so Elisp assumes it would be a function and complains at evaluation time. But I could further define ‘bar’ as a macro: (defmacro bar (&rest body)` (baz ,@body)) > > > > > > In this case, evaluating the original form shows that Elisp expanded > > > both macros ‘foo’ and ‘bar’, and then tried to call the undefined > > > function ‘baz’: > > > > > > (foo 'quux) > > > ⇒ Debugger entered--Lisp error: (void-function baz) > > > > > > Meanwhile, ‘macroexpand’ still just expands a single level of macros: > > > > > > (macroexpand '(foo 'quux)) > > > ⇒ (bar 'quux) > > > > > > and you can invoke it repeatedly until you get to the fixed point: > > > > > > (macroexpand (macroexpand '(foo 'quux))) > > > ⇒ (baz 'quux) > > > > > > (macroexpand (macroexpand (macroexpand '(foo 'quux)))) > > > ⇒ (baz 'quux) > > > > Then macroexpand is useful for diagnostics to expand at one level only > > at a time. Thusly, if I just want to get the expanded code produced by > > a macro, I can just do pp-to-string upon the object made by a macro. > > > > (defmacro adder (mopi mopj) > > `(+ ,(cl-second mopi) ,(cl-third mopj))) > > > > (princ (pp-to-string '(adder (* 3 5) (* 5 7)) )) > > ^ > don't do this > > If you quote an expression, it won't be evaluated or macro-expanded any > further. You can sort-of think of a macro like a kind of inline > function call. The evaluation would go along these lines: > > (princ (pp-to-string (adder (* 3 5) (* 5 7)))) > > will be transformed into this at macro-expansion time, and evaluation > would do this: > > (princ (pp-to-string (+ (cl-second '(* 3 5)) (cl-third '(* 5 7))))) > (princ (pp-to-string (+ 3 7))) > (princ (pp-to-string 10)) > (princ "10\n") > "10\n" What I want to do is print the code made by adder of its final expansion code. Rather than the last evaluation of 10, I want to print (+ 3 7). Can my print command be modified in such a way that the message shows (+ 3 7) ? IT seems that I would need to use macroexpand-all, to get to the final unevaluated sexp. > > I would not do > > > > (princ (pp-to-string (macroexpand '(adder (* 3 5) (* 5 7))) )) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 18:06 ` Heime @ 2023-08-07 20:08 ` Philip Kaludercic 2023-08-07 20:56 ` Heime 0 siblings, 1 reply; 14+ messages in thread From: Philip Kaludercic @ 2023-08-07 20:08 UTC (permalink / raw) To: Heime; +Cc: Yuri Khan, Heime via Users list for the GNU Emacs text editor Heime <heimeborgia@protonmail.com> writes: > Sent with Proton Mail secure email. > > ------- Original Message ------- > On Tuesday, August 8th, 2023 at 2:22 AM, Philip Kaludercic <philipk@posteo.net> wrote: > > >> Heime heimeborgia@protonmail.com writes: >> >> > Sent with Proton Mail secure email. >> > >> > ------- Original Message ------- >> > On Monday, August 7th, 2023 at 11:46 PM, Yuri Khan yuri.v.khan@gmail.com wrote: >> > >> > > On Mon, 7 Aug 2023 at 18:04, Heime heimeborgia@protonmail.com wrote: >> > > >> > > > I have made a macro and know that they are supposed to return >> > > > expanded code for use. Still I cannot understand the need to >> > > > call "macroexpand". Should't the macro already perform the >> > > > expansion ? >> > > >> > > You should be posting small examples of code that you’re trying, >> > > otherwise, there is high chance people will either misunderstand you >> > > or just disregard your questions as ill-posed. >> > > >> > > ---- >> > > >> > > When you define a macro, you indeed write the definition similarly to >> > > a function that returns expanded code. >> > > >> > > (defmacro foo (&rest body) >> > > `(bar ,@body)) When you evaluate a form that references a macro, >> > > Elisp will (1) expand the macro, and (2) evaluate the result of >> > > the expansion: (foo 'quux) ⇒ Debugger entered--Lisp error: >> > > (void-function bar) On the other hand, calling ‘macroexpand’ on >> > > a data representation of that form will just return the >> > > expansion result: (macroexpand '(foo 'quux)) ⇒ (bar 'quux) In >> > > this example, I did not bother to define ‘bar’, so Elisp assumes >> > > it would be a function and complains at evaluation time. But I >> > > could further define ‘bar’ as a macro: (defmacro bar (&rest >> > > body)` (baz ,@body)) >> > > >> > > In this case, evaluating the original form shows that Elisp expanded >> > > both macros ‘foo’ and ‘bar’, and then tried to call the undefined >> > > function ‘baz’: >> > > >> > > (foo 'quux) >> > > ⇒ Debugger entered--Lisp error: (void-function baz) >> > > >> > > Meanwhile, ‘macroexpand’ still just expands a single level of macros: >> > > >> > > (macroexpand '(foo 'quux)) >> > > ⇒ (bar 'quux) >> > > >> > > and you can invoke it repeatedly until you get to the fixed point: >> > > >> > > (macroexpand (macroexpand '(foo 'quux))) >> > > ⇒ (baz 'quux) >> > > >> > > (macroexpand (macroexpand (macroexpand '(foo 'quux)))) >> > > ⇒ (baz 'quux) >> > >> > Then macroexpand is useful for diagnostics to expand at one level only >> > at a time. Thusly, if I just want to get the expanded code produced by >> > a macro, I can just do pp-to-string upon the object made by a macro. >> > >> > (defmacro adder (mopi mopj) >> > `(+ ,(cl-second mopi) ,(cl-third mopj))) >> > >> > (princ (pp-to-string '(adder (* 3 5) (* 5 7)) )) >> >> ^ >> don't do this >> >> If you quote an expression, it won't be evaluated or macro-expanded any >> further. You can sort-of think of a macro like a kind of inline >> function call. The evaluation would go along these lines: >> >> (princ (pp-to-string (adder (* 3 5) (* 5 7)))) >> >> will be transformed into this at macro-expansion time, and evaluation >> would do this: >> >> (princ (pp-to-string (+ (cl-second '(* 3 5)) (cl-third '(* 5 7))))) >> (princ (pp-to-string (+ 3 7))) >> (princ (pp-to-string 10)) >> (princ "10\n") >> "10\n" > > What I want to do is print the code made by adder of its final expansion code. > Rather than the last evaluation of 10, I want to print (+ 3 7). > > Can my print command be modified in such a way that the message shows (+ 3 7) ? > IT seems that I would need to use macroexpand-all, to get to the final unevaluated > sexp. You can modify your macro, to return a quoted expression. (defmacro adder (mopi mopj) `'(+ ,(cl-second mopi) ,(cl-third mopj))) ^ note this This is synonymous with (defmacro adder (mopi mopj) (list 'quote (list '+ (cl-second mopi) (cl-third mopj)))) which makes sense, if you keep in mind that the result of evaluating the macro is what replaces the macro expression in the syntax tree. >> > I would not do >> > >> > (princ (pp-to-string (macroexpand '(adder (* 3 5) (* 5 7))) )) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 20:08 ` Philip Kaludercic @ 2023-08-07 20:56 ` Heime 2023-08-07 22:10 ` Emanuel Berg 2023-08-08 5:57 ` Philip Kaludercic 0 siblings, 2 replies; 14+ messages in thread From: Heime @ 2023-08-07 20:56 UTC (permalink / raw) To: Philip Kaludercic Cc: Yuri Khan, Heime via Users list for the GNU Emacs text editor ------- Original Message ------- On Tuesday, August 8th, 2023 at 8:08 AM, Philip Kaludercic <philipk@posteo.net> wrote: > Heime heimeborgia@protonmail.com writes: > > > Sent with Proton Mail secure email. > > > > ------- Original Message ------- > > On Tuesday, August 8th, 2023 at 2:22 AM, Philip Kaludercic philipk@posteo.net wrote: > > > > > Heime heimeborgia@protonmail.com writes: > > > > > > > Sent with Proton Mail secure email. > > > > > > > > ------- Original Message ------- > > > > On Monday, August 7th, 2023 at 11:46 PM, Yuri Khan yuri.v.khan@gmail.com wrote: > > > > > > > > > On Mon, 7 Aug 2023 at 18:04, Heime heimeborgia@protonmail.com wrote: > > > > > > > > > (defmacro adder (mopi mopj) > > > > `(+ ,(cl-second mopi) ,(cl-third mopj))) > > > > > > > > (princ (pp-to-string '(adder (* 3 5) (* 5 7)) )) > > > > > > ^ > > > don't do this > > > > > > If you quote an expression, it won't be evaluated or macro-expanded any > > > further. You can sort-of think of a macro like a kind of inline > > > function call. The evaluation would go along these lines: > > > > > > (princ (pp-to-string (adder (* 3 5) (* 5 7)))) > > > > > > will be transformed into this at macro-expansion time, and evaluation > > > would do this: > > > > > > (princ (pp-to-string (+ (cl-second '(* 3 5)) (cl-third '(* 5 7))))) > > > (princ (pp-to-string (+ 3 7))) > > > (princ (pp-to-string 10)) > > > (princ "10\n") > > > "10\n" > > > > What I want to do is print the code made by adder of its final expansion code. > > Rather than the last evaluation of 10, I want to print (+ 3 7). > > > > Can my print command be modified in such a way that the message shows (+ 3 7) ? > > IT seems that I would need to use macroexpand-all, to get to the final unevaluated > > sexp. > > > You can modify your macro, to return a quoted expression. > > (defmacro adder (mopi mopj) > `'(+ ,(cl-second mopi) ,(cl-third mopj))) > ^ > note this That means that you do not evaluate the sexp. I see this more of a hack to be able to print the sexp as elisp code, rather than the way a macro will be coded for practical use. Am I right ? What I want to have is a function that is able to print the end sexp result produced by a practically implemented macro, without evaluating the expression. > This is synonymous with > > (defmacro adder (mopi mopj) > (list 'quote (list '+ (cl-second mopi) (cl-third mopj)))) > > which makes sense, if you keep in mind that the result of evaluating the > macro is what replaces the macro expression in the syntax tree. > > > > > I would not do > > > > > > > > (princ (pp-to-string (macroexpand '(adder (* 3 5) (* 5 7))) )) ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 20:56 ` Heime @ 2023-08-07 22:10 ` Emanuel Berg 2023-08-08 20:35 ` Heime 2023-08-08 5:57 ` Philip Kaludercic 1 sibling, 1 reply; 14+ messages in thread From: Emanuel Berg @ 2023-08-07 22:10 UTC (permalink / raw) To: help-gnu-emacs Heime wrote: > What I want to have is a function that is able to print the > end sexp result produced by a practically implemented macro, > without evaluating the expression. Isn't this what `macroexpand' does? -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 22:10 ` Emanuel Berg @ 2023-08-08 20:35 ` Heime 0 siblings, 0 replies; 14+ messages in thread From: Heime @ 2023-08-08 20:35 UTC (permalink / raw) To: Emanuel Berg; +Cc: help-gnu-emacs ------- Original Message ------- On Tuesday, August 8th, 2023 at 10:10 AM, Emanuel Berg <incal@dataswamp.org> wrote: > Heime wrote: > > > What I want to have is a function that is able to print the > > end sexp result produced by a practically implemented macro, > > without evaluating the expression. > > > Isn't this what `macroexpand' does? I think so, it is what could keep the code expansion from evaluating. > -- > underground experts united > https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 20:56 ` Heime 2023-08-07 22:10 ` Emanuel Berg @ 2023-08-08 5:57 ` Philip Kaludercic 1 sibling, 0 replies; 14+ messages in thread From: Philip Kaludercic @ 2023-08-08 5:57 UTC (permalink / raw) To: Heime; +Cc: Yuri Khan, Heime via Users list for the GNU Emacs text editor Heime <heimeborgia@protonmail.com> writes: > ------- Original Message ------- > On Tuesday, August 8th, 2023 at 8:08 AM, Philip Kaludercic <philipk@posteo.net> wrote: > > >> Heime heimeborgia@protonmail.com writes: >> >> > Sent with Proton Mail secure email. >> > >> > ------- Original Message ------- >> > On Tuesday, August 8th, 2023 at 2:22 AM, Philip Kaludercic philipk@posteo.net wrote: >> > >> > > Heime heimeborgia@protonmail.com writes: >> > > >> > > > Sent with Proton Mail secure email. >> > > > >> > > > ------- Original Message ------- >> > > > On Monday, August 7th, 2023 at 11:46 PM, Yuri Khan yuri.v.khan@gmail.com wrote: >> > > > >> > > > > On Mon, 7 Aug 2023 at 18:04, Heime heimeborgia@protonmail.com wrote: >> > > > > > >> > > > (defmacro adder (mopi mopj) >> > > > `(+ ,(cl-second mopi) ,(cl-third mopj))) >> > > > >> > > > (princ (pp-to-string '(adder (* 3 5) (* 5 7)) )) >> > > >> > > ^ >> > > don't do this >> > > >> > > If you quote an expression, it won't be evaluated or macro-expanded any >> > > further. You can sort-of think of a macro like a kind of inline >> > > function call. The evaluation would go along these lines: >> > > >> > > (princ (pp-to-string (adder (* 3 5) (* 5 7)))) >> > > >> > > will be transformed into this at macro-expansion time, and evaluation >> > > would do this: >> > > >> > > (princ (pp-to-string (+ (cl-second '(* 3 5)) (cl-third '(* 5 7))))) >> > > (princ (pp-to-string (+ 3 7))) >> > > (princ (pp-to-string 10)) >> > > (princ "10\n") >> > > "10\n" >> > >> > What I want to do is print the code made by adder of its final expansion code. >> > Rather than the last evaluation of 10, I want to print (+ 3 7). >> > >> > Can my print command be modified in such a way that the message shows (+ 3 7) ? >> > IT seems that I would need to use macroexpand-all, to get to the final unevaluated >> > sexp. >> >> >> You can modify your macro, to return a quoted expression. >> >> (defmacro adder (mopi mopj) >> `'(+ ,(cl-second mopi) ,(cl-third mopj))) >> ^ >> note this > > That means that you do not evaluate the sexp. I see this more of a hack > to be able to print the sexp as elisp code, rather than the way a macro > will be coded for practical use. Am I right ? > > What I want to have is a function that is able to print the end sexp result > produced by a practically implemented macro, without evaluating the expression. In that case, if I understand you correctly (a concrete example might be useful), macroexpand-all is the right approach. >> This is synonymous with >> >> (defmacro adder (mopi mopj) >> (list 'quote (list '+ (cl-second mopi) (cl-third mopj)))) >> >> which makes sense, if you keep in mind that the result of evaluating the >> macro is what replaces the macro expression in the syntax tree. >> >> > > > I would not do >> > > > >> > > > (princ (pp-to-string (macroexpand '(adder (* 3 5) (* 5 7))) )) ^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [External] : macros and macroexpand 2023-08-07 11:03 macros and macroexpand Heime 2023-08-07 11:46 ` Yuri Khan @ 2023-08-07 14:28 ` Drew Adams 2023-08-07 18:22 ` Heime 2023-08-07 19:04 ` Emanuel Berg 2023-08-07 18:59 ` Emanuel Berg 2 siblings, 2 replies; 14+ messages in thread From: Drew Adams @ 2023-08-07 14:28 UTC (permalink / raw) To: Heime, Heime via Users list for the GNU Emacs text editor > I have made a macro and know that they are supposed to return > expanded code for use. Still I cannot understand the need to > call "macroexpand". Should't the macro already perform the > expansion ? This was amply explained in the answers to your question when you posted in to emacs.SE: https://emacs.stackexchange.com/q/78347 ____ In sum (repeating), the Lisp interpreter evaluates sexps, including macro calls. When it evaluates a macro call, it first expands it according to the macro body (which is effectively a sexp-to-sexp pure function, regardless of how it's implemented). This is _rewriting_ code. After expanding the macro call, i.e., replacing it with a different sexp, the interpreter evaluates that sexp (which returns the result of that evaluation). ____ The byte-compiler just _expands_ macro calls, then byte-compiles the expansions. That is, byte-compilation doesn't also _evaluate_ the result of macro expansion. Evaluation is done when the byte-compiled code is evaluated/interpreted. ____ A macro call is a particular kind of sexp, of course: it's a list with a symbol as car, that is, it looks to Lisp like a function call. (There are also symbol macros, which act similarly, but on symbols not lists.) ____ You've been told all of this a few times now. If there's some particular part of it that you don't understand then you should ask only about that part. Instead, your MO is to broadcast the same question multiple times to multiple places. I can understand your wanting to get different opinions, but your understanding (which does progress) isn't reflected in narrower questions. Why is that? ^ permalink raw reply [flat|nested] 14+ messages in thread
* RE: [External] : macros and macroexpand 2023-08-07 14:28 ` [External] : " Drew Adams @ 2023-08-07 18:22 ` Heime 2023-08-07 19:04 ` Emanuel Berg 1 sibling, 0 replies; 14+ messages in thread From: Heime @ 2023-08-07 18:22 UTC (permalink / raw) To: Drew Adams; +Cc: Heime via Users list for the GNU Emacs text editor Sent with Proton Mail secure email. ------- Original Message ------- On Tuesday, August 8th, 2023 at 2:28 AM, Drew Adams <drew.adams@oracle.com> wrote: > > I have made a macro and know that they are supposed to return > > expanded code for use. Still I cannot understand the need to > > call "macroexpand". Should't the macro already perform the > > expansion ? > > > This was amply explained in the answers > to your question when you posted in to > emacs.SE: > > https://emacs.stackexchange.com/q/78347 > ____ > > In sum (repeating), the Lisp interpreter > evaluates sexps, including macro calls. > > When it evaluates a macro call, it first > expands it according to the macro body > (which is effectively a sexp-to-sexp > pure function, regardless of how it's > implemented). This is rewriting code. > > After expanding the macro call, i.e., > replacing it with a different sexp, the > interpreter evaluates that sexp (which > returns the result of that evaluation). > ____ > > The byte-compiler just expands macro > calls, then byte-compiles the expansions. > That is, byte-compilation doesn't also > evaluate the result of macro expansion. > Evaluation is done when the byte-compiled > code is evaluated/interpreted. > ____ > > A macro call is a particular kind of > sexp, of course: it's a list with a > symbol as car, that is, it looks to Lisp > like a function call. (There are also > symbol macros, which act similarly, but > on symbols not lists.) > ____ > > You've been told all of this a few times > now. If there's some particular part of > it that you don't understand then you > should ask only about that part. Instead, > your MO is to broadcast the same question > multiple times to multiple places. I understand your discussion. What I am trying to do is print the last sexp (sexp at last level) produced by a macro. But without evaluating the sexp. I just want the see the command generated by the macro in an emacs-lisp-mode buffer. For this task, our discussion suggests that it becomes necessary to use macroexpand-all. Have a look at the following. (defconst buffer-name "BF") (defun emboss-estring (string &optional bfname) "Show STRING in a temporary buffer." (or bfname (setq bfname buffer-name)) (with-output-to-temp-buffer bfname (princ string) (emacs-lisp-mode))) (defun emboss-object (object &optional bfname) "Show a pretty-printed version of OBJECT in a temporary buffer." (or bfname (setq bfname buffer-name)) (emboss-estring (pp-to-string object) bfname)) (defun emboss-mcode (code &optional bfname) "Same as (emboss-object (macroexpand-all CODE))." (or bfname (setq bfname buffer-name)) (apply 'emboss-object (list (macroexpand-all code) bfname)) ) This means that to get the final sexp from a macro named "adder" I do (emboss-mcode '(adder (* 3 5) (* 5 7))) Philip suggests that I could use (emboss-mcode (adder (* 3 5) (* 5 7))) I would be keen to see what improvements I can do to this aforementioned sexp printing implementation. And also about the capability of simplifying the implementation. > I can understand your wanting to get > different opinions, but your understanding > (which does progress) isn't reflected in > narrower questions. Why is that? I am striving to reflect my progress with the last code implementation provided. ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: [External] : macros and macroexpand 2023-08-07 14:28 ` [External] : " Drew Adams 2023-08-07 18:22 ` Heime @ 2023-08-07 19:04 ` Emanuel Berg 1 sibling, 0 replies; 14+ messages in thread From: Emanuel Berg @ 2023-08-07 19:04 UTC (permalink / raw) To: help-gnu-emacs Drew Adams wrote: > You've been told all of this a few times > now. Yes, but he is like that ... > If there's some particular part of it that you don't > understand then you should ask only about that part. > Instead, your MO is to broadcast the same question multiple > times to multiple places. The more the marrier! -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 14+ messages in thread
* Re: macros and macroexpand 2023-08-07 11:03 macros and macroexpand Heime 2023-08-07 11:46 ` Yuri Khan 2023-08-07 14:28 ` [External] : " Drew Adams @ 2023-08-07 18:59 ` Emanuel Berg 2 siblings, 0 replies; 14+ messages in thread From: Emanuel Berg @ 2023-08-07 18:59 UTC (permalink / raw) To: help-gnu-emacs Heime wrote: > I have made a macro [...] Try to solve the problem without macros first, macros are always going to be more error-prone, and harder to debug. -- underground experts united https://dataswamp.org/~incal ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2023-08-08 20:35 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2023-08-07 11:03 macros and macroexpand Heime 2023-08-07 11:46 ` Yuri Khan 2023-08-07 12:43 ` Heime 2023-08-07 14:22 ` Philip Kaludercic 2023-08-07 18:06 ` Heime 2023-08-07 20:08 ` Philip Kaludercic 2023-08-07 20:56 ` Heime 2023-08-07 22:10 ` Emanuel Berg 2023-08-08 20:35 ` Heime 2023-08-08 5:57 ` Philip Kaludercic 2023-08-07 14:28 ` [External] : " Drew Adams 2023-08-07 18:22 ` Heime 2023-08-07 19:04 ` Emanuel Berg 2023-08-07 18:59 ` Emanuel Berg
Code repositories for project(s) associated with this external index https://git.savannah.gnu.org/cgit/emacs.git https://git.savannah.gnu.org/cgit/emacs/org-mode.git This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.