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

+1 vote
in Namespaces and vars by

Clojure core language is small. More advanced syntax tends to be implemented using macros expanding to a handful of core special forms. One of the special symbols is def, used for interning Vars in the current namespace. Yet, there's also intern that does virtually the same thing (bar the choice of ns) and is implemented with a mere function and some interop.

Why does def deserve a special form? Are there use-cases def makes possible that couldn't be achieved with intern and some more interop or macros?

1 Answer

0 votes

defmacro expands to defn which expands to def. So how would that work if def wasn't a special form? Some things have to be known to the compiler for bootstrapping.

Thanks, although I'm not sure if this answer is complete. There's a whole bunch of symbols bootstrapped in RT.java, including macros, like `ns` used at the top of `clojure/core.clj`. I'm sure `def` could get the same treatment.

Or it could be bootstrapped at the top of `clojure/core.clj`, here's my attempt: https://gist.github.com/mszajna/4ff83117f05b94418be21eb28ece4c78

Unless there's anything else special about that symbol, that is - hence the question.
user=> (def f (fn [] f))
user=> (intern *ns* 'h (fn [] h))
Syntax error compiling at (REPL:1:17).
Unable to resolve symbol: h in this context