

Clojure from the ground up: Macros - llambda
http://aphyr.com/posts/305-clojure-from-the-ground-up-macros

======
juliangamble
One of the most powerful uses of Clojure's macro system has been in the
core.async library. This has enabled the construction of a library with
operators similar to Go's Communicating Sequential Processes [Hoare 1978].

What is different about Clojure's implementation is that no changes to the
compiler were required - 'deep walking macros'
([http://blog.fogus.me/2013/07/17/an-introduction-to-deep-
code...](http://blog.fogus.me/2013/07/17/an-introduction-to-deep-code-walking-
macros-with-clojure/)) were used - that actually restructure the code.

The benefit of this in the library is that when a process is blocked, the wait
is converted to data and the thread is freed up and returned to the pool. You
can have multiple processes talking to each other with a thread-pool size of
one. (And still reason about the code in a neat way).

The benefit of this comes in the JavaScript environment, (via ClojureScript)
where you can compile code that you would ordinarily coordinate with threads
using CSP. (With Go-lang style operators)

You can see an example of this on David Nolen's pages here: * 10,000 processes
[http://swannodette.github.io/2013/08/02/100000-processes/](http://swannodette.github.io/2013/08/02/100000-processes/)
* 100,000 updates [http://swannodette.github.io/2013/08/02/100000-dom-
updates/](http://swannodette.github.io/2013/08/02/100000-dom-updates/)

This is the power of macros in Clojure - things that would require a compiler
extension in another language, are a library in Clojure.

~~~
gnaritas
That last sentence should more aptly be "This is the power of macros in a Lisp
- things that would require a compiler extension in another language, are a
library in a Lisp." as all the other Lisp's have the same advantage; Clojure
is not special in this regard.

~~~
cbp
Clojure has other advantages which other lisps and go don't have such as
immutable values and a prevalence of expressions (as opposed to statements),
both of which give core.async certain features that go's implementation lacks.

~~~
carterschonwald
False.

Please go read up on modern scheme. particularly racket lang.

In many respects, Clojure is Racket, but on the JVM rather than native.

~~~
rsanders
Racket is one other good example but he was responding to the "all other
lisps" claim. Racket pretty unusual in many regards, so I think the Dwightian
"False" was unnecessary here. Or anywhere, really.

~~~
brudgers
_Racket is a Scheme:_ _Racket is still a dialect of Lisp and a descendant of
Scheme. The tools developed by PLT will continue to support R5RS, R6RS, the
old mzscheme environment, Typed Scheme, and more. At the same time, instead of
having to say “PLT 's main variant of Scheme,” programmers can now simply say
“Racket” to refer to the specific descendant of Scheme that powers PLT's
languages and libraries._

[http://racket-lang.org/new-name.html](http://racket-lang.org/new-name.html)

~~~
rsanders
Indeed. Now name all the other Lisps and Schemes in wide use that are based on
immutable data structures.

------
jlongster
These articles tend to miss a new development in JavaScript: sweet.js
([http://sweetjs.org/](http://sweetjs.org/)), hygienic macros for JavaScript.
It is essentially scheme's syntax-case/rules completely for JS, and it's done
_really_ well.

~~~
chc
Sweet.js is really cool, but it's not really a new development in JavaScript
per se. It's a preprocessor. You can't actually use it in a JavaScript program
any more than you can use CoffeeScript in a JavaScript program — instead, you
have to write a Sweet.js program and have it create your JavaScript for you.
It's a great addition to the JavaScript ecosystem, though.

------
groovy2shoes
Code-walking macros are very powerful, but there's a performance caveat:

[https://code.google.com/p/chibi-
scheme/issues/detail?id=114#...](https://code.google.com/p/chibi-
scheme/issues/detail?id=114#c3)

For most macros, this won't be an issue. But if you wind up with code-walking
macros than can be nested, you need to be mindful of the nesting or your code
might take a while to compile.

------
film42
Superb set of examples, thank you very much :)

