Hugh Lawson hlaw...@gmail.com writes:
To improve my scanty knowledge of elisp, I want to
rewrite a macro as a function.
Macros are functions that accept code as arguments
(without evaluating it), and then use that code to put
together a new program, which is at last executed.
So macros are programs that write programs (macros are
metaprograms). The outcome of the macro invocation
is a function of the dynamically created program, in
turn the result of the code provided as well as the
macro itself.
Compare this to the much simpler model of an ordinary,
static function that just crunches input data and maps
it to the output result!
Macros are hard to understand, read, and write. It is
nothing for beginners, I would say, tho I don't want
to disencourage anyone from doing even difficult
things (unless difficult means climbing K2).
One example where macros can be useful is to create
functions that have a syntax that isn't that of the
programming language below (Elisp in this case). After
it is done, those functions can be used transparently
breaking the rules of the syntax. (So macros provide
for metaprogramming as well!)
As for me,
grep defun **/*.el | wc -l
tells me I've 213 functions. I have only one
defmacro, which I didn't even write. In the same
file, I have a defun which I *did* write, so let me
illustrate:
The function, which isn't the easiest one to read...
(defun show-time-and-date (optional insert)
(interactive P)
(let ((date-script long-date))
(if insert (insert-shell-command date-script)
(with-temp-buffer
(shell-command date-script 1)
(message (buffer-substring (point-min) (1- (point-max)) ))
...is still one thousand times easier to read than
the macro:
(defmacro measure-time (rest body)
Measure and return the running time of the code block.
http://nullprogram.com/blog/2009/05/28/;
(declare (indent defun))
(let ((start (make-symbol start)))
`(let ((,start (float-time)))
,@body
(- (float-time) ,start
(shell-command COMMAND optional OUTPUT-BUFFER
ERROR-BUFFER)
This should be read like this:
1. There is a function called shell-command.
2. shell-command always accepts one argument, which is
referenced as COMMAND in the documentation and
command in the code
3. shell-command may also accept two arguments,
COMMAND and OUTPUT-BUFFER, or three: COMMAND,
OUTPUT-BUFFER, and ERROR-BUFFER
3. I accomplised this with this keyboard macro:
;;look up latin words (fset 'whitaker [?\M-x ?c ?o ?p
?y ?- ?w ?o tab return ?\M-x ?s ?h ?e ?l tab ?- ?c ?o
?m ?m tab return ?l ?a ?t ?i ?n ? ?\C-y return])
Oh, no! KEYBOARD macro! Well, I'll just leave the
above... Perhaps it can be education to some.
(Keyboard macros are poor man's programming, plain
automatization of keystrokes, they don't relate to the
defmacro stuff I wrote about.)
If you get it to work with a keyboard macro, then just
use `C-h k' to get the function names. Put them
together in your functions. Check the documentation
for all the functions - sometimes, there are better
ways in Elisp code, than their keyboard/interactive
counterparts. If you are inpatient, you can use this
command
emacs -batch -f batch-byte-compile source.el
and Emacs will tell you if there are improvements to
be made.
Good luck!
--
underground experts united
___
info-gnus-english mailing list
info-gnus-english@gnu.org
https://lists.gnu.org/mailman/listinfo/info-gnus-english