views:

291

answers:

2

Ninth bullet point in Paul Graham's What Made Lisp Different says,

9. The whole language always available.

There is no real distinction between read-time, compile-time, and runtime. You can compile or run code while reading, read or run code while compiling, and read or compile code at runtime.

Running code at read-time lets users reprogram Lisp's syntax; running code at compile-time is the basis of macros; compiling at runtime is the basis of Lisp's use as an extension language in programs like Emacs; and reading at runtime enables programs to communicate using s-expressions, an idea recently reinvented as XML.

Does this last bullet point hold for Clojure?

+2  A: 

It does hold,

(eval (read-string "(println \"Hello World!!\")"))
Hello World!!
nil

Just like emacs you can have your program configuration in Clojure, one project that I know Clojure for is static which allows you to have your template as a Clojure vector along with arbitrary code which will be executed at read time.

Hamza Yerlikaya
+10  A: 

You can mix runtime and compile-time freely in Clojure, although Common Lisp is still somewhat more flexible here (due to the presence of compiler macros and symbol macros and a fully supported macrolet; Clojure has an advantage in its cool approach to macro hygiene through automagic symbol resolution in syntax-quote). The reader is currently closed, so the free mixing of runtime, compile-time and read-time is not possible1.


1 Except through unsupported clever hacks.

Michał Marczyk
Just to be clear, it is possible in Clojure to `read` code at arbitrary times and then compile and execute it; it is not, however, possible to plug into the reader to execute arbitrary code at read-time, as it is in Common Lisp.
Michał Marczyk
Love the hack. Thanks for the link! :-D
missingfaktor
Clojure can execute arbitrary code at read-time with the `#=` reader macro.
Stuart Sierra
@Stuart Sierra: Thanks for the comment, I should have mentioned that! Still, that's nothing close to a programmable reader, which is what I understand PG's point to be about (you can't use `#=` to "reprogram [Clojure]'s syntax"). Also, it's a terrible safety hazard (and `*read-eval*` being `true` by default seems to me to be rather a misfeature); which is of course a very good reason to want to mention it in contexts like the present one, so thanks again.
Michał Marczyk