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