guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

syntax closures


From: Stefan Israelsson Tampe
Subject: syntax closures
Date: Thu, 17 Jan 2013 21:51:11 +0100

____ FUN with syntax case ____ 

Hi all, I wanted to resurrect the idea of a syntactic closure. I did some thinking and
decided on the following system:

The low level routine is a special macro 'syntax-closure' put in (ice-9 syntax-closure)
The macro has the following ideom

  (syntax-closure closure-object template1 ...)

e.g.

  #`(syntax-closure #,(lambda (x y) (f x 1 y)) #'(+ x z) #'w)

1. Note that we use #, to insert a function object into the syntax _expression_
2. The idea is to capture the syntactic environment in template1 ... and  call the
    closure with the captured syntactic elements and insert the resulting syntax into
.

The code for syntax-closure is simple:

(define-syntax-rule (syntax-closure f x ...)
  (let-syntax ((capture (lambda (stx)
                          (syntax-case stx ()
                            ((_ y (... ...)) 
                             (apply f #'(y (... ...))))))))
    (capture x ...)))

And with this tool we can device a very useful reader extension #_ e.g.

(define (syntax-closure-reader chr port)
  (define (g-loop x)
    (let loop ((x x) (a '()) (g '()) (t '()))
      (match x
        (((and stx ('syntax x)) . l)
         (let ((gen (gensym "template")))
           (loop l (cons gen a) (cons gen g) (cons x t))))
        ((x . l)
         (loop l (cons x a) g t))
        (()
         (values (reverse a) (reverse g) (reverse t))))))
       
  (let ((code (read port)))
    (match code
      ((F X ...)
       (call-with-values (lambda () (g-loop X))
         (lambda (args gensyms template)
           `(syntax-closure 
             (unsyntax (lambda ,gensyms
                         (,F ,@args)))
             ,@template))))
      (_ (error "wrong format in syntax-closure-reader")))))
    
(read-hash-extend #\_ syntax-closure-reader)

And with this we can now do

  (define (g x) x)
  (define-syntax f (lambda (x) #`(let ((x 1)) #_(g #'x))))

leading to

scheme@(guile-user)> f
$2 = 1

The reader extension will be of the form
#_(F a ...)

And all (syntax x) arguments in a ... will be automatically captured from the environment 
e.g. #_ is as #, but with the syntax arguments correctly captured from the surrounding
environment.

With this tool we will get close enough to srfi-72 and that code will not be needed.

I'm I out of the blue here?

The question for me is how to treat this code, as a library of it's own supporting e.g. 
racket and guile and other schemes with the syntax case system, or should we try to make this reader extension as nice as possible and incorporate the code in guile. Is #_ ok? do you have any other suggestion?

Regards
/Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]