Skip to content

athos/syntactic-closure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

39 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

syntactic-closure

syntactic-closure is a Clojure library that provides some facilities to define hygienic macros with syntactic closures. It aims to implement a hygienic macro system interoperable with Clojure's macro system.

For details about syntactic closures, see Syntactic Closures or Chicken Scheme's wiki page.

Note: syntactic-closure is still of alpha quality.

Usage

Add the following to your project.clj dependencies:

[syntactic-closure "0.1.0"]

Use via:

(use 'syntactic-closure.core)

or, for the shorthand, use via:

(use 'syntactic-closure)

About

As on some Scheme implementations, you can define hygienic macros using syntactic closures, like this:

(use 'syntactic-closure.core)

(define-syntax let1 [name init & body]
  (sc-macro-transformer
    (fn [env]
      (quasiquote
        (let [~name ~(make-syntactic-closure env nil init)]
          ~@(map #(make-syntactic-closure env [name] %) body))))))

(let1 x 10 (* x x))

In this case, the input name x is automatically renamed.

(macroexpand '(let1 x 10 (* x x)))
;=> (let* [x403 10] (clojure.core/* x403 x403))

Using syntactic closures, you can also define anaphoric macros.

(define-syntax aif [test then else]
  (sc-macro-transformer
    (fn [env]
      (let [it ~(make-syntactic-closure env nil test)]
        (if it
          ~(make-syntactic-closure env '[it] then)
          ~(make-syntactic-closure env nil else))))))

Since Scheme-like interfaces are somehow verbose, syntactic-closure namespace provides a simple shorthand for them (, though it is subject to change).

(use 'syntactic-closure)

(defsyntax let1 [name init & body]
  (qq (let [~name ~^:? init]
        ~@^{:? name} body)))

(defsyntax aif [test then else]
  (qq (let [it ~^:? test]
        (if it
          ~^{:? 'it} then
          ~^:? else))))

For details about the shorthand, see Shorthand section below.

For more examples, see example code in the /examples directory. Each example includes both verbose and concise versions of code.

Shorthand

syntactic-closure namespace provides qq macro, which is almost the same as quasiquote except that in qq form, the following shorthand can be used.

  • ~^:? foo is equivalent to ~(make-syntactic-closure *env* nil foo)
  • For any symbol id, ~^{:? id} foo is equivalent to ~(make-syntactic-closure *env* [id] foo)
  • For any list of symbols ids, ~^{:? ids} foo is equivalent to ~(make-syntactic-closure *env* ids foo)
  • ~@^:? foo is equivalent to ~@(map (bound-fn [x#] (make-syntactic-closure *env* nil x#)) foo)
  • For any symbol id, ~@^{:? id} foo is equivalent to ~@(map (bound-fn [x#] (make-syntactic-closure *env* [id] x#)) foo)
  • For any list of symbols ids, ~@{:? ids} foo is equivalent to ~@(map (bound-fn [x#] (make-syntactic-closure *env* ids x#)) foo)

Resources

License

Copyright (C) 2012 OHTA Shogo

Distributed under the Eclipse Public License, the same as Clojure.

About

syntactic closures built on top of Clojure's macro system

Resources

Stars

Watchers

Forks

Packages

No packages published