unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* 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: [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: 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: [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: 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

* 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 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 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: 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

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).