On Sun, Sep 5, 2010 at 11:56 AM, Yakov Zaytsev <span dir="ltr"><<a href="mailto:zaytsev.yakov@gmail.com">zaytsev.yakov@gmail.com</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br><div><div>(defmacro define-struct-getter (struct package &rest slots)</div><div> (loop for s in slots</div><div> do (let ((acc (intern (concatenate 'string (symbol-name struct) "-" (symbol-name s))))</div>
<div> (sp (intern s package)))</div><div> (eval `(defmacro ,acc (object)</div><div> `(access-slot ,object ',',sp)))))) <br></div></div></blockquote><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div> <br></div></blockquote></div><br>Rather than eval-ing the consed defmacro form at macroexpansion time, which doesn't do the right thing when a DEFINE-STRUCT-GETTER form is in a file being compiled, it would be better to do something like this:<br>
<br>(defmacro define-struct-getter (struct package &rest slots)<br> `(progn<br> ,@(mapcar (lambda (s)<br> (let ((acc (intern (concatenate 'string (symbol-name struct) "-" (symbol-name s))))<br>
(sp (intern s package))<br> `(defmacro ,acc (object)<br> `(access-slot object ',',sp))))<br> slots)))<br><br>As tempting as it is to call EVAL for various purposes, the reality is that correct uses of EVAL are quite rare. In fact, unless you're writing your own read-eval-print loop of some kind, the best rule of thumb is that if you're calling EVAL explicitly, you've made a mistake. I have trouble coming up with any exceptions to this rule other than a REPL.<br>
<br>Also, supplying a package to re-intern the slot names in, while not outright wrong, is an unusual kind of thing to do. Is it that hard to just type the slot names with package prefixes?<br><br>All that said -- if you're using nested backquotes successfully, you're clearly starting to get the hang of macros.<br>
<br>-- Scott<br><br>