help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: [External] : Re: Why is defun not executed during load-file?


From: Drew Adams
Subject: RE: [External] : Re: Why is defun not executed during load-file?
Date: Mon, 31 May 2021 23:41:16 +0000

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]