ProductPromotion
Logo

Clojure

made by https://0x3d.site

GitHub - brandonbloom/metaclj: Staged compilation for Clojure through environment & special-form aware syntax-quoting.
Staged compilation for Clojure through environment & special-form aware syntax-quoting. - brandonbloom/metaclj
Visit Site

GitHub - brandonbloom/metaclj: Staged compilation for Clojure through environment & special-form aware syntax-quoting.

GitHub - brandonbloom/metaclj: Staged compilation for Clojure through environment & special-form aware syntax-quoting.

Meta-Clojure

Overview

Meta-Clojure provides staged compilation for Clojure. It includes a form of syntax quoting that is aware of both local environments and special-forms. Among other things, this makes many macros easier to write. Perhaps more importantly, it simplifies control over when code gets evaluated or compiled.

Usage

(require '[metaclj.core :refer [defmeta defbn syntax] :as meta])

Meta-Macros

The defmeta form is analogous to defmacro, but is expected to return Syntax objects (forms plus their environments) instead of plain forms.

(defmeta my-if [test then else]
  (syntax (if test then else)))

Note that you don't need to unquote any of the parameters to if, since the syntax form is aware of the meta-macro's environment.

Call-By-Name

Since it's common for macros to have a body that always templates code with a syntax-quoter, the convenience macro defbn provides a way to create "call-by-name" macros:

(defbn my-if [test then else]
  (if test then else))

Both versions of my-if have correct "lazy" behavior: they will only evaluate one arm of the conditional.

Staged Compilation

The meta/do macro will perform meta-quoting on zero or more forms, then evaluate each of them:

(meta/do 1 2 3)
;;=> 3

Combined with unquoting, this enables you to perform arbitrary computation at compile time:

(let [x 2 y 4]
  (meta/do ~(+ x y)))
;;=> 6

Unquoting is syntax aware and provides automatic splicing:

(let [args (syntax 2 4)]
  (meta/do ~(+ args)))
;;=> 6

You can use function expressions to defer computation. Note that the unquoted expression will still be evaluated at compile time:

(let [x 2 y 4]
  (meta/do (fn [] ~(+ x y))))
;=> #<Fn@32b2ad39 user/eval15784$fn__15788>

You can prove this to yourself by using meta/translate, which is a cousin of macroexpand-all:

(let [x 2 y 4]
  (meta/translate (fn [] ~(+ x y))))
=> ((fn* ([] 6)))

Note that the returned value is wrapped in a seq, since Meta-Clojure uniformly supports multiple expressions with implicit splicing:

(let [x (syntax 2 3)]
  (meta/translate 1 x 4))
;=> (1 2 3 4)

Status

  • The comments at the bottom of core.clj and the code in core_test.clj form my testbed.
  • Many known bugs and incomplete behavior.
  • Some special forms not yet supported: case, deftype, and reify.
  • No progress yet on Exotypes
  • Use of clojure.core/eval is unavoidable at the top level, but it could be compiled away for more interior forms.
  • Maybe someday I'll revive EClj and build its compiler on Meta-Clojure.

References

License

Copyright © 2016 Brandon Bloom

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

More Resources
to explore the angular.

mail [email protected] to add your project or resources here 🔥.

Related Articles
to learn about angular.

FAQ's
to learn more about Angular JS.

mail [email protected] to add more queries here 🔍.

More Sites
to check out once you're finished browsing here.

0x3d
https://www.0x3d.site/
0x3d is designed for aggregating information.
NodeJS
https://nodejs.0x3d.site/
NodeJS Online Directory
Cross Platform
https://cross-platform.0x3d.site/
Cross Platform Online Directory
Open Source
https://open-source.0x3d.site/
Open Source Online Directory
Analytics
https://analytics.0x3d.site/
Analytics Online Directory
JavaScript
https://javascript.0x3d.site/
JavaScript Online Directory
GoLang
https://golang.0x3d.site/
GoLang Online Directory
Python
https://python.0x3d.site/
Python Online Directory
Swift
https://swift.0x3d.site/
Swift Online Directory
Rust
https://rust.0x3d.site/
Rust Online Directory
Scala
https://scala.0x3d.site/
Scala Online Directory
Ruby
https://ruby.0x3d.site/
Ruby Online Directory
Clojure
https://clojure.0x3d.site/
Clojure Online Directory
Elixir
https://elixir.0x3d.site/
Elixir Online Directory
Elm
https://elm.0x3d.site/
Elm Online Directory
Lua
https://lua.0x3d.site/
Lua Online Directory
C Programming
https://c-programming.0x3d.site/
C Programming Online Directory
C++ Programming
https://cpp-programming.0x3d.site/
C++ Programming Online Directory
R Programming
https://r-programming.0x3d.site/
R Programming Online Directory
Perl
https://perl.0x3d.site/
Perl Online Directory
Java
https://java.0x3d.site/
Java Online Directory
Kotlin
https://kotlin.0x3d.site/
Kotlin Online Directory
PHP
https://php.0x3d.site/
PHP Online Directory
React JS
https://react.0x3d.site/
React JS Online Directory
Angular
https://angular.0x3d.site/
Angular JS Online Directory