From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: duthen.mac.01@gmail.com Newsgroups: gmane.emacs.help Subject: Re: Evaluation of macro arguments Date: Fri, 8 Jan 2016 15:13:38 -0800 (PST) Message-ID: <259755f5-ff9a-452f-b5fb-0d7e6061ab09@googlegroups.com> References: <87fuycs35f.fsf@mbork.pl> <87h9irn85y.fsf@kuiper.lan.informatimago.com> <874merstn3.fsf@mbork.pl> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: ger.gmane.org 1452294920 18774 80.91.229.3 (8 Jan 2016 23:15:20 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Fri, 8 Jan 2016 23:15:20 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sat Jan 09 00:15:18 2016 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1aHgFZ-0001W4-9d for geh-help-gnu-emacs@m.gmane.org; Sat, 09 Jan 2016 00:15:17 +0100 Original-Received: from localhost ([::1]:38361 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aHgFY-00016G-Aq for geh-help-gnu-emacs@m.gmane.org; Fri, 08 Jan 2016 18:15:16 -0500 X-Received: by 10.107.169.130 with SMTP id f2mr54639101ioj.10.1452294819226; Fri, 08 Jan 2016 15:13:39 -0800 (PST) X-Received: by 10.50.73.201 with SMTP id n9mr59725igv.9.1452294819198; Fri, 08 Jan 2016 15:13:39 -0800 (PST) Original-Path: usenet.stanford.edu!h5no1813653igh.0!news-out.google.com!f6ni47620igq.0!nntp.google.com!h5no1813649igh.0!postnews.google.com!glegroupsg2000goo.googlegroups.com!not-for-mail Original-Newsgroups: gnu.emacs.help In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: glegroupsg2000goo.googlegroups.com; posting-host=46.20.162.131; posting-account=53aBfAoAAAAUDfozzkyZI3tTzStI93X_ Original-NNTP-Posting-Host: 46.20.162.131 User-Agent: G2/1.0 Injection-Date: Fri, 08 Jan 2016 23:13:39 +0000 Original-Xref: usenet.stanford.edu gnu.emacs.help:216373 X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.14 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 Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:108663 Archived-At: Hello! Le mardi 5 janvier 2016 21:30:52 UTC+1, Marcin Borkowski a =E9crit=A0: > On 2016-01-05, at 20:39, Marcin Borkowski wrote: >=20 > > On 2016-01-05, at 20:22, Pascal J. Bourguignon wrote: > >> > >> (let ((i 0)) > >> (list (range i 'upto (incf i 10)) ; bam! > >> i)) > >> > >> I hope you may debug it well. > OK, technically you win, since I didn't notice that I evaluated `to' > multiple times. Still, this was not what I was asking about - though > thank you for pointing that out to me. It would be rather embarassing > if I missed it. If you plan to use a variable "dir" with a "dynamic" value like this,=20 (range a (if some-test 'upto 'downto) b) you have to "evaluate" "dir" at run time. But if you want to restrict it to a "lexical" symbol, you can do something = like this: (defmacro range (from dir to) (declare (debug (form symbolp form)) (indent 3)) (let ((delta (cond ((eq dir 'upto) 1) ((eq dir 'downto) -1) (t (error "wrong dir: %s" dir))))) `(let ((i ,from) (to ,to) (list (list))) (while (not (=3D i to)) (push i list) (setq i (+ i ,delta))) (nreverse list)))) (defun test () (let ((i 0)) (list (range i upto (incf i 10)) i))) (test) -> ((0 1 2 3 4 5 6 7 8 9) 10) Note that "dir" is checked at expansion time and may generate an error. I have just a couple of remarks concerning macros: * if some variable is to be used more than once inside the body macro, it s= hould be better to link it to a local variable (like "to" and "from" here),= as already seen. * if the body of the macro does not embed any user code, you don't need to = be afraid of variable conflict. You don't need to generate local variables. * you must respect the order of argument "evaluation". For example, this couple of macros seem ok, but... (defmacro range-up (from to) (declare (debug (form form)) (indent 2)) `(let ((i ,from) (to ,to) (list (list))) (while (not (> i to)) (push i list) (incf i)) (nreverse list))) (defmacro range-down (from to) (declare (debug (form form)) (indent 2)) `(nreverse (range-up ,to ,from))) ELISP> (range-up 3 7) (3 4 5 6 7) ELISP> (range-down 7 3) (7 6 5 4 3) ELISP> (let ((i 7)) (range-down i (decf i 4))) (3) HTH jack