Welcome! Please see the About page for a little more info on how this works.

0 votes
in Syntax and reader by

Read-time evaluation of functions work as expected. For instance, submitting #=(+ 1 1) to the REPL will indeed return 2. However, read-time evaluation forms such as (if true 1 0) will produce an error. The errors reported are not consistent across macros and special forms.

#=(if true 1 0)
;;=> Can't resolve if
#=(let [] nil)
;;=> Wrong number of args (2) passed to: clojure.core/let

Is this expected behavior? Languages like Common Lisp do not produce errors in this scenario--e.g. the code #.(if t 1 0) returns 1.

2 Answers

+2 votes
selected by
Best answer

Read-eval is not a public feature and generally you should not use it. This is a big (and intentional) difference from Common Lisp. It is primarily used internally in some corner cases to read forms that reconstruct Java objects that lack print forms.

Thanks to you and Fogus for quick and straightforward answers! I really wish I could mark two answers as best answers. :)
Marking Alex's answer is better since he used the key phrase "generally you should not use it" :)
+1 vote

Clojure's #= reader form is undocumented and as a result its behavior is defined by how it works. As it stands the implementation is such that it attempts to resolve the first thing in the form to a Var (with some special handling of static methods and constructors). Because if is a special form its symbol does not resolve to a Var. However, even symbols that resolve to macros like let will fail because the EvalReader will attempt to call apply on the resolved Var and because it's a macro it will not work. I think that this would fall into the expected behavior category as the use of #= in Clojure itself is very constrained and falls within the bounds defined by its capability.