Clojure Best Practice: When to use Metadata?
clojure
Solution
Several of the core features of the language depend on metadata:
macros one feature that depends on metadata. A macro is a function with a bit of metadata that causes the function to run at compiletime.
user> (meta #'when)
{:macro true,
:ns #<Namespace clojure.core>,
:name when, :arglists ([test & body]),
:column 1, :added "1.0",
:doc "Evaluates test. If logical true, evaluates body in an implicit do.",
:line 471,
:file "clojure/core.clj"}
Types are another feature of the language that depends on metadata. The type of something is expressed as metadata on that object.
tests also use metadata. when you (or lein) call `run-tests` it looks at the metadata on the functions in each namespace to find the ones that are tests.
There are many more cases ranging from core of the language like types to peripheral things like n-repl/cider displaying the function arguments at the bottom of the screen while you work that use metadata. It is not a design smell to use metadata provided you are not using it to do ugly things of course ;)
Problem
I don't mean this as a subjective question -- I am trying to understand why exactly `with-meta` is in the language. I realize it can be used for many purposes (so can `eval`, but its use outside specific circumstances is a sign of Bad Design). From a design perspective, what unique purpose does Clojure's metadata structure serve? Is it primarily for documentation? Is it sugar? What are some strong applications for `with-meta`/`meta`? In what cases is it a bad idea? Can you give an example of the use of metadata to do something that would be impossible/difficult/tedious without it?