From: Stefan Israelsson Tampe <stefan.itampe@gmail.com>
To: guile-devel@gnu.org
Subject: splicing macros
Date: Sat, 26 Jan 2013 14:03:20 +0100 [thread overview]
Message-ID: <5103d30a.6718700a.6306.350b@mx.google.com> (raw)
Hi all,
This is something fun to implement using ck-macros and
local-syntax-value.
The idea is to patch guile's quasisyntax.scm in ice-9 to implement
splicing of macros.
If we assume a reader macro #.code ==> (macro-splicing code), with the
proposed hack I can now write:
(define-syntax-rule (2x x) (x x))
and
(define-syntax 4x
(lambda (x)
(syntax-case x ()
((_ x) #`(#.(2x x) #.(2x x))))))
and
(define-syntax g (lambda (x) #`(#.(4x 1) #.(4x 2))))
$4 = (1 1 1 1 2 2 2 2)
------------------------------------------------------------
I will assume that you are familliar with th ck macro, included in
recent guile releases or else consider looking it up at
http://okmij.org/ftp/Scheme/macros.html
It is now quite natural to use his c-append macro to do do the
transformation:
(a b #.(f x) c d)
-->
(ck () (c-append '(a b) (c-append (ck-it '(f x)) '(c d))))
And assuming that ck-it can dispatch the macro (f x) the appending would
be obvious. The second magic is ck-it, it is defined as
(use-modules (system syntax))
(define-syntax ck-it
(lambda (x)
(syntax-case x (quote)
((_ s (quote f))
(and (identifier? #'f) (eq? (syntax-local-binding #'f) 'macro))
(call-with-values (lambda () (syntax-local-binding #'f))
(lambda (m transformer)
(list #'ck-it #'s (list #'quote (transformer #'f))))))
((_ s (quote (quote x)))
(list #'ck #'s #'(quote x)))
((_ s (quote (f . x)))
(and (identifier? #'f) (eq? (syntax-local-binding #'f) 'macro))
(call-with-values (lambda () (syntax-local-binding #'f))
(lambda (m transformer)
(list #'ck-it #'s (list #'quote (transformer #'(f . x)))))))
((_ s f)
(list #'ck #'s #'f)))))
It will iterativelly apply macros until a non macro sexp is appearing,
To inhibit macro expeansion one need to quote it. This is a bit unclean
because if the macro returns (quote x), x any sexp, it will return x in
stead. A better solution might be to introduce a special inhibit
macro. Also notice how splicing in already spliced syntaxes works as the
example above works. Another thing to note is how we use
syntax-local-binding to search find the macro transformer and use that
in order to make all this work.
Any thoughts? Should we add ck-it to guile's ck.scm? Should we add
splicing macros?
/Stefan
next reply other threads:[~2013-01-26 13:03 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-01-26 13:03 Stefan Israelsson Tampe [this message]
2013-01-27 10:17 ` splicing macros Andy Wingo
2013-01-28 11:27 ` Stefan Israelsson Tampe
2013-02-08 20:53 ` Stefan Israelsson Tampe
2013-04-29 20:46 ` Fwd: " Stefan Israelsson Tampe
2014-03-20 20:32 ` Andy Wingo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5103d30a.6718700a.6306.350b@mx.google.com \
--to=stefan.itampe@gmail.com \
--cc=guile-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).