unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
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



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