Seeking explanation of some clojure special forms and metadata

clojure

Solution

In Clojure, it's common for the internal version of a function (or macro) to end in `*`: the non-* version is the public one that users should call. Sometimes that's a macro that provides custom syntax around the internal function.

An extreme case of this occurs in the Clojure core library, where several forms (`fn*`, `let*`, etc) bottom out as special forms that are understood and implemented in the compiler itself. It's merely a convention that their names end in `*`.

The meta tags you mention at the end are described at http://clojure.org/metadata.

- The `^Type` form is used to provide a type-hint for the type of the next form: this is used to avoid reflection when compiling a Java interop call where the type is ambiguous. More here: http://clojure.org/java_interop#Java%20Interop-Type%20Hints

- The `^:key` form is used to supply a variety of boolean flags - for example `^:dynamic` marks dynamic vars. See http://clojure.org/vars

- The `^:private` form prevents a symbol from being listed in the public symbols for a namespace (although it is still available for lookup and dereferencing as a Var: #'foo. More here: http://clojure.org/special_forms

- The `^{:once true}` is a bit of metadata the compiler can use to avoid retaining an intermediate object for garbage collection (see here for more detail). This is an advanced optimization and something you should rarely worry about.

Problem

I am fairly new to clojure and I am going through various code challenges/exercises, as well as the general APIs. I understand the convention of naming dynamic variables with * at both ends of the symbol `eg: *myvar*` .. I also understand the application of the caret symbol, for example on a dynamic variable `eg: ^:dynamic` .. But I am confused by the convention of sometimes having a symbol/variable end with a *, but not start with a * .. `eg: list*`. The following are some other metadata forms I am finding confusing .. I understand they provide additional information for macros and special forms .. But, when would you use which and how? .. ``` ^Type → ^{:tag Type} ^:key → ^{:key true} ^:private ^{:once true} ``` Any explanations or links with clear explanations would be appreciated.

Original source