unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* macro-replacement with quotes
@ 2016-01-24 21:56 Phillip Lord
  2016-01-24 22:26 ` Marcin Borkowski
  0 siblings, 1 reply; 11+ messages in thread
From: Phillip Lord @ 2016-01-24 21:56 UTC (permalink / raw)
  To: help-gnu-emacs



Is it possible to build a list within a macro which contains backquote,
quote or comma symbols in it?

Specifically, I was thinking of building a macro which expands to a
pcase form, but I need the ` symbol in the expansion.

For example, say I have a list

'(a b c)

which I want to expand to

`(,a ,b ,c)

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))



Phil




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-24 21:56 macro-replacement with quotes Phillip Lord
@ 2016-01-24 22:26 ` Marcin Borkowski
  2016-01-25 10:17   ` Phillip Lord
  0 siblings, 1 reply; 11+ messages in thread
From: Marcin Borkowski @ 2016-01-24 22:26 UTC (permalink / raw)
  To: Phillip Lord; +Cc: help-gnu-emacs


On 2016-01-24, at 22:56, Phillip Lord <phillip.lord@russet.org.uk> wrote:

> Is it possible to build a list within a macro which contains backquote,
> quote or comma symbols in it?
>
> Specifically, I was thinking of building a macro which expands to a
> pcase form, but I need the ` symbol in the expansion.

I'm not sure whether this would help (I know next to nothing about
pcase), but would \` and \, suffice for you?

If I do M-: (read) and type `(a ,b), I get (\` (a (\, b))), which seems
to be equivalent to `(a ,b) in terms of `eval'.  Dunno about pcase,
though.

> Phil

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
       [not found] <mailman.2870.1453672579.843.help-gnu-emacs@gnu.org>
@ 2016-01-24 22:45 ` Joost Kremers
  2016-01-24 22:50 ` Pascal J. Bourguignon
  1 sibling, 0 replies; 11+ messages in thread
From: Joost Kremers @ 2016-01-24 22:45 UTC (permalink / raw)
  To: help-gnu-emacs

Phillip Lord wrote:
> Is it possible to build a list within a macro which contains backquote,
> quote or comma symbols in it?
>
> Specifically, I was thinking of building a macro which expands to a
> pcase form, but I need the ` symbol in the expansion.

Aren't ' and ` simply shorthands for the functions `quote' and
`backquote' respectively? (Well, ok, `quote' is a special form and
`backquote' is a macro, but that shouldn't make a difference.) I've
never used a macro to create code that requires a backquote, but I've
often done it with `quote'. Works like a charm.



-- 
Joost Kremers                                   joostkremers@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
       [not found] <mailman.2870.1453672579.843.help-gnu-emacs@gnu.org>
  2016-01-24 22:45 ` Joost Kremers
@ 2016-01-24 22:50 ` Pascal J. Bourguignon
  2016-01-24 22:54   ` Pascal J. Bourguignon
  2016-01-24 23:08   ` Joost Kremers
  1 sibling, 2 replies; 11+ messages in thread
From: Pascal J. Bourguignon @ 2016-01-24 22:50 UTC (permalink / raw)
  To: help-gnu-emacs

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.

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 #<sb-internal:unquote …>; 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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-24 22:50 ` Pascal J. Bourguignon
@ 2016-01-24 22:54   ` Pascal J. Bourguignon
  2016-01-24 23:08   ` Joost Kremers
  1 sibling, 0 replies; 11+ messages in thread
From: Pascal J. Bourguignon @ 2016-01-24 22:54 UTC (permalink / raw)
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> 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 #<sb-internal:unquote …>; 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


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-24 22:50 ` Pascal J. Bourguignon
  2016-01-24 22:54   ` Pascal J. Bourguignon
@ 2016-01-24 23:08   ` Joost Kremers
  2016-01-25 19:52     ` Pascal J. Bourguignon
  1 sibling, 1 reply; 11+ messages in thread
From: Joost Kremers @ 2016-01-24 23:08 UTC (permalink / raw)
  To: help-gnu-emacs

Pascal J. Bourguignon wrote:
> I can't help here without knowing more about your PCASE macro.

(info "(elisp) Pattern matching case statement")


-- 
Joost Kremers                                   joostkremers@fastmail.fm
Selbst in die Unterwelt dringt durch Spalten Licht
EN:SiS(9)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-24 22:26 ` Marcin Borkowski
@ 2016-01-25 10:17   ` Phillip Lord
  2016-01-25 11:10     ` Marcin Borkowski
  0 siblings, 1 reply; 11+ messages in thread
From: Phillip Lord @ 2016-01-25 10:17 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: help-gnu-emacs

Marcin Borkowski <mbork@mbork.pl> writes:

> On 2016-01-24, at 22:56, Phillip Lord <phillip.lord@russet.org.uk> wrote:
>
>> Is it possible to build a list within a macro which contains backquote,
>> quote or comma symbols in it?
>>
>> Specifically, I was thinking of building a macro which expands to a
>> pcase form, but I need the ` symbol in the expansion.
>
> I'm not sure whether this would help (I know next to nothing about
> pcase), but would \` and \, suffice for you?
>
> If I do M-: (read) and type `(a ,b), I get (\` (a (\, b))), which seems
> to be equivalent to `(a ,b) in terms of `eval'.  Dunno about pcase,
> though.
>
>> Phil
>
> Best,


Hmm, yes, you are right. I didn't realise that (\` x) was equivalent to
`x, but this works...

(pcase 10
  ((\` (\, a)) a))

And this...

(defun quote-and-comma-arg (def)
  (list '\` (list (list '\, (car def)))))

(defmacro p-test (def)
  `(pcase 10
     (,(quote-and-comma-arg def)
      ,(car def))))

(p-test (a))

expands to

(pcase 10
  (`(,a)
   a))

which returns "10".

The joy of lisp!



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-25 10:17   ` Phillip Lord
@ 2016-01-25 11:10     ` Marcin Borkowski
  2016-01-25 14:02       ` Phillip Lord
  0 siblings, 1 reply; 11+ messages in thread
From: Marcin Borkowski @ 2016-01-25 11:10 UTC (permalink / raw)
  To: Phillip Lord; +Cc: help-gnu-emacs


On 2016-01-25, at 11:17, Phillip Lord <phillip.lord@russet.org.uk> wrote:

> Marcin Borkowski <mbork@mbork.pl> writes:
>
>> On 2016-01-24, at 22:56, Phillip Lord <phillip.lord@russet.org.uk> wrote:
>>
>>> Is it possible to build a list within a macro which contains backquote,
>>> quote or comma symbols in it?
>>>
>>> Specifically, I was thinking of building a macro which expands to a
>>> pcase form, but I need the ` symbol in the expansion.
>>
>> I'm not sure whether this would help (I know next to nothing about
>> pcase), but would \` and \, suffice for you?
>>
>> If I do M-: (read) and type `(a ,b), I get (\` (a (\, b))), which seems
>> to be equivalent to `(a ,b) in terms of `eval'.  Dunno about pcase,
>> though.
>>
>>> Phil
>>
>> Best,
>
>
> Hmm, yes, you are right. I didn't realise that (\` x) was equivalent to
> `x, but this works...
>
> (pcase 10
>   ((\` (\, a)) a))
>
> And this...
>
> (defun quote-and-comma-arg (def)
>   (list '\` (list (list '\, (car def)))))
>
> (defmacro p-test (def)
>   `(pcase 10
>      (,(quote-and-comma-arg def)
>       ,(car def))))
>
> (p-test (a))
>
> expands to
>
> (pcase 10
>   (`(,a)
>    a))
>
> which returns "10".
>
> The joy of lisp!

Glad that it helped.

It occurred to me now that another way might be to use something like
``(a b), which apparently yields a similar result, but less of a pain to
type.

Best,

-- 
Marcin Borkowski
http://octd.wmi.amu.edu.pl/en/Marcin_Borkowski
Faculty of Mathematics and Computer Science
Adam Mickiewicz University



^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-25 11:10     ` Marcin Borkowski
@ 2016-01-25 14:02       ` Phillip Lord
  2016-01-25 14:35         ` Michael Heerdegen
  0 siblings, 1 reply; 11+ messages in thread
From: Phillip Lord @ 2016-01-25 14:02 UTC (permalink / raw)
  To: Marcin Borkowski; +Cc: help-gnu-emacs


Marcin Borkowski <mbork@mbork.pl> writes:
>
> Glad that it helped.
>
> It occurred to me now that another way might be to use something like
> ``(a b), which apparently yields a similar result, but less of a pain to
> type.
>
> Best,

It's a thought, so I tried this....

(defmacro p-test-2 (var)
  `(pcase 10
     ('`(,var) ,var)))


but this fails because the ' quotes the ` and the list following it. So
you get:

(p-test-2 a)

expands

(pcase 10
  ('`(,var)
   a))

It's all very complicated isn't it?

Phil





^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-25 14:02       ` Phillip Lord
@ 2016-01-25 14:35         ` Michael Heerdegen
  0 siblings, 0 replies; 11+ messages in thread
From: Michael Heerdegen @ 2016-01-25 14:35 UTC (permalink / raw)
  To: help-gnu-emacs

phillip.lord@russet.org.uk (Phillip Lord) writes:

> It's a thought, so I tried this....
>
> (defmacro p-test-2 (var)
>   `(pcase 10
>      ('`(,var) ,var)))
>
>
> but this fails because the ' quotes the ` and the list following it. So
> you get:
>
> (p-test-2 a)
>
> expands
>
> (pcase 10
>   ('`(,var)
>    a))
>
> It's all very complicated isn't it?

It is indeed.

The problem here is that you cant even combine backquote, quote and
unquote like e.g. in macro definitions where you see things like

  ,',var

because the ` in pcase patterns is never expanded by the backquote
macro.

My standard solution to such situations is to use the long forms

 (, thing), (` thing)

and to paste in with , the quoted , or `, so that at the end, you have
what you want (just ` and ,).  That looks like this in your example:

(defmacro p-test-2 (var)
  `(pcase 10
     ((,'\` ((,'\, ,var))) ,var)))

(macroexpand-1 '(p-test-2 a))

==>

(pcase 10
  (`(,a) a))


(hoping this is what you wanted).

I wonder if there is a more elegant solution...


Regards,

Michael.




^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: macro-replacement with quotes
  2016-01-24 23:08   ` Joost Kremers
@ 2016-01-25 19:52     ` Pascal J. Bourguignon
  0 siblings, 0 replies; 11+ messages in thread
From: Pascal J. Bourguignon @ 2016-01-25 19:52 UTC (permalink / raw)
  To: help-gnu-emacs

Joost Kremers <joost.m.kremers@gmail.com> writes:

> Pascal J. Bourguignon wrote:
>> I can't help here without knowing more about your PCASE macro.
>
> (info "(elisp) Pattern matching case statement")

Oh, I see.  They reuse \` and \, and \,@ with a different meaning, as a
pattern.

So indeed, using the forms (\` …)  (\, …) (\,@ …)
in your expansion will do what you want.

-- 
__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


^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-01-25 19:52 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-24 21:56 macro-replacement with quotes Phillip Lord
2016-01-24 22:26 ` Marcin Borkowski
2016-01-25 10:17   ` Phillip Lord
2016-01-25 11:10     ` Marcin Borkowski
2016-01-25 14:02       ` Phillip Lord
2016-01-25 14:35         ` Michael Heerdegen
     [not found] <mailman.2870.1453672579.843.help-gnu-emacs@gnu.org>
2016-01-24 22:45 ` Joost Kremers
2016-01-24 22:50 ` Pascal J. Bourguignon
2016-01-24 22:54   ` Pascal J. Bourguignon
2016-01-24 23:08   ` Joost Kremers
2016-01-25 19:52     ` Pascal J. Bourguignon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).