unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Drew Adams <drew.adams@oracle.com>
To: Emanuel Berg <moasenwood@zoho.eu>
Cc: "Help-Gnu-Emacs \(help-gnu-emacs@gnu.org\)" <help-gnu-emacs@gnu.org>
Subject: RE: [External] : Re: Why is defun not executed during load-file?
Date: Mon, 31 May 2021 23:41:16 +0000	[thread overview]
Message-ID: <SA2PR10MB4474544E4F0679214B88CE54F33F9@SA2PR10MB4474.namprd10.prod.outlook.com> (raw)
In-Reply-To: <87a6oad81r.fsf@zoho.eu>

> Hm ... interesting. Yeah, maybe we should start do that more?

Dunno what you mean by "do that more".  If you mean use
`defmacro' more or something, then let me be clear that
I'm NOT suggesting that.  I'm not suggesting that people
should define more Lisp macros.

In general, don't define a macro if a function will do
what you want.

I just wanted to point out that I think the supposed
difficulty or bugginess of defining macros is due partly
(largely?) to the fact that we (all of us) write macros
much less often than we write functions.

> But I'm unsure even what is the entry point...

I'm guessing that here you're asking about how to use
a macro to just translate one Lisp sexp to another
(where the first is a list with symbol car).

If so, the answer is to use function `macroexpand'.
(or `macroexpand-1' or `macroexpand-all').  That just
does the first step: it expands an input sexp to its
expansion.  `eval', on the other hand, does both steps:
it expands the input sexp and then it evaluates the
resulting sexp.

(defun bar (x y z)
  (format "%s, %s! Is the answer really %s?" y x z)) 

(defmacro foo (a b) `(bar ,b ,a 42))

(macroexpand '(foo "Hello" 'alpha))
; ==> (bar 'alpha "Hello" 42)

(eval '(foo "Hello" 'alpha)))
; ==> "Hello, alpha! Is the answer really 42?"

> What kind of things or problems could or should you solve
> with macros?

Sexp translation.  One common use is to define control
structures (conditionals etc.), since a macro need not
evaluate all (or any) of its arguments.  Emacs Lisp
(like most Lisps) is not lazy - functions evaluate all
of their args before the function body is invoked.  So
you can't define a conditional such as `my-if' as a
Lisp function.  But you can define it as a macro.

Another common use is to define access functions, e.g.,
provide recognizable, domain-specific names.  E.g.:

(defmacro antenna-frobulator (satellite)
  `(caddr (caar (cddr (cdaar satellite)))))

Defining a domain-specific language is a major use
case for Lisp macros.  Of course, with Emacs Lisp the
resulting language still has Lisp-like syntax to a
large extent.  But with Common Lisp you also have
reader macros, which means you can end up with pretty
much any syntax you want for your DSL.

Most uses of macros are something like these.

Paul Graham describes what Lisp macros are all about,
what they're used for, and how to use them, in several
of his essays, and in his book "On Lisp".  Here's one
such short essay - search for "macro":

http://www.paulgraham.com/avg.html
___

What's a use case of just macro-expanding, i.e., just
translating Lisp sexps, without evaluating the result?

This is not common.  Let me be clear about that.

But as one example, the first non-trivial Lisp program
I wrote did just that.  It essentially used `macrolet'
to define a zillion macros that translated all of the
predefined forms (functions, special forms, macros) of
Franz Lisp to Common Lisp (this was before Franz Inc.
went Common).  (Another part of the code translation
translated predefined global variables.)

The program was used to make a first, automatic, pass
at translating lots of Franz-Lisp code to Common Lisp
for a Lisp/Prolog machine we built.  (This was back
when there were few CL implementations.  A preliminary
implementation of Kyoto CL was all we had.  We were
writing a CL implementation for the Lisp machine.)

Franz then was only dynamically scoped, and CL is
lexically scoped, so exact translation is ultimately
impossible.

But a given sexp translation (e.g. `(apply #+ foobar)'
could sometimes be relatively straightforward.
(Actually, even `+' was not straightforward, as the
type systems were different etc.)

In a simple case, a sexp translation might only mean
changing the order of some arguments.  The two Lisps
had a lot in common, even though they were also very
different.  There were plenty of "faux amis" and such.

More generally, the output would be a sexp with lambda
forms that had doc strings describing correspondences
for functions/macros etc. (the closest correspondences
to be found), args, limitations, etc.

The result of translating a short program could thus
be a large program of approximate code.  The point was
to serve as an aid to humans who had to produce a CL
version of the code.  We translated tons of code this
way.  The translation tool was only that - a tool that
helped people translate code.

You could also use the tool interactively to evaluate
the translation result.  That is, it gave us a way to
to interpret Franz code on the fly using CL, in a
first-pass way.  That helped with testing & debugging.
  




      parent reply	other threads:[~2021-05-31 23:41 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-30 22:48 Why is defun not executed during load-file? Drew Adams
2021-05-30 22:57 ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-31  2:05   ` [External] : " Drew Adams
2021-05-31  2:56     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-31  5:05       ` Drew Adams
2021-05-31 19:20         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-31 19:47           ` Stefan Monnier via Users list for the GNU Emacs text editor
2021-05-31 20:09             ` Marcin Borkowski
2021-06-07  2:19             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-06-07  6:27               ` Jean Louis
2021-06-07 14:18               ` FW: " Drew Adams
2021-06-07 14:41                 ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-31 21:40           ` Example use of macro to minimize and generalize the code Jean Louis
2021-05-31 23:37             ` Michael Heerdegen
2021-05-31 23:59               ` Jean Louis
2021-06-01  0:34                 ` Michael Heerdegen
2021-06-01  0:39                   ` Jean Louis
2021-06-01  0:59                     ` Michael Heerdegen
2021-06-01  1:25                       ` Jean Louis
2021-06-01 14:02                         ` Michael Heerdegen
2021-06-01 16:33                           ` Jean Louis
2021-06-01 16:54                             ` Yuri Khan
2021-06-01 17:24                               ` Jean Louis
2021-06-01 17:57                                 ` Yuri Khan
2021-06-01 18:12                                   ` Jean Louis
2021-05-31 21:45           ` Example use of macro to minimize and generalize the code (2) Jean Louis
2021-05-31 21:48           ` [External] : Re: Why is defun not executed during load-file? Michael Heerdegen
2021-05-31 23:41           ` Drew Adams [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=SA2PR10MB4474544E4F0679214B88CE54F33F9@SA2PR10MB4474.namprd10.prod.outlook.com \
    --to=drew.adams@oracle.com \
    --cc=help-gnu-emacs@gnu.org \
    --cc=moasenwood@zoho.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).