From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Pascal J. Bourguignon" Newsgroups: gmane.emacs.help Subject: Re: macro-replacement with quotes Date: Sun, 24 Jan 2016 23:54:10 +0100 Organization: Informatimago Message-ID: <87fuxmk2r1.fsf@kuiper.lan.informatimago.com> References: <87mvruk2x1.fsf@kuiper.lan.informatimago.com> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Trace: ger.gmane.org 1453676127 11767 80.91.229.3 (24 Jan 2016 22:55:27 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sun, 24 Jan 2016 22:55:27 +0000 (UTC) To: help-gnu-emacs@gnu.org Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sun Jan 24 23:55:22 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 1aNTZ3-00068f-NL for geh-help-gnu-emacs@m.gmane.org; Sun, 24 Jan 2016 23:55:21 +0100 Original-Received: from localhost ([::1]:33639 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aNTZ3-00050H-2k for geh-help-gnu-emacs@m.gmane.org; Sun, 24 Jan 2016 17:55:21 -0500 Original-Path: usenet.stanford.edu!fu-berlin.de!uni-berlin.de!individual.net!not-for-mail Original-Newsgroups: gnu.emacs.help Original-Lines: 164 Original-X-Trace: individual.net rcr7J6RFrsE9UTuxYTZL3Ak14DZ/D7PXbjYWNjWsdQ9A92QMNz Cancel-Lock: sha1:Zjc5N2JmM2Y2YTI0MmUwMDIwMTE2NmY4OTdiMTc5OGE0ZWI1YjM2Ng== sha1:r/ESWEq07AQvRRblkiJzDCxHIfc= Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwAQMAAABtzGvEAAAABlBMVEUAAAD///+l2Z/dAAAA oElEQVR4nK3OsRHCMAwF0O8YQufUNIQRGIAja9CxSA55AxZgFO4coMgYrEDDQZWPIlNAjwq9 033pbOBPtbXuB6PKNBn5gZkhGa86Z4x2wE67O+06WxGD/HCOGR0deY3f9Ijwwt7rNGNf6Oac l/GuZTF1wFGKiYYHKSFAkjIo1b6sCYS1sVmFhhhahKQssRjRT90ITWUk6vvK3RsPGs+M1RuR mV+hO/VvFAAAAABJRU5ErkJggg== X-Accept-Language: fr, es, en User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) Original-Xref: usenet.stanford.edu gnu.emacs.help:216547 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:108838 Archived-At: "Pascal J. Bourguignon" writes: > phillip.lord@russet.org.uk (Phillip Lord) writes: > >> Is it possible to build a list within a macro which contains backquote, >> quote or comma symbols in it? > > Sure: > > (defmacro m () > `(quote or comma symbols)) > > >> Specifically, I was thinking of building a macro which expands to a >> pcase form, but I need the ` symbol in the expansion. Oops, sorry, I didn't notice it was gnu.emacs.help, and not comp.lang.lisp. Anyways, even if emacs-lisp has a specific implementation of backquote, I would consider it to be better style to stick to the more general Common Lisp advice. sbcl changed it's handling of backquote recently. I wouldn't be surprised if emacs-lisp changed its implementation of backquote some day too. > I assume you mean A ` symbol. There can be a lot of different symbols > named "`", one in each different package: > > (defpackage "A" (:use)) > (defpackage "B" (:use)) > (defpackage "C" (:use)) > > (list 'A::\` 'B::|`| (intern "`" "C") (intern "`" *package*)) > --> (a::\` b::\` c::\` \`) > > >> For example, say I have a list >> >> '(a b c) >> >> which I want to expand to >> >> `(,a ,b ,c) > > This is a problem. > > '(a b c) is read as a list that contains TWO elements: > - the symbol CL:QUOTE > - a list of three elements (A B C). > > The form '(a b c) returns the list of three elements (A B C). > > > On the other hand, what `(,a ,b ,c) is read as a form that is not > specified. It can be any form that when evaluated, returns a sexp of > the same form as for example, the form (list a b c). But it could also > be (list* a (list* b (list* c))) or some other variant. > > You can introspect the form read form the backquote reader macro: > > [pjb@kuiper :0.0 tmp]$ clall '(loop :for item :in (quote `(,a ,b ,c)) :do (print item))' > > > Clozure Common Lisp: > LIST* > A > (LIST* B (LIST C)) > --> NIL > > > CLISP: > SYSTEM::BACKQUOTE > ((SYSTEM::UNQUOTE A) (SYSTEM::UNQUOTE B) (SYSTEM::UNQUOTE C)) > --> NIL > > > CMU Common Lisp: > LISP::BACKQ-LIST > A > B > C > --> NIL > > > ECL: > SI:QUASIQUOTE > ((SI:UNQUOTE A) (SI:UNQUOTE B) (SI:UNQUOTE C)) > --> NIL > > > SBCL: > SB-INT:QUASIQUOTE > (,A ,B ,C) > --> NIL > > Notice that when printing, the implementation may cheat: > > [pjb@kuiper :0.0 tmp]$ clall -r '(quote `(,a ,b ,c))' > > Clozure Common Lisp --> (LIST* A (LIST* B (LIST C))) > CLISP --> `(,A ,B ,C) > CMU Common Lisp --> `(,A ,B ,C) > ECL --> (SI:QUASIQUOTE > ((SI:UNQUOTE A) (SI:UNQUOTE B) > (SI:UNQUOTE C))) > SBCL --> `(,A ,B ,C) > > sbcl is even cheating on the printing of the unquote expressions, since > it prints a comma, instead of printing a standard representation for a > lisp object. On the other hand, the standard representation for the > unquoted objects sbcl has read from the backquote reader macro would > probably something like #; it's probably better > that it uses an implementation specific way to print this implementation > specific kind of objects. > > > Now the question is, given that you are given access to the internal > data structures used by the lisp interpreter or the lisp compiler > instead of a textual form, why do you want to generate a textual form to > be read again, instead of giving directly the data structure you want > the compiler to process??? > > >> Or in full I want to expand something like >> >> (((a) a) >> ((a b) a b) >> ((a b c) a b c)) >> >> into >> >> (pcase x >> (`(,a) a) >> (`(,a ,b) a b) >> (`(,a ,b ,c) a b c)) > > I can't help here without knowing more about your PCASE macro. > From the only example you give, I would assume that it will evaluate the > backquoted expressions. Therefore you can generate it like this: > > (defun gen-pcase (clauses) > (list* 'pcase 'x > (mapcar (lambda (clause) > (list* (cons 'list (first clause)) (rest clause))) > clauses))) > > gen-pcase > '(((a) a) > ((a b) a b) > ((a b c) a b c))) > --> (pcase x > ((list a) a) > ((list a b) a b) > ((list a b c) a b c)) > > Notice that `(,a) is read as an unspecified form that will be equivalent > to (list a), and so on. -- __Pascal Bourguignon__ http://www.informatimago.com/ “The factory of the future will have only two employees, a man and a dog. The man will be there to feed the dog. The dog will be there to keep the man from touching the equipment.” -- Carl Bass CEO Autodesk