From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Kevin Rodgers Newsgroups: gmane.emacs.help Subject: Re: defining many similar functions using macros Date: Mon, 04 Oct 2004 09:55:33 -0600 Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Message-ID: <41617275.5000108@yahoo.com> References: NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-Trace: sea.gmane.org 1096905737 27263 80.91.229.6 (4 Oct 2004 16:02:17 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Mon, 4 Oct 2004 16:02:17 +0000 (UTC) Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Mon Oct 04 18:02:13 2004 Return-path: Original-Received: from lists.gnu.org ([199.232.76.165]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1CEVHw-0004Zq-00 for ; Mon, 04 Oct 2004 18:02:13 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CEVOX-0007sU-Jr for geh-help-gnu-emacs@m.gmane.org; Mon, 04 Oct 2004 12:09:01 -0400 Original-Path: shelby.stanford.edu!newsfeed.stanford.edu!news.tele.dk!news.tele.dk!small.news.tele.dk!fu-berlin.de!uni-berlin.de!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 77 Original-X-Trace: news.uni-berlin.de 7+DJzHWu1cM/QWP13g5QTAeztqJdFThwgV9xLyXKaI5ZnOea4= User-Agent: Mozilla/5.0 (X11; U; SunOS i86pc; en-US; rv:0.9.4.1) Gecko/20020406 Netscape6/6.2.2 X-Accept-Language: en-us Original-Xref: shelby.stanford.edu gnu.emacs.help:125687 Original-To: help-gnu-emacs@gnu.org X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: main.gmane.org gmane.emacs.help:21047 X-Report-Spam: http://spam.gmane.org/gmane.emacs.help:21047 Joe Corneli wrote: > I would like to define them all in one go: > > (dolist (elt '("alpha" > "beta" > ...)) > (define-tex-symbol elt)) > > This seems like a good chance to use a macro. My first experiment > along these lines fails however, and I could use some help > re-designing it. > > This macro works on single elements: > > (defmacro define-tex-symbol (name) > `(defun ,(intern (concat "tex-" name)) () > (interactive) > (insert "\\" ,name))) > > E.g. (define-tex-symbol "alpha") ;=> tex-alpha > > But > > (dolist (elt '("alpha" > "beta")) > (define-tex-symbol elt)) [M-x rhetorical] Why is that better than: (define-text-symbol "alpha") (define-text-symbol "beta") > triggers an error: > > Debugger entered--Lisp error: (wrong-type-argument sequencep elt) > concat("tex-" elt) > (intern (concat "tex-" name)) > (list (quote defun) (intern (concat "tex-" name)) nil (quote (interactive)) (list (quote insert) "\\" name)) > ... > > There seem to be some subtleties associated with macro expansion > that I'm missing here. Help would be appreciated. The macro argument NAME is bound to the unevaluated form the macro is called with, e.g. "alpha". If you want to be able to call the macro with some other kind of form that must be evaluated to yield a string, you have to write your macro to take that into account. In Lisp, a macro transforms one expression into another, which is then evaluated. The backquote syntax makes it easy to specify the output expression, and the comma syntax allows you to substitute forms evaluated at compile-time for literal forms. But then the resulting expression still has to be evaluated. A problem arises when you want to generate a call to another macro (e.g. defun) that requires an unevaluated form (i.e. the function name symbol) that you compute dynamically. That's why you have to put the comma before the (intern ...) form: because this is valid (defun tex-alpha ...) but this isn't (defun (intern (concat "tex-" "alpha")) ...) As someone else pointed out, the solution is to use the fset function instead of the macro: (defmacro define-tex-symbol (name) `(fset (intern (concat "tex-" ,name)) (lambda () (interactive) (insert "\\" ,name)))) -- Kevin Rodgers